Hi,
I'm trying to use CFFI in order to wrap execve (2). The wrapper also uses fork (2) and wait (2). While I have absolutely no problems with execve or fork I'm stumbling on a problem with wait.
Wait takes a pointer to an int to store child process' status. The problem is: after the call to wait the value stored in the pointer is the same as before the call.
I am using CFFI 0.10.5 and GNU CLISP 2.47 on Fedora 13.
The code follows:
(defcfun ("fork" c-fork) :int) (defcfun ("execve" c-execve) :int (filename :string) (args :pointer) (env :pointer)) (defcfun ("wait" c-wait) :int (status :pointer))
(defun execute-program (path argv env) (let ((child-pid (c-fork))) (if (= child-pid -1) (error "Unable to create child process") (if (= child-pid 0) ;; Child (progn ;; Remember: (nth 0 argv) must be the full path to the executable. (let ((c-argv (foreign-alloc :string :initial-contents (append (list path) argv) :null-terminated-p t)) (c-env (foreign-alloc :string :initial-contents env :null-terminated-p t))) (c-execve path c-argv c-env) (foreign-free c-argv) (foreign-free c-env))) ;; Parent code (progn (let ((wait-status (foreign-alloc :int))) (c-wait wait-status) ;; This test condition is a reimplementation of __WIFEXITED macro defined at ;; /usr/include/bits/waitstatus.h (if (= 0 (logand (mem-ref wait-status :int) #x7f)) ;; This test condition is a reimplementation of __WEXITSTATUS macro defined at ;; /usr/include/bits/waitstatus.h (when (/= 0 (ash (logand (mem-ref wait-status :int) #xff00) -8)) (error "Child returned an error")) (error "Failed to execute child process")) (foreign-free wait-status)))))))