fork, exec, and disown

Isaac To kkto at
Sun Feb 8 15:22:37 CET 2004

>>>>> "Benoit" == Benoit Dejean <bnet at> writes:

    Benoit> hello, i have a question about forking processes atm, i have
    Benoit> some code which i want to rewrite

    Benoit> os.system("cd ~ && exec " + cmd + " & disown")

    Benoit> i want to remove this os.system call

    Benoit> def fork_exec_disown(cmd, dir="~"):
    Benoit> if os.fork()==0:
    Benoit> os.chdir(os.path.expanduser(dir)) os.setsid() os.umask(0)
    Benoit> if os.fork(): sys.exit(0)
    Benoit> cmd = cmd.split() os.execvp(cmd[0], cmd)
    Benoit> but i am not sure that this have the same behaviour.  is the
    Benoit> second fork needed ? i think so to detach the spawn process i
    Benoit> have found in the os doc, os.setsid, i think i have to use it.

    Benoit> am i going wrong or is this simple

    Benoit> def fork_exec_disown(cmd, dir="~"):
    Benoit> if os.fork()==0: os.chdir(os.path.expanduser(dir)) cmd =
    Benoit> cmd.split() os.execvp(cmd[0], cmd)
    Benoit> a good replacement for my os.system call

You can do that, but if you run ps you'll notice that all you processes get
into a Z (zombie), <defunct> state.  Sooner or later you'll have the fork()
giving you error that "resource temporarily not available" because all
process numbers are used up.  With the "double fork" technique you can avoid
this by adding a wait at the end:

def fork_exec_disown(cmd, dir="~"):
    if os.fork() == 0:
        if os.fork():
        cmd = cmd.split()
        os.execvp(cmd[0], cmd)

The wait will wait only for the child, not the grand-child.  If you don't
have that you'll start accumulating zombies.  In some OS you can avoid the
double forking overhead by manipulating the signal handler of SIGCHLD (so
that it has the flag SA_NOCLDWAIT and has handler SIG_IGN), but that is more
platform dependent than fork().


More information about the Python-list mailing list