Raymond Toy pushed to branch issue-381-cmucl-unix-os-specific at cmucl / cmucl
Commits:
-
03081eeb
by Raymond Toy at 2025-02-17T01:52:03+00:00
-
ee669070
by Raymond Toy at 2025-02-17T01:52:04+00:00
-
459c91bc
by Raymond Toy at 2025-02-18T02:53:23+00:00
-
daf83c84
by Raymond Toy at 2025-02-18T02:53:23+00:00
-
ef48eb2a
by Carl Shapiro at 2025-02-18T22:46:55-08:00
-
6c8861a0
by Raymond Toy at 2025-02-20T13:55:13+00:00
-
5b452f9a
by Raymond Toy at 2025-02-20T13:55:13+00:00
-
a6846d44
by Raymond Toy at 2025-02-21T03:13:50+00:00
-
f21c6507
by Raymond Toy at 2025-02-21T03:13:51+00:00
-
f370206e
by Raymond Toy at 2025-02-21T13:25:03+00:00
-
8ea8e2a0
by Raymond Toy at 2025-02-21T13:25:03+00:00
-
576f422e
by Raymond Toy at 2025-02-21T05:42:51-08:00
-
cb65bb7e
by Raymond Toy at 2025-02-21T05:52:50-08:00
-
705a8753
by Raymond Toy at 2025-02-21T07:06:41-08:00
-
5fb73c95
by Raymond Toy at 2025-02-21T07:20:13-08:00
10 changed files:
- src/code/commandline.lisp
- src/code/pathname.lisp
- src/code/unix.lisp
- src/docs/cmu-user/unix.tex
- src/general-info/release-21f.md
- src/i18n/locale/cmucl-unix.pot
- src/i18n/locale/cmucl.pot
- src/lisp/Linux-os.c
- src/lisp/elf.h
- + tests/unix.lisp
Changes:
... | ... | @@ -190,17 +190,17 @@ |
190 | 190 | (demons *command-switch-demons*))
|
191 | 191 | (flet ((invoke-demon (switch)
|
192 | 192 | (let* ((name (cmd-switch-name switch))
|
193 | - (demon (cdr (assoc name demons :test #'string-equal))))
|
|
193 | + (demon (cdr (assoc name demons :test #'string=))))
|
|
194 | 194 | (cond (demon (funcall demon switch))
|
195 | - ((or (member name *legal-cmd-line-switches* :test #'string-equal :key #'car)
|
|
195 | + ((or (member name *legal-cmd-line-switches* :test #'string= :key #'car)
|
|
196 | 196 | (not *complain-about-illegal-switches*)))
|
197 | 197 | (t (warn (intl:gettext "~S is an illegal switch") switch)))
|
198 | 198 | (lisp::finish-standard-output-streams))))
|
199 | 199 | ;; We want to process -help (or --help) first, if it's given.
|
200 | 200 | ;; Since we're asking for help, we don't want to process any of
|
201 | 201 | ;; the other switches.
|
202 | - (let ((maybe-help (or (find "help" switches :key #'cmd-switch-name :test #'string-equal)
|
|
203 | - (find "-help" switches :key #'cmd-switch-name :test #'string-equal))))
|
|
202 | + (let ((maybe-help (or (find "help" switches :key #'cmd-switch-name :test #'string=)
|
|
203 | + (find "-help" switches :key #'cmd-switch-name :test #'string=))))
|
|
204 | 204 | (if maybe-help
|
205 | 205 | (invoke-demon maybe-help)
|
206 | 206 | (dolist (switch switches t)
|
... | ... | @@ -268,13 +268,12 @@ |
268 | 268 | ;;; from parsed arguments.
|
269 | 269 | |
270 | 270 | #+darwin
|
271 | -(intl:with-textdomain ("cmucl-darwin-os")
|
|
272 | 271 | (defvar *enable-darwin-path-normalization* nil
|
273 | - "When non-NIL, pathnames are on Darwin are normalized when created.
|
|
272 | + _N"When non-NIL, pathnames are on Darwin are normalized when created.
|
|
274 | 273 | Otherwise, the pathnames are unchanged.
|
275 | 274 | |
276 | 275 | This must be NIL during bootstrapping because Unicode is not yet
|
277 | - available."))
|
|
276 | + available.")
|
|
278 | 277 | |
279 | 278 | (defun %make-pathname-object (host device directory name type version)
|
280 | 279 | (if (typep host 'logical-host)
|
... | ... | @@ -2053,9 +2053,7 @@ |
2053 | 2053 | _N"Returns a string describing the error number which was returned by a
|
2054 | 2054 | UNIX system call."
|
2055 | 2055 | (declare (type integer error-number))
|
2056 | - (if (array-in-bounds-p *unix-errors* error-number)
|
|
2057 | - (svref *unix-errors* error-number)
|
|
2058 | - (format nil _"Unknown error [~d]" error-number)))
|
|
2056 | + (unix::unix-strerror error-number))
|
|
2059 | 2057 | |
2060 | 2058 | |
2061 | 2059 | ;;;; Lisp types used by syscalls.
|
... | ... | @@ -2913,28 +2911,82 @@ |
2913 | 2911 | (defun unix-mkstemp (template)
|
2914 | 2912 | _N"Generates a unique temporary file name from TEMPLATE, and creates
|
2915 | 2913 | and opens the file. On success, the corresponding file descriptor
|
2916 | - and name of the file is returned.
|
|
2917 | - |
|
2918 | - The last six characters of the template must be \"XXXXXX\"."
|
|
2919 | - ;; Hope this buffer is large enough!
|
|
2920 | - (let ((octets (%name->file template)))
|
|
2921 | - (syscall ("mkstemp" c-call:c-string)
|
|
2914 | + and name of the file is returned. Otherwise, NIL and the UNIX error
|
|
2915 | + code is returned."
|
|
2916 | + (let* ((format (if (eql *filename-encoding* :null)
|
|
2917 | + :iso8859-1
|
|
2918 | + *filename-encoding*))
|
|
2919 | + ;; Convert the string to octets using the
|
|
2920 | + ;; *FILENAME-ENCODING*. Should we signal an error if the
|
|
2921 | + ;; string can't be encoded?
|
|
2922 | + (octets (stream:string-to-octets template
|
|
2923 | + :external-format format))
|
|
2924 | + (length (length octets)))
|
|
2925 | + (with-alien ((buffer (* c-call:unsigned-char)))
|
|
2926 | + (setf buffer (make-alien c-call:unsigned-char (1+ length)))
|
|
2927 | + ;; Copy the octets from OCTETS to the null-terminated array BUFFER.
|
|
2928 | + (system:without-gcing
|
|
2929 | + (kernel:system-area-copy (vector-sap octets) 0
|
|
2930 | + (alien-sap buffer) 0
|
|
2931 | + (* length vm:byte-bits)))
|
|
2932 | + (setf (deref buffer length) 0)
|
|
2933 | + |
|
2934 | + (syscall ("mkstemp" (* c-call:char))
|
|
2922 | 2935 | (values result
|
2923 | - ;; Convert the file name back to a Lisp string.
|
|
2924 | - (%file->name octets))
|
|
2925 | - octets)))
|
|
2936 | + (progn
|
|
2937 | + ;; Copy out the alien bytes and convert back
|
|
2938 | + ;; to a lisp string.
|
|
2939 | + (system:without-gcing
|
|
2940 | + (kernel:system-area-copy (alien-sap buffer) 0
|
|
2941 | + (vector-sap octets) 0
|
|
2942 | + (* length vm:byte-bits)))
|
|
2943 | + (stream:octets-to-string octets
|
|
2944 | + :external-format format)))
|
|
2945 | + (cast buffer (* c-call:char))))))
|
|
2926 | 2946 | |
2927 | 2947 | (defun unix-mkdtemp (template)
|
2928 | - _N"Generate a uniquely named temporary directory from Template,
|
|
2929 | - which must have \"XXXXXX\" as the last six characters. The
|
|
2948 | + _N"Generate a uniquely named temporary directory from Template. The
|
|
2930 | 2949 | directory is created with permissions 0700. The name of the
|
2931 | - directory is returned."
|
|
2932 | - (let* ((octets (%name->file template))
|
|
2933 | - (result (alien-funcall
|
|
2934 | - (extern-alien "mkdtemp"
|
|
2935 | - (function (* char)
|
|
2936 | - c-call:c-string))
|
|
2937 | - octets)))
|
|
2938 | - (if (null-alien result)
|
|
2939 | - (values nil (unix-errno))
|
|
2940 | - (%file->name octets)))) |
|
2950 | + directory is returned.
|
|
2951 | + |
|
2952 | + If the directory cannot be created NIL and the UNIX error code is
|
|
2953 | + returned."
|
|
2954 | + (let* ((format (if (eql *filename-encoding* :null)
|
|
2955 | + :iso8859-1
|
|
2956 | + *filename-encoding*))
|
|
2957 | + ;; Encode the string using the appropriate
|
|
2958 | + ;; *filename-encoding*. Should we signal an error if the
|
|
2959 | + ;; string can't be encoded in that format?
|
|
2960 | + (octets (stream:string-to-octets template
|
|
2961 | + :external-format format))
|
|
2962 | + (length (length octets)))
|
|
2963 | + (with-alien ((buffer (* c-call:unsigned-char)))
|
|
2964 | + (setf buffer (make-alien c-call:unsigned-char (1+ length)))
|
|
2965 | + ;; Copy the octets from OCTETS to the null-terminated array BUFFER.
|
|
2966 | + (system:without-gcing
|
|
2967 | + (kernel:system-area-copy (vector-sap octets) 0
|
|
2968 | + (alien-sap buffer) 0
|
|
2969 | + (* length vm:byte-bits)))
|
|
2970 | + (setf (deref buffer length) 0)
|
|
2971 | + |
|
2972 | + (let ((result (alien-funcall
|
|
2973 | + (extern-alien "mkdtemp"
|
|
2974 | + (function (* char)
|
|
2975 | + (* char)))
|
|
2976 | + (cast buffer (* char)))))
|
|
2977 | + ;; If mkdtemp worked, a non-NIL value is returned, return the
|
|
2978 | + ;; resulting name. Otherwise, return NIL and the errno.
|
|
2979 | + (if (null-alien result)
|
|
2980 | + (values nil (unix-errno))
|
|
2981 | + (%file->name (cast result c-call:c-string)))))))
|
|
2982 | + |
|
2983 | +(defun unix-strerror (errno)
|
|
2984 | + _N"Returns a string that describes the error code Errno"
|
|
2985 | + (let ((result
|
|
2986 | + (alien-funcall
|
|
2987 | + (extern-alien "strerror"
|
|
2988 | + (function (* char) int))
|
|
2989 | + errno)))
|
|
2990 | + ;; Result from strerror can be localized so we need to decode
|
|
2991 | + ;; those octets to get a proper Lisp string.
|
|
2992 | + (string-decode (cast result c-string) :default))) |
... | ... | @@ -244,9 +244,10 @@ for SAPs when possible, so the consing overhead is generally minimal. |
244 | 244 | |
245 | 245 | \begin{defun}{system:}{sap-ref-8}{\args{\var{sap} \var{offset}}}
|
246 | 246 | \defunx[system:]{sap-ref-16}{\args{\var{sap} \var{offset}}}
|
247 | - \defunx[system:]{sap-ref-32}{\args{\var{sap} \var{offset}}}
|
|
248 | -
|
|
249 | - These functions return the 8, 16 or 32 bit unsigned integer at
|
|
247 | + \defunx[system:]{sap-ref-32}{\args{\var{sap} \var{offset}}
|
|
248 | + \defunx[system:]{sap-ref-64}{\args{\var{sap} \var{offset}}}
|
|
249 | + |
|
250 | + These functions return the 8, 16, 32 or 64 bit unsigned integer at
|
|
250 | 251 | \var{offset} from \var{sap}. The \var{offset} is always a byte
|
251 | 252 | offset, regardless of the number of bits accessed. \code{setf} may
|
252 | 253 | be used with the these functions to deposit values into virtual
|
... | ... | @@ -256,7 +257,8 @@ for SAPs when possible, so the consing overhead is generally minimal. |
256 | 257 | \begin{defun}{system:}{signed-sap-ref-8}{\args{\var{sap} \var{offset}}}
|
257 | 258 | \defunx[system:]{signed-sap-ref-16}{\args{\var{sap} \var{offset}}}
|
258 | 259 | \defunx[system:]{signed-sap-ref-32}{\args{\var{sap} \var{offset}}}
|
259 | -
|
|
260 | + \defunx[system:]{signed-sap-ref-64}{\args{\var{sap} \var{offset}}}
|
|
261 | + |
|
260 | 262 | These functions are the same as the above unsigned operations,
|
261 | 263 | except that they sign-extend, returning a negative number if the
|
262 | 264 | high bit is set.
|
... | ... | @@ -117,9 +117,12 @@ public domain. |
117 | 117 | * ~~#363~~ Version numbers added to files and directories. The
|
118 | 118 | distribution layout has changed.
|
119 | 119 | * ~~#364~~ Add interface to `mkdtemp` and `mkstemp`
|
120 | - * ~~#367~~ Add stream:string-count-octets to count octets in a string
|
|
120 | + * ~~#367~~ Add `stream:string-count-octets` to count octets in a string
|
|
121 | 121 | * ~~#369~~ Improve docstring for `unix::unix-setlocale`
|
122 | + * ~~#375~~ `unix-mkstemp` and `unix-mkdtemp` actually returns the
|
|
123 | + file names now.
|
|
122 | 124 | * ~~#379~~ Support GNU-style command-line option names
|
125 | + * ~~#382~~ Command-line options are case-sensitive
|
|
123 | 126 | * Other changes:
|
124 | 127 | * Improvements to the PCL implementation of CLOS:
|
125 | 128 | * Changes to building procedure:
|
... | ... | @@ -1284,10 +1284,6 @@ msgid "" |
1284 | 1284 | " UNIX system call."
|
1285 | 1285 | msgstr ""
|
1286 | 1286 | |
1287 | -#: src/code/unix.lisp
|
|
1288 | -msgid "Unknown error [~d]"
|
|
1289 | -msgstr ""
|
|
1290 | - |
|
1291 | 1287 | #: src/code/unix.lisp
|
1292 | 1288 | msgid ""
|
1293 | 1289 | "Perform the UNIX select(2) system call.\n"
|
... | ... | @@ -1434,16 +1430,21 @@ msgstr "" |
1434 | 1430 | msgid ""
|
1435 | 1431 | "Generates a unique temporary file name from TEMPLATE, and creates\n"
|
1436 | 1432 | " and opens the file. On success, the corresponding file descriptor\n"
|
1437 | -" and name of the file is returned.\n"
|
|
1438 | -"\n"
|
|
1439 | -" The last six characters of the template must be \"XXXXXX\"."
|
|
1433 | +" and name of the file is returned. Otherwise, NIL and the UNIX error\n"
|
|
1434 | +" code is returned."
|
|
1440 | 1435 | msgstr ""
|
1441 | 1436 | |
1442 | 1437 | #: src/code/unix.lisp
|
1443 | 1438 | msgid ""
|
1444 | -"Generate a uniquely named temporary directory from Template,\n"
|
|
1445 | -" which must have \"XXXXXX\" as the last six characters. The\n"
|
|
1439 | +"Generate a uniquely named temporary directory from Template. The\n"
|
|
1446 | 1440 | " directory is created with permissions 0700. The name of the\n"
|
1447 | -" directory is returned."
|
|
1441 | +" directory is returned.\n"
|
|
1442 | +"\n"
|
|
1443 | +" If the directory cannot be created NIL and the UNIX error code is\n"
|
|
1444 | +" returned."
|
|
1445 | +msgstr ""
|
|
1446 | + |
|
1447 | +#: src/code/unix.lisp
|
|
1448 | +msgid "Returns a string that describes the error code Errno"
|
|
1448 | 1449 | msgstr ""
|
1449 | 1450 |
... | ... | @@ -9667,6 +9667,15 @@ msgid "" |
9667 | 9667 | " an otherwise undefined logical host."
|
9668 | 9668 | msgstr ""
|
9669 | 9669 | |
9670 | +#: src/code/pathname.lisp
|
|
9671 | +msgid ""
|
|
9672 | +"When non-NIL, pathnames are on Darwin are normalized when created.\n"
|
|
9673 | +" Otherwise, the pathnames are unchanged.\n"
|
|
9674 | +"\n"
|
|
9675 | +" This must be NIL during bootstrapping because Unicode is not yet\n"
|
|
9676 | +" available."
|
|
9677 | +msgstr ""
|
|
9678 | + |
|
9670 | 9679 | #: src/code/pathname.lisp
|
9671 | 9680 | msgid "A path specification, either a string, file-stream or pathname."
|
9672 | 9681 | msgstr ""
|
... | ... | @@ -476,7 +476,7 @@ sigsegv_handler(HANDLER_ARGS) |
476 | 476 | #endif
|
477 | 477 | if (gc_write_barrier(code->si_addr))
|
478 | 478 | return;
|
479 | - DPRINTF(0, (stderr, "sigsegv: PC: %p\n", SC_PC(os_context)));
|
|
479 | + DPRINTF(0, (stderr, "sigsegv: PC: %#lx\n", SC_PC(os_context)));
|
|
480 | 480 | |
481 | 481 | #ifdef RED_ZONE_HIT
|
482 | 482 | {
|
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | * interface to both elf and mach-o support. I (rtoy) was too lazy to
|
10 | 10 | * change the name to something more descriptive.
|
11 | 11 | */
|
12 | -#if !defined(_ELF_H_INCLUDED_)
|
|
12 | +#if !defined(ELF_H_INCLUDED)
|
|
13 | 13 | |
14 | 14 | #define ELF_H_INCLUDED
|
15 | 15 |
1 | +;;; Tests for the unix interface
|
|
2 | + |
|
3 | +(defpackage :unix-tests
|
|
4 | + (:use :cl :lisp-unit))
|
|
5 | + |
|
6 | +(in-package "UNIX-TESTS")
|
|
7 | + |
|
8 | +(define-test mkstemp.name-returned
|
|
9 | + (:tag :issues)
|
|
10 | + (let (fd filename)
|
|
11 | + (unwind-protect
|
|
12 | + (progn
|
|
13 | + (let ((template "test-XXXXXX"))
|
|
14 | + (multiple-value-setq (fd filename)
|
|
15 | + (unix::unix-mkstemp (copy-seq template)))
|
|
16 | + (assert-true fd)
|
|
17 | + (assert-true (equalp (length filename) (length template)))
|
|
18 | + (assert-false (equalp filename template))
|
|
19 | + (assert-true (>= 5 (mismatch filename template))))))
|
|
20 | + (when fd
|
|
21 | + (unix:unix-unlink filename)))))
|
|
22 | + |
|
23 | +(define-test mkstemp.non-ascii-name-returned
|
|
24 | + (:tag :issues)
|
|
25 | + (let ((unix::*filename-encoding* :utf-8)
|
|
26 | + fd name)
|
|
27 | + (unwind-protect
|
|
28 | + (progn
|
|
29 | + ;; Temp name starts with a lower case alpha character.
|
|
30 | + (let* ((template (concatenate 'string (string #\u+3b1)
|
|
31 | + "test-XXXXXX"))
|
|
32 | + (x-posn (position #\X template)))
|
|
33 | + (multiple-value-setq (fd name)
|
|
34 | + (unix::unix-mkstemp template))
|
|
35 | + (assert-true fd)
|
|
36 | + (assert-false (search "XXXXXX" name)
|
|
37 | + name)
|
|
38 | + (assert-true (string= name template :end1 x-posn :end2 x-posn)
|
|
39 | + name)))
|
|
40 | + (when fd
|
|
41 | + (unix:unix-unlink name)))))
|
|
42 | + |
|
43 | +(define-test mkstemp.bad-path
|
|
44 | + (:tag :issues)
|
|
45 | + (multiple-value-bind (fd errno)
|
|
46 | + ;; Assumes that the directory "random-dir" doesn't exist
|
|
47 | + (unix::unix-mkstemp "random-dir/test-XXXXXX")
|
|
48 | + ;; Can't create and open the file so the FD should be NIL, and a
|
|
49 | + ;; positive Unix errno value should be returned.
|
|
50 | + (assert-false fd)
|
|
51 | + (assert-true (and (integerp errno) (plusp errno)))))
|
|
52 | + |
|
53 | +(define-test mkdtemp.name-returned
|
|
54 | + (:tag :issues)
|
|
55 | + (let (name)
|
|
56 | + (unwind-protect
|
|
57 | + (progn
|
|
58 | + (setf name (unix::unix-mkdtemp "dir-XXXXXX"))
|
|
59 | + ;; Verify that the dir name no longer has X's.
|
|
60 | + (assert-true (stringp name))
|
|
61 | + (assert-false (search "XXXXXX" name)))
|
|
62 | + (when name
|
|
63 | + (unix:unix-rmdir name)))))
|
|
64 | + |
|
65 | +(define-test mkdtemp.non-ascii-name-returned
|
|
66 | + (:tag :issues)
|
|
67 | + (let ((unix::*filename-encoding* :utf-8)
|
|
68 | + name)
|
|
69 | + (unwind-protect
|
|
70 | + (progn
|
|
71 | + ;; Temp name starts with a lower case alpha character.
|
|
72 | + (let* ((template (concatenate 'string (string #\u+3b1)
|
|
73 | + "dir-XXXXXX"))
|
|
74 | + (x-posn (position #\X template)))
|
|
75 | + (setf name (unix::unix-mkdtemp template))
|
|
76 | + ;; Verify that the dir name no longer has X's.
|
|
77 | + (assert-true (stringp name))
|
|
78 | + (assert-false (search "XXXXXX" name))
|
|
79 | + (assert-true (string= name template :end1 x-posn :end2 x-posn)
|
|
80 | + name x-posn)))
|
|
81 | + (when name
|
|
82 | + (unix:unix-rmdir name)))))
|
|
83 | + |
|
84 | +(define-test mkdtemp.bad-path
|
|
85 | + (:tag :issues)
|
|
86 | + (multiple-value-bind (result errno)
|
|
87 | + (unix::unix-mkdtemp "random-dir/dir-XXXXXX")
|
|
88 | + (assert-false result)
|
|
89 | + (assert-true (and (integerp errno) (plusp errno)))))
|
|
90 | + |
|
91 | + |