atomic.ss
#lang scheme/base
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; FILE.plt - file, path, and atomic file operation utilities 
;;
;;
;; Bonzai Lab, LLC.  All rights reserved.
;;
;; Licensed under LGPL.
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; atomic.ss - provides atomic file saving operation (save/rename) wrappers
;; yc 9/21/2009 - first version
;; yc 10/2/2009 - fix the flush-output bug (return 0 instead of void now)
;; yc 2/13/2010 - refactor to use open-output-temp-file for open-output-atomic-file
(require "depend.ss"
         "path.ss"
         "base.ss"
         "file.ss"
         "temp.ss" 
         )

(define (open-output-atomic-file path)
  (mkdir* (parent-path path)) ;; ensure the parent-path exists... this might still fail.
  (open-output-temp-file #:base (parent-path path)
                         #:close (lambda (temp)
                                   (lambda ()
                                     ;; the window's rename-file might also still fail
                                     ;; due to file locking...
                                     ;; need to figure out how to unlock the file...
                                     ;; which would require the appropriate level of permission
                                     (+:windows (rename-file temp path)
                                                (rename temp path #t))))))


(define call-with-output-atomic-file
  (make-call-with-output-port open-output-atomic-file path))

(provide/contract 
 (open-output-atomic-file (-> path-string? output-port?))
 (call-with-output-atomic-file
     (-> path-string? (-> output-port? any) any))
 )