Raymond Toy pushed to branch issue-364-add-mkstemp-mkdtemp at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/code/extensions.lisp
    ... ... @@ -22,7 +22,8 @@
    22 22
     		read-char-no-edit listen-skip-whitespace concat-pnames
    
    23 23
     		iterate once-only collect do-anonymous undefined-value
    
    24 24
     		required-argument define-hash-cache defun-cached
    
    25
    -		cache-hash-eq do-hash))
    
    25
    +		cache-hash-eq do-hash
    
    26
    +	  with-temporary-file))
    
    26 27
     
    
    27 28
     (import 'lisp::whitespace-char-p)
    
    28 29
     
    
    ... ... @@ -622,7 +623,7 @@
    622 623
     				  decoding-error
    
    623 624
     				  encoding-error)
    
    624 625
     			       &parse-body (forms decls))
    
    625
    -  "A temporary file is opened using the Open-args and bound to the
    
    626
    +  _N"A temporary file is opened using the Open-args and bound to the
    
    626 627
      variable Var.  The name of the temporary file uses Template-prefix
    
    627 628
      for the name.  If the temporary file cannot be opened, the forms are
    
    628 629
      not evaluated.  The Forms are executed, and when they terminate,
    
    ... ... @@ -639,19 +640,19 @@
    639 640
     	(template (gensym "TEMPLATE-")))
    
    640 641
         
    
    641 642
         `(let* ((,template (concatenate 'string
    
    642
    -					,template-prefix
    
    643
    -					"XXXXXX"))
    
    644
    -		(,var (lisp::make-fd-stream (unix::unix-mkstemp ,template)
    
    645
    -					    :auto-close t
    
    646
    -					    :file ,template
    
    647
    -					    :output t
    
    648
    -					    :input t
    
    649
    -					    :element-type ',element-type
    
    650
    -					    :external-format ,external-format
    
    651
    -					    :decoding-error ,decoding-error
    
    652
    -					    :encoding-error ,encoding-error
    
    653
    -					    :buffering ,buffering))
    
    654
    -		(,abortp t))
    
    643
    +				    ,template-prefix
    
    644
    +				    "XXXXXX"))
    
    645
    +	    (,var (lisp::make-fd-stream (unix::unix-mkstemp ,template)
    
    646
    +					:auto-close t
    
    647
    +					:file ,template
    
    648
    +					:output t
    
    649
    +					:input t
    
    650
    +					:element-type ',element-type
    
    651
    +					:external-format ,external-format
    
    652
    +					:decoding-error ,decoding-error
    
    653
    +					:encoding-error ,encoding-error
    
    654
    +					:buffering ,buffering))
    
    655
    +	    (,abortp t))
    
    655 656
            ,@decls
    
    656 657
            (unwind-protect
    
    657 658
     	    (multiple-value-prog1
    
    ... ... @@ -659,3 +660,21 @@
    659 660
     	      (setq ,abortp nil))
    
    660 661
     	 (when ,var
    
    661 662
     	   (close ,var :abort ,abortp))))))
    
    663
    +
    
    664
    +;; WITH-TEMPORARY-DIRECTORY -- Public
    
    665
    +(defmacro with-temporary-directory ((var template-prefix)
    
    666
    +				    &parse-body (forms decls))
    
    667
    +  _N"Create a temporary directory using Template-prefix as the name of the directory."
    
    668
    +  (let ((template (gensym "TEMPLATE-")))
    
    669
    +    `(let ((,template (concatenate 'string ,template-prefix
    
    670
    +				   "XXXXXX")))
    
    671
    +       ,@decls
    
    672
    +       (let ((,var (unix::unix-mkdtemp ,template)))
    
    673
    +	 (unless ,var
    
    674
    +	   (error "Could not create temporary directory using template ~A"
    
    675
    +		  ,template))
    
    676
    +	 (unwind-protect
    
    677
    +	      (multiple-value-prog1
    
    678
    +		  (progn ,@forms)))
    
    679
    +	 ;; Remove the directory
    
    680
    +	 (unix:unix-rmdir ,var)))))

  • src/code/unix.lisp
    ... ... @@ -2909,3 +2909,33 @@
    2909 2909
       (syscall ("mkstemp" c-call:c-string)
    
    2910 2910
     	   result
    
    2911 2911
     	   (copy-seq template)))
    
    2912
    +
    
    2913
    +(defun unix-mkdtemp (template)
    
    2914
    +  _N"Generate a uniquely named temporary directory from Template,
    
    2915
    +  which must have \"XXXXXX\" as the last six characters.  The
    
    2916
    +  directory is created with permissions 0700.  The name of the
    
    2917
    +  directory is returned."
    
    2918
    +  (let* ((new-template (copy-seq template))
    
    2919
    +	 (result (alien-funcall
    
    2920
    +		  (extern-alien "mkdtemp"
    
    2921
    +				(function (* char)
    
    2922
    +					  c-call:c-string))
    
    2923
    +		  new-template)))
    
    2924
    +    (if (zerop (deref result 0))
    
    2925
    +	(values nil (unix-errno))
    
    2926
    +	(cast result c-call:c-string))))
    
    2927
    +
    
    2928
    +(defun unix-mkdtemp (template)
    
    2929
    +  _N"Generate a uniquely named temporary directory from Template,
    
    2930
    +  which must have \"XXXXXX\" as the last six characters.  The
    
    2931
    +  directory is created with permissions 0700.  The name of the
    
    2932
    +  directory is returned."
    
    2933
    +  (let* ((new-template (copy-seq template))
    
    2934
    +	 (result (alien-funcall
    
    2935
    +		  (extern-alien "mkdtemp"
    
    2936
    +				(function (* char)
    
    2937
    +					  c-call:c-string))
    
    2938
    +		  new-template)))
    
    2939
    +    (if (zerop (sap-int (alien-sap result)))
    
    2940
    +	(values nil (unix-errno))
    
    2941
    +	(cast result c-string))))