C++ exec函数无法从linux守护进程运行

C++ exec函数无法从linux守护进程运行,c++,daemon,shell-exec,C++,Daemon,Shell Exec,我一直在编写一个linux守护进程,它在TCP/IP上侦听请求,并在收到该请求时启动应用程序。我的问题是,当我从命令提示符或IDE(Eclipse3.7)运行这个守护程序时,一切正常,可执行文件启动。但是当我使用 sudo服务启动 它将在套接字上接收请求,但不会启动该可执行文件 下面是我用来对进程进行后台监控的标准代码 ///Linux守护进程相关的东西 /// Create the lock file as the current user int lfp = open( "/var/loc

我一直在编写一个linux守护进程,它在TCP/IP上侦听请求,并在收到该请求时启动应用程序。我的问题是,当我从命令提示符或IDE(Eclipse3.7)运行这个守护程序时,一切正常,可执行文件启动。但是当我使用
sudo服务启动
它将在套接字上接收请求,但不会启动该可执行文件

下面是我用来对进程进行后台监控的标准代码 ///Linux守护进程相关的东西

/// Create the lock file as the current user 
int lfp = open( "/var/lock/subsys/LauncherService", O_RDWR|O_CREAT, 0640);
if ( lfp < 0 ) 
{
    LOG_ERROR ("Unable to open lockfile");
    LOG_ERROR ( strerror(errno) );
}

/// All
/// Our process ID and Session ID
pid_t pid, sid;

/// Fork off the parent process
pid = fork();
if (pid < 0) {
       exit(EXIT_FAILURE);
}

/// If we got a good PID, then
///  we can exit the parent process.
if (pid > 0)
{
    exit(EXIT_SUCCESS);
}

/// Change the file mode mask
umask(0);

/// Create a new SID for the child process
sid = setsid();
if (sid < 0)
{
    LOG_ERROR ("Error Setting sid");
    exit(EXIT_FAILURE);
}
LOG_INFO ("sid set");

/// Change the current working directory
if ( (chdir("/usr/local/<mylocaldir>/bin")) < 0 )
{
       LOG_ERROR ("Error changing Directory");
       exit(EXIT_FAILURE);
}
LOG_INFO ("chdir successful");

/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
///以当前用户身份创建锁文件
int lfp=open(“/var/lock/subsys/LauncherService”,O|RDWR | O|u CREAT,0640);
if(lfp<0)
{
日志错误(“无法打开锁定文件”);
日志错误(strerror(errno));
}
///全部
///我们的进程ID和会话ID
pid_t pid,sid;
///离开父进程
pid=fork();
if(pid<0){
退出(退出失败);
}
///如果我们有一个好的PID,那么
///我们可以退出父进程。
如果(pid>0)
{
退出(退出成功);
}
///更改文件模式掩码
乌马斯克(0);
///为子进程创建新SID
sid=setsid();
如果(sid<0)
{
日志错误(“错误设置sid”);
退出(退出失败);
}
日志信息(“sid集”);
///更改当前工作目录
如果((chdir(“/usr/local//bin”))<0)
{
日志_错误(“更改目录错误”);
退出(退出失败);
}
日志信息(“chdir成功”);
/*关闭标准文件描述符*/
关闭(标准文件号);
关闭(标准文件号);
关闭(标准文件号);
这是一个函数,我在其中启动需要启动的二进制文件。此函数在分叉子进程中调用

std::string configFile = "/usr/local/<mydir>/config/Settings.config";
std::string binary = "<binaryname>";
std::string path ="/usr/local/<mydir>/bin/<binaryname>";

//char *argv[] = { "<binaryname>", "/usr/local/<mydir>/config/Settings.config", (char *)0 };

LOG_INFO("Calling Process" );
if ( execlp( path.c_str(), binary.c_str(), configFile.c_str(), (char *)0 ) == -1 )
//if ( execv("/usr/local/<mydir>/bin/<binaryname>", argv) == -1 )
//if ( execvp("/usr/local/<mydir>/bin/<binaryname>", argv) == -1 )
{
    LOG_ERROR("System call failed !!")
    std::string errString = strerror(errno);
    LOG_ERROR (errString );
}
else
{        
    LOG_INFO("System call successful");
}
std::string configFile=“/usr/local//config/Settings.config”;
std::string binary=“”;
std::string path=“/usr/local//bin/”;
//char*argv[]={“””/usr/local//config/Settings.config“,(char*)0};
日志信息(“呼叫过程”);
if(execlp(path.c_str()、binary.c_str()、configFile.c_str(),(char*)0)==-1)
//如果(execv(“/usr/local//bin/”,argv)=-1)
//如果(execvp(“/usr/local//bin/”,argv)=-1)
{
日志错误(“系统调用失败!!”)
std::string errString=strerror(errno);
日志错误(errString);
}
其他的
{        
日志信息(“系统调用成功”);
}

因此,在与Casey讨论后,我进一步调查了我被调用的程序,发现我的程序确实被调用了。我还发现环境变量并不是子进程从父进程本身获取环境的问题。我正在主程序中创建QApplication(QtGUI应用程序)。这与linux系统守护进程有关。我会设法弄清楚这一点,如果需要的话,我会提出单独的问题

编辑:最终解决方案 这是一个QtGUI应用程序,无法连接到XServer。我不得不接受凯西的建议,并在这篇文章中给出了一些改变


之后,它开始启动。

它记录了什么错误?它没有记录任何东西。我想它只是阻塞了,或者因为当前进程映像被替换了,所以我无法获取任何日志。如果它没有记录错误,那么执行lp就成功了。您应该尝试找出另一个程序无法正常工作的原因。好的,当我从init.d脚本运行此服务时,我设置了某些环境变量,如
LD\u LIBRARY\u PATH
,它们是否仍可用于此子进程?我关心的是,这段代码在IDE或命令行中运行得非常好,但它只在系统服务中不起作用。如果它成功了,那么它至少应该记录成功消息,也就是我没有得到消息。我一直在获取日志,直到“调用进程”如果
exec()
成功,它将永远不会返回:新程序加载到进程中并开始执行。调用程序中的
else
分支是死代码。GUI应用程序?它可能找不到X显示屏。尝试将
DISPLAY=:0
添加到环境中。是的,这是一个GUI应用程序。它在QApplicationConstructor中崩溃,仅使用系统服务。我尝试设置
DISPLAY=:0
,但没有效果。它甚至没有抛出任何异常或信号。好的,我还必须做'xhost+local:在那之后它就可以工作了。