Linux fork/exec到同一目录下的应用程序

Dav*_*eer 6 c++ linux qt fork exec

是否有一个exec变体将使用当前的应用程序目录来定位目标程序?

我正在使用C++和Qt来实现"最后沟渠"错误报告系统.使用Google Breakpad,我可以创建一个minidump并将其直接执行到处理程序.因为我的应用程序处于不稳定状态,所以我只想使用最小的依赖项来分叉并启动一个单独的错误处理过程.错误报告应用程序将部署在与应用程序可执行文件相同的目录中.

我对这些forkexec选项并不熟悉,并且找不到exec包含搜索路径中当前应用程序目录的选项.这是我到目前为止:

static bool dumpCallback(const char* /*dump_path*/,
                         const char* /*minidump_id*/,
                         void* /*context*/,
                         bool succeeded)
{
  pid_t pid = fork();
  if (pid == 0)
  {
    // This is what I would *like* to work.
    const char* error_reporter_path = "error_reporter";

    // This works, but requires hard-coding the entire path, which seems lame,
    // and really isn't an option, given our deployment model.
    //
    // const char* error_reporter_path = "/path/to/app/error_reporter";

    // This also works, but I don't like the dependency on QApplication at this
    // point, since the application is unstable.
    //
    // const char* error_reporter_path =
    //     QString("%1/%2")
    //    .arg(QApplication::applicationDirPath())
    //    .arg("error_reporter").toLatin1().constData();

    execlp(error_reporter_path,
           error_reporter_path,
           (char *) 0);
  }
  return succeeded;
}
Run Code Online (Sandbox Code Playgroud)

关于使用最佳做法的任何其他建议,forkexec将受到赞赏; 这是我第一次使用它们.我现在只关心Linux(Ubuntu,Fedora); 我稍后会处理其他操作系统的处理程序.

zwo*_*wol 6

你要求的实际上很容易:

{
  pid_t pid = fork();
  if (pid == 0)
  {
    const char* error_reporter_path = "./error_reporter";
    execl(error_reporter_path,
          error_reporter_path,
          (char *) 0);
    _exit(127);
  }
  else
    return pid != -1;
}
Run Code Online (Sandbox Code Playgroud)

但它没有做你想要的.在当前工作目录并不一定是同样的事情包含当前可执行文件目录 -事实上,在几乎所有的情况下,也不会是.

我建议你做的是创建error_reporter_path一个全局变量,并在开头main使用"选项2"代码初始化它

     QString("%1/%2")
    .arg(QApplication::applicationDirPath())
    .arg("error_reporter").toLatin1().constData();
Run Code Online (Sandbox Code Playgroud)

然后,QString对象(不仅仅是它constData)必须在程序的生命周期中存在,但这应该不是问题.请注意,您应该转换为UTF-8,而不是Latin1(我想QString使用宽字符?)