Skip to content

Commit 82a4d92

Browse files
committed
implment move-file runtime primitive
1 parent fc917a9 commit 82a4d92

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

src/gerbil/core/runtime.ss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,7 @@ package: gerbil/core
14301430
display*
14311431
file-newer?
14321432
create-directory*
1433+
move-file
14331434
absent-obj
14341435
absent-value
14351436
true

src/gerbil/runtime/util.ss

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,40 @@ namespace: #f
9696
(create1 dir)))))
9797
(void))
9898

99+
(def (move-file (src : :string) (dest : :string) (replace? : :boolean := #t))
100+
=> :void
101+
(def (force-move-it)
102+
(let (tmp (and replace?
103+
(file-exists? dest)
104+
(string-append dest "." (number->string (##current-time-point)))))
105+
(when tmp
106+
(rename-file dest tmp))
107+
(with-exception-catcher
108+
(lambda (e)
109+
(when tmp
110+
(rename-file tmp dest #t))
111+
(raise e))
112+
(lambda ()
113+
(let (fi (file-info src #f))
114+
(if (eq? (file-info-type fi) 'symbolic-link)
115+
;; there is no portable way to get the immediate link, so the
116+
;; best we can do is to normalize the path
117+
(create-symbolic-link (path-normalize src) dest)
118+
(copy-file src dest)))
119+
(delete-file src)
120+
(when tmp
121+
(with-exception-catcher void (cut delete-file tmp)))))))
122+
123+
(with-exception-catcher
124+
(lambda (e)
125+
;; ideally we would check the exception for errno=EXDEV, but this is
126+
;; not portable, so we just try to force move it if it exists
127+
(if (file-exists? src)
128+
(force-move-it)
129+
(raise e)))
130+
(cut rename-file src dest replace?))
131+
(void))
132+
99133
(def absent-obj
100134
(##absent-object))
101135

0 commit comments

Comments
 (0)