> Maybe replace > > (symlink target pivot) > > by (symlink/remove-old target pivot) > > where > > (define (symlink/remove-old target link) > "Make a symbolic link named LINK pointing to TARGET. > If LINK already exists, it will be removed first. > This is not an atomic operation." > (catch 'system-error > (lambda () > (symlink target link)) > (lambda stuff > (if (= (system-error-errno stuff) EEXIST) > (begin > ;; remove old link and retry > (delete-file link) > (symlink/remove-old link target)) > (apply throw stuff))))) > > ?
Could we implement symlink/remove-old without catch and throw? Something like: --8<---------------cut here---------------start------------->8--- (define (symlink/remove-old target link) "Make a symbolic link named LINK pointing to TARGET. If LINK already exists, it will be removed first. This is not an atomic operation." (when (file-exists? link) (delete-file link)) (symlink target link)) --8<---------------cut here---------------end--------------->8--- We might also inline this into switch-symlinks like so. --8<---------------cut here---------------start------------->8--- (define (switch-symlinks link target) "Atomically switch LINK, a symbolic link, to point to TARGET. Works both when LINK already exists and when it does not." (let ((pivot (string-append link ".new"))) ;; Delete pivot link in case it already exists. This can happen if ;; a previous switch-symlinks was interrupted. (when (file-exists? pivot) (delete-file pivot)) (symlink target pivot) (rename-file pivot link))) --8<---------------cut here---------------end--------------->8--- WDYT?