1.0.26.13: OpenBSD x86-64 support
[sbcl.git] / src / code / unix.lisp
index f5f28ca..c3c97a3 100644 (file)
@@ -113,9 +113,9 @@ 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
+  "Return the \"value\" part of the environment string \"name=value\" which
 corresponds to NAME, or NIL if there is none."
-    (name c-string))
+  (name c-string))
 \f
 ;;; from stdio.h
 
@@ -190,7 +190,7 @@ corresponds to NAME, or NIL if there is none."
 (defun sb-mkstemp (template-string mode)
   (declare (type string template-string)
            (type unix-file-mode mode))
-  (let ((template-buffer (string-to-octets template-string)))
+  (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) int))
@@ -206,12 +206,21 @@ corresponds to NAME, or NIL if there is none."
 ;; 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
@@ -395,15 +404,15 @@ corresponds to NAME, or NIL if there is none."
   ;; 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
@@ -772,11 +781,21 @@ corresponds to NAME, or NIL if there is none."
 
 ;; 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
@@ -996,9 +1015,21 @@ corresponds to NAME, or NIL if there is none."
       (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))