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 | + |