gtk3 and fork/exec of non-gtk child




Hi all,

I have a few questions relating to the use of fork/exec within a gtk3 program. Briefly, (i) can this be made to work at all, and (ii) should I perform any specific operations related to disconnecting from gtk within the child process code of my gtk parent in the very brief interval between the fork() and the exec()? Following are details of my situation which I believe is extremely simple, and I want to use the very simplest working solution.

I am porting someone else's old X11/Motif process management GUI to gtk3. It makes extensive use of fork/exec and a SIGCHLD signal handler (which waitpid(.. WNOHANG)s on terminated children) to manage somewhere between 5 and 20 or so child processes. These children do NOT have any GUI and are background data logging processes which read serial and/or network data sources and write reformatted output to serial, network and/or disk destinations. The management GUI is a simple tabular display with one row per child that shows whether each child is running or not and has a clickable button allowing the operator to start/stop/restart that particular child. The manager needs to remain running for time periods as long as 3 months.

Porting this to gtk3 seemed trivial until I started reading these archives yesterday and encountered numerous warnings about using fork/exec with gtk. It's unclear whether or not they apply to me since my child processes will have absolutely no GUI of any kind (not gtk, X11 or anything else) either related to or even completely independent of the gtk GUI running in the manager process. Opinion about this does not seem to be uniform: some people say that fork/exec works just fine if you have a simple scenario, others give dire warnings and recommend more complicated systems of forks within threads, use of various glib spawn/task functions, etc. I do not want to (i) expend more effort than is truly needed, or (ii) unnecessarily burden the code with complexity specific to the needs of gtk/glib that will all have to be unraveled and redone ten years from now when the inevitable next-generation API displaces gtk. (No offense intended, but I've seen this movie a few times. ;-> )

Following is the existing fork-to-exec segment of the child code in the X11/Motif manager. Only a couple things of interest take place here: (i) an Xt input handler process registered at program startup via XtAppAddInput() which was periodically reading some non-X11 file descriptor is deregistered, and (ii) a bunch of other non-stdio file descriptors are closed (presumably including the X11 display socket). The latter was written as a brute force loop that just tries to close everything in sight whether it might have been open or not, even though the manager seems to be opening only a couple of other file descriptors outside of X11.

        pid= fork();
        if (pid == 0) {
                XtRemoveInput(xtinputid);
                for (i= 3; i < 20; i++)
                        (void) close(i);
                execlp("yada", "yada", "yada", 0);
                exit(-1);
        }

Given that I want the gtk/gdk/etc. library code running within my parent manager process to remain ignorant of all children and continue operating as if there were none, my more particular questions with regard to this child process code are:

(1) Do I need to deregister the gtk input handler that I will be substituting for the old Xt input handler?

(2) Do I need to explicitly call any kind of gtk shutdown or main loop exit function or should I very clearly avoid doing so?

(3) Should I do the same kind of brute force file descriptor closedown as the original code? Analogously to X11, I have to think this would close at least one gtk-opened decriptor, which might be something that I should definitely either do or NOT do.

(4) I read one archive reference that said children should always use _exit() rather than exit() in this context. Is that true, and if so does that apply only to the cleanup after a failed execlp() in this fragment or should it be done for all exit instances within the child's own source code as well? This processing system includes dozens of child process programs and doing the latter would be a real pain (and perhaps have other unwanted consequences for the child).

My gut instinct is that given that the exec() will give the child process an essentially clean slate EXCEPT for inheritance of open descriptors, I probably do want to close all non-stdio descriptors one way or another prior to the exec -- the essential question is how to do this in a way that causes no impact whatsoever to the gtk ennvironment of the manager parent.

Thanks!

Roger Davis
Univ. of Hawaii



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]