0.pre7.109:
[sbcl.git] / src / code / run-program.lisp
index a4d7b7b..6fcfa55 100644 (file)
@@ -10,7 +10,7 @@
 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
 ;;;; files for more information.
 
-(in-package "SB-IMPL")
+(in-package "SB-IMPL") ;(SB-IMPL, not SB!IMPL, since we're built in warm load.)
 \f
 ;;;; hacking the Unix environment
 ;;;;
 ;;;; which (at least in sbcl-0.6.10 on Red Hat Linux 6.2) is not
 ;;;; visible at GENESIS time.
 
-(def-alien-variable "environ" (* c-string))
+(define-alien-variable "environ" (* c-string))
+(push (lambda ()
+       ;; We redo this here to protect ourselves from this scenario:
+       ;;   * Build under one version of shared lib, save a core.
+       ;;   * Load core under another version of shared lib. ("Now
+       ;;     where was environ again?" SIGSEGV, etc.)
+       ;; Obviously it's a KLUDGE to do this hack for every alien
+       ;; variable, but as it happens, as of sbcl-0.7.0 this is the
+       ;; only alien variable used to implement SBCL, so it's not
+       ;; worth coming up with a general solution. (A general
+       ;; solution would be nice for users who want to have their
+       ;; alien code be preserved across a save/load cycle, but this
+       ;; problem with alien variables is only one of several
+       ;; problems which'd need to be solved before that can happen.)
+        (define-alien-variable "environ" (* c-string)))
+      *after-save-initializations*)
 
 (defun posix-environ ()
   "Return the Unix environment (\"man environ\") as a list of SIMPLE-STRINGs."
 \f
 ;;;; Import wait3(2) from Unix.
 
-(sb-alien:def-alien-routine ("wait3" c-wait3) sb-c-call:int
+(sb-alien:define-alien-routine ("wait3" c-wait3) sb-c-call:int
   (status sb-c-call:int :out)
   (options sb-c-call:int)
   (rusage sb-c-call:int))
 (defmethod print-object ((process process) stream)
   (print-unreadable-object (process stream :type t)
     (format stream
-           "~D ~S"
+           "~W ~S"
            (process-pid process)
            (process-status process)))
   process)
 (defvar *handlers-installed* nil)
 
 #+FreeBSD
-(def-alien-type nil
+(define-alien-type nil
   (struct sgttyb
          (sg-ispeed sb-c-call:char)    ; input speed
          (sg-ospeed sb-c-call:char)    ; output speed
          (sg-kill sb-c-call:char)      ; kill character
          (sg-flags sb-c-call:short)))  ; mode flags
 #+OpenBSD
-(def-alien-type nil
+(define-alien-type nil
   (struct sgttyb
          (sg-four sb-c-call:int)
          (sg-chars (array sb-c-call:char 4))
       (when (streamp pty)
        (multiple-value-bind (new-fd errno) (sb-unix:unix-dup master)
          (unless new-fd
-           (error "couldn't SB-UNIX:UNIX-DUP ~D: ~A" master (strerror errno)))
+           (error "couldn't SB-UNIX:UNIX-DUP ~W: ~A" master (strerror errno)))
          (push new-fd *close-on-error*)
          (copy-descriptor-to-stream new-fd pty cookie)))
       (values name
          ;; Blast the string into place.
          (sb-kernel:copy-to-system-area (the simple-string s)
                                         (* sb-vm:vector-data-offset
-                                           sb-vm:word-bits)
+                                           sb-vm:n-word-bits)
                                         string-sap 0
-                                        (* (1+ n) sb-vm:byte-bits))
+                                        (* (1+ n) sb-vm:n-byte-bits))
          ;; Blast the pointer to the string into place.
          (setf (sap-ref-sap vec-sap i) string-sap)
          (setf string-sap (sap+ string-sap (round-bytes-to-words (1+ n))))
             ,@body)
        (sb-sys:deallocate-system-memory ,sap ,size)))))
 
-(sb-alien:def-alien-routine spawn sb-c-call:int
+(sb-alien:define-alien-routine spawn sb-c-call:int
   (program sb-c-call:c-string)
   (argv (* sb-c-call:c-string))
   (envp (* sb-c-call:c-string))
   (stdout sb-c-call:int)
   (stderr sb-c-call:int))
 
+;;; Is UNIX-FILENAME the name of a file that we can execute?
+(defun unix-filename-is-executable-p (unix-filename)
+  (declare (type simple-string unix-filename))
+  (values (and (eq (sb-unix:unix-file-kind unix-filename) :file)
+              (sb-unix:unix-access unix-filename sb-unix:x_ok))))
+
 ;;; FIXME: There shouldn't be two semiredundant versions of the
 ;;; documentation. Since this is a public extension function, the
 ;;; documentation should be in the doc string. So all information from
               ;; "path:" defined in sbcl-0.6.10. It would probably be 
               ;; reasonable to restore Unix PATH searching in SBCL, e.g.
               ;; with a function FIND-EXECUTABLE-FILE-IN-POSIX-PATH.
-              ;; (I don't want to do it with search lists the way
-              ;; that CMU CL did, because those are a non-ANSI
-              ;; extension which I'd like to get rid of. -- WHN)
-              (pfile (unix-namestring program t t))
+              ;; CMU CL did it with a "PATH:" search list, but CMU CL
+              ;; search lists are a non-ANSI extension that SBCL
+              ;; doesn't support. -- WHN)
+              (pfile (unix-namestring program t))
               (cookie (list 0)))
           (unless pfile
             (error "no such program: ~S" program))
+          (unless (unix-filename-is-executable-p pfile)
+            (error "not executable: ~S" program))
           (multiple-value-bind (stdin input-stream)
               (get-descriptor-for input cookie
                                   :direction :input
                                   (sb-kernel:copy-from-system-area
                                    (alien-sap buf) 0
                                    string (* sb-vm:vector-data-offset
-                                             sb-vm:word-bits)
-                                   (* count sb-vm:byte-bits))
+                                             sb-vm:n-word-bits)
+                                   (* count sb-vm:n-byte-bits))
                                   (write-string string stream
                                                 :end count)))))))))))