Next: , Previous: , Up: posix process fork   [Index]


4.6.2.2 Preparing file descriptors

Function: fork-with-fds parent-proc child-thunk

Wrapper for fork that sets up the file descriptor pipes to communicate with the child process, fork. When successful: return the same return value of fork; otherwise raise the same exception of fork.

The procedure parent-proc is called as follows:

(parent-proc child-pid
             parent->child-stdin
             parent<-child-stdout
             parent<-child-stderr)

where the arguments are the following objects:

child-pid

It is a fixnum representing the pid of the child process.

parent->child-stdin

It is a file descriptor writing into the standard input of the child process.

parent<-child-stdout

It is a file descriptor reading from the standard output of the child process.

parent<-child-stderr

It is a file descriptor reading from the standard error of the child process.

The thunk child-thunk is called with no arguments. The child can use the standard file descriptors 0, 1, 2 which are made distinct from the parent’s standard file descriptors.

Function: after-fork/prepare-child-file-descriptors child-stdin child-stdout child-stderr

To be called in the child process, after a fork operation, to replace the standard file descriptors 0, 1, 2 with the file descriptors child-stdin, child-stdout, child-stderr. When successful: return unspecified values; otherwise raise an exception.

Perform the following operations:

  1. Close the standard file descriptors 0, 1, 2.
  2. Duplicate the file descriptors child-stdin, child-stdout, child-stderr so that they become new standard file descriptors 0, 1, 2.
  3. Close the file descriptors child-stdin, child-stdout, child-stderr.

Notice that:

Here is an example that forks a process, sets up the file descriptors in the child process, waits for child to terminate.

(import (vicare)
  (prefix (vicare posix) px.))

(let-values
    (((child-stdin          parent->child-stdin) (px.pipe))
     ((parent<-child-stdout child-stdout)        (px.pipe))
     ((parent<-child-stderr child-stderr)        (px.pipe)))

  (define (parent-proc child-pid)
    (px.close child-stdin)
    (px.close child-stdout)
    (px.close child-stderr)
    (unwind-protect
        (let ((bufout (make-bytevector 4 0))
              (buferr (make-bytevector 4 0)))
          (px.write parent->child-stdin '#ve(ascii "ciao\n"))
          (let ((status (px.waitpid child-pid 0)))
            (if (and (px.WIFEXITED status)
                     (zero? (px.WEXITSTATUS status)))
                (begin
                  (px.read parent<-child-stdout bufout)
                  (px.read parent<-child-stderr buferr)
                  (values bufout buferr))
              (error #f
                "child process exited abnormally"
                status))))
      (px.close parent->child-stdin)
      (px.close parent<-child-stdout)
      (px.close parent<-child-stderr)))

  (define (child-thunk)
    (guard (E (else
               (print-condition E)
               (exit 1)))
      (px.close parent->child-stdin)
      (px.close parent<-child-stdout)
      (px.close parent<-child-stderr)
      (px.after-fork/prepare-child-file-descriptors
          child-stdin child-stdout child-stderr)
      (let ((buf (make-bytevector 5 0)))
        (px.read 0 buf)
        (assert (bytevector=? buf '#ve(ascii "ciao\n")))
        (px.write 1 '#ve(ascii "out\n"))
        (px.write 2 '#ve(ascii "err\n"))
        (exit 0))))

  (flush-output-port (console-output-port))
  (flush-output-port (console-error-port))
  (px.fork parent-proc child-thunk))

here is the same example using fork-with-fds:

(import (vicare)
  (prefix (vicare posix) px.))

(define (parent-proc child-pid
           parent->child-stdin
           parent<-child-stdout
           parent<-child-stderr)
  (unwind-protect
      (let ((bufout (make-bytevector 4 0))
            (buferr (make-bytevector 4 0)))
        (px.write parent->child-stdin '#ve(ascii "ciao\n"))
        (let ((status (px.waitpid child-pid 0)))
          (if (and (px.WIFEXITED status)
                   (zero? (px.WEXITSTATUS status)))
              (begin
                (px.read parent<-child-stdout bufout)
                (px.read parent<-child-stderr buferr)
                (values bufout buferr))
            (error #f
              "child process exited abnormally"
              status))))
    (px.close parent->child-stdin)
    (px.close parent<-child-stdout)
    (px.close parent<-child-stderr)))

(define (child-thunk)
  (guard (E (else
             (print-condition E)
             (exit 1)))
    (let ((buf (make-bytevector 5 0)))
      (px.read 0 buf)
      (assert (bytevector=? buf '#ve(ascii "ciao\n")))
      (px.write 1 '#ve(ascii "out\n"))
      (px.write 2 '#ve(ascii "err\n"))
      (exit 0))))

(px.fork-with-fds parent-proc child-thunk)

Next: , Previous: , Up: posix process fork   [Index]