diff --git a/cffi-unistd.lisp b/cffi-unistd.lisp
index f573bc4..5edb30e 100644
--- a/cffi-unistd.lisp
+++ b/cffi-unistd.lisp
@@ -348,6 +348,256 @@ without changing the file pointer. Returns number of bytes written."
#+test
(getenv "HOME")
+(defcfun ("execve" c-execve) :int
+ (path :string)
+ (argv (:pointer :string))
+ (envp (:pointer :string)))
+
+(defun execve (path argv envp)
+ (let ((r (c-execve path argv envp)))
+ (if (= -1 r)
+ (error-errno path)
+ (error "execve ~S" path))))
+
+(defcfun ("execv" c-execv) :int
+ (path :string)
+ (argv (:pointer :string)))
+
+(defun execv (path argv)
+ (let ((r (c-execv path argv)))
+ (if (= -1 r)
+ (error-errno path)
+ (error "execv ~S" path))))
+
+(defcfun ("execvp" c-execvp) :int
+ (path :string)
+ (argv (:pointer :string)))
+
+(defun execvp (path argv)
+ (let ((r (c-execvp path argv)))
+ (if (= -1 r)
+ (error-errno path)
+ (error "execv ~S" path))))
+
+(defcfun ("execvpe" c-execvpe) :int
+ (path :string)
+ (argv (:pointer :string))
+ (envp (:pointer :string)))
+
+(defun execvpe (path argv envp)
+ (let ((r (c-execvpe path argv envp)))
+ (if (= -1 r)
+ (error-errno path)
+ (error "execvpe ~S" path))))
+
+(defcfun ("nice" c-nice) :int
+ (inc :int))
+
+(defun nice (inc)
+ (setf errno 0)
+ (let ((r (c-nice inc)))
+ (unless (= 0 errno)
+ (error-errno "nice"))
+ r))
+
+(defcfun ("_exit" c-_exit) :void
+ (status :int))
+
+(defun _exit (status)
+ (c-_exit status))
+
+(defcfun ("pathconf" c-pathconf) :long
+ (path :string)
+ (name :int))
+
+(defun pathconf (path name)
+ (c-pathconf path name))
+
+(defcfun ("sysconf" c-sysconf) :long
+ (name :int))
+
+(defun sysconf (name)
+ (c-sysconf name))
+
+(defcfun ("getpid" c-getpid) pid-t)
+
+(defun getpid ()
+ (c-getpid))
+
+(defcfun ("getppid" c-getppid) pid-t)
+
+(defun getppid ()
+ (c-getppid))
+
+(defcfun ("getpgrp" c-getpgrp) pid-t)
+
+(defun getpgrp ()
+ (c-getpgrp))
+
+(defcfun ("getpgid" c-getpgid) pid-t)
+
+(defun getpgid ()
+ (c-getpgid))
+
+(defcfun ("setpgid" c-setpgid) pid-t)
+
+(defun setpgid ()
+ (c-setpgid))
+
+(defcfun ("setpgrp" c-setpgrp) :int)
+
+(defun setpgrp ()
+ (c-setpgrp))
+
+(defcfun ("setsid" c-setsid) pid-t)
+
+(defun setsid ()
+ (c-setsid))
+
+(defcfun ("getsid" c-getsid) pid-t
+ (pid pid-t))
+
+(defun getsid (pid)
+ (c-getsid pid))
+
+(defcfun ("getuid" c-getuid) pid-t)
+
+(defun getuid ()
+ (c-getuid))
+
+(defcfun ("geteuid" c-geteuid) pid-t)
+
+(defun geteuid ()
+ (c-geteuid))
+
+(defcfun ("getgid" c-getgid) pid-t)
+
+(defun getgid ()
+ (c-getgid))
+
+(defcfun ("getegid" c-getegid) pid-t)
+
+(defun getegid ()
+ (c-getegid))
+
+(defcfun ("getgroups" c-getgroups) :int
+ (size :int)
+ (list gid-t))
+
+(defcfun ("setuid" c-setuid) :int
+ (uid uid-t))
+
+(defun setuid (uid)
+ (c-setuid uid))
+
+(defcfun ("seteuid" c-seteuid) :int
+ (uid uid-t))
+
+(defun seteuid (uid)
+ (c-seteuid uid))
+
+(defcfun ("setgid" c-setgid) :int
+ (gid gid-t))
+
+(defun setgid (gid)
+ (c-setgid gid))
+
+(defcfun ("setegid" c-setegid) :int
+ (gid gid-t))
+
+(defun setegid (gid)
+ (c-setegid gid))
+
+(defcfun ("fork" c-fork) pid-t)
+
+(defun fork ()
+ (let ((r (c-fork)))
+ (when (= -1 r)
+ (error-errno "fork"))
+ r))
+
+(defcfun ("vfork" c-vfork) pid-t)
+
+(defun vfork ()
+ (let ((r (c-vfork)))
+ (when (= -1 r)
+ (error-errno "vfork"))
+ r))
+
+(defcfun ("ttyname" c-ttyname) :string
+ (fd :int))
+
+(defun ttyname (fd)
+ (or (c-ttyname fd)
+ (error-errno "ttyname")))
+
+(defcfun ("isatty" c-isatty) :int
+ (fd :int))
+
+(defun isatty (fd)
+ (let ((r (c-isatty fd)))
+ (when (= -1 r)
+ (error-errno "isatty"))
+ r))
+
+(defcfun ("link" c-link) :int
+ (from :string)
+ (to :string))
+
+(defun link (from to)
+ (let ((r (c-link from to)))
+ (when (= -1 r)
+ (error-errno "link"))
+ r))
+
+(defcfun ("symlink" c-symlink) :int
+ (from :string)
+ (to :string))
+
+(defun symlink (from to)
+ (let ((r (c-symlink from to)))
+ (when (= -1 r)
+ (error-errno "symlink"))
+ r))
+
+(defcfun ("readlink" c-readlink) ssize-t
+ (path :string)
+ (buf :string)
+ (len size-t))
+
+(defun readlink (path)
+ (let ((len *path-max*))
+ (with-foreign-object (buf :char len)
+ (let ((r (c-readlink path buf len)))
+ (when (= -1 r)
+ (error-errno path))
+ (let ((octets (make-array `(,r) :element-type '(unsigned-byte 8)
+ :initial-element 0)))
+ (dotimes (i r)
+ (setf (aref octets i) (mem-aref buf :unsigned-char i)))
+ (babel:octets-to-string octets :encoding :utf-8))))))
+
+#+nil
+(readlink "/home/dx/common-lisp/RailsOnLisp/rol/assets")
+
+(defcfun ("unlink" c-unlink) :int
+ (name :string))
+
+(defun unlink (name)
+ (let ((r (c-unlink name)))
+ (when (= -1 r)
+ (error-errno "unlink"))
+ r))
+
+(defcfun ("rmdir" c-rmdir) :int
+ (path :string))
+
+(defun rmdir (path)
+ (let ((r (c-rmdir path)))
+ (when (= -1 r)
+ (error-errno "rmdir"))
+ r))
+
;; Select
(defcstruct fd-set
diff --git a/package.lisp b/package.lisp
index 91db247..3bb20d5 100644
--- a/package.lisp
+++ b/package.lisp
@@ -30,6 +30,7 @@
#:sleep
#:write)
(:export
+ #:_exit
#:+f-ok+
#:+fd-setsize+
#:+nfdbits+
@@ -46,6 +47,7 @@
#:+x-ok+
#:access
#:alarm
+ #:c-_exit
#:c-access
#:c-alarm
#:c-chdir
@@ -56,22 +58,55 @@
#:c-dup3
#:c-environ
#:c-euidaccess
+ #:c-execv
+ #:c-execve
+ #:c-execvp
+ #:c-execvpe
#:c-fchdir
#:c-fchown
#:c-fchownat
+ #:c-fork
#:c-getcwd
+ #:c-getegid
+ #:c-geteuid
+ #:c-getgid
+ #:c-getgroups
+ #:c-getpgid
+ #:c-getpgrp
+ #:c-getpid
+ #:c-getppid
+ #:c-getsid
+ #:c-getuid
+ #:c-isatty
#:c-lchown
+ #:c-link
#:c-lseek
+ #:c-nice
+ #:c-pathconf
#:c-pause
#:c-pipe
#:c-pipe2
#:c-pread
#:c-pwrite
#:c-read
+ #:c-readlink
+ #:c-rmdir
#:c-select
+ #:c-setegid
+ #:c-seteuid
+ #:c-setgid
+ #:c-setpgid
+ #:c-setpgrp
+ #:c-setsid
+ #:c-setuid
#:c-sleep
+ #:c-symlink
+ #:c-sysconf
+ #:c-ttyname
#:c-ualarm
+ #:c-unlink
#:c-usleep
+ #:c-vfork
#:c-write
#:chdir
#:chown
@@ -82,6 +117,10 @@
#:dup3
#:environ
#:euidaccess
+ #:execv
+ #:execve
+ #:execvp
+ #:execvpe
#:fchdir
#:fchown
#:fchownat
@@ -93,14 +132,28 @@
#:fd-set-filter
#:fd-zero
#:fds-bits
+ #:fork
#:getcwd
+ #:getegid
+ #:geteuid
#:getenv
+ #:getgid
+ #:getgroups
+ #:getpgid
+ #:getpid
+ #:getppid
+ #:getsid
+ #:getuid
#:gid-t
#:intptr-t
+ #:isatty
#:lchown
+ #:link
#:list-to-fd-set
#:lseek
+ #:nice
#:off-t
+ #:pathconf
#:pause
#:pid-t
#:pipe
@@ -109,19 +162,33 @@
#:pwrite
#:read
#:read-non-blocking
+ #:readlink
+ #:rmdir
#:seconds-to-timeval
#:select
+ #:setegid
+ #:seteuid
+ #:setgid
+ #:setpgid
+ #:setpgrp
+ #:setsid
+ #:setuid
#:size-t
#:sleep
#:socklen-t
#:ssize-t
+ #:symlink
+ #:sysconf
#:timeval
+ #:ttyname
#:tv-sec
#:tv-usec
#:ualarm
#:uid-t
+ #:unlink
#:useconds-t
#:usleep
+ #:vfork
#:with-pipe
#:with-selected
#:write