mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 13:49:17 +02:00
Avoiding a race condition in synchronized-rewrite-file.
This commit is contained in:
parent
0df0dc3e2b
commit
c7d64a19c4
1 changed files with 18 additions and 22 deletions
|
@ -126,36 +126,32 @@
|
||||||
|
|
||||||
(define (file-lock-loop port-or-fd mode)
|
(define (file-lock-loop port-or-fd mode)
|
||||||
(let lp ()
|
(let lp ()
|
||||||
(let ((res (file-lock port-or-fd mode)))
|
(cond
|
||||||
(cond
|
((file-lock port-or-fd mode))
|
||||||
(res)
|
((memv (errno) '(11 35)) (thread-sleep! 0.01) (lp))
|
||||||
((memv (errno) '(11 35)) (thread-sleep! 0.01) (lp))
|
(else (error "couldn't lock file" (integer->error-string))))))
|
||||||
(else (error "couldn't lock file" (integer->error-string)))))))
|
|
||||||
|
|
||||||
(define (call-with-locked-file path proc . o)
|
(define (call-with-locked-file path proc . o)
|
||||||
(let ((fd (open path open/read-write (if (pair? o) (car o) #o644))))
|
(let ((fd (open path
|
||||||
|
(+ open/create open/read-write)
|
||||||
|
(if (pair? o) (car o) #o644))))
|
||||||
(file-lock-loop fd (+ lock/exclusive lock/non-blocking))
|
(file-lock-loop fd (+ lock/exclusive lock/non-blocking))
|
||||||
(exception-protect (proc fd) (file-lock fd lock/unlock))))
|
(exception-protect (proc fd) (file-lock fd lock/unlock))))
|
||||||
|
|
||||||
;; Rewrites file in place with the result of (proc orig-contents),
|
;; Rewrites file in place with the result of (proc orig-contents),
|
||||||
;; synchronized with file-lock.
|
;; synchronized with file-lock.
|
||||||
(define (synchronized-rewrite-text-file path proc . o)
|
(define (synchronized-rewrite-text-file path proc . o)
|
||||||
(cond
|
(call-with-locked-file
|
||||||
((file-exists? path)
|
path
|
||||||
(call-with-locked-file
|
(lambda (fd)
|
||||||
path
|
(let* ((str (port->string (open-input-file-descriptor fd)))
|
||||||
(lambda (fd)
|
(res (proc str))
|
||||||
(let* ((str (port->string (open-input-file-descriptor fd)))
|
(out (open-output-file-descriptor fd)))
|
||||||
(res (proc str))
|
(set-file-position! out seek/set 0)
|
||||||
(out (open-output-file-descriptor fd)))
|
(display res out)
|
||||||
(set-file-position! out seek/set 0)
|
(file-truncate out (string-size res))
|
||||||
(display res out)
|
(close-output-port out)
|
||||||
(file-truncate out (string-size res))
|
res))))
|
||||||
(close-output-port out)
|
|
||||||
res))))
|
|
||||||
(else
|
|
||||||
(call-with-output-file path
|
|
||||||
(lambda (out) (display (proc (if (pair? o) (car o) "")) out))))))
|
|
||||||
|
|
||||||
(define (synchronized-rewrite-sexp-file path proc . o)
|
(define (synchronized-rewrite-sexp-file path proc . o)
|
||||||
(apply synchronized-rewrite-text-file
|
(apply synchronized-rewrite-text-file
|
||||||
|
|
Loading…
Add table
Reference in a new issue