Update of /project/osicat/cvsroot/src In directory common-lisp.net:/tmp/cvs-serv17972
Modified Files: ffi.lisp osicat-glue.c osicat.lisp packages.lisp test-osicat.lisp test-tools.lisp Log Message: Experimental addition of MAKE-TEMPORARY-FILE, WITH-TEMPORARY-FILE. Some minor cleanups.
Date: Tue Jul 5 18:55:47 2005 Author: jsquires
Index: src/ffi.lisp diff -u src/ffi.lisp:1.3 src/ffi.lisp:1.4 --- src/ffi.lisp:1.3 Fri Apr 23 02:01:20 2004 +++ src/ffi.lisp Tue Jul 5 18:55:46 2005 @@ -69,6 +69,10 @@ :module "osicat" :returning :cstring)
+(def-function "osicat_tmpfile" () + :module "osicat" + :returning :int) + ;;;; PLAIN POSIX
(def-function "opendir" ((name :cstring)) @@ -130,3 +134,7 @@ (def-function "chdir" ((name :cstring)) :module "osicat" :returning :int) + +(def-function "tmpnam" ((template :cstring)) + :module "osicat" + :returning :cstring) \ No newline at end of file
Index: src/osicat-glue.c diff -u src/osicat-glue.c:1.8 src/osicat-glue.c:1.9 --- src/osicat-glue.c:1.8 Fri Apr 23 02:01:20 2004 +++ src/osicat-glue.c Tue Jul 5 18:55:46 2005 @@ -25,6 +25,7 @@ #include <sys/stat.h> #include <pwd.h> #include <errno.h> +#include <unistd.h>
extern int osicat_mode (char * name, int follow_p) @@ -116,3 +117,16 @@ return pwent->pw_shell; }
+ +#include <stdio.h> +#include <stdlib.h> + +extern int +osicat_tmpfile (void) +{ + FILE *fp; + + fp = tmpfile (); + if (fp == NULL) return -1; + return fileno (fp); +}
Index: src/osicat.lisp diff -u src/osicat.lisp:1.31 src/osicat.lisp:1.32 --- src/osicat.lisp:1.31 Mon Jul 26 15:25:30 2004 +++ src/osicat.lisp Tue Jul 5 18:55:46 2005 @@ -45,7 +45,7 @@ regular-file symbolic-link pipe socket)) (t (error 'bug :message - (format nil "Unknown file mode: ~H." mode))))))))) + (format nil "Unknown file mode: ~A." mode))))))))) (def))
(defmacro with-c-file @@ -129,6 +129,39 @@ (with-cstring (cfile (namestring path)) (c-file-kind cfile nil))))
+;;;; Temporary files + +(defun make-temporary-file (&key (element-type 'character)) + "function MAKE-TEMPORARY-FILE (&key element-type) => stream + +Makes a temporary file setup for input and output, and returns a +stream connected to that file. ELEMENT-TYPE specifies the unit of +transaction of the stream. + +On failure, a FILE-ERROR may be signalled." + #+(or cmu sbcl) + (let ((fd (osicat-tmpfile))) + (unless (>= fd 0) (signal 'file-error)) + #+cmu(sys:make-fd-stream fd :input t :output t + :element-type element-type) + #+sbcl(sb-sys:make-fd-stream fd :input t :output t + :element-type element-type)) + ;; XXX Warn about insecurity? Or is any platform too dumb to have + ;; fds, also relatively safe from race conditions through obscurity? + ;; XXX Another bug with this: the file doesn't get unlinked. + #-(or cmu sbcl) + (open (tmpnam nil) :direction :io :element-type element-type)) + + +(defmacro with-temporary-file ((stream &key element-type) &body body) + "macro WITH-TEMPORARY-FILE (stream &key element-type) &body body => stream" + `(let ((,stream (make-temporary-file + ,@(when element-type + `(:element-type ,element-type))))) + (unwind-protect + (progn ,@body) + (close ,stream :abort t)))) + ;;;; Directory access
(defmacro with-directory-iterator ((iterator pathspec) &body body) @@ -346,7 +379,7 @@ (if hard "hard" "symbolic") new old)))) (setf (current-directory) old))))
-;;; File permissions +;;;; File permissions
(defconstant +permissions+ (if (boundp '+permissions+) (symbol-value '+permissions+)
Index: src/packages.lisp diff -u src/packages.lisp:1.12 src/packages.lisp:1.13 --- src/packages.lisp:1.12 Sun Apr 25 16:59:06 2004 +++ src/packages.lisp Tue Jul 5 18:55:46 2005 @@ -57,6 +57,9 @@ #:make-link ;; Permissions #:file-permissions + ;; Temporary files + #:make-temporary-file + #:with-temporary-file ;; Password entries #:user-info ;; Version info
Index: src/test-osicat.lisp diff -u src/test-osicat.lisp:1.10 src/test-osicat.lisp:1.11 --- src/test-osicat.lisp:1.10 Sun Apr 25 17:10:58 2004 +++ src/test-osicat.lisp Tue Jul 5 18:55:47 2005 @@ -49,6 +49,8 @@ (error () :error))))) t)
+;;; XXX: (user-homedir-pathname) is "home:" under CMUCL, so this test +;;; will fail. (deftest environment.1 (namestring (probe-file (cdr (assoc "HOME" (environment) :test #'equal)))) @@ -312,20 +314,20 @@
;; Does this test still work in the case of su/sudo? It should, I ;; think. -#+sbcl (deftest user-info.2 - (let ((user-id (cdr (assoc :user-id (user-info (sb-posix:getuid)))))) - (equal user-id (sb-posix:getuid))) + (let* ((uid (our-getuid)) + (user-info (user-info uid))) + (equal (cdr (assoc :user-id user-info)) uid)) t)
;; Just get our home directory, and see if it exists. I don't ;; think this will work 100% of the time, but it should for most ;; people testing the package; given that, would it be even better ;; to compare the value to (user-homedir-pathname)? -#+sbcl (deftest user-info.3 - (let ((home (cdr (assoc :home (user-info (sb-posix:getuid)))))) - (file-kind home)) + (let* ((uid (our-getuid)) + (user-info (user-info uid))) + (file-kind (cdr (assoc :home user-info)))) :directory)
;; We'll go out on a limb and assume that not only does the root @@ -336,3 +338,11 @@ (file-kind home)) :directory)
+ +(deftest temporary-file.1 + (with-temporary-file (stream) + (let ((pos (file-position stream))) + (print 'foo stream) + (file-position stream pos) + (eql (read stream) 'foo))) + t)
Index: src/test-tools.lisp diff -u src/test-tools.lisp:1.2 src/test-tools.lisp:1.3 --- src/test-tools.lisp:1.2 Mon Mar 1 00:28:22 2004 +++ src/test-tools.lisp Tue Jul 5 18:55:47 2005 @@ -49,6 +49,11 @@ ((null kind) (make-link link :target target)) (t (error "File exists and is not a link.")))))
+(defun our-getuid () + #+sbcl (sb-posix:getuid) + #+cmu (unix:unix-getuid) + #-(or sbcl cmu) 0) ; A sane enough default for testing? + ;;; Test environment
(defun teardown ()