Re: gtk3 and fork/exec of non-gtk child




Hi Emmanuele,

Thanks very much for that additional explication, and I think your reasoning on these issues is quite sound. I am being particularly careful about making changes to working code here for two reasons. First, this is mission-critical software running on a research vessel at sea -- if it fails, (i) there will be no programmer on board who can fix it and poor off-ship comms make it virtually impossible for a programmer on shore to fix it either, and (ii) the jaw-dropping daily ship operation costs make failure absolutely unacceptable (and employment-threatening ;-> ). Second, despite the fact that the operating environment for the child processes is complex and unstable (they are communicating with sensors that might euphemistically be described as moderately ephemeral), the original code seems to cope with it quite adequately. Thus, the "ain't broke ---> don't fix" law applies strongly here. The part of the code that IS broken is the Motif, which has become increasingly difficult to maintain (as X11 itself will likely be in a few more years), hence the gtk3 port.

I think that perhaps what I will do is create two versions, one with GSubProcess and one with fork/exec. The former will be used preferentially unless it breaks, at which time the latter can be substituted as a fallback. Given your statement that I don't need to do anything special after forking (like deregister a gtk input handler or anything else related to gtk?), then the following fork-to-exec segment should work, yes?

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

Note that I am still using the original brute force loop to close miscellaneous non-stdio descriptors. Probably one or more of these will be gtk-related, would that be a problem? If so, I would need to be more meticulous on this point, perhaps tracking down all of the parent's other open descriptors and making them close-on-exec like gtk's.

Thanks so much for your help!

Roger

On Sat, 14 Jan 2017, Emmanuele Bassi wrote:

Hi;

On 14 January 2017 at 16:24, rbd <rbd soest hawaii edu> wrote:


However, I am still curious as to whether the fork/exec/SIGCHLDhandler model
of my existing X11/Motif app will or will not work with gtk3. This design
has worked quite well in this particular application for many years and I am
reluctant to change it unless there is a strong argument that it either (i)
no longer works as well as it did because of circumstances peculiar to gtk3
vs. X11/Motif or (ii) is likely to stop working in the near-to-medium future
given current gtk3(/4?) development direction.

If you're not calling any GTK/GDK/X11 functionality in the children,
then you don't need to do anything special after forking. This has
been true for years, and will remain true for the foreseeable future.
The only thing you have to worry about are the usual interactions
between forking and system calls like malloc, or threading primitives.

Instead of GSubprocess, you could even use g_spawn_async() and friends:

 https://developer.gnome.org/glib/stable/glib-Spawning-Processes.html

Which is what GSubprocess uses anyway, though it's harder to set up
and still does not provide everything you may need without having to
reimplement it yourself.

The reason why I'm suggesting you to use the API provided by GLib and
GIO is that it's reliable, well tested, and maintained to take into
account changes in the userspace of modern system. For instance,
GSubprocess uses O_CLOEXEC to avoid leaking file descriptors from
parent to child; it uses a watcher thread to ensure that communication
and Unix signals are handled correctly, race free, and delivered to
the right main context; it controls the environment used to spawn the
child process in a safe way; it allows non-blocking handling of
communication between parent and multiple children.

In short: I would not generally recommend throwing away working code,
but I would strongly suggest using the safest implementation provided
by the platform you're targeting. Old code may be still working, but
does not imply that it's working according to the best practices of
modern systems. If the code in question is as old as you mention,
written for a very different era, then you may end up paying the
technological debt later on.

Ciao,
Emmanuele.


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