1.0.26.13: OpenBSD x86-64 support
[sbcl.git] / src / code / unix.lisp
index e3a4ba2..c3c97a3 100644 (file)
@@ -114,7 +114,7 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted."
 #!-win32
 (define-alien-routine ("getenv" posix-getenv) c-string
   "Return the \"value\" part of the environment string \"name=value\" which
-   corresponds to NAME, or NIL if there is none."
+corresponds to NAME, or NIL if there is none."
   (name c-string))
 \f
 ;;; from stdio.h
@@ -180,16 +180,22 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted."
 ;;;; stdlib.h
 
 ;;; There are good reasons to implement some OPEN options with an
-;;; mkstemp(3) followed by a fchmod(2) followed by a rename(2), but we
-;;; don't do that yet.  Instead, this function is used only to make a
-;;; temporary file for RUN-PROGRAM.  sb_mkstemp() is a wrapper that
-;;; lives in src/runtime/wrap.c.
-(defun unix-mkstemp (template-string)
-  (let ((template-buffer (string-to-octets template-string)))
+;;; mkstemp(3)-like routine, but we don't do that yet.  Instead, this
+;;; function is used only to make a temporary file for RUN-PROGRAM.
+;;; sb_mkstemp() is a wrapper that lives in src/runtime/wrap.c.  Since
+;;; SUSv3 mkstemp() doesn't specify the mode of the created file and
+;;; since we have to implement most of this ourselves for Windows
+;;; anyway, it seems worthwhile to depart from the mkstemp()
+;;; specification by taking a mode to use when creating the new file.
+(defun sb-mkstemp (template-string mode)
+  (declare (type string template-string)
+           (type unix-file-mode mode))
+  (let ((template-buffer (string-to-octets template-string :null-terminate t)))
     (with-pinned-objects (template-buffer)
       (let ((fd (alien-funcall (extern-alien "sb_mkstemp"
-                                             (function int (* char)))
-                               (vector-sap template-buffer))))
+                                             (function int (* char) int))
+                               (vector-sap template-buffer)
+                               mode)))
         (if (minusp fd)
             (values nil (get-errno))
             (values fd (octets-to-string template-buffer)))))))
@@ -200,12 +206,21 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted."
 ;; microsecond but also has a range of years.
 ;; CLH: Note that tv-usec used to be a time-t, but that this seems
 ;; problematic on Darwin x86-64 (and wrong). Trying suseconds-t.
-#!-win32
+#!-(or win32 openbsd)
 (define-alien-type nil
   (struct timeval
           (tv-sec time-t)           ; seconds
           (tv-usec suseconds-t)))   ; and microseconds
 
+;; The above definition doesn't work on 64-bit OpenBSD platforms.
+;; Both tv_sec and tv_usec are declared as long instead of time_t, and
+;; time_t is a typedef for int.
+#!+openbsd
+(define-alien-type nil
+  (struct timeval
+          (tv-sec long)             ; seconds
+          (tv-usec long)))          ; and microseconds
+
 #!+win32
 (define-alien-type nil
   (struct timeval
@@ -296,6 +311,10 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted."
 ;;; It attempts to read len bytes from the device associated with fd
 ;;; and store them into the buffer. It returns the actual number of
 ;;; bytes read.
+
+#!-sb!fluid
+(declaim (maybe-inline unix-read))
+
 (defun unix-read (fd buf len)
   (declare (type unix-fd fd)
            (type (unsigned-byte 32) len))
@@ -385,15 +404,15 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted."
   ;; comma not inside a backquote. This error has absolutely nothing
   ;; to do with the actual meaning of the error (and little to do with
   ;; its location, either).
-  #!-(or linux openbsd freebsd netbsd sunos osf1 darwin win32) (,stub,)
-  #!+(or linux openbsd freebsd netbsd sunos osf1 darwin win32)
+  #!-(or linux openbsd freebsd netbsd sunos osf1 darwin hpux win32) (,stub,)
+  #!+(or linux openbsd freebsd netbsd sunos osf1 darwin hpux win32)
   (or (newcharstar-string (alien-funcall (extern-alien "getcwd"
                                                        (function (* char)
                                                                  (* char)
                                                                  size-t))
                                          nil
                                          #!+(or linux openbsd freebsd netbsd darwin win32) 0
-                                         #!+(or sunos osf1) 1025))
+                                         #!+(or sunos osf1 hpux) 1025))
       (simple-perror "getcwd")))
 
 ;;; Return the Unix current directory as a SIMPLE-STRING terminated
@@ -757,27 +776,26 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted."
     (syscall ("fstat_wrapper" int (* (struct wrapped_stat)))
              (%extract-stat-results (addr buf))
              fd (addr buf))))
-
-;;; RUN-PROGRAM creates temporary files with mkstemp, but SUSv3
-;;; doesn't specify the mode of a newly created file under mkstemp,
-;;; and C libraries may vary, so we fix the mode ourselves.
-;;; Eventually some OPEN actions should probably be implemented with
-;;; mkstemp(3)/chmod(2)/rename(2) as well.
-#!-win32
-(defun unix-chmod (path mode)
-  (declare (type unix-pathname path)
-           (type unix-file-mode mode))
-  (void-syscall ("chmod" c-string int) path mode))
 \f
 ;;;; time.h
 
 ;; the POSIX.4 structure for a time value. This is like a "struct
 ;; timeval" but has nanoseconds instead of microseconds.
+#!-openbsd
 (define-alien-type nil
     (struct timespec
             (tv-sec long)   ; seconds
             (tv-nsec long))) ; nanoseconds
 
+;; Just as with struct timeval, 64-bit OpenBSD has problems with the
+;; above definition.  tv_sec is declared as time_t instead of long,
+;; and time_t is a typedef for int.
+#!+openbsd
+(define-alien-type nil
+    (struct timespec
+            (tv-sec time-t)  ; seconds
+            (tv-nsec long))) ; nanoseconds
+
 ;; used by other time functions
 (define-alien-type nil
     (struct tm
@@ -997,9 +1015,21 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted."
       (setf (values e-sec e-msec) (system-real-time-values)
             c-sec 0
             c-msec 0))
-    ;; If two threads call this at the same time, we're still safe, I believe,
-    ;; as long as NOW is updated before either of C-MSEC or C-SEC. Same applies
-    ;; to interrupts. --NS
+    ;; If two threads call this at the same time, we're still safe, I
+    ;; believe, as long as NOW is updated before either of C-MSEC or
+    ;; C-SEC. Same applies to interrupts. --NS
+    ;;
+    ;; I believe this is almost correct with x86/x86-64 cache
+    ;; coherency, but if the new value of C-SEC, C-MSEC can become
+    ;; visible to another CPU without NOW doing the same then it's
+    ;; unsafe. It's `almost' correct on x86 because writes by other
+    ;; processors may become visible in any order provided transitity
+    ;; holds. With at least three cpus, C-MSEC and C-SEC may be from
+    ;; different threads and an incorrect value may be returned.
+    ;; Considering that this failure is not detectable by the caller -
+    ;; it looks like time passes a bit slowly - and that it should be
+    ;; an extremely rare occurance I'm inclinded to leave it as it is.
+    ;; --MG
     (defun get-internal-real-time ()
       (multiple-value-bind (sec msec) (system-real-time-values)
         (unless (and (= msec c-msec) (= sec c-sec))