#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# $URL: svn://tengen/forker/trunk/forker/forker.py $

# _include_licence_

import os
import sys

__version__="$Id: forker.py 2896 2006-07-09 10:56:17Z jd $"

def raz_file_descriptor():
    try:
        maxfd = os.sysconf("SC_OPEN_MAX")
    except (AttributeError, ValueError):
        maxfd = 256       # default maximum

    for fd in range(0, maxfd):
        try:
            os.close(fd)
        except OSError:   # ERROR (ignore)
            pass

    # Redirect the standard file descriptors to /dev/null.
    os.open("/dev/null", os.O_RDONLY)     # standard input (0)
    os.open("/dev/null", os.O_RDWR)       # standard output (1)
    os.open("/dev/null", os.O_RDWR)       # standard error (2)

def forker(fonction,*args):
    # first, let's fork
    pid=os.fork()
    if pid==0:
        #we are child
        os.setsid()
        # second fork
        mpid=os.fork()
        if mpid==0:
            # we are the second child
            raz_file_descriptor()
            fonction(*args)
            os._exit(0)
        else:
            # still 1st child
            try:
                os.waitpid(mpid,os.WNOHANG)
            except:
                pass
            os._exit(0)
    else:    
        # we are still there, continue our duty
        try:
            os.waitpid(pid,os.WNOHANG)
        except:
            pass
        return 

if __name__=="__main__":
    import time
    def forked_funct(delay):
        "test fonction: open a file, wait delay second, close the file."
        pid=os.getpid()
        of=open("./test_forker_%s"%pid,"w")
        of.write("Start  %s\n"%time.asctime())
        of.write("waiting %s sec.\n"%delay)
        time.sleep(delay)
        of.write("End    %s\n"%time.asctime())
        of.close()
        return

    forker(forked_funct,10)
    forker(forked_funct,8)
    forker(forked_funct,12)

