[osicat-devel] Patch to fix osicat on OpenBSD

Timo Myyrä timo.myyra at gmail.com
Sun Jan 8 09:55:44 UTC 2012


Hi,

Here's diff to make osicat work on OpenBSD.

OpenBSD doesn't define blksize_t and blkcnt_t so define them as
'long'. Not sure if this is correct but seems to work.
Neither does OpenBSD have the timer functions so omit them on OpenBSD.
The tests need to be tweaked for OpenBSD too, its similar to darwin in
this. Testing with other BSD's would be welcome to see if it its
needed there as well.

The funcall-getpw function seems to handle return values incorrectly.
As result it would cause exception on OpenBSD with incorrect entries
and not nil value as expected. The fix below works on OpenBSD but
could use some testing on other platforms as well.

Hopefully gmail won't break the diff.

Timo


diff --git a/posix/basic-unixint.lisp b/posix/basic-unixint.lisp
index 3ee3710..88371ae 100644
--- a/posix/basic-unixint.lisp
+++ b/posix/basic-unixint.lisp
@@ -286,12 +286,18 @@
 (ctype dev "dev_t")
 (ctype ino "ino_t")

-#-windows
+#-(or windows openbsd)
 (progn
   (ctype nlink "nlink_t")
   (ctype blksize "blksize_t")
   (ctype blkcnt "blkcnt_t"))

+#+openbsd
+(progn
+  (ctype nlink "nlink_t")
+  (ctype blksize "long")
+  (ctype blkcnt "long"))
+
 (cstruct stat "struct stat"
   (dev     "st_dev"     :type #-mips dev #+mips :unsigned-long)
   (ino     "st_ino"     :type ino)
diff --git a/posix/unix.lisp b/posix/unix.lisp
index 702d32d..f65ff55 100644
--- a/posix/unix.lisp
+++ b/posix/unix.lisp
@@ -394,8 +394,10 @@
     (with-foreign-object (ts 'timespec)
       (with-foreign-slots ((sec nsec) ts timespec)
         (%clock-settime clock-id ts)
-        (values sec nsec))))
+        (values sec nsec)))))

+#-(or darwin openbsd)
+(progn
   (defsyscall ("timer_create" %timer-create) :int
     (clockid clockid)
     (sigevent :pointer)
@@ -646,21 +648,22 @@ than C's printf) with format string FORMAT and
arguments ARGS."
   (result  :pointer))

 (defun funcall-getpw (fn arg)
+  ;; http://pubs.opengroup.org/onlinepubs/009695399/functions/getpwnam.html
+  ;; "Applications wishing to check for error situations should set
+  ;; errno to 0 before calling getpwnam(). If getpwnam() returns null
+  ;; pointer and errno is non-zero, an error occured.
+  (set-errno 0)
   (with-foreign-objects ((pw 'passwd) (pwp :pointer))
     (with-foreign-pointer (buf 4096 bufsize)
       (with-foreign-slots ((name passwd uid gid gecos dir shell) pw passwd)
         (let ((ret (funcall fn arg pw buf bufsize pwp)))
-          ;; Darwin's getpwnam_r() is broken a returns -1 when the
-          ;; user is not found.  Not sure if it returns the error
-          ;; number as specified by posix.
-          #+darwin
-          (when (= ret -1)
-            (return-from funcall-getpw nil))
-          (if (zerop ret)
-              (if (null-pointer-p (mem-ref pwp :pointer))
-                  nil
-                  (values name passwd uid gid gecos dir shell))
-              (posix-error ret)))))))
+          (cond ((and (null-pointer-p (mem-ref pwp :pointer))
+                      (not (zerop (get-errno))))
+                 (posix-error ret))
+                ((and (null-pointer-p (mem-ref pwp :pointer))
+                      (zerop (get-errno)))
+                 nil)
+                (t (values name passwd uid gid gecos dir shell))))))))

 (defun getpwuid (uid)
   "Gets the password-entry of a user, by user id."
diff --git a/posix/unixint.lisp b/posix/unixint.lisp
index 43273c9..cee4337 100644
--- a/posix/unixint.lisp
+++ b/posix/unixint.lisp
@@ -105,6 +105,7 @@
   (int "sival_int" :type :int)
   (ptr "sival_ptr" :type :pointer))

+#-openbsd
 (cstruct sigevent "struct sigevent"
   (notify            "sigev_notify"            :type :int)
   (signo             "sigev_signo"             :type :int)
diff --git a/tests/posix.lisp b/tests/posix.lisp
index 32a4eef..de4f35d 100644
--- a/tests/posix.lisp
+++ b/tests/posix.lisp
@@ -139,9 +139,9 @@
 (define-posix-test mkdir.error.2
     (handler-case
         (nix:mkdir "/" 0)
-      (#+darwin nix:eisdir
+      (#+(or darwin openbsd) nix:eisdir
        #+windows nix:eacces
-       #-(or darwin windows) nix:eexist () 'failed))
+       #-(or darwin windows openbsd) nix:eexist () 'failed))
   failed)

 (define-eacces-test mkdir.error.3
@@ -189,9 +189,9 @@
 (define-posix-test rmdir.error.3
     (handler-case
         (nix:rmdir "/")
-      (#+darwin nix:eisdir
+      (#+(or darwin openbsd) nix:eisdir
        #+windows nix:eacces
-       #-(or darwin windows) nix:ebusy () 'failed))
+       #-(or darwin windows openbsd) nix:ebusy () 'failed))
   failed)

 (define-posix-test rmdir.error.4
@@ -206,7 +206,7 @@
           (nix:rmdir dir)
           ;; documented by POSIX
           (not (null (member (system-error-identifier c)
-                             '(:eexist :enotempty #+darwin :enonet
+                             '(:eexist :enotempty #+(or darwin openbsd) :enonet
                                #+windows :enosr)))))))
   t)




More information about the osicat-devel mailing list