4

I probably have a mis-understanding of how Qt's startDetached() works but I am witnessing a problem where I have an application that functions as a remote launcher.

The launcher spawns processes off using startDetached which I thought separates the launcher app completely from the new process. However, something fishy is happening with the ports that the launcher utilizes. It seems the spawned processes are also listening on these same ports, despite the fact that they don't use any network code.

The problem lies when I kill the launcher process, I can't restart it because the spawned processes seem to be still using the port the launcher is attempting to start on.

My question is, what am I doing wrong? Is there a better way for a remote agent to launch processes that don't also attach themselves to ports?

This is in a Linux environment.

EDIT: Qt Bug I ended up employing that bug fix and just recompiled Qt. Seemed to work!

Robb
  • 2,666
  • 4
  • 20
  • 24

1 Answers1

1

According to that bug report, all file and socket descriptors opened by Qt (QFile, QTcpSocket...) are flagged with FD_CLOEXEC to prevent them from being shared with child-processes.

So, if you are opening the sockets without Qt, you should probably do the same.

Edit

I am opening sockets with the ICE framework.

You could:

  • try the loop given in how to set close-on-exec by default, just below the line /* please don't do this */, or
  • insert the first line of the same link in the function createSocket from Ice/cpp/src/Ice/Network.cpp, if you can change ICE source code (and redistribute your changes if you use their GPL license), or
  • use a wrapper process like daemonize to close all the descriptors before running the real child-process.
    Maybe something simpler like the following code might work too (it compiles and runs fine, but I didn't test it with open sockets):

    #include <unistd.h>
    #include <iostream>
    #include <cstring>
    #include <cerrno>
    
    int main(int argc, char**argv)
    {
        // close all descriptors except stdout/stdin/stderr
        int maxfd = sysconf(_SC_OPEN_MAX);
        for(int fd = 3; fd < maxfd; fd++)
            close(fd);
    
        // pass all the program arguments except the wrapper name
        execve(argv[1], &argv[1], environ);
    
        // exec() only returns if an error occurred
        std::cerr << strerror(errno) << std::endl;
        return 1;
    }
    
Community
  • 1
  • 1
alexisdm
  • 29,448
  • 6
  • 64
  • 99