wanted: open-temp-file and with-temp-file

Bug #393104 reported by Tobias C. Rittweiler
18
This bug affects 3 people
Affects Status Importance Assigned to Milestone
SBCL
Invalid
Undecided
Unassigned

Bug Description

I think SBCL should provide SB-EXT:OPEN-TEMP-FILE (and possibly also a WITH-TEMP-FILE macro.)
It should be based on tmpfile(3) on Unix, and whatever Windows provides.

I regularly see code that uses something like (open (make-temp-file-name) ...) which may
contain a race condition that can be abused as a DoS attack -- depending on the
implementation of OPEN and :IF-EXISTS. SBCL seems to do it right, passing O_EXCL and
O_CREATE to open(3).

Providing such a function, and documenting it appropriately, may rise attention of the
problem. And, of course, it would be convenient for a need that comes up quite frequently.

Revision history for this message
Evrim Ulu (evrimulu) wrote :

Hi,

We've been using

;; Generate unique filename for temporary usage
(sb-alien:define-alien-routine "tmpnam" sb-alien:c-string
  (dest (* sb-alien:c-string)))

in Core Server project (http://labs.core.gen.tr) but it seems we are getting errors. It would be nice to have some convenient way.

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

While I'm not exactly opposed to this, I wonder if SBCL is the right place for this. Libraries such as Osicat cater to this need already.

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

Marking as invalid: I don't think this belongs in SBCL as such.

It seems to me that right choices are:

1. Use OSICAT:WITH-TEMPORARY-FILE or OSICAT:OPEN-TEMPORARY-FILE.

2. Roll your own using SBCL interfaces, for example:

(defun open-temporary-file (&key (element-type 'character) (external-format :default))
  (multiple-value-bind (fd namestring) (sb-posix:mkstemp "/tmp/XXXXXXXXXXXX")
    (handler-case
        (sb-posix:unlink namestring)
      (error (e)
        (sb-posix:close fd)
        (error "Could not unlink created temporary file ~A:~% ~A" namestring e)))
    (sb-sys:make-fd-stream fd
                           :input t :output t
                           :element-type element-type
                           :external-format external-format
                           :auto-close t)))

(let ((f (open-temporary-file)))
  (write-line "foo" f)
  (file-position f :start)
  (read-line f)) ; => "foo", NIL

-- all the APIs here are public (though SB-SYS:MAKE-FD-STREAM isn't documented yet, unfortunately.)

3. If something like the above is wanted in SBCL, I think it belongs in a higher-level contrib akin to Osicat -- say SB-OSI, or something.

Changed in sbcl:
status: New → Invalid
Revision history for this message
Tobias C. Rittweiler (tcr) wrote : Re: [Bug 393104] Re: wanted: open-temp-file and with-temp-file

Nikodemus Siivola <email address hidden> writes:

> Marking as invalid: I don't think this belongs in SBCL as such.
>
> It seems to me that right choices are:
>
> 1. Use OSICAT:WITH-TEMPORARY-FILE or OSICAT:OPEN-TEMPORARY-FILE.

The functionality is nice to have in SBCL itself because its need arises
often even e.g. for scripting and testing purposes.

In particular, SBCL's swank backend would need it, too.

It's also applicable in the test suite.

> 2. Roll your own using SBCL interfaces, for example:
>
> (defun open-temporary-file (&key (element-type 'character) (external-format :default))
> (multiple-value-bind (fd namestring) (sb-posix:mkstemp "/tmp/XXXXXXXXXXXX")
> (handler-case
> (sb-posix:unlink namestring)
> (error (e)
> (sb-posix:close fd)
> (error "Could not unlink created temporary file ~A:~% ~A" namestring e)))
> (sb-sys:make-fd-stream fd
> :input t :output t
> :element-type element-type
> :external-format external-format
> :auto-close t)))
>
> (let ((f (open-temporary-file)))
> (write-line "foo" f)
> (file-position f :start)
> (read-line f)) ; => "foo", NIL
>
> -- all the APIs here are public (though SB-SYS:MAKE-FD-STREAM isn't
> documented yet, unfortunately.)

(SB-SYS is not a public package.) It's very nice that SBCL exposes the
necessary ingredients; I don't see why users are supposed to reinvent
the wheel, though.

> 3. If something like the above is wanted in SBCL, I think it belongs in
> a higher-level contrib akin to Osicat -- say SB-OSI, or something.

I'd be fine with that.

  -T.

--
Diese Nachricht wurde auf Viren und andere gefaerliche Inhalte untersucht
und ist - aktuelle Virenscanner vorausgesetzt - sauber.
Freebits E-Mail Virus Scanner

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

2009/11/20 Tobias C. Rittweiler <email address hidden>:

>> -- all the APIs here are public (though SB-SYS:MAKE-FD-STREAM isn't
>> documented yet, unfortunately.)
>
> (SB-SYS is not a public package.) It's very nice that SBCL exposes the
> necessary ingredients; I don't see why users are supposed to reinvent
> the wheel, though.

Heh, that's what happens when I go by memory. :)

I could have sworn SB-SYS was semi-public: ugly and ill-documented, and requiring care from users, but supported unlike SB-UNIX.

Huh, and it's a lot more cluttered than I remembered! Either the generally useful stuff should be moved to another (public) package, or the internals cleared out.

These are the things I think should be at least semi-public and semi-supported (just a quick cull through the exports list):

               "*LONG-SITE-NAME*" "*SHORT-SITE-NAME*"
               "*PERIODIC-POLLING-FUNCTION*"
               "*PERIODIC-POLLING-PERIOD*"
               "*STDERR*" "*STDIN*"
               "*STDOUT*"
               "*TTY*"
               "ADD-FD-HANDLER"
               "ALLOCATE-SYSTEM-MEMORY"
               "ALLOW-WITH-INTERRUPTS"
               "DEADLINE-TIMEOUT"
               "DEALLOCATE-SYSTEM-MEMORY"
               "DECODE-TIMEOUT"
               "DECODE-INTERNAL-TIME"
               "DEFER-DEADLINE"
               "ENABLE-INTERRUPT"
               "EXTERN-ALIEN-NAME"
               "FD-STREAM" "FD-STREAM-FD" "FD-STREAM-P"
               "INTERACTIVE-INTERRUPT"
               "INT-SAP"
               "IO-TIMEOUT"
               "LIST-DYNAMIC-FOREIGN-SYMBOLS"
               "MAKE-FD-STREAM"
               "MEMORY-FAULT-ERROR"
               "REMOVE-FD-HANDLER"
               "SAP+" "SAP-"
               "SAP-INT"
               "SAP-REF-16" "SAP-REF-32" "SAP-REF-64" "SAP-REF-WORD"
               "SAP-REF-8"
               "SAP-REF-DOUBLE" "SAP-REF-LONG"
               "SAP-REF-SAP" "SAP-REF-SINGLE"
               "SAP<" "SAP<=" "SAP=" "SAP>" "SAP>="
               "SERVE-ALL-EVENTS"
               "SIGNAL-DEADLINE"
               "SERVE-EVENT"
               "SIGNED-SAP-REF-16" "SIGNED-SAP-REF-32"
               "SIGNED-SAP-REF-64" "SIGNED-SAP-REF-WORD" "SIGNED-SAP-REF-8"
               "SYSTEM-AREA-POINTER" "SYSTEM-AREA-POINTER-P"
               "SYSTEM-CONDITION" "SYSTEM-CONDITION-ADDRESS"
               "SYSTEM-CONDITION-CONTEXT"
               "VECTOR-SAP"
               "WAIT-UNTIL-FD-USABLE"
               "WITH-DEADLINE"
               "WITH-FD-HANDLER"
               "WITH-INTERRUPTS" "WITH-LOCAL-INTERRUPTS"
               "WITH-PINNED-OBJECTS" "WITHOUT-GCING"
               "WITHOUT-INTERRUPTS"

The SAP stuff should probably be in SB-ALIEN. Various conditions could go in SB-EXT, along with interrupt and GC stuff. Stream-related things could maybe have a package of their own: SB-FD-STREAMS.

Cheers,

 -- Nikodemus

Revision history for this message
pipping (pipping) wrote :

Something like this would be useful for bug #626930 as well.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.