[Git][cmucl/cmucl][issue-365-add-strerror] 6 commits: Autogenerate def-unix-errors in code/unix-errno.lisp
Raymond Toy pushed to branch issue-365-add-strerror at cmucl / cmucl Commits: 967de6a7 by Raymond Toy at 2025-01-30T06:58:14-08:00 Autogenerate def-unix-errors in code/unix-errno.lisp Add the file create-errno.c that generates prints out appropriate `def-unix-error` forms. Add a make rule in GNUMakefile to build `create-errno`. This means we had to comment out the rules for internals.h/internals.inc because we need to run make to create unix-errno.lisp before doing the build. Update Config.x86_linux with a make rule to create code/unix-errno.lisp via create-errno. - - - - - d122b95f by Raymond Toy at 2025-01-30T07:01:45-08:00 Add rule to create code/unix-errno.lisp Just copied from Config.x86_linux. - - - - - 07a998ee by Raymond Toy at 2025-01-30T07:31:19-08:00 Add CMUCL-style file header to unix-errno.lisp Make the generated file look like a typical source file. And add a note not to edit the file because it's autogenerated. - - - - - 034c685d by Raymond Toy at 2025-01-30T07:42:59-08:00 Preserve def-unix-error for other OSes than Linux (for now) Since on Linux we currently auto-generate the errno definitions, we don't need to define them here. For other OSes, we leave the definitions here until they are also auto-generated. - - - - - 55db6026 by Raymond Toy at 2025-01-30T07:44:09-08:00 Create code/unix-errno.lisp before compiling the world We need to generate code/unix-errno.lisp before compiling the world. Call make to do that. - - - - - e3504ec0 by Raymond Toy at 2025-01-30T07:44:59-08:00 Compile and load code/unix-errno.lisp This is only done for Linux for now since we only generate this file on Linux. - - - - - 8 changed files: - bin/build.sh - src/code/unix.lisp - src/lisp/Config.x86_linux - src/lisp/Config.x86_linux_clang - src/lisp/GNUmakefile - + src/lisp/create-errno.c - src/tools/worldbuild.lisp - src/tools/worldcom.lisp Changes: ===================================== bin/build.sh ===================================== @@ -129,6 +129,8 @@ buildit () if [ "$ENABLE" = "yes" ]; then $TOOLDIR/clean-target.sh $CLEAN_FLAGS $TARGET || { echo "Failed: $TOOLDIR/clean-target.sh"; exit 1; } + # Generate code/unix-errno.lisp + $MAKE -C $TARGET/lisp ../code/unix-errno.lisp time $BUILDWORLD $TARGET $OLDLISP $BOOT || { echo "Failed: $BUILDWORLD"; exit 1; } if [ "$REBUILD_LISP" = "yes" ]; then $TOOLDIR/rebuild-lisp.sh $TARGET ===================================== src/code/unix.lisp ===================================== @@ -1742,13 +1742,16 @@ (defparameter *compiler-unix-errors* nil) -(defmacro def-unix-error (name number description) +(defmacro def-unix-error (name number &optional description) + "Define a constant named Name corresponding to the Unix errno value + Number. A description of the errno is optional in Description." `(progn (eval-when (compile eval) (push (cons ,number ,description) *compiler-unix-errors*)) (defconstant ,name ,number ,description) (export ',name))) +#-linux (defmacro emit-unix-errors () (let* ((max (apply #'max (mapcar #'car *compiler-unix-errors*))) (array (make-array (1+ max) :initial-element nil))) @@ -1760,6 +1763,10 @@ ) ;eval-when +;;; For Linux, the def-unix-error forms are auto-generated and are not +;;; defined here. +#-linux +(progn ;;; ;;; From <errno.h> ;;; @@ -1945,101 +1952,11 @@ (def-unix-error EINPROGRESS 150 _N"Operation now in progress") (def-unix-error ESTALE 151 _N"Stale NFS file handle") ) -#+linux -(progn -(def-unix-error EDEADLK 35 _N"Resource deadlock would occur") -(def-unix-error ENAMETOOLONG 36 _N"File name too long") -(def-unix-error ENOLCK 37 _N"No record locks available") -(def-unix-error ENOSYS 38 _N"Function not implemented") -(def-unix-error ENOTEMPTY 39 _N"Directory not empty") -(def-unix-error ELOOP 40 _N"Too many symbolic links encountered") -(def-unix-error EWOULDBLOCK 11 _N"Operation would block") -(def-unix-error ENOMSG 42 _N"No message of desired type") -(def-unix-error EIDRM 43 _N"Identifier removed") -(def-unix-error ECHRNG 44 _N"Channel number out of range") -(def-unix-error EL2NSYNC 45 _N"Level 2 not synchronized") -(def-unix-error EL3HLT 46 _N"Level 3 halted") -(def-unix-error EL3RST 47 _N"Level 3 reset") -(def-unix-error ELNRNG 48 _N"Link number out of range") -(def-unix-error EUNATCH 49 _N"Protocol driver not attached") -(def-unix-error ENOCSI 50 _N"No CSI structure available") -(def-unix-error EL2HLT 51 _N"Level 2 halted") -(def-unix-error EBADE 52 _N"Invalid exchange") -(def-unix-error EBADR 53 _N"Invalid request descriptor") -(def-unix-error EXFULL 54 _N"Exchange full") -(def-unix-error ENOANO 55 _N"No anode") -(def-unix-error EBADRQC 56 _N"Invalid request code") -(def-unix-error EBADSLT 57 _N"Invalid slot") -(def-unix-error EDEADLOCK EDEADLK _N"File locking deadlock error") -(def-unix-error EBFONT 59 _N"Bad font file format") -(def-unix-error ENOSTR 60 _N"Device not a stream") -(def-unix-error ENODATA 61 _N"No data available") -(def-unix-error ETIME 62 _N"Timer expired") -(def-unix-error ENOSR 63 _N"Out of streams resources") -(def-unix-error ENONET 64 _N"Machine is not on the network") -(def-unix-error ENOPKG 65 _N"Package not installed") -(def-unix-error EREMOTE 66 _N"Object is remote") -(def-unix-error ENOLINK 67 _N"Link has been severed") -(def-unix-error EADV 68 _N"Advertise error") -(def-unix-error ESRMNT 69 _N"Srmount error") -(def-unix-error ECOMM 70 _N"Communication error on send") -(def-unix-error EPROTO 71 _N"Protocol error") -(def-unix-error EMULTIHOP 72 _N"Multihop attempted") -(def-unix-error EDOTDOT 73 _N"RFS specific error") -(def-unix-error EBADMSG 74 _N"Not a data message") -(def-unix-error EOVERFLOW 75 _N"Value too large for defined data type") -(def-unix-error ENOTUNIQ 76 _N"Name not unique on network") -(def-unix-error EBADFD 77 _N"File descriptor in bad state") -(def-unix-error EREMCHG 78 _N"Remote address changed") -(def-unix-error ELIBACC 79 _N"Can not access a needed shared library") -(def-unix-error ELIBBAD 80 _N"Accessing a corrupted shared library") -(def-unix-error ELIBSCN 81 _N".lib section in a.out corrupted") -(def-unix-error ELIBMAX 82 _N"Attempting to link in too many shared libraries") -(def-unix-error ELIBEXEC 83 _N"Cannot exec a shared library directly") -(def-unix-error EILSEQ 84 _N"Illegal byte sequence") -(def-unix-error ERESTART 85 _N"Interrupted system call should be restarted _N") -(def-unix-error ESTRPIPE 86 _N"Streams pipe error") -(def-unix-error EUSERS 87 _N"Too many users") -(def-unix-error ENOTSOCK 88 _N"Socket operation on non-socket") -(def-unix-error EDESTADDRREQ 89 _N"Destination address required") -(def-unix-error EMSGSIZE 90 _N"Message too long") -(def-unix-error EPROTOTYPE 91 _N"Protocol wrong type for socket") -(def-unix-error ENOPROTOOPT 92 _N"Protocol not available") -(def-unix-error EPROTONOSUPPORT 93 _N"Protocol not supported") -(def-unix-error ESOCKTNOSUPPORT 94 _N"Socket type not supported") -(def-unix-error EOPNOTSUPP 95 _N"Operation not supported on transport endpoint") -(def-unix-error EPFNOSUPPORT 96 _N"Protocol family not supported") -(def-unix-error EAFNOSUPPORT 97 _N"Address family not supported by protocol") -(def-unix-error EADDRINUSE 98 _N"Address already in use") -(def-unix-error EADDRNOTAVAIL 99 _N"Cannot assign requested address") -(def-unix-error ENETDOWN 100 _N"Network is down") -(def-unix-error ENETUNREACH 101 _N"Network is unreachable") -(def-unix-error ENETRESET 102 _N"Network dropped connection because of reset") -(def-unix-error ECONNABORTED 103 _N"Software caused connection abort") -(def-unix-error ECONNRESET 104 _N"Connection reset by peer") -(def-unix-error ENOBUFS 105 _N"No buffer space available") -(def-unix-error EISCONN 106 _N"Transport endpoint is already connected") -(def-unix-error ENOTCONN 107 _N"Transport endpoint is not connected") -(def-unix-error ESHUTDOWN 108 _N"Cannot send after transport endpoint shutdown") -(def-unix-error ETOOMANYREFS 109 _N"Too many references: cannot splice") -(def-unix-error ETIMEDOUT 110 _N"Connection timed out") -(def-unix-error ECONNREFUSED 111 _N"Connection refused") -(def-unix-error EHOSTDOWN 112 _N"Host is down") -(def-unix-error EHOSTUNREACH 113 _N"No route to host") -(def-unix-error EALREADY 114 _N"Operation already in progress") -(def-unix-error EINPROGRESS 115 _N"Operation now in progress") -(def-unix-error ESTALE 116 _N"Stale NFS file handle") -(def-unix-error EUCLEAN 117 _N"Structure needs cleaning") -(def-unix-error ENOTNAM 118 _N"Not a XENIX named type file") -(def-unix-error ENAVAIL 119 _N"No XENIX semaphores available") -(def-unix-error EISNAM 120 _N"Is a named type file") -(def-unix-error EREMOTEIO 121 _N"Remote I/O error") -(def-unix-error EDQUOT 122 _N"Quota exceeded") -) ;;; ;;; And now for something completely different ... (emit-unix-errors) +) (def-alien-routine ("os_get_errno" unix-get-errno) int) (def-alien-routine ("os_set_errno" unix-set-errno) int (newvalue int)) ===================================== src/lisp/Config.x86_linux ===================================== @@ -14,3 +14,6 @@ OS_LINK_FLAGS = -m32 -rdynamic -Xlinker --export-dynamic -Xlinker -Map -Xlinker OS_LINK_FLAGS += -Wl,-z,noexecstack EXEC_FINAL_OBJ = exec-final.o + +../code/unix-errno.lisp : create-errno + ./create-errno /usr/include/asm-generic/errno* | uniq > $@ ===================================== src/lisp/Config.x86_linux_clang ===================================== @@ -19,3 +19,6 @@ OS_LINK_FLAGS = -m32 -rdynamic -Xlinker --export-dynamic -Xlinker -Map -Xlinker OS_LINK_FLAGS += -Wl,-z,noexecstack EXEC_FINAL_OBJ = exec-final.o + +../code/unix-errno.lisp : create-errno + ./create-errno /usr/include/asm-generic/errno* | uniq > $@ ===================================== src/lisp/GNUmakefile ===================================== @@ -66,9 +66,9 @@ endif version: echo 0 > version -internals.h internals.inc: - @echo "You must run genesis to create internals.h!" - @false +#internals.h internals.inc: +# @echo "You must run genesis to create internals.h!" +# @false clean: $(RM) Depends *.o lisp lisp.nm core lisp.a @@ -139,3 +139,7 @@ translations-update: done; done +# Compile program that creates the unix-error.lisp file. Actual +# generation of the file is OS-dependent. +create-errno : create-errno.c + $(CC) -o $@ $^ ===================================== src/lisp/create-errno.c ===================================== @@ -0,0 +1,91 @@ +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +struct Err { + char *name; + int num; +#if 0 + char *descr; +#endif +} err[256]; + +int nerr = 0; + +regex_t reg; + +void match(const char *line) { + regmatch_t match[3]; + regoff_t len; + + if (regexec(®, line, 3, match, 0) == REG_NOMATCH) + return; + + len = match[1].rm_eo - match[1].rm_so; + err[nerr].name = malloc(len + 1); + sprintf(err[nerr].name, "%.*s", len, line + match[1].rm_so); + + err[nerr].num = atoi(line + match[2].rm_so); + +#if 0 + err[nerr].descr = strerror(err[nerr].num); +#endif + + nerr++; +} + +int cmp(const void *a, const void *b) { + return ((struct Err *)a)->num - ((struct Err *)b)->num; +} + +int main(int argc, char **argv) +{ + int i; + FILE *fp; + char line[1024]; + + regcomp(®, "^#define[ \t]*(E[A-Z0-9]+)[ \t]*([0-9]+)", REG_EXTENDED); + + for (i = 1; i < argc; i++) { + if ((fp = fopen(argv[i], "r")) == NULL) { + perror("fopen"); + exit(1); + } + while (fgets(line, sizeof(line), fp) != NULL) + match(line); + fclose(fp); + } + + qsort(err, nerr, sizeof(*err), cmp); + + /* + * Print out CMUCL-style file header + */ + puts(";;; -*- Package: UNIX -*-\n\ +;;;\n\ +;;; **********************************************************************\n\ +;;; This code was written as part of the CMU Common Lisp project at\n\ +;;; Carnegie Mellon University, and has been placed in the public domain.\n\ +;;;\n\ +(ext:file-comment\n\ + \"$Header: src/code/unix-errno.lisp $\")\n\ +;;;\n\ +;;; **********************************************************************\n\ +;;;\n\ +;;; This file contains the values of the UNIX errno values.\n\ +;;;\n \ +;;; DO NOT EDIT! This is auto-generated from create-errno.\n\ +;;;\n"); + + puts("(in-package \"UNIX\")\n"); + for (i = 0; i < nerr; i++) { +#if 0 + printf("(def-unix-error %s %d \"%s\")\n", err[i].name, err[i].num, err[i].descr); +#else + printf("(def-unix-error %s %d)\n", err[i].name, err[i].num); +#endif + } + + return 0; +} ===================================== src/tools/worldbuild.lisp ===================================== @@ -136,6 +136,10 @@ "target:code/c-call" "target:code/sap" "target:code/unix" + ,@(when (or (c:backend-featurep :linux)) + ;; This is currently only available for some OSes. Ideally, + ;; it should be available for all OSes. + "target:code/unix-errno") ,@(when (c:backend-featurep :mach) '("target:code/mach" "target:code/mach-os")) ===================================== src/tools/worldcom.lisp ===================================== @@ -163,6 +163,10 @@ (comf "target:code/mipsstrops") (comf "target:code/unix" :proceed t) +(when (or (c:backend-featurep :linux)) + ;; This is currently only available for some OSes. Ideally, it + ;; should be available for all OSes. + (comf "target:code/unix-errno" :proceed t)) (when (c:backend-featurep :mach) (comf "target:code/mach") View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/3c324a95caff5e9533c5628... -- View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/3c324a95caff5e9533c5628... You're receiving this email because of your account on gitlab.common-lisp.net.
participants (1)
-
Raymond Toy (@rtoy)