[X2Go-Commits] [x2goclient] 15/18: x2goclient.cpp: don't start the UNIX cleanup helper process right after forking.

git-admin at x2go.org git-admin at x2go.org
Wed Mar 18 06:08:00 CET 2015


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch bugfix/osx
in repository x2goclient.

commit 9aa8c8b086b7d99f73898319a10b8a0538d398f6
Author: Mihai Moldovan <ionic at ionic.de>
Date:   Wed Mar 18 01:04:33 2015 +0100

    x2goclient.cpp: don't start the UNIX cleanup helper process right after forking.
    
    Introduce a new command line option --unixhelper and re-execute the main
    binary with this new option to indicate that the UNIX cleanup helper
    tool is requested. It is necessary to call exec() after fork on
    virtually all operating system, especially on OS X.
---
 debian/changelog   |    5 ++++
 src/x2goclient.cpp |   65 ++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index dc4c7c8..82279c8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -267,6 +267,11 @@ x2goclient (4.0.4.0-0x2go1) UNRELEASED; urgency=low
       and we certainly do not need to fork to force it to succeed. Whether we
       are a process group leader already or become one doesn't matter, if the
       end result is that we are process group leader.
+    - x2goclient.cpp: don't start the UNIX cleanup helper process right after
+      forking, but introduce a new command line option --unixhelper and
+      re-execute the main binary with this new option to indicate that the
+      UNIX cleanup helper tool is requested. It is necessary to call exec()
+      after fork on virtually all operating system, especially on OS X.
 
  -- X2Go Release Manager <git-admin at x2go.org>  Thu, 19 Feb 2015 13:25:28 +0100
 
diff --git a/src/x2goclient.cpp b/src/x2goclient.cpp
index f7f7c81..2aff41f 100644
--- a/src/x2goclient.cpp
+++ b/src/x2goclient.cpp
@@ -22,6 +22,10 @@
 #include <cstring>
 #include <cerrno>
 #include <cstdlib>
+#include <string>
+#include <algorithm>
+#include <cctype>
+#include <vector>
 
 #include "unixhelper.h"
 #include "ongetpass.h"
@@ -38,7 +42,28 @@ int fork_helper (int argc, char **argv) {
   /* Child. */
   if (0 == tmp_pid) {
     /* Starting unixhelper. */
-    return (unixhelper::unix_cleanup ());
+    std::vector<std::string> new_argv;
+    new_argv.push (std::string (argv[0]));
+    new_argv.push ("--unixhelper");
+
+    std::vector<const char *> new_argv_c_str;
+    for (const_iterator it = new_argv.begin (); it != new_argv.end (); ++it) {
+      new_argv_c_str.push ((*it).c_str ());
+    }
+    new_argv_c_str.push ("");
+
+    if (0 != execv (new_argv_c_str.data (), new_argv_c_str.data ())) {
+      std::cerr << "Failed to re-execute process as UNIX cleanup helper tool: " << std::strerror (errno) << "\n"
+                << "Terminating and killing parent." << "\n"
+                << "Please report a bug, refer to this documentation: http://wiki.x2go.org/doku.php/wiki:bugs" << std::endl;
+
+      pid_t parent_pid = getppid ();
+      if (0 != kill (parent_pid, SIGTERM)) {
+        std::cerr << "Failed to kill parent process: " << std::strerror (errno) << std::endl;
+      }
+
+      std::exit (EXIT_FAILURE);
+    }
 
     /* Anything here shall be unreachable. */
   }
@@ -59,15 +84,35 @@ int fork_helper (int argc, char **argv) {
 
 int main (int argc, char **argv) {
 #ifdef Q_OS_UNIX
-  /*
-   * setsid() may succeed and we become a session and process
-   * group leader, or it may fail indicating that we already
-   * are a process group leader. Either way is fine.
-   */
-  setsid ();
-
-  /* We should be process group leader by now. */
-  return (fork_helper (argc, argv));
+  /* Scan program arguments for --unixhelper flag. */
+  bool unix_helper_request = 0;
+  for (int i = 0; i < argc; ++i) {
+    std::string cur_arg (argv[i]);
+
+    /* Make the current argument lowercase. */
+    std::transform (cur_arg.begin (), cur_arg.end (), cur_arg.begin (), std::tolower);
+
+    if ((!cur_arg.empty ()) && (cur_arg.compare ("--unixhelper"))) {
+      unix_helper_request = 1;
+      break;
+    }
+  }
+
+  if (unix_helper_request) {
+    /* We were instructed to start as the UNIX cleanup helper tool. */
+    return (unixhelper::unix_cleanup ());
+  }
+  else {
+    /*
+     * setsid() may succeed and we become a session and process
+     * group leader, or it may fail indicating that we already
+     * are a process group leader. Either way is fine.
+     */
+    setsid ();
+
+    /* We should be process group leader by now. */
+    return (fork_helper (argc, argv));
+  }
 #else /* defined (Q_OS_UNIX) */
   return (wrap_x2go_main (argc, argv));
 #endif /* defined (Q_OS_UNIX) */

--
Alioth's /srv/git/code.x2go.org/x2goclient.git//..//_hooks_/post-receive-email on /srv/git/code.x2go.org/x2goclient.git


More information about the x2go-commits mailing list