... |
... |
@@ -627,22 +627,29 @@ |
627
|
627
|
(filename (gensym "FILENAME-"))
|
628
|
628
|
(dir (gensym "DIRECTION-"))
|
629
|
629
|
(okay (gensym "OKAY-"))
|
630
|
|
- (err (gensym "ERR-")))
|
|
630
|
+ (err (gensym "ERR-"))
|
|
631
|
+ (file-template (gensym "FILE-TEMPLATE-")))
|
631
|
632
|
`(progn
|
632
|
633
|
(unless (member ,direction '(:output :io))
|
633
|
634
|
(error ":direction must be one of :output or :io, not ~S"
|
634
|
635
|
,direction))
|
635
|
|
- (let (,fd ,filename ,s)
|
|
636
|
+ (let ((,file-template (concatenate 'string
|
|
637
|
+ "/tmp/cmucl-temp-stream-"
|
|
638
|
+ "XXXXXX"))
|
|
639
|
+ ,fd ,filename ,s)
|
636
|
640
|
(unwind-protect
|
637
|
641
|
(progn
|
638
|
642
|
(multiple-value-setq (,fd ,filename)
|
639
|
|
- (unix::unix-mkstemp "/tmp/temp-stream-XXXXXX"))
|
|
643
|
+ (unix::unix-mkstemp ,file-template))
|
|
644
|
+ (unless ,fd
|
|
645
|
+ (error "Unable to create temporary stream at ~S: ~A~%"
|
|
646
|
+ ,file-template
|
|
647
|
+ (unix:get-unix-error-msg ,filename)))
|
640
|
648
|
(let* ((,dir ,direction))
|
641
|
649
|
(setf ,s (make-fd-stream ,fd
|
642
|
650
|
:input (member ,dir '(:input :io))
|
643
|
651
|
:output (member ,dir '(:output :io))
|
644
|
652
|
:element-type ',element-type
|
645
|
|
- :name ,filename
|
646
|
653
|
:external-format ,external-format
|
647
|
654
|
:decoding-error ,decoding-error
|
648
|
655
|
:encoding-error ,encoding-error)))
|
... |
... |
@@ -654,47 +661,62 @@ |
654
|
661
|
,filename (unix:get-unix-error-msg ,err))))
|
655
|
662
|
(locally ,@decls
|
656
|
663
|
,@forms))
|
657
|
|
- ;; Close the stream and the fd now that we're done.
|
658
|
|
- (close ,s)
|
659
|
|
- (unix:unix-close ,fd))))))
|
|
664
|
+ ;; Close the stream which will close the fd now that we're
|
|
665
|
+ ;; done.
|
|
666
|
+ (when ,s
|
|
667
|
+ (close ,s)))))))
|
660
|
668
|
|
661
|
669
|
;;; WITH-TEMPORARY-FILE -- Public
|
662
|
|
-(defmacro with-temporary-file ((filename)
|
|
670
|
+(defmacro with-temporary-file ((filename &key prefix)
|
663
|
671
|
&parse-body (forms decls))
|
664
|
|
- (let ((fd (gensym "FD-")))
|
665
|
|
- `(let (,filename)
|
|
672
|
+ (let ((fd (gensym "FD-"))
|
|
673
|
+ (file-template (gensym "TEMP-PATH-")))
|
|
674
|
+ `(let ((,file-template (concatenate 'string
|
|
675
|
+ (or ,prefix
|
|
676
|
+ "/tmp/cmucl-temp-file-")
|
|
677
|
+ "XXXXXX"))
|
|
678
|
+ ,filename)
|
666
|
679
|
(unwind-protect
|
667
|
680
|
(let (,fd)
|
668
|
681
|
(multiple-value-setq (,fd ,filename)
|
669
|
|
- (unix::unix-mkstemp "/tmp/cmucl-temp-file-XXXXXX"))
|
|
682
|
+ (unix::unix-mkstemp ,file-template))
|
|
683
|
+ (unless ,fd
|
|
684
|
+ (error "Unable to create temporary file with template ~S: ~A~%"
|
|
685
|
+ ,file-template
|
|
686
|
+ (unix:get-unix-error-msg ,filename)))
|
670
|
687
|
(unix:unix-close ,fd)
|
671
|
688
|
(locally ,@decls
|
672
|
689
|
,@forms))
|
673
|
|
- (delete-file ,filename)))))
|
674
|
|
-
|
|
690
|
+ ;; We're done so delete the temp file, if one was created.
|
|
691
|
+ (when (stringp ,filename)
|
|
692
|
+ (delete-file ,filename))))))
|
675
|
693
|
|
676
|
694
|
;;; WITH-TEMPORARY-DIRECTORY -- Public
|
677
|
|
-(defmacro with-temporary-directory ((dirname template)
|
|
695
|
+(defmacro with-temporary-directory ((dirname &key prefix)
|
678
|
696
|
&parse-body (forms decls))
|
679
|
697
|
"Return a pathname to a temporary directory. TEMPLATE is a string that
|
680
|
698
|
is used as a prefix for the name of the temporary directory. The
|
681
|
699
|
directory and all its contents are automatically removed afterward."
|
682
|
|
- (let ((err (gensym "ERR-")))
|
683
|
|
- `(let (,dirname ,err)
|
|
700
|
+ (let ((err (gensym "ERR-"))
|
|
701
|
+ (dir-path (gensym "DIR-PATH"))
|
|
702
|
+ (dir-template (gensym "DIR-TEMPLATE-")))
|
|
703
|
+ `(let ((,dir-template (concatenate 'string
|
|
704
|
+ (or ,prefix
|
|
705
|
+ "/tmp/cmucl-temp-dir")
|
|
706
|
+ "XXXXXX"))
|
|
707
|
+ ,dirname ,err)
|
684
|
708
|
(unwind-protect
|
685
|
709
|
(progn
|
686
|
710
|
(multiple-value-setq (,dirname ,err)
|
687
|
|
- (unix::unix-mkdtemp (concatenate 'string ,template
|
688
|
|
- "XXXXXX")))
|
|
711
|
+ (unix::unix-mkdtemp ,dir-template))
|
689
|
712
|
(unless ,dirname
|
690
|
|
- (error "Unable to create temporary directory: ~A"
|
|
713
|
+ (error "Unable to create temporary directory at ~S: ~A"
|
|
714
|
+ ,dir-template
|
691
|
715
|
(unix:get-unix-error-msg ,err)))
|
692
|
716
|
(setf ,dirname (concatenate 'string ,dirname "/"))
|
693
|
717
|
(locally ,@decls
|
694
|
718
|
,@forms))
|
695
|
|
- ;; Remove the temp directory and all its contents. Is there a
|
696
|
|
- ;; better way?
|
|
719
|
+ ;; If a temp directory was created, remove it and all its
|
|
720
|
+ ;; contents. Is there a better way?
|
697
|
721
|
(when ,dirname
|
698
|
722
|
(ext:run-program "/bin/rm" (list "-rf" ,dirname))))))) |
699
|
|
-
|
700
|
|
- |