Search code examples
c++socketssocketpair

socketpair() & creating new child processes after close() of worker socket


First off: this is not a Unix/Linux system. I am working on an IBM AS/400 V7R1 (C++ 98) and do not have access to fork(). Nevertheless, I do have spawnp() to start new child processes and the AS/400 supports the notion of process groups.

In my system, I have a "head" program that starts X number of children. This head calls accept() on incoming connections and immediately gives the socket away to one of the child process via sendmsg(). The children are all sitting on recvmsg(). For the head program, it goes something like this:

rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, pair_sd);
if (rc != 0) {
    perror("socketpair() failed");
    close(listen_sd);
    exit(-1);
}
server_sd = pair_sd[0];
worker_sd = pair_sd[1];

// do some other stuff, set up arguments for spawnp()...
// ...

spawn_fdmap[0] = worker_sd;

for (int i = 0; i < numOfChildren; i++) {
    pid = spawnp(spawn_argv[0], 1, spawn_fdmap, &inherit, spawn_argv, spawn_envp);
    if (pid < 0) {
        CERR << "errno=" << errno << ", " << strerror(errno) << endl;
        CERR << "command line [";
        for (int x = 0; spawn_argv[x] != 0; ++x) {
            cerr << spawn_argv[x] << " ";
        }
        cerr << ']' << endl;
        close(listen_sd);
        exit(-1);
    }
    else {
        CERR << "Child worker PID = " << pid << endl;
        child_pids.push_back(pid);
    }
}

// Close down the worker side of the socketpair.
close(worker_sd);

I've got a reason/scheme to start additional child processes after initial program start. I plan to send the head program some signal which would cause the spawnp() call to execute again. The "close(worker_sd)" has me concerned though. Can I call spawnp() again after I've closed the worker socket? It's just a number, after all. Is it OK to keep the worker_sd open?


Solution

  • I think calling socketpair() for every child is unnecessary, and it means having to keep track of additional sockets on the server side. What I found is that removing the close() on 'worker_sd' allows me to create as many additional child processes as I want. Closing it and creating a child process caused the new child to die when it tried to receive something from the parent. I felt this is what would happen, and it did.