"fork and exit" needed?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Vincent Delporte

    #1

    "fork and exit" needed?

    Hi

    I'm a Python newbie, and would like to rewrite this Perl scrip
    to be run with the Asterisk PBX:

    NetCID is a free network callerid popup program from Imptec and can be used with an AGI script called from Asterisk for talking callerid notification. NetCID can be downloaded here: NetCID Speech Engine place the following script in...


    Anyone knows if those lines are necessary, why, and what their
    alternative is in Python?

    -------
    open STDOUT, '>/dev/null';
    fork and exit;
    -------

    Thank you.
  • sjdevnull@yahoo.com

    #2
    Re: "fork and exit" needed?

    Vincent Delporte wrote:
    Hi
    >
    I'm a Python newbie, and would like to rewrite this Perl scrip
    to be run with the Asterisk PBX:
    >
    NetCID is a free network callerid popup program from Imptec and can be used with an AGI script called from Asterisk for talking callerid notification. NetCID can be downloaded here: NetCID Speech Engine place the following script in...

    >
    Anyone knows if those lines are necessary, why, and what their
    alternative is in Python?
    open STDOUT, '>/dev/null';
    Either redefine stdout to an open file object for /dev/null or run the
    script as "script.py >/dev/null"
    fork and exit;
    something like:

    if os.fork():
    sys.exit(0)

    Tells the parent to exit after the fork while the child keeps running.
    These are both steps in becoming a daemon (the comp.unix.progr ammer
    FAQ, while skewed toward C, explains why some of these steps are
    needed).

    Comment

    • Marc 'BlackJack' Rintsch

      #3
      Re: "fork and exit" needed?

      In <8osmm21skionil dtnme1j0nvqbla6 oqk72@4ax.com>, Vincent Delporte wrote:
      Anyone knows if those lines are necessary, why, and what their
      alternative is in Python?
      >
      -------
      open STDOUT, '>/dev/null';
      sys.stdout = open(os.devnull , 'w')

      Ciao,
      Marc 'BlackJack' Rintsch

      Comment

      • Nick Craig-Wood

        #4
        Re: &quot;fork and exit&quot; needed?

        Marc 'BlackJack' Rintsch <bj_666@gmx.net wrote:
        In <8osmm21skionil dtnme1j0nvqbla6 oqk72@4ax.com>, Vincent Delporte wrote:
        >
        Anyone knows if those lines are necessary, why, and what their
        alternative is in Python?

        open STDOUT, '>/dev/null';
        >
        sys.stdout = open(os.devnull , 'w')
        This doesn't have the desired effect

        If you run this

        import os,sys,time
        print os.getpid()
        sys.stdout = open(os.devnull , 'w')
        time.sleep(60)

        It prints its pid.

        $ ls -l /proc/32004/fd
        total 4
        lrwx------ 1 ncw ncw 64 Nov 28 09:55 0 -/dev/pts/17
        lrwx------ 1 ncw ncw 64 Nov 28 09:55 1 -/dev/pts/17
        lrwx------ 1 ncw ncw 64 Nov 28 09:55 2 -/dev/pts/17
        l-wx------ 1 ncw ncw 64 Nov 28 09:55 3 -/dev/null

        That quite clearly shows that stdout isn't /dev/null which is required
        for proper deamonisation under unix.

        I'm not sure how you do open stdout to /dev/null in python though!

        I suspect something like this...

        import posix
        posix.close(1)
        posix.open("/dev/null", posix.O_WRONLY)


        --
        Nick Craig-Wood <nick@craig-wood.com-- http://www.craig-wood.com/nick

        Comment

        • Fredrik Lundh

          #5
          Re: &quot;fork and exit&quot; needed?

          Nick Craig-Wood wrote:
          If you run this
          >
          import os,sys,time
          print os.getpid()
          sys.stdout = open(os.devnull , 'w')
          time.sleep(60)
          >
          It prints its pid.
          and not only that, if you run

          print "world",
          print "hello"

          it prints "hello world" in the wrong order!

          </F>

          Comment

          • Nick Craig-Wood

            #6
            Re: &quot;fork and exit&quot; needed?

            Dennis Lee Bieber <wlfraed@ix.net com.comwrote:
            On Tue, 28 Nov 2006 04:30:09 -0600, Nick Craig-Wood
            <nick@craig-wood.comdeclaim ed the following in comp.lang.pytho n:
            >

            If you run this

            import os,sys,time
            print os.getpid()
            sys.stdout = open(os.devnull , 'w')
            time.sleep(60)

            It prints its pid.
            I would hope so, as you performed the print BEFORE reassigning
            stdout...
            That is what I intended. I wanted the pid to look in /proc/<pid>/fd
            to see what file descriptors were really open.
            import os,sys,time
            print "pre:", os.getpid()
            sys.stdout = open(os.devnull , 'w')
            print "post:", os.getpid()
            time.sleep(60)
            >
            (Granted, I'm on WinXP; I also suspect the original stdout is still open
            in the background, maybe dualled with stderr?)
            Yes that is the point - the original stdout is still open.

            I don't think this discussion is relevant to windows though - windows
            has its own way of making daemons.

            --
            Nick Craig-Wood <nick@craig-wood.com-- http://www.craig-wood.com/nick

            Comment

            • Mitja Trampus

              #7
              Re: Really closing stdout (was: &quot;fork and exit&quot; needed?)

              Nick Craig-Wood wrote:
              >>open STDOUT, '>/dev/null';
              > sys.stdout = open(os.devnull , 'w')
              $ ls -l /proc/32004/fd
              total 4
              lrwx------ 1 ncw ncw 64 Nov 28 09:55 0 -/dev/pts/17
              lrwx------ 1 ncw ncw 64 Nov 28 09:55 1 -/dev/pts/17
              lrwx------ 1 ncw ncw 64 Nov 28 09:55 2 -/dev/pts/17
              l-wx------ 1 ncw ncw 64 Nov 28 09:55 3 -/dev/null
              >
              I'm not sure how you do open stdout to /dev/null in python though!
              I suspect something like this...
              import posix
              posix.close(1)
              posix.open("/dev/null", posix.O_WRONLY)
              Yes, you're close enough... The explanations are here:
              http://www.google.com/search?q=python%20close%20stdout,
              I like this one in particular:


              If you explicitly want to leave file descriptors 0-2 present
              (Do you gain anything by not closing them? If you know, do
              tell...), but pointing do /dev/null, you could do:

              null = os.open(os.devn ull,os.O_WRONLY )
              os.dup2(null,0)
              os.dup2(null,1)
              os.dup2(null,2)
              os.close(null)

              Untested.

              More info on file descriptors and python here:


              Mitja

              Comment

              • Vincent Delporte

                #8
                Re: &quot;fork and exit&quot; needed?

                On Tue, 28 Nov 2006 08:30:03 -0600, Nick Craig-Wood
                <nick@craig-wood.comwrote:
                > import os,sys,time
                > print "pre:", os.getpid()
                > sys.stdout = open(os.devnull , 'w')
                > print "post:", os.getpid()
                > time.sleep(60)
                >>
                > (Granted, I'm on WinXP; I also suspect the original stdout is still open
                > in the background, maybe dualled with stderr?)
                >
                >Yes that is the point - the original stdout is still open.
                >
                >I don't think this discussion is relevant to windows though - windows
                >has its own way of making daemons.
                Thanks everyone. I'll see if the Python script runs OK in an Asterisk
                PBX on Linux.

                Comment

                • Nick Craig-Wood

                  #9
                  Re: Really closing stdout (was: &quot;fork and exit&quot; needed?)

                  Mitja Trampus <nun@example.co mwrote:
                  Nick Craig-Wood wrote:
                  I'm not sure how you do open stdout to /dev/null in python though!
                  I suspect something like this...
                  import posix
                  posix.close(1)
                  posix.open("/dev/null", posix.O_WRONLY)
                  >
                  Yes, you're close enough... The explanations are here:
                  http://www.google.com/search?q=python%20close%20stdout,
                  I like this one in particular:

                  >
                  If you explicitly want to leave file descriptors 0-2 present
                  (Do you gain anything by not closing them? If you know, do
                  tell...),
                  It is traditional I think...

                  From the unix FAQ, http://www.erlenstar.demon.co.uk/unix/faq.txt :-

                  6. `close()' fds 0, 1, and 2. This releases the standard in, out, and
                  error we inherited from our parent process. We have no way of knowing
                  where these fds might have been redirected to. Note that many daemons
                  use `sysconf()' to determine the limit `_SC_OPEN_MAX'. `_SC_OPEN_MAX'
                  tells you the maximun open files/process. Then in a loop, the daemon
                  can close all possible file descriptors. You have to decide if you
                  need to do this or not. If you think that there might be
                  file-descriptors open you should close them, since there's a limit on
                  number of concurrent file descriptors.

                  7. Establish new open descriptors for stdin, stdout and stderr. Even if
                  you don't plan to use them, it is still a good idea to have them open.
                  The precise handling of these is a matter of taste; if you have a
                  logfile, for example, you might wish to open it as stdout or stderr,
                  and open `/dev/null' as stdin; alternatively, you could open
                  `/dev/console' as stderr and/or stdout, and `/dev/null' as stdin, or
                  any other combination that makes sense for your particular daemon.
                  but pointing do /dev/null, you could do:
                  >
                  null = os.open(os.devn ull,os.O_WRONLY )
                  os.dup2(null,0)
                  os.dup2(null,1)
                  os.dup2(null,2)
                  os.close(null)
                  >
                  Untested.
                  Ah, dup2() was on the tip of my mind's tongue ;-)

                  You could write it like this, and then it even works on Windows!

                  import os
                  import sys
                  import time
                  print os.getpid()
                  null = os.open(os.devn ull,os.O_RDWR)
                  os.dup2(null, sys.stdin.filen o())
                  os.dup2(null, sys.stdout.file no())
                  os.dup2(null, sys.stderr.file no())
                  os.close(null)
                  print "You won't see this"
                  print >>sys.stderr, "Or this"
                  time.sleep(60)

                  --
                  Nick Craig-Wood <nick@craig-wood.com-- http://www.craig-wood.com/nick

                  Comment

                  • Vincent Delporte

                    #10
                    Re: &quot;fork and exit&quot; needed?

                    On Tue, 28 Nov 2006 04:30:09 -0600, Nick Craig-Wood
                    <nick@craig-wood.comwrote:
                    >I'm not sure how you do open stdout to /dev/null in python though!
                    >
                    >I suspect something like this...
                    >
                    import posix
                    posix.close(1)
                    posix.open("/dev/null", posix.O_WRONLY)
                    Thanks everyone, but no go :-/ Neither the above nor "sys.stdout =
                    open(os.devnull , 'w') " trigger the application.

                    This is a script that is launched by the Asterisk open-source PBX
                    server when a call comes in. Its goal is to broadcast some messages to
                    a Windows caller ID application that is installed on all client hosts
                    so that they know who's calling.

                    Before I go ask in an Asterisk forum, is there some Python-related
                    issue that experienced Python developers can spot in this rewrite of a
                    Perl script that works?

                    Here's the original Perl script:
                    NetCID is a free network callerid popup program from Imptec and can be used with an AGI script called from Asterisk for talking callerid notification. NetCID can be downloaded here: NetCID Speech Engine place the following script in...


                    Here's my Python rewrite:


                    Yes, I changed the UDP port from 42685 to 42687 so that my development
                    client host is the only one getting the broadcast :-)

                    Thank you!

                    Comment

                    • Vincent Delporte

                      #11
                      Re: &quot;fork and exit&quot; needed?

                      On Thu, 30 Nov 2006 15:38:11 +0100, Vincent Delporte <bla@bla.com>
                      wrote:More information. Here's what Asterisk says when I call in:

                      *CLI>

                      -- Executing LookupCIDName(" SIP/fxo-0844e458", "") in new stack

                      -- Changed Caller*ID name to Work

                      -- Executing AGI("SIP/fxo-0844e458",
                      "ncid.python.ag i|087077XXXX|Bu reau Freebox") in new stack

                      -- Launched AGI Script /var/lib/asterisk/agi-bin/ncid.python.agi
                      Failed to execute '/var/lib/asterisk/agi-bin/ncid.python.agi ': Exec
                      format error

                      -- AGI Script ncid.python.agi completed, returning 0

                      FWIW, I wrote the original in a Windows text editor, and copy-pasted
                      the script in Asterisk by sshing into the server. CRLF vs. CR issue?
                      Something else?

                      Thanks.

                      Comment

                      • Vincent Delporte

                        #12
                        Re: &quot;fork and exit&quot; needed?

                        On Thu, 30 Nov 2006 15:48:53 +0100, Vincent Delporte <bla@bla.com>
                        wrote:
                        -- Launched AGI Script /var/lib/asterisk/agi-bin/ncid.python.agi
                        >Failed to execute '/var/lib/asterisk/agi-bin/ncid.python.agi ': Exec
                        >format error
                        Stupid me :-/ Forgot the all-important

                        #!/usr/bin/python

                        Sorry for the disturbance..

                        Comment

                        • Mike C. Fletcher

                          #13
                          Re: &quot;fork and exit&quot; needed?

                          Vincent Delporte wrote:
                          On Thu, 30 Nov 2006 15:38:11 +0100, Vincent Delporte <bla@bla.com>
                          wrote:
                          >
                          First line of your script should be:

                          #! /usr/bin/env python

                          which is how Linux knows what interpreter to use for the script.

                          HTH,
                          Mike

                          --
                          _______________ _______________ _______________ ___
                          Mike C. Fletcher
                          Designer, VR Plumber, Coder



                          Comment

                          • Vincent Delporte

                            #14
                            Re: &quot;fork and exit&quot; needed?

                            On Thu, 30 Nov 2006 10:18:24 -0500, "Mike C. Fletcher"
                            <mcfletch@vrplu mber.comwrote:
                            >which is how Linux knows what interpreter to use for the script.
                            Thanks. That's what I found out after a bit more research. I didn't
                            pay attention to this because it's not needed to run under Windows,
                            and I was focusing on the fork() and stdout thing.

                            Comment

                            Working...