Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to to get the pid of a daemon created by a double fork?

I've have a simple means to a daemon via a double fork:

    try:
        child = os.fork()
        if child > 0:
            sys.exit(0)
    except OSError:
        print("fork 1 failed")
        sys.exit(1)
    try:
        child = os.fork()
        if child > 0:
            sys.exit(0)
    except OSError:
        print("fork 2 failed")
        sys.exit(1)
    os.execvp(args[0], args) # what the daemon's supposed to be doing

Or alternatively, this is what I had before, but I suspect that it's not correct:

child = os.fork()
if not child:
    secondchild = os.fork()
    if not secondchild:
        os.execvp(args[0], args)
    else:
        os._exit(0)

I'd like to get back the process id of the daemon in the grandparent process that it gets disconnected from. Is this possible while still using os.fork() and os.execvp() (as opposed to threads, subprocesses, etc.)?

like image 862
false_azure Avatar asked Sep 30 '22 01:09

false_azure


1 Answers

Using os.pipe:

import os
import sys

try:
    r, w = os.pipe()
    print('grandparent {}'.format(os.getpid()))
    child = os.fork()
    if child > 0:
        grandchild_pid = int(os.fdopen(r).readline().strip())
        print('grand child pid: {}'.format(grandchild_pid))
        sys.exit(0)
except OSError:
    print("fork 1 failed")
    sys.exit(1)
try:
    print('parent {}'.format(os.getpid()))
    child = os.fork()
    if child > 0:
        # Pass child (grandchild)'s pid to parent.
        os.write(w, '{}\n'.format(child)) 
        sys.exit(0)
except OSError:
    print("fork 2 failed")
    sys.exit(1)

print('child {}'.format(os.getpid()))

UPDATE

Replace following line:

os.write(w, '{}\n'.format(child))

with:

os.write(w, '{}\n'.format(child).encode())

to make it work in Python 3.x.

like image 152
falsetru Avatar answered Oct 03 '22 03:10

falsetru