1 (defpackage "SB-POSIX-TESTS"
2 (:use "COMMON-LISP" "SB-RT"))
4 (in-package "SB-POSIX-TESTS")
6 (defvar *test-directory*
7 (ensure-directories-exist
8 (merge-pathnames (make-pathname :directory '(:relative "test-lab"))
9 (make-pathname :directory
10 (pathname-directory *load-truename*)))))
12 (defvar *current-directory* *default-pathname-defaults*)
14 (defvar *this-file* *load-truename*)
16 (eval-when (:compile-toplevel :load-toplevel)
17 (defconstant +mode-rwx-all+ (logior sb-posix::s-irusr sb-posix::s-iwusr sb-posix::s-ixusr
18 sb-posix::s-irgrp sb-posix::s-iwgrp sb-posix::s-ixgrp
19 sb-posix::s-iroth sb-posix::s-iwoth sb-posix::s-ixoth)))
22 (sb-posix:chdir *test-directory*)
26 (sb-posix:chdir (namestring *test-directory*))
34 (sb-posix:chdir #p"/")
38 (sb-posix:chdir *current-directory*)
42 (sb-posix:chdir "/../")
46 (sb-posix:chdir #p"/../")
50 (sb-posix:chdir (make-pathname :directory '(:absolute :up)))
53 (deftest chdir.error.1
54 (let ((dne (make-pathname :directory '(:relative "chdir.does-not-exist"))))
56 (sb-posix:chdir (merge-pathnames dne *test-directory*))
57 (sb-posix:syscall-error (c)
58 (sb-posix:syscall-errno c))))
61 (deftest chdir.error.2
63 (sb-posix:chdir *this-file*)
64 (sb-posix:syscall-error (c)
65 (sb-posix:syscall-errno c)))
69 (let ((dne (make-pathname :directory '(:relative "mkdir.does-not-exist.1"))))
71 (sb-posix:mkdir (merge-pathnames dne *test-directory*) 0)
72 ;; FIXME: no delete-directory in CL, but using our own operators
73 ;; is probably not ideal
74 (ignore-errors (sb-posix:rmdir (merge-pathnames dne *test-directory*)))))
78 (let ((dne (make-pathname :directory '(:relative "mkdir.does-not-exist.2"))))
80 (sb-posix:mkdir (namestring (merge-pathnames dne *test-directory*)) 0)
81 (ignore-errors (sb-posix:rmdir (merge-pathnames dne *test-directory*)))))
84 (deftest mkdir.error.1
86 (sb-posix:mkdir *test-directory* 0)
87 (sb-posix:syscall-error (c)
88 (sb-posix:syscall-errno c)))
91 (deftest mkdir.error.2
93 (sb-posix:mkdir "/" 0)
94 (sb-posix:syscall-error (c)
95 (sb-posix:syscall-errno c)))
98 (deftest mkdir.error.3
99 (let* ((dir (merge-pathnames
100 (make-pathname :directory '(:relative "mkdir.error.3"))
102 (dir2 (merge-pathnames
103 (make-pathname :directory '(:relative "does-not-exist"))
105 (sb-posix:mkdir dir 0)
107 (sb-posix:mkdir dir2 0)
108 (sb-posix:syscall-error (c)
110 (sb-posix:syscall-errno c))
112 (sb-posix:rmdir dir2)
118 (let ((dne (make-pathname :directory '(:relative "rmdir.does-not-exist.1"))))
119 (ensure-directories-exist (merge-pathnames dne *test-directory*))
120 (sb-posix:rmdir (merge-pathnames dne *test-directory*)))
124 (let ((dne (make-pathname :directory '(:relative "rmdir.does-not-exist.2"))))
125 (ensure-directories-exist (merge-pathnames dne *test-directory*))
126 (sb-posix:rmdir (namestring (merge-pathnames dne *test-directory*))))
129 (deftest rmdir.error.1
130 (let ((dne (make-pathname :directory '(:relative "rmdir.dne.error.1"))))
132 (sb-posix:rmdir (merge-pathnames dne *test-directory*))
133 (sb-posix:syscall-error (c)
134 (sb-posix:syscall-errno c))))
137 (deftest rmdir.error.2
139 (sb-posix:rmdir *this-file*)
140 (sb-posix:syscall-error (c)
141 (sb-posix:syscall-errno c)))
144 (deftest rmdir.error.3
147 (sb-posix:syscall-error (c)
148 (sb-posix:syscall-errno c)))
151 (deftest rmdir.error.4
152 (let* ((dir (ensure-directories-exist
154 (make-pathname :directory '(:relative "rmdir.error.4"))
156 (file (make-pathname :name "foo" :defaults dir)))
157 (with-open-file (s file :direction :output)
158 (write "" :stream s))
161 (sb-posix:syscall-error (c)
164 (let ((errno (sb-posix:syscall-errno c)))
165 ;; documented by POSIX
166 (or (= errno sb-posix::eexist) (= errno sb-posix::enotempty))))))
169 (deftest rmdir.error.5
170 (let* ((dir (merge-pathnames
171 (make-pathname :directory '(:relative "rmdir.error.5"))
173 (dir2 (merge-pathnames
174 (make-pathname :directory '(:relative "unremovable"))
176 (sb-posix:mkdir dir +mode-rwx-all+)
177 (sb-posix:mkdir dir2 +mode-rwx-all+)
178 (sb-posix:chmod dir 0)
180 (sb-posix:rmdir dir2)
181 (sb-posix:syscall-error (c)
182 (sb-posix:chmod dir (logior sb-posix::s-iread sb-posix::s-iwrite sb-posix::s-iexec))
183 (sb-posix:rmdir dir2)
185 (sb-posix:syscall-errno c))
187 (sb-posix:chmod dir (logior sb-posix::s-iread sb-posix::s-iwrite sb-posix::s-iexec))
193 (let* ((stat (sb-posix:stat *test-directory*))
194 (mode (sb-posix::stat-mode stat)))
195 ;; FIXME: Ugly ::s everywhere
196 (logand mode (logior sb-posix::s-iread sb-posix::s-iwrite sb-posix::s-iexec)))
197 #.(logior sb-posix::s-iread sb-posix::s-iwrite sb-posix::s-iexec))
200 (let* ((stat (sb-posix:stat "/"))
201 (mode (sb-posix::stat-mode stat)))
202 ;; it's logically possible for / to be writeable by others... but
203 ;; if it is, either someone is playing with strange security
204 ;; modules or they want to know about it anyway.
205 (logand mode sb-posix::s-iwoth))
209 (let* ((now (get-universal-time))
210 ;; FIXME: (encode-universal-time 00 00 00 01 01 1970)
211 (unix-now (- now 2208988800))
212 (stat (sb-posix:stat *test-directory*))
213 (atime (sb-posix::stat-atime stat)))
214 ;; FIXME: breaks if mounted noatime :-(
215 (< (- atime unix-now) 10))
219 (let* ((stat (sb-posix:stat (make-pathname :directory '(:absolute :up))))
220 (mode (sb-posix::stat-mode stat)))
221 ;; it's logically possible for / to be writeable by others... but
222 ;; if it is, either someone is playing with strange security
223 ;; modules or they want to know about it anyway.
224 (logand mode sb-posix::s-iwoth))
227 ;;; FIXME: add tests for carrying a stat structure around in the
228 ;;; optional argument to SB-POSIX:STAT
230 (deftest stat.error.1
231 (handler-case (sb-posix:stat "")
232 (sb-posix:syscall-error (c)
233 (sb-posix:syscall-errno c)))
236 (deftest stat.error.2
237 (let* ((dir (merge-pathnames
238 (make-pathname :directory '(:relative "stat.error.2"))
240 (file (merge-pathnames
241 (make-pathname :name "unstatable")
243 (sb-posix:mkdir dir +mode-rwx-all+)
244 (with-open-file (s file :direction :output)
245 (write "" :stream s))
246 (sb-posix:chmod dir 0)
249 (sb-posix:syscall-error (c)
250 (sb-posix:chmod dir (logior sb-posix::s-iread sb-posix::s-iwrite sb-posix::s-iexec))
251 (sb-posix:unlink file)
253 (sb-posix:syscall-errno c))
255 (sb-posix:chmod dir (logior sb-posix::s-iread sb-posix::s-iwrite sb-posix::s-iexec))
256 (sb-posix:unlink file)
262 (defmacro with-stat-mode ((mode pathname) &body body)
263 (let ((stat (gensym)))
264 `(let* ((,stat (sb-posix:stat ,pathname))
265 (,mode (sb-posix::stat-mode ,stat)))
268 (defmacro with-lstat-mode ((mode pathname) &body body)
269 (let ((stat (gensym)))
270 `(let* ((,stat (sb-posix:lstat ,pathname))
271 (,mode (sb-posix::stat-mode ,stat)))
275 (with-stat-mode (mode *test-directory*)
276 (sb-posix:s-isreg mode))
280 (with-stat-mode (mode *test-directory*)
281 (sb-posix:s-isdir mode))
285 (with-stat-mode (mode *test-directory*)
286 (sb-posix:s-ischr mode))
290 (with-stat-mode (mode *test-directory*)
291 (sb-posix:s-isblk mode))
295 (with-stat-mode (mode *test-directory*)
296 (sb-posix:s-isfifo mode))
300 (with-stat-mode (mode *test-directory*)
301 (sb-posix:s-issock mode))
305 (let ((link-pathname (make-pathname :name "stat-mode.7"
306 :defaults *test-directory*)))
309 (sb-posix:symlink *test-directory* link-pathname)
310 (with-lstat-mode (mode link-pathname)
311 (sb-posix:s-islnk mode)))
312 (ignore-errors (sb-posix:unlink link-pathname))))
316 (let ((pathname (make-pathname :name "stat-mode.8"
317 :defaults *test-directory*)))
320 (with-open-file (out pathname :direction :output)
321 (write-line "test" out))
322 (with-stat-mode (mode pathname)
323 (sb-posix:s-isreg mode)))
324 (ignore-errors (delete-file pathname))))
327 ;;; see comment in filename's designator definition, in macros.lisp
328 (deftest filename-designator.1
329 (let ((file (format nil "~A/[foo].txt" (namestring *test-directory*))))
330 ;; creat() with a string as argument
331 (sb-posix:creat file 0)
332 ;; if this test fails, it will probably be with
333 ;; "System call error 2 (No such file or directory)"
334 (let ((*default-pathname-defaults* *test-directory*))
335 (sb-posix:unlink (car (directory "*.txt")))))
339 (let ((fd (sb-posix:open *test-directory* sb-posix::o-rdonly)))
340 (ignore-errors (sb-posix:close fd))
344 (deftest open.error.1
345 (handler-case (sb-posix:open *test-directory* sb-posix::o-wronly)
346 (sb-posix:syscall-error (c)
347 (sb-posix:syscall-errno c)))
351 (let ((fd (sb-posix:open "/dev/null" sb-posix::o-nonblock)))
352 (= (sb-posix:fcntl fd sb-posix::f-getfl) sb-posix::o-nonblock))