X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=contrib%2Fsb-posix%2Finterface.lisp;h=c01f0310709655f0009717267202835dd41b1c39;hb=1f03c7f326823245708a84af86b31ac72bdb1742;hp=1da9d8fa09a18b8bc8389e76357b4a1f17c8ea6d;hpb=b6ef430541de83d0adf4378ba2d814a1136c9d68;p=sbcl.git diff --git a/contrib/sb-posix/interface.lisp b/contrib/sb-posix/interface.lisp index 1da9d8f..c01f031 100644 --- a/contrib/sb-posix/interface.lisp +++ b/contrib/sb-posix/interface.lisp @@ -281,10 +281,16 @@ (define-call "setup_mach_exceptions" void never-fails) (define-call ("posix_fork" :c-name "fork") pid-t minusp) (defun fork () - (let ((pid (posix-fork))) - (when (= pid 0) - (setup-mach-exceptions)) - pid)) + (tagbody + (sb-thread::with-all-threads-lock + (when (cdr sb-thread::*all-threads*) + (go :error)) + (let ((pid (posix-fork))) + (when (= pid 0) + (setup-mach-exceptions)) + (return-from fork pid))) + :error + (error "Cannot fork with multiple threads running."))) (export 'fork :sb-posix)) #-mach-exception-handler @@ -615,6 +621,11 @@ (syscall-error)) (setf termios (alien-to-termios a-termios termios)))) termios) + (define-call "tcdrain" int minusp (fd file-descriptor)) + (define-call "tcflow" int minusp (fd file-descriptor) (action int)) + (define-call "tcflush" int minusp (fd file-descriptor) (queue-selector int)) + (define-call "tcgetsid" pid-t minusp (fd file-descriptor)) + (define-call "tcsendbreak" int minusp (fd file-descriptor) (duration int)) (export 'cfsetispeed :sb-posix) (declaim (inline cfsetispeed)) (defun cfsetispeed (speed &optional termios) @@ -717,7 +728,10 @@ ;;; environment -(export 'getenv :sb-posix) +(eval-when (:compile-toplevel :load-toplevel) + ;; Do this at compile-time as Win32 code below refers to it as + ;; sb-posix:getenv. + (export 'getenv :sb-posix)) (defun getenv (name) (let ((r (alien-funcall (extern-alien "getenv" (function (* char) c-string)) @@ -725,7 +739,40 @@ (declare (type (alien (* char)) r)) (unless (null-alien r) (cast r c-string)))) -(define-call "putenv" int minusp (string c-string)) +#-win32 +(progn + (define-call "setenv" int minusp (name c-string) (value c-string) (overwrite int)) + (define-call "unsetenv" int minusp (name c-string)) + (export 'putenv :sb-posix) + (defun putenv (string) + (declare (string string)) + ;; We don't want to call actual putenv: the string passed to putenv ends + ;; up in environ, and we any string we allocate GC might move. + ;; + ;; This makes our wrapper nonconformant if you squit hard enough, but + ;; users who care about that should really be calling putenv() directly in + ;; order to be able to manage memory sanely. + (let ((p (position #\= string)) + (n (length string))) + (if p + (if (= p n) + (unsetenv (subseq string 0 p)) + (setenv (subseq string 0 p) (subseq string (1+ p)) 1)) + (error "Invalid argument to putenv: ~S" string))))) +#+win32 +(progn + ;; Windows doesn't define a POSIX setenv, but happily their _putenv is sane. + (define-call* "putenv" int minusp (string c-string)) + (export 'setenv :sb-posix) + (defun setenv (name value overwrite) + (declare (string name value)) + (if (and (zerop overwrite) (sb-posix:getenv name)) + 0 + (putenv (concatenate 'string name "=" value)))) + (export 'unsetenv :sb-posix) + (defun unsetenv (name) + (declare (string name)) + (putenv (concatenate 'string name "=")))) ;;; syslog #-win32