Task

Create a temporary file, securely and exclusively (opening it such that there are no possible race conditions).

It's fine assuming local filesystem semantics (NFS or other networking filesystems can have signficantly more complicated semantics for satisfying the "no race conditions" criteria).

The function should automatically resolve name collisions and should only fail in cases where permission is denied, the filesystem is read-only or full, or similar conditions exist (returning an error or raising an exception as appropriate to the language/environment).




      file% = FNopentempfile
      IF file% = 0 ERROR 100, "Failed to open temp file"
      PRINT #file%, "Hello world!"
      PTR#file% = 0
      INPUT #file%, message$
      CLOSE #file%
      PRINT message$
      END
 
      DEF FNopentempfile
      LOCAL pname%, hfile%, chan%
      OPEN_EXISTING = 3
      FILE_FLAG_DELETE_ON_CLOSE = &4000000
      GENERIC_READ = &80000000
      GENERIC_WRITE = &40000000
      INVALID_HANDLE_VALUE = -1
      DIM pname% LOCAL 260
      FOR chan% = 5 TO 12
        IF @hfile%(chan%) = 0 EXIT FOR
      NEXT
      IF chan% > 12 THEN = 0
      SYS "GetTempFileName", @tmp$, "BBC", 0, pname%
      SYS "CreateFile", $$pname%, GENERIC_READ OR GENERIC_WRITE, 0, 0, \
      \                 OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 TO hfile%
      IF hfile% = INVALID_HANDLE_VALUE THEN = 0
      @hfile%(chan%) = hfile%
      = chan%