summaryrefslogtreecommitdiff
path: root/tests/syscalls.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2016-05-06 13:12:45 +0200
committerLudovic Courtès <ludo@gnu.org>2016-05-06 13:25:30 +0200
commit4e0ea3eb288c2143b44bf324c64047762c72d3b3 (patch)
treea261da4f5d972b0a90827347a3a987534ab80ac7 /tests/syscalls.scm
parentba2613bb4e47938044a3c96b92debf1bddcf0140 (diff)
utils: Move 'fcntl-flock' to (guix build syscalls).
* guix/utils.scm (%struct-flock, F_SETLKW, F_SETLK, F_xxLCK) (fcntl-flock): Move to... * guix/build/syscalls.scm: ... here. New variables. * guix/nar.scm: Adjust imports accordingly. * tests/utils.scm ("fcntl-flock wait", "fcntl-flock non-blocking"): Move to... * tests/syscalls.scm: ... here. New tests. (temp-file): New variable.
Diffstat (limited to 'tests/syscalls.scm')
-rw-r--r--tests/syscalls.scm88
1 files changed, 88 insertions, 0 deletions
diff --git a/tests/syscalls.scm b/tests/syscalls.scm
index 0b73fb4b0cd..73fa8a7acfa 100644
--- a/tests/syscalls.scm
+++ b/tests/syscalls.scm
@@ -29,6 +29,10 @@
29;; Test the (guix build syscalls) module, although there's not much that can 29;; Test the (guix build syscalls) module, although there's not much that can
30;; actually be tested without being root. 30;; actually be tested without being root.
31 31
32(define temp-file
33 (string-append "t-utils-" (number->string (getpid))))
34
35
32(test-begin "syscalls") 36(test-begin "syscalls")
33 37
34(test-equal "mount, ENOENT" 38(test-equal "mount, ENOENT"
@@ -172,6 +176,88 @@
172 (status:exit-val status)))) 176 (status:exit-val status))))
173 (eq? #t result)))))))) 177 (eq? #t result))))))))
174 178
179(false-if-exception (delete-file temp-file))
180(test-equal "fcntl-flock wait"
181 42 ; the child's exit status
182 (let ((file (open-file temp-file "w0b")))
183 ;; Acquire an exclusive lock.
184 (fcntl-flock file 'write-lock)
185 (match (primitive-fork)
186 (0
187 (dynamic-wind
188 (const #t)
189 (lambda ()
190 ;; Reopen FILE read-only so we can have a read lock.
191 (let ((file (open-file temp-file "r0b")))
192 ;; Wait until we can acquire the lock.
193 (fcntl-flock file 'read-lock)
194 (primitive-exit (read file)))
195 (primitive-exit 1))
196 (lambda ()
197 (primitive-exit 2))))
198 (pid
199 ;; Write garbage and wait.
200 (display "hello, world!" file)
201 (force-output file)
202 (sleep 1)
203
204 ;; Write the real answer.
205 (seek file 0 SEEK_SET)
206 (truncate-file file 0)
207 (write 42 file)
208 (force-output file)
209
210 ;; Unlock, which should let the child continue.
211 (fcntl-flock file 'unlock)
212
213 (match (waitpid pid)
214 ((_ . status)
215 (let ((result (status:exit-val status)))
216 (close-port file)
217 result)))))))
218
219(test-equal "fcntl-flock non-blocking"
220 EAGAIN ; the child's exit status
221 (match (pipe)
222 ((input . output)
223 (match (primitive-fork)
224 (0
225 (dynamic-wind
226 (const #t)
227 (lambda ()
228 (close-port output)
229
230 ;; Wait for the green light.
231 (read-char input)
232
233 ;; Open FILE read-only so we can have a read lock.
234 (let ((file (open-file temp-file "w0")))
235 (catch 'flock-error
236 (lambda ()
237 ;; This attempt should throw EAGAIN.
238 (fcntl-flock file 'write-lock #:wait? #f))
239 (lambda (key errno)
240 (primitive-exit (pk 'errno errno)))))
241 (primitive-exit -1))
242 (lambda ()
243 (primitive-exit -2))))
244 (pid
245 (close-port input)
246 (let ((file (open-file temp-file "w0")))
247 ;; Acquire an exclusive lock.
248 (fcntl-flock file 'write-lock)
249
250 ;; Tell the child to continue.
251 (write 'green-light output)
252 (force-output output)
253
254 (match (waitpid pid)
255 ((_ . status)
256 (let ((result (status:exit-val status)))
257 (fcntl-flock file 'unlock)
258 (close-port file)
259 result)))))))))
260
175(test-assert "all-network-interface-names" 261(test-assert "all-network-interface-names"
176 (match (all-network-interface-names) 262 (match (all-network-interface-names)
177 (((? string? names) ..1) 263 (((? string? names) ..1)
@@ -303,3 +389,5 @@
303 0)) 389 0))
304 390
305(test-end) 391(test-end)
392
393(false-if-exception (delete-file temp-file))