Raymond Toy pushed to branch master at cmucl / cmucl
Commits: 9245bc06 by Raymond Toy at 2014-11-15T17:04:49Z First cut at simplifying unix.lisp.
* Moved original unix.lisp to src/contrib/unix/unix.lisp. * Copied just enough from unix.lisp to compile and load the first build. (Second build doesn't yet work.) * Trimmed exports.lisp to the current UNIX symbols.
This is currently for Darwin/x86. Nothing else is supported yet.
- - - - - fdc539f9 by Raymond Toy at 2014-11-16T09:22:39Z Add more stuff to unix.lisp. Not yet enough to compile cmucl.
- - - - - fe8f398c by Raymond Toy at 2014-11-16T14:49:08Z Add more unix stuff.
* asdf wants unix-rmdir * Add some missing structs.
- - - - - 836d21bf by Raymond Toy at 2014-11-16T20:20:04Z Add more unix functions, for motif and hemlock.
- - - - - a71198af by Raymond Toy at 2014-11-16T20:20:23Z Fix indentation.
- - - - - 11ecbb80 by Raymond Toy at 2014-11-16T21:14:42Z More support for hemlock.
- - - - - db12154d by Raymond Toy at 2014-11-18T21:35:46Z Add UNIX-SYMLINK. This allows the testsuite to run. Tests behave as expected.
- - - - - 5efddf51 by Raymond Toy at 2014-12-02T19:57:34Z Merge branch 'master' into rtoy-unix-core
- - - - - 31cb9cfe by Raymond Toy at 2014-12-02T19:58:45Z Fix some silly typos!
- - - - - 822beed8 by Raymond Toy at 2014-12-02T20:18:57Z Try to collect some of the unix export names by file in which they are used.
Mostly as information on who uses what, but otherwise not necessary.
- - - - - 2a6b55bb by Raymond Toy at 2015-04-16T19:04:59Z Merge branch 'master' into rtoy-unix-core
- - - - - d3f0167d by Raymond Toy at 2015-04-18T16:39:26Z Put back a comment.
- - - - - 852b35a7 by Raymond Toy at 2015-04-18T16:40:05Z Remove items that are already in code/unix.lisp.
- - - - - 17c7bba5 by Raymond Toy at 2015-04-18T16:42:53Z Add a unix module so users can (require :unix) to get the rest of the unix package functions.
This is for backward copmatibility.
- - - - - b81c7be3 by Raymond Toy at 2015-04-21T19:55:56Z %name->file and %file->name macros need to be defined for contrib/unix/unix.lisp.
Why are these macros anyway? Can't they be functions?
- - - - - 4f53f883 by Raymond Toy at 2015-04-21T19:57:45Z Install unix.lisp along with asdf and defsystem.
- - - - - 77a830ba by Raymond Toy at 2015-04-21T20:43:58Z Compile unix.lisp like we do for asdf and defsystem.
- - - - - f2601215 by Raymond Toy at 2015-04-21T20:49:44Z Regenerated.
- - - - - 743c80c8 by Raymond Toy at 2015-05-03T22:46:09Z Move unix-glibc2.lisp to contrib/unix.
- - - - - d6b8e188 by Raymond Toy at 2015-05-03T22:48:18Z Small version of unix-glibc2.lisp that will compile lisp.
This is enough to get do a full build of cmucl, but not motif. More work needed; I didn't yet check build logs for warnings or errors.
- - - - - 3a837db1 by Raymond Toy at 2015-05-06T21:01:31Z Add support for hemlock.
With these additions, hemlock builds now and runs. (I only tested that hemlock starts and that text can be entered.)
- - - - - 3191f538 by Raymond Toy at 2015-05-06T21:07:00Z For linux, Load unix-glibc2.lisp instead of unix.lisp.
- - - - - 19997c21 by Raymond Toy at 2015-05-06T22:03:22Z Compile the appropriate unix contrib file.
- - - - - e549b338 by Raymond Toy at 2015-05-07T22:39:30Z Don't pass in the command line args to lisp when building asdf and friends.
The command line args aren't relevant to lisp.
- - - - - 6b33a1f0 by Raymond Toy at 2015-05-07T22:43:06Z Install the appropriate compiled unix file.
- - - - - d76358f8 by Raymond Toy at 2015-05-08T18:35:30Z Split the UNIX exports into linux and non-linux parts.
For the non-linux part, add all of the other symbols that are currently exported from the UNIX package.
- - - - - 1fe89808 by Raymond Toy at 2015-05-08T21:34:31Z Remove exports.
- - - - - 1b5ef8a9 by Raymond Toy at 2015-05-08T21:34:52Z Fix typo in reader conditional. Should be +linux.
- - - - - 6abb21d8 by Raymond Toy at 2015-05-08T21:38:14Z Export other symbols from the UNIX package.
- - - - - 4de937f5 by Raymond Toy at 2015-05-09T14:13:10Z Clean up UNIX exports, putting common items together.
- - - - - 16f35f1a by Raymond Toy at 2015-05-09T15:15:11Z Add UNIX functions that were previously missed.
- - - - - c5dfebd6 by Raymond Toy at 2015-05-09T15:19:26Z Merge branch 'master' into rtoy-unix-core
- - - - - 1bc6485e by Raymond Toy at 2015-05-10T09:23:45Z fchmod, creat, and utimes are in both unix and unix-glibc2.
- - - - - 494e09f2 by Raymond Toy at 2015-05-10T09:28:27Z Need unix-symlink in unix-glibc2 for tests.
- - - - - 8a9a7ae2 by Raymond Toy at 2015-05-10T09:43:23Z unix-glibc2 needs unix-munmap. prot_read is available for both.
- - - - - f957ba84 by Raymond Toy at 2015-05-10T09:58:38Z Both unix.lisp and unix-glibc2.lisp have unix-rmdir.
- - - - - 9a9c5377 by Raymond Toy at 2015-05-10T10:29:34Z Add a few comments.
- - - - - b7436b55 by Raymond Toy at 2015-05-10T10:29:50Z Remove the things that are already in code/unix-glibc2.
- - - - - f5368940 by Raymond Toy at 2015-05-10T10:47:55Z Oops. Forgot to remove mmap stuff for contrib/unix/unix-glibc2.lisp.
- - - - - eb4a83b4 by Raymond Toy at 2015-05-10T14:16:20Z Load up the unix fasl file using compile-file-pathname.
- - - - - 1f888009 by Raymond Toy at 2015-05-10T14:23:23Z Remove set -x that was accidentally left in.
- - - - - b3b95e25 by Raymond Toy at 2015-05-10T14:33:06Z Gather the other common symbols into one place, and leave conditionals for the ones that differ.
- - - - - 13513a76 by Raymond Toy at 2015-05-10T15:56:35Z Remove sgttyb from unix exports; run-program doesn't use it on linux.
- - - - - be68140d by Raymond Toy at 2015-05-11T19:34:06Z Add terminal-speeds to unix-glibc2.lisp.
- - - - - bff46014 by Raymond Toy at 2015-05-11T19:34:39Z Export FIONREAD and TERMINAL-SPEEDS. Bot unix and unix-glibc2 have these.
- - - - - 30055476 by Raymond Toy at 2015-05-11T19:44:18Z Remove terminal-speeds since it's in code/unix-glibc2.lisp now.
- - - - - e79435f6 by Raymond Toy at 2015-05-13T20:29:36Z Add support for solaris/sparc.
Includes * support for large files * unix-times * unix-get-minutes-west and friends * unix-uname
- - - - - dd85f37a by Raymond Toy at 2015-05-13T21:42:13Z Solaris needs u-int64-t.
- - - - - 56dac608 by Raymond Toy at 2015-05-13T21:44:15Z unix-uname needs struct utsname.
- - - - - f4d7036b by Raymond Toy at 2015-05-16T13:50:01Z Add stat and friends for solaris.
- - - - - 72afb878 by Raymond Toy at 2015-05-16T21:33:11Z Add timestruc-t for solaris. Needed by stat and stat64.
- - - - - 42675559 by Raymond Toy at 2015-05-16T21:59:29Z Export unix-uname. Used on linux and solaris.
- - - - - c076d550 by Raymond Toy at 2015-05-16T22:09:57Z Support for netbsd. From Robert Swindells.
- - - - - a08b9be0 by Raymond Toy at 2015-05-16T22:16:15Z Remove utsname and unix-uname.
- - - - - 68001f49 by Raymond Toy at 2015-05-17T07:45:18Z Add some comments from unix/unix.lisp.
- - - - - a85043ac by Raymond Toy at 2015-05-17T07:45:34Z Remove items that are in code/unix.lisp
- - - - - 0f59b9a3 by Raymond Toy at 2015-05-17T08:00:51Z Regenerated.
- - - - - e46eaa11 by Raymond Toy at 2015-05-17T08:15:28Z Regenerated.
- - - - - 7f683946 by Raymond Toy at 2015-05-17T17:04:37Z Add exported symbols for solaris unix.lisp.
- - - - - 7be5c100 by Raymond Toy at 2015-05-17T17:57:44Z More exported symbols for solaris.
- - - - - 0e3ab8bd by Raymond Toy at 2015-05-18T18:52:30Z Make sure the target directory exists before compiling the unix contrib.
- - - - -
11 changed files:
- bin/build.sh - bin/make-main-dist.sh - src/code/exports.lisp - src/code/module.lisp - src/code/unix-glibc2.lisp - src/code/unix.lisp - + src/contrib/load-unix.lisp - + src/contrib/unix/unix-glibc2.lisp - + src/contrib/unix/unix.lisp - src/i18n/locale/cmucl-unix-glibc2.pot - src/i18n/locale/cmucl-unix.pot
Changes:
===================================== bin/build.sh ===================================== --- a/bin/build.sh +++ b/bin/build.sh @@ -251,7 +251,7 @@ buildit
# Asdf and friends are part of the base install, so we need to build # them now. -$TARGET/lisp/lisp -noinit -nositeinit -batch "$@" << EOF || exit 3 +$TARGET/lisp/lisp -noinit -nositeinit -batch << EOF || exit 3 (in-package :cl-user) (setf (ext:search-list "target:") '("$TARGET/" "src/")) @@ -260,6 +260,12 @@ $TARGET/lisp/lisp -noinit -nositeinit -batch "$@" << EOF || exit 3
(compile-file "modules:asdf/asdf") (compile-file "modules:defsystem/defsystem") +(intl::install) +(ext:without-package-locks + (let ((path #-linux "modules:unix/unix" + #+linux "modules:unix/unix-glibc2")) + (ensure-directories-exist (compile-file-pathname path)) + (compile-file path))) EOF
===================================== bin/make-main-dist.sh ===================================== --- a/bin/make-main-dist.sh +++ b/bin/make-main-dist.sh @@ -133,6 +133,14 @@ do install -d ${GROUP} ${OWNER} -m 0755 $DESTDIR/lib/cmucl/lib/contrib/$f done
+case `uname -s` in + Linux*) UCONTRIB="unix-glibc2" ;; + *) UCONTRIB="unix" ;; +esac + +install -d ${GROUP} ${OWNER} -m 0755 $DESTDIR/lib/cmucl/lib/contrib/unix +install ${GROUP} ${OWNER} -m 0644 $TARGET/contrib/unix/$UCONTRIB.$FASL $DESTDIR/lib/cmucl/lib/contrib/unix + # Copy the source files for asdf and defsystem for f in `(cd src; find contrib/asdf contrib/defsystem -type f -print | grep -v CVS)` do
===================================== src/code/exports.lisp ===================================== --- a/src/code/exports.lisp +++ b/src/code/exports.lisp @@ -196,200 +196,349 @@ "NEGATE-BIGNUM" "SUBTRACT-BIGNUM"))
(defpackage "UNIX" - (:export "CADDR-T" "D-INO" "D-NAME" "D-NAMLEN" "D-OFF" "D-RECLEN" - "DADDR-T" "DEV-T" "DIRECT" "EXECGRP" "EXECOTH" "EXECOWN" "F-DUPFD" - "F-GETFD" "F-GETFL" "F-GETOWN" "F-SETFD" "F-SETFL" "F-SETOWN" - "FSFILCNT-T" "FSBLKCNT-T" "BLKCNT-T" - "FAPPEND" "FASYNC" "FCREAT" "FEXCL" "FIONREAD" "FNDELAY" "FTRUNC" - "F_TEST" "F_TLOCK" "UNIX-LOCKF" "F_LOCK" "F_ULOCK" - "F_OK" "GET-UNIX-ERROR-MSG" "GID-T" "INO-T" "IT-INTERVAL" - "IT-VALUE" "ITIMERVAL" "UNIX-SETITIMER" "UNIX-GETITIMER" - "BLKCNT-T" "FSBLKCNT-T" "FSFILCNT-T" - "F_TEST" "F_TLOCK" "F_LOCK" "F_ULOCK" "UNIX-LOCKF" - "PROT_READ" "PROT_WRITE" "PROT_EXEC" "PROT_NONE" - "MAP_SHARED" "MAP_PRIVATE" "MAP_FIXED" "MAP_ANONYMOUS" - "MS_ASYNC" "MS_SYNC" "MS_INVALIDATE" - "UNIX-MMAP" "UNIX-MUNMAP" "UNIX-MSYNC" "UNIX-MPROTECT" - "KBDCGET" "KBDCRESET" "KBDCRST" "KBDCSET" - "KBDCSSTD" "KBDGCLICK" "KBDSCLICK" "KBDSGET" "L_INCR" "L_SET" - "L_XTND" "OFF-T" "O_APPEND" "O_CREAT" "O_EXCL" "O_RDONLY" "O_RDWR" - "O_TRUNC" "O_WRONLY" "READGRP" "READOTH" "READOWN" "RLIM-CUR" - "RLIM-MAX" "RLIMIT" "RU-IDRSS" "RU-INBLOCK" "RU-ISRSS" "RU-IXRSS" - "RU-MAJFLT" "RU-MAXRSS" "RU-MINFLT" "RU-MSGRCV" "RU-MSGSND" - "RU-NIVCSW" "RU-NSIGNALS" "RU-NSWAP" "RU-NVCSW" "RU-OUBLOCK" - "RU-STIME" "RU-UTIME" "RUSAGE_CHILDREN" "RUSAGE_SELF" "RUSEAGE" - "R_OK" "S-IEXEC" "S-IFBLK" "S-IFCHR" "S-IFDIR" "S-IFLNK" "S-IFMT" - "S-IFREG" "S-IFSOCK" "S-IREAD" "S-ISGID" "S-ISUID" "S-ISVTX" - "S-IWRITE" "SAVETEXT" "SC-MASK" "SC-ONSTACK" "SC-PC" "SETGIDEXEC" - "SETUIDEXEC" "SG-ERASE" "SG-FLAGS" "SG-ISPEED" "SG-KILL" - "SG-OSPEED" "SGTTYB" "SIGCONTEXT" "SIZE-T" "ST-ATIME" "ST-BLKSIZE" - "ST-BLOCKS" "ST-CTIME" "ST-DEV" "ST-GID" "ST-MODE" "ST-MTIME" - "ST-NLINK" "ST-RDEV" "ST-SIZE" "ST-UID" "STAT" "SWBLK-T" "T-BRKC" - "T-DSUSPC" "T-EOFC" "T-FLUSHC" "T-INTRC" "T-LNEXTC" "T-QUITC" - "T-RPRNTC" "T-STARTC" "T-STOPC" "T-SUSPC" "T-WERASC" "TCHARS" - "TERMINAL-SPEEDS" "TIME-T" "TIMEVAL" "TIMEZONE" "TIOCFLUSH" - "TIOCGETC" "TIOCGETP" "TIOCGLTC" "TIOCGPGRP" "TIOCGWINSZ" - "TIOCNOTTY" "TIOCSETC" "TIOCSETP" "TIOCSLTC" "TIOCSPGRP" - "TIOCSWINSZ" "TTY-CBREAK" "TTY-CRMOD" "TTY-LCASE" - "TTY-RAW" "TTY-TANDEM" "TV-SEC" "TV-USEC" "TZ-DSTTIME" - "TZ-MINUTESWEST" "UID-T" "UNIX-ACCEPT" "UNIX-ACCESS" "UNIX-BIND" - "UNIX-CHDIR" "UNIX-CHMOD" "UNIX-CHOWN" "UNIX-CLOSE" "UNIX-CONNECT" - "UNIX-CREAT" "UNIX-CURRENT-DIRECTORY" "UNIX-DUP" "UNIX-DUP2" - "UNIX-ERRNO" "UNIX-EXECVE" "UNIX-EXIT" "UNIX-FCHMOD" "UNIX-FCHOWN" - "UNIX-FCNTL" "UNIX-FD" "UNIX-FILE-MODE" "UNIX-FORK" "UNIX-FSTAT" - "UNIX-FSYNC" "UNIX-FTRUNCATE" "UNIX-GETDTABLESIZE" "UNIX-GETEGID" - "UNIX-GETGID" "UNIX-GETHOSTID" "UNIX-GETHOSTNAME" - "UNIX-GETPAGESIZE" "UNIX-GETPEERNAME" "UNIX-GETPGRP" - "UNIX-GETPID" "UNIX-GETPPID" "UNIX-GETRUSAGE" "UNIX-GETSOCKNAME" - "UNIX-GETSOCKOPT" "UNIX-GETTIMEOFDAY" "UNIX-GETUID" "UNIX-GID" - "UNIX-IOCTL" "UNIX-ISATTY" "UNIX-LINK" "UNIX-LISTEN" "UNIX-LSEEK" - "UNIX-LSTAT" "UNIX-MKDIR" "UNIX-OPEN" "UNIX-PATHNAME" "UNIX-PID" - "UNIX-PIPE" "UNIX-READ" "UNIX-READLINK" "UNIX-RECV" "UNIX-RENAME" - "UNIX-RMDIR" "UNIX-SCHED-YIELD" "UNIX-SELECT" - "UNIX-SEND" "UNIX-SETPGID" "UNIX-SETPGRP" - "UNIX-SETREGID" "UNIX-SETREUID" "UNIX-SETSOCKOPT" "UNIX-SOCKET" - "UNIX-SETUID" "UNIX-SETGID" - "UNIX-STAT" "UNIX-SYMLINK" "UNIX-SYNC" - "UNIX-TIMES" "UNIX-TRUNCATE" "UNIX-TTYNAME" "UNIX-UID" - "UNIX-UNAME" "UNIX-UNLINK" "UNIX-UTIMES" "UNIX-WRITE" "WINSIZE" - "WRITEGRP" "WRITEOTH" "WRITEOWN" "WS-COL" "WS-ROW" "WS-XPIXEL" - "WS-YPIXEL" "W_OK" "X_OK" "SIGSYS" "TCSETPGRP" "FD-ZERO" - "SIGEMSG" "SIGQUIT" "SIGCHLD" "SIGSEGV" "FD-CLR" "SIGUSR2" - "EALREADY" "SIGPIPE" "EACCES" "SIGXCPU" "EOPNOTSUPP" - "SIGFPE" "SIGHUP" "ENOTSOCK" "OPEN-DIR" "SIGMASK" "EINTR" - "SIGCONT" "UNIX-RESOLVE-LINKS" "SIGKILL" "EMSGSIZE" "ERANGE" - "EPROTOTYPE" "UNIX-SIGNAL-NUMBER" "EPFNOSUPPORT" "SIGILL" - "EDOM" "UNIX-SIGPAUSE" "EDQUOT" "FD-SETSIZE" "SIGTSTP" - "EAFNOSUPPORT" "TCGETPGRP" "EMFILE" "ECONNRESET" - "EADDRNOTAVAIL" "SIGALRM" "ENETDOWN" "EVICEOP" - "UNIX-FAST-GETRUSAGE" "EPERM" "SIGINT" "EXDEV" "EDEADLK" - "ENOSPC" "ECONNREFUSED" "SIGWINCH" "ENOPROTOOPT" "ESRCH" - "EUSERS" "SIGVTALRM" "ENOTCONN" "ESUCCESS" "EPIPE" - "UNIX-SIMPLIFY-PATHNAME" "EISCONN" "FD-ISSET" "SIGMSG" - "ESHUTDOWN" "EBUSY" "SIGTERM" "ENAMETOOLONG" "EMLINK" - "EADDRINUSE" "SIGBUS" "ERESTART" "TTY-PROCESS-GROUP" - "UNIX-SIGNAL-NAME" "ETIMEDOUT" "ECHILD" "EFBIG" "SIGTRAP" - "UNIX-KILLPG" "ENOTBLK" "SIGIOT" "SIGUSR1" "ECONNABORTED" - "EHOSTUNREACH" "EBADF" "EINVAL" "FD-SET" "CLOSE-DIR" "EISDIR" - "SIGTTIN" "UNIX-KILL" "ENOTDIR" "EHOSTDOWN" "E2BIG" "ESPIPE" - "UNIX-FAST-SELECT" "ENXIO" "ENOTTY" "ELOOP" "LTCHARS" - "UNIX-SIGNAL-DESCRIPTION" "SIGXFSZ" "EINPROGRESS" "ENOENT" - "EPROTONOSUPPORT" "UNIX-SIGBLOCK" "SIGIO" "ENOMEM" "SIGEMT" - "EFAULT" "ENODEV" "EIO" "EVICEERR" "ETXTBSY" "EWOULDBLOCK" - "EAGAIN" "EDESTADDRREQ" "ENOEXEC" "ENETUNREACH" "ENOTEMPTY" - "READ-DIR" "UNIX-MAYBE-PREPEND-CURRENT-DIRECTORY" "ENFILE" - "SIGTTOU" "EEXIST" "SIGPROF" "SIGSTOP" "ENETRESET" "SIGURG" - "ENOBUFS" "EPROCLIM" "EROFS" "ETOOMANYREFS" "UNIX-FILE-KIND" - "ELOCAL" "UNIX-SIGSETMASK" "EREMOTE" "ESOCKTNOSUPPORT" - "TIOCSIGSEND" "SIGWAITING" "SIGABRT" - "C-IFLAG" "UNIX-TCGETATTR" "C-LFLAG" "C-OFLAG" "C-CFLAG" - "TCSAFLUSH" "C-CC" "C-ISPEED" "C-OSPEED" "SIOCSPGRP" "TERMIOS" - "UNIX-TCSETATTR" "O_NDELAY" "O_NOCTTY" - "O_NONBLOCK" "TCSANOW" "TCSADRAIN" "TCIFLUSH" "TCOFLUSH" - "TCIOFLUSH" "UNIX-CFGETOSPEED" "UNIX-CFSETOSPEED" - "UNIX-CFGETISPEED" "UNIX-CFSETISPEED" - "TTY-IGNBRK" "TTY-BRKINT" "TTY-IGNPAR" "TTY-PARMRK" - "TTY-INPCK" "TTY-ISTRIP" "TTY-INLCR" "TTY-IGNCR" "TTY-ICRNL" - "TTY-IUCLC" "TTY-IXON" "TTY-IXANY" "TTY-IXOFF" "TTY-IENQAK" - "TTY-IMAXBEL" "TTY-OPOST" "TTY-OLCUC" "TTY-ONLCR" "TTY-OCRNL" - "TTY-ONOCR" "TTY-ONLRET" "TTY-OFILL" "TTY-OFDEL" "TTY-ISIG" - "TTY-ICANON" "TTY-XCASE" "TTY-ECHO" "TTY-ECHOE" "TTY-ECHOK" - "TTY-ECHONL" "TTY-NOFLSH" "TTY-IEXTEN" "TTY-TOSTOP" "TTY-ECHOCTL" - "TTY-ECHOPRT" "TTY-ECHOKE" "TTY-DEFECHO" "TTY-FLUSHO" - "TTY-PENDIN" "TTY-CSTOPB" "TTY-CREAD" "TTY-PARENB" "TTY-PARODD" - "TTY-HUPCL" "TTY-CLOCAL" "RCV1EN" "XMT1EN" "TTY-LOBLK" "VINTR" - "VQUIT" "VERASE" "VKILL" "VEOF" "VEOL" "VEOL2" "TTY-CBAUD" - "TTY-CSIZE" "TTY-CS5" "TTY-CS6" "TTY-CS7" "TTY-CS8" "VMIN" "VTIME" - "VSUSP" "VSTART" "VSTOP" "VDSUSP" "UNIX-TCSENDBREAK" - "UNIX-TCDRAIN" "UNIX-TCFLUSH" "UNIX-TCFLOW" - "UNIX-GETENV" "UNIX-SETENV" "UNIX-PUTENV" "UNIX-UNSETENV" - - #+(or svr4 bsd linux) "O_NDELAY" - "CHECK" - - "UNIX-RECVFROM" "UNIX-SENDTO" "UNIX-SHUTDOWN" - "UNIX-OPENPTY") - #+(or svr4 linux) - (:export "EADDRINUSE" "EADDRNOTAVAIL" "EADV" "EAFNOSUPPORT" - "EALREADY" "EBADE" "EBADFD" "EBADMSG" "EBADR" "EBADRQC" - "EBADSLT" "EBFONT" #+svr4 "ECANCELED" "ECHRNG" "ECOMM" - "ECONNABORTED" "ECONNREFUSED" "ECONNRESET" "EDEADLK" - "EDEADLOCK" "EDESTADDRREQ" #+linux "EDOTDOT" #+linux "EDQUOT" - "EHOSTDOWN" "EHOSTUNREACH" "EIDRM" "EILSEQ" "EINPROGRESS" - "EISCONN" #+linux "EISNAM" "EL2HLT" "EL2NSYNC" "EL3HLT" - "EL3RST" "ELIBACC" "ELIBBAD" "ELIBEXEC" "ELIBMAX" "ELIBSCN" - "ELNRNG" "ELOOP" "EMSGSIZE" "EMULTIHOP" "ENAMETOOLONG" - #+linux "ENAVAIL" "ENETDOWN" "ENETRESET" "ENETUNREACH" "ENOANO" - "ENOBUFS" "ENOCSI" "ENODATA" "ENOLCK" "ENOLINK" "ENOMSG" "ENONET" - "ENOPKG" "ENOPROTOOPT" "ENOSR" "ENOSTR" "ENOSYS" "ENOTCONN" - "ENOTEMPTY" #+linux "ENOTNAM" "ENOTSOCK" #+svr4 "ENOTSUP" - "ENOTUNIQ" "EOPNOTSUPP" "EOVERFLOW" "EPFNOSUPPORT" "EPROTO" - "EPROTONOSUPPORT" "EPROTOTYPE" "EREMCHG" "EREMOTE" - #+linux "EREMOTEIO" "ERESTART" "ESHUTDOWN" "ESOCKTNOSUPPORT" - "ESRMNT" "ESTALE" "ESTRPIPE" "ETIME" "ETIMEDOUT" "ETOOMANYREFS" - #+linux "EUCLEAN" "EUNATCH" "EUSERS" "EWOULDBLOCK" "EXFULL" - "UTSNAME" - #+linux "SIGSTKFLT" - "UNIX-GETPWNAM" "UNIX-GETPWUID" "UNIX-GETGRNAM" "UNIX-GETGRGID" - "USER-INFO" "USER-INFO-NAME" "USER-INFO-PASSWORD" "USER-INFO-UID" - "USER-INFO-GID" "USER-INFO-GECOS" "USER-INFO-DIR" "USER-INFO-SHELL" - "GROUP-INFO" "GROUP-INFO-NAME" "GROUP-INFO-GID" "GROUP-INFO-MEMBERS") - #+freebsd - (:export "GROUP-INFO" - "GROUP-INFO-GID" - "GROUP-INFO-MEMBERS" - "GROUP-INFO-NAME" - "UNIX-GETGRGID" - "UNIX-GETGRNAM" - "UNIX-GETPWNAM" - "UNIX-GETPWUID" - "USER-INFO" - "USER-INFO-DIR" - "USER-INFO-GECOS" - "USER-INFO-GID" - "USER-INFO-NAME" - "USER-INFO-PASSWORD" - "USER-INFO-SHELL" - "USER-INFO-UID") - #+ppc - (:export "UNIX-GETPWUID" - "USER-INFO" - "USER-INFO-SHELL" - "USER-INFO-GECOS" - "UNIX-GETPWNAM" - "GROUP-INFO-NAME" - "GROUP-INFO-MEMBERS" + (:export "UNIX-CURRENT-DIRECTORY" + "UNIX-OPEN" + "UNIX-READ" + "UNIX-WRITE" + "UNIX-GETPAGESIZE" + "UNIX-ERRNO" + "UNIX-MAYBE-PREPEND-CURRENT-DIRECTORY" + "UNIX-RESOLVE-LINKS" + "UNIX-SIMPLIFY-PATHNAME" + "UNIX-CLOSE" + "UNIX-STAT" + "UNIX-LSTAT" + "UNIX-FSTAT" + "UNIX-GETHOSTNAME" + "UNIX-LSEEK" + "UNIX-EXIT" + "UNIX-CHDIR" + "UNIX-ACCESS" + "UNIX-DUP" + "UNIX-CHMOD" + "UNIX-READLINK" + "UNIX-RENAME" + "UNIX-SELECT" + "UNIX-FAST-GETRUSAGE" + "UNIX-GETRUSAGE" + "UNIX-GETTIMEOFDAY" + "UNIX-ISATTY" + "UNIX-MKDIR" + "UNIX-RMDIR" + "UNIX-UNLINK" + "TIMEZONE" + "TIMEVAL" + "SIZE-T" + "OFF-T" + "INO-T" + "DEV-T" + "TIME-T" "USER-INFO-NAME" - "USER-INFO-PASSWORD" - "GROUP-INFO" - "USER-INFO-UID" - "USER-INFO-DIR" - "USER-INFO-GID" - "GROUP-INFO-GID" - "UNIX-GETGRNAM" - "UNIX-GETGRGID") - #+(and solaris svr4) - (:export "UNIX-SYSINFO" - "SI-SYSNAME" "SI-HOSTNAME" "SI-RELEASE" "SI-VERSION" "SI-MACHINE" - "SI-ARCHITECTURE" "SI-HW-SERIAL" "SI-HW-PROVIDER" "SI-SRPC-DOMAIN" - "SI-PLATFORM" "SI-ISALIST" "SI-DHCP-CACHE" - - "UNIX-GETRLIMIT" - "RLIMIT_CPU" "RLIMIT_FSIZE" "RLIMIT_DATA" "RLIMIT_STACK" "RLIMIT_CORE" - "RLIMIT_AS" "RLIMIT_VMEM" "RLIMIT_NOFILE") - ;; Should this be conditionalized on glibc2? These come from - ;; unix-glibc2.lisp. - #+(and darwin x86) - (:export "GROUP-INFO" "UNIX-GETPWUID" "USER-INFO-DIR" "UNIX-GETPWNAM" - "USER-INFO-SHELL" "USER-INFO-PASSWORD" "USER-INFO-UID" - "GROUP-INFO-GID" "USER-INFO" "USER-INFO-NAME" "USER-INFO-GID" - "GROUP-INFO-MEMBERS" "UNIX-GETGRGID" "USER-INFO-GECOS" - "GROUP-INFO-NAME" - "UNIX-GETGRNAM" - - "UNIX-GETRLIMIT" - "RLIMIT_CPU" "RLIMIT_FSIZE" "RLIMIT_DATA" "RLIMIT_STACK" "RLIMIT_CORE" - "RLIMIT_AS" "RLIMIT_RSS" "RLIMIT_MEMLOCK" "RLIMIT_NPROC" "RLIMIT_NOFILE")) + "INT64-T" + "MODE-T" + "UNIX-FAST-SELECT" + "UNIX-PIPE" + "UNIX-GETPID" + "UNIX-GETHOSTID" + "UNIX-UID" + "UNIX-GID" + "GET-UNIX-ERROR-MSG" + "WINSIZE" + "TIMEVAL" + "CLOSE-DIR" + "OPEN-DIR" + "READ-DIR" + + ;; linux-os, sunos-os. + "UNIX-UNAME" + + ;; filesys.lisp + "UNIX-GETPWUID" + + ;; multi-proc.lisp + "UNIX-SETITIMER" + + ;; run-program.lisp + "UNIX-TTYNAME" + "UNIX-IOCTL" + "UNIX-OPENPTY" + + ;; alien-callback.lisp + "UNIX-MPROTECT" + + ;; internet.lisp + "UNIX-SOCKET" + "UNIX-CONNECT" + "UNIX-BIND" + "UNIX-LISTEN" + "UNIX-ACCEPT" + "UNIX-GETSOCKOPT" + "UNIX-SETSOCKOPT" + "UNIX-GETPEERNAME" + "UNIX-GETSOCKNAME" + "UNIX-RECV" + "UNIX-SEND" + "UNIX-RECVFROM" + "UNIX-SENDTO" + "UNIX-SHUTDOWN" + "UNIX-FCNTL" + + ;; serve-event.lisp + "FD-SETSIZE" + "FD-ISSET" + "FD-CLR" + + ;; Simple streams + "PROT_READ" + "UNIX-MMAP" + "UNIX-MUNMAP" + "UNIX-MSYNC" + + ;; Motif + "UNIX-GETUIO" + + ;; Hemlock + "UNIX-CFGETOSPEED" + "TERMIOS" + "UNIX-TCGETATTR" + "UNIX-TCSETATTR" + "UNIX-FCHMOD" + "UNIX-CREAT" + "UNIX-UTIMES" + + ;; Tests + "UNIX-SYMLINK" + + ;; Other symbols from structures, etc. + "C-CC" "C-CFLAG" "C-IFLAG" "C-ISPEED" "C-LFLAG" "C-OFLAG" "C-OSPEED" + "CHECK" "D-NAME" "D-RECLEN" "E2BIG" "EACCES" "EADDRINUSE" "EADDRNOTAVAIL" + "EAFNOSUPPORT" "EAGAIN" "EALREADY" "EBADF" "EBUSY" "ECHILD" + "ECONNABORTED" "ECONNREFUSED" "ECONNRESET" "EDEADLK" "EDESTADDRREQ" + "EDOM" "EDQUOT" "EEXIST" "EFAULT" "EFBIG" "EHOSTDOWN" "EHOSTUNREACH" + "EINPROGRESS" "EINTR" "EINVAL" "EIO" "EISCONN" "EISDIR" "ELOOP" "EMFILE" + "EMLINK" "EMSGSIZE" "ENAMETOOLONG" "ENETDOWN" "ENETRESET" "ENETUNREACH" + "ENFILE" "ENOBUFS" "ENODEV" "ENOENT" "ENOEXEC" "ENOMEM" "ENOPROTOOPT" + "ENOSPC" "ENOTBLK" "ENOTCONN" "ENOTDIR" "ENOTEMPTY" "ENOTSOCK" "ENOTTY" + "ENXIO" "EOPNOTSUPP" "EPERM" "EPFNOSUPPORT" "EPIPE" "EPROTONOSUPPORT" + "EPROTOTYPE" "ERANGE" "EREMOTE" "EROFS" "ESHUTDOWN" "ESOCKTNOSUPPORT" + "ESPIPE" "ESRCH" "ESUCCESS" "ETIMEDOUT" "ETOOMANYREFS" "ETXTBSY" "EUSERS" + "EWOULDBLOCK" "EXDEV" "F-GETFL" "F-GETOWN" "F-SETFL" "F-SETOWN" "FAPPEND" + "FASYNC" "FD-SET" "FD-ZERO" "FNDELAY" "F_OK" "GID-T" "IT-INTERVAL" + "IT-VALUE" "ITIMERVAL" "L_INCR" "L_SET" "L_XTND" "MAP_ANONYMOUS" + "MAP_FIXED" "MAP_PRIVATE" "MAP_SHARED" "MS_ASYNC" "MS_INVALIDATE" + "MS_SYNC" "O_APPEND" "O_CREAT" "O_EXCL" "O_NDELAY" "O_NONBLOCK" + "O_RDONLY" "O_RDWR" "O_TRUNC" "O_WRONLY" "PROT_EXEC" "PROT_NONE" + "PROT_WRITE" "RU-IDRSS" "RU-INBLOCK" "RU-ISRSS" "RU-IXRSS" "RU-MAJFLT" + "RU-MAXRSS" "RU-MINFLT" "RU-MSGRCV" "RU-MSGSND" "RU-NIVCSW" "RU-NSIGNALS" + "RU-NSWAP" "RU-NVCSW" "RU-OUBLOCK" "RU-STIME" "RU-UTIME" + "RUSAGE_CHILDREN" "RUSAGE_SELF" "R_OK" "S-IFBLK" "S-IFCHR" "S-IFDIR" + "S-IFLNK" "S-IFMT" "S-IFREG" "S-IFSOCK" "SIGABRT" "SIGALRM" "SIGBUS" + "SIGCHLD" "SIGCONT" "SIGCONTEXT" "SIGFPE" "SIGHUP" "SIGILL" "SIGINT" + "SIGIO" "SIGIOT" "SIGKILL" "SIGMASK" "SIGPIPE" "SIGPROF" "SIGQUIT" + "SIGSEGV" "SIGSTOP" "SIGTERM" "SIGTRAP" "SIGTSTP" "SIGTTIN" "SIGTTOU" + "SIGURG" "SIGUSR1" "SIGUSR2" "SIGVTALRM" "SIGWINCH" "SIGXCPU" "SIGXFSZ" + "ST-ATIME" "ST-BLKSIZE" "ST-BLOCKS" "ST-CTIME" "ST-DEV" "ST-GID" + "ST-MODE" "ST-MTIME" "ST-NLINK" "ST-RDEV" "ST-SIZE" "ST-UID" "STAT" + "TCSADRAIN" "TCSAFLUSH" "TCSANOW" "TIOCGPGRP" "TIOCGWINSZ" "TIOCNOTTY" + "TIOCSPGRP" "TIOCSWINSZ" "TTY-BRKINT" "TTY-ECHO" "TTY-ECHOCTL" + "TTY-ECHOE" "TTY-ECHOK" "TTY-ECHOKE" "TTY-ECHONL" "TTY-ECHOPRT" + "TTY-FLUSHO" "TTY-ICANON" "TTY-ICRNL" "TTY-IEXTEN" "TTY-IGNBRK" + "TTY-IGNCR" "TTY-IGNPAR" "TTY-IMAXBEL" "TTY-INLCR" "TTY-INPCK" "TTY-ISIG" + "TTY-ISTRIP" "TTY-IXANY" "TTY-IXOFF" "TTY-IXON" "TTY-NOFLSH" "TTY-ONLCR" + "TTY-OPOST" "TTY-PARMRK" "TTY-PENDIN" "TTY-TOSTOP" "TV-SEC" "TV-USEC" + "TZ-DSTTIME" "TZ-MINUTESWEST" "UID-T" "UNIX-FD" "UNIX-FILE-KIND" + "UNIX-FILE-MODE" "UNIX-GETUID" "UNIX-KILL" "UNIX-KILLPG" "UNIX-PATHNAME" + "UNIX-SIGBLOCK" "UNIX-SIGNAL-DESCRIPTION" "UNIX-SIGNAL-NAME" + "UNIX-SIGNAL-NUMBER" "UNIX-SIGPAUSE" "UNIX-SIGSETMASK" "USER-INFO" + "USER-INFO-DIR" "USER-INFO-GECOS" "USER-INFO-GID" "USER-INFO-PASSWORD" + "USER-INFO-SHELL" "USER-INFO-UID" "VDSUSP" "VEOF" "VEOL" "VEOL2" "VERASE" + "VINTR" "VKILL" "VMIN" "VQUIT" "VSTART" "VSTOP" "VSUSP" "VTIME" + "WRITEOWN" "WS-COL" "WS-ROW" "WS-XPIXEL" "WS-YPIXEL" "W_OK" "X_OK" + "FIONREAD" + "TERMINAL-SPEEDS" + ) + #-(or linux solaris) + (:export "TCHARS" + "LTCHARS" + "D-NAMLEN" + + + ;; run-program.lisp + "SGTTYB" + + ;; Other symbols from structures, etc. + "DIRECT" "ELOCAL" "EPROCLIM" "EVICEERR" "EVICEOP" "EXECGRP" "EXECOTH" + "EXECOWN" "F-DUPFD" "F-GETFD" "F-SETFD" "FCREAT" "FEXCL" + "FTRUNC" "READGRP" "READOTH" "READOWN" "S-IEXEC" "S-IREAD" "S-ISGID" + "S-ISUID" "S-ISVTX" "S-IWRITE" "SAVETEXT" "SETGIDEXEC" "SETUIDEXEC" + "SG-ERASE" "SG-FLAGS" "SG-ISPEED" "SG-KILL" "SG-OSPEED" "SIGEMT" "SIGSYS" + "T-BRKC" "T-DSUSPC" "T-EOFC" "T-FLUSHC" "T-INTRC" "T-LNEXTC" "T-QUITC" + "T-RPRNTC" "T-STARTC" "T-STOPC" "T-SUSPC" "T-WERASC" "TCIFLUSH" + "TCIOFLUSH" "TCOFLUSH" "TIOCFLUSH" "TIOCGETC" + "TIOCGETP" "TIOCGLTC" "TIOCSETC" "TIOCSETP" "TIOCSLTC" "TTY-CBREAK" + "TTY-CLOCAL" "TTY-CREAD" "TTY-CRMOD" "TTY-CS5" "TTY-CS6" "TTY-CS7" + "TTY-CS8" "TTY-CSIZE" "TTY-CSTOPB" "TTY-HUPCL" "TTY-LCASE" "TTY-PARENB" + "TTY-PARODD" "TTY-RAW" "TTY-TANDEM" "WRITEGRP" "WRITEOTH" + ) + #+linux + (:export "TCHARS" + "LTCHARS" + "D-NAMLEN" + + ;; Other symbols + "BLKCNT-T" "D-INO" "D-OFF" "EADV" "EBADE" "EBADFD" "EBADMSG" "EBADR" + "EBADRQC" "EBADSLT" "EBFONT" "ECHRNG" "ECOMM" "EDEADLOCK" "EDOTDOT" + "EIDRM" "EILSEQ" "EISNAM" "EL2HLT" "EL2NSYNC" "EL3HLT" "EL3RST" "ELIBACC" + "ELIBBAD" "ELIBEXEC" "ELIBMAX" "ELIBSCN" "ELNRNG" "EMULTIHOP" "ENAVAIL" + "ENOANO" "ENOCSI" "ENODATA" "ENOLCK" "ENOLINK" "ENOMSG" "ENONET" "ENOPKG" + "ENOSR" "ENOSTR" "ENOSYS" "ENOTNAM" "ENOTUNIQ" "EOVERFLOW" "EPROTO" + "EREMCHG" "EREMOTEIO" "ERESTART" "ESRMNT" "ESTALE" "ESTRPIPE" "ETIME" + "EUCLEAN" "EUNATCH" "EXFULL" "O_NOCTTY" "SIGSTKFLT" "TTY-IUCLC" + "TTY-OCRNL" "TTY-OFDEL" "TTY-OFILL" "TTY-OLCUC" "TTY-ONLRET" "TTY-ONOCR" + "TTY-XCASE" "UNIX-DUP2" "UNIX-GETITIMER" "UNIX-PID" "UNIX-UNAME" + "UTSNAME" + ) + #+solaris + (:export "D-INO" + "D-OFF" + "DIRECT" + "EADV" + "EBADE" + "EBADFD" + "EBADMSG" + "EBADR" + "EBADRQC" + "EBADSLT" + "EBFONT" + "ECANCELED" + "ECHRNG" + "ECOMM" + "EDEADLOCK" + "EIDRM" + "EILSEQ" + "EL2HLT" + "EL2NSYNC" + "EL3HLT" + "EL3RST" + "ELIBACC" + "ELIBBAD" + "ELIBEXEC" + "ELIBMAX" + "ELIBSCN" + "ELNRNG" + "EMULTIHOP" + "ENOANO" + "ENOCSI" + "ENODATA" + "ENOLCK" + "ENOLINK" + "ENOMSG" + "ENONET" + "ENOPKG" + "ENOSR" + "ENOSTR" + "ENOSYS" + "ENOTSUP" + "ENOTUNIQ" + "EOVERFLOW" + "EPROTO" + "EREMCHG" + "ERESTART" + "ESRMNT" + "ESTALE" + "ESTRPIPE" + "ETIME" + "EUNATCH" + "EXECGRP" + "EXECOTH" + "EXECOWN" + "EXFULL" + "F-DUPFD" + "F-GETFD" + "F-SETFD" + "FCREAT" + "FEXCL" + "FTRUNC" + "LTCHARS" + "O_NOCTTY" + "RCV1EN" + "READGRP" + "READOTH" + "READOWN" + "S-IEXEC" + "S-IREAD" + "S-ISGID" + "S-ISUID" + "S-ISVTX" + "S-IWRITE" + "SAVETEXT" + "SETGIDEXEC" + "SETUIDEXEC" + "SG-ERASE" + "SG-FLAGS" + "SG-ISPEED" + "SG-KILL" + "SG-OSPEED" + "SGTTYB" + "SIGEMT" + "SIGSYS" + "SIGWAITING" + "T-BRKC" + "T-DSUSPC" + "T-EOFC" + "T-FLUSHC" + "T-INTRC" + "T-LNEXTC" + "T-QUITC" + "T-RPRNTC" + "T-STARTC" + "T-STOPC" + "T-SUSPC" + "T-WERASC" + "TCHARS" + "TCIFLUSH" + "TCIOFLUSH" + "TCOFLUSH" + "TIOCFLUSH" + "TIOCGETC" + "TIOCGETP" + "TIOCGLTC" + "TIOCSETC" + "TIOCSETP" + "TIOCSLTC" + "TTY-CBAUD" + "TTY-CBREAK" + "TTY-CLOCAL" + "TTY-CREAD" + "TTY-CRMOD" + "TTY-CS5" + "TTY-CS6" + "TTY-CS7" + "TTY-CS8" + "TTY-CSIZE" + "TTY-CSTOPB" + "TTY-DEFECHO" + "TTY-HUPCL" + "TTY-IUCLC" + "TTY-LCASE" + "TTY-LOBLK" + "TTY-OCRNL" + "TTY-OFDEL" + "TTY-OFILL" + "TTY-OLCUC" + "TTY-ONLRET" + "TTY-ONOCR" + "TTY-PARENB" + "TTY-PARODD" + "TTY-RAW" + "TTY-TANDEM" + "TTY-XCASE" + "UNIX-TIMES" + "UTSNAME" + "WRITEGRP" + "WRITEOTH" + "XMT1EN" + ))
(defpackage "FORMAT")
===================================== src/code/module.lisp ===================================== --- a/src/code/module.lisp +++ b/src/code/module.lisp @@ -161,3 +161,6 @@
(defmodule :cmu-contribs "modules:contrib") + +(defmodule :unix + "modules:load-unix")
===================================== src/code/unix-glibc2.lisp ===================================== --- a/src/code/unix-glibc2.lisp +++ b/src/code/unix-glibc2.lisp @@ -67,147 +67,11 @@ ;; Must be set to NIL initially to enable building Lisp! (defvar *filename-encoding* nil)
-(export '( - daddr-t caddr-t ino-t swblk-t size-t time-t dev-t off-t uid-t gid-t - blkcnt-t fsblkcnt-t fsfilcnt-t - unix-lockf f_ulock f_lock f_tlock f_test - timeval tv-sec tv-usec timezone tz-minuteswest tz-dsttime - itimerval it-interval it-value tchars t-intrc t-quitc t-startc - t-stopc t-eofc t-brkc ltchars t-suspc t-dsuspc t-rprntc t-flushc - t-werasc t-lnextc sgttyb sg-ispeed sg-ospeed sg-erase sg-kill - sg-flags winsize ws-row ws-col ws-xpixel ws-ypixel - direct d-off d-ino d-reclen d-name - stat st-dev st-mode st-nlink st-uid st-gid st-rdev st-size - st-atime st-mtime st-ctime st-blksize st-blocks - s-ifmt s-ifdir s-ifchr s-ifblk s-ifreg s-iflnk s-ifsock - s-isuid s-isgid s-isvtx s-iread s-iwrite s-iexec - ruseage ru-utime ru-stime ru-maxrss ru-ixrss ru-idrss - ru-isrss ru-minflt ru-majflt ru-nswap ru-inblock ru-oublock - ru-msgsnd ru-msgrcv ru-nsignals ru-nvcsw ru-nivcsw - rlimit rlim-cur rlim-max sc-onstack sc-mask sc-pc - unix-errno get-unix-error-msg - prot_read prot_write prot_exec prot_none - map_shared map_private map_fixed map_anonymous - ms_async ms_sync ms_invalidate - unix-mmap unix-munmap unix-msync unix-mprotect - unix-pathname unix-file-mode unix-fd unix-pid unix-uid unix-gid - unix-setitimer unix-getitimer - unix-access r_ok w_ok x_ok f_ok unix-chdir unix-chmod setuidexec - setgidexec savetext readown writeown execown readgrp writegrp - execgrp readoth writeoth execoth unix-fchmod unix-chown unix-fchown - unix-getdtablesize unix-close unix-creat unix-dup unix-dup2 - unix-fcntl f-dupfd f-getfd f-setfd f-getfl f-setfl f-getown f-setown - fndelay fappend fasync fcreat ftrunc fexcl unix-link unix-lseek - l_set l_incr l_xtnd unix-mkdir unix-open o_rdonly o_wronly o_rdwr - o_ndelay - o_noctty - o_append o_creat o_trunc o_excl unix-pipe unix-read unix-readlink - unix-rename unix-rmdir unix-fast-select fd-setsize fd-set fd-clr - fd-isset fd-zero unix-select unix-sync unix-fsync unix-truncate - unix-ftruncate unix-symlink unix-unlink unix-write unix-ioctl - unix-uname utsname - tcsetpgrp tcgetpgrp tty-process-group - terminal-speeds tty-raw tty-crmod tty-echo tty-lcase - tty-cbreak - termios - c-lflag - c-iflag - c-oflag - tty-icrnl - tty-ocrnl - veof - vintr - vquit - vstart - vstop - vsusp - c-cflag - c-cc - tty-icanon - vmin - vtime - tty-ixon - tcsanow - tcsadrain - tciflush - tcoflush - tcioflush - tcsaflush - unix-tcgetattr - unix-tcsetattr - tty-ignbrk - tty-brkint - tty-ignpar - tty-parmrk - tty-inpck - tty-istrip - tty-inlcr - tty-igncr - tty-iuclc - tty-ixany - tty-ixoff - tty-imaxbel - tty-opost - tty-olcuc - tty-onlcr - tty-onocr - tty-onlret - tty-ofill - tty-ofdel - tty-isig - tty-xcase - tty-echoe - tty-echok - tty-echonl - tty-noflsh - tty-iexten - tty-tostop - tty-echoctl - tty-echoprt - tty-echoke - tty-pendin - tty-cstopb - tty-cread - tty-parenb - tty-parodd - tty-hupcl - tty-clocal - vintr - verase - vkill - veol - veol2 - TIOCGETP TIOCSETP TIOCFLUSH TIOCSETC TIOCGETC TIOCSLTC - TIOCGLTC TIOCNOTTY TIOCSPGRP TIOCGPGRP TIOCGWINSZ TIOCSWINSZ - TIOCSIGSEND - - KBDCGET KBDCSET KBDCRESET KBDCRST KBDCSSTD KBDSGET KBDGCLICK - KBDSCLICK FIONREAD unix-exit unix-stat unix-lstat unix-fstat - unix-getrusage unix-fast-getrusage rusage_self rusage_children - unix-gettimeofday - unix-utimes unix-sched-yield unix-setreuid - unix-setregid - unix-getpid unix-getppid - unix-getgid unix-getegid unix-getpgrp unix-setpgrp unix-getuid - unix-getpagesize unix-gethostname unix-gethostid unix-fork - unix-getenv unix-setenv unix-putenv unix-unsetenv - unix-current-directory unix-isatty unix-ttyname unix-execve - unix-socket unix-connect unix-bind unix-listen unix-accept - unix-recv unix-send unix-getpeername unix-getsockname - unix-getsockopt unix-setsockopt unix-openpty - - unix-recvfrom unix-sendto unix-shutdown - - unix-getpwnam unix-getpwuid unix-getgrnam unix-getgrgid - user-info user-info-name user-info-password user-info-uid - user-info-gid user-info-gecos user-info-dir user-info-shell - group-info group-info-name group-info-gid group-info-members)) - (pushnew :unix *features*) (pushnew :glibc2 *features*)
;; needed for bootstrap -(eval-when (:compile-toplevel) +(eval-when (:compile-toplevel :load-toplevel :execute) (defmacro %name->file (string) `(if *filename-encoding* (string-encode ,string *filename-encoding*) @@ -217,8 +81,124 @@ (string-decode ,string *filename-encoding*) ,string)))
+(defconstant +max-u-long+ 4294967295) + +(def-alien-type size-t #-alpha unsigned-int #+alpha long) +(def-alien-type time-t long) + +(def-alien-type uquad-t #+alpha unsigned-long + #-alpha (array unsigned-long 2)) +(def-alien-type u-int32-t unsigned-int) +(def-alien-type int64-t (signed 64)) +(def-alien-type u-int64-t (unsigned 64)) + +(def-alien-type dev-t #-amd64 uquad-t #+amd64 u-int64-t) +(def-alien-type uid-t unsigned-int) +(def-alien-type gid-t unsigned-int) +(def-alien-type ino-t #-amd64 u-int32-t #+amd64 u-int64-t) +(def-alien-type ino64-t u-int64-t) +(def-alien-type mode-t u-int32-t) +(def-alien-type nlink-t #-amd64 unsigned-int #+amd64 u-int64-t) +(def-alien-type off-t int64-t) +(def-alien-type blkcnt-t u-int64-t) + ;;;; Common machine independent structures.
+ +;; Needed early in bootstrap. +(defun unix-current-directory () + _N"Put the absolute pathname of the current working directory in BUF. + If successful, return BUF. If not, put an error message in + BUF and return NULL. BUF should be at least PATH_MAX bytes long." + ;; 5120 is some randomly selected maximum size for the buffer for getcwd. + (with-alien ((buf (array c-call:char 5120))) + (let ((result (alien-funcall + (extern-alien "getcwd" + (function (* c-call:char) + (* c-call:char) c-call:int)) + (cast buf (* c-call:char)) + 5120))) + + (values (not (zerop (sap-int (alien-sap result)))) + (%file->name (cast buf c-call:c-string)))))) + +;;; fcntlbits.h +(defconstant o_read o_rdonly _N"Open for reading") +(defconstant o_write o_wronly _N"Open for writing") + +(defconstant o_rdonly 0 _N"Read-only flag.") +(defconstant o_wronly 1 _N"Write-only flag.") +(defconstant o_rdwr 2 _N"Read-write flag.") +(defconstant o_accmode 3 _N"Access mode mask.") + +#-alpha +(progn + (defconstant o_creat #o100 _N"Create if nonexistant flag. (not fcntl)") + (defconstant o_excl #o200 _N"Error if already exists. (not fcntl)") + (defconstant o_noctty #o400 _N"Don't assign controlling tty. (not fcntl)") + (defconstant o_trunc #o1000 _N"Truncate flag. (not fcntl)") + (defconstant o_append #o2000 _N"Append flag.") + (defconstant o_ndelay #o4000 _N"Non-blocking I/O") + (defconstant o_nonblock #o4000 _N"Non-blocking I/O") + (defconstant o_ndelay o_nonblock) + (defconstant o_sync #o10000 _N"Synchronous writes (on ext2)") + (defconstant o_fsync o_sync) + (defconstant o_async #o20000 _N"Asynchronous I/O")) +#+alpha +(progn + (defconstant o_creat #o1000 _N"Create if nonexistant flag. (not fcntl)") + (defconstant o_trunc #o2000 _N"Truncate flag. (not fcntl)") + (defconstant o_excl #o4000 _N"Error if already exists. (not fcntl)") + (defconstant o_noctty #o10000 _N"Don't assign controlling tty. (not fcntl)") + (defconstant o_nonblock #o4 _N"Non-blocking I/O") + (defconstant o_append #o10 _N"Append flag.") + (defconstant o_ndelay o_nonblock) + (defconstant o_sync #o40000 _N"Synchronous writes (on ext2)") + (defconstant o_fsync o_sync) + (defconstant o_async #o20000 _N"Asynchronous I/O")) + +#-alpha +(progn + (defconstant f-getlk 5 _N"Get lock") + (defconstant f-setlk 6 _N"Set lock") + (defconstant f-setlkw 7 _N"Set lock, wait for release") + (defconstant f-setown 8 _N"Set owner (for sockets)") + (defconstant f-getown 9 _N"Get owner (for sockets)")) +#+alpha +(progn + (defconstant f-getlk 7 _N"Get lock") + (defconstant f-setlk 8 _N"Set lock") + (defconstant f-setlkw 9 _N"Set lock, wait for release") + (defconstant f-setown 5 _N"Set owner (for sockets)") + (defconstant f-getown 6 _N"Get owner (for sockets)")) + +(defconstant F-CLOEXEC 1 _N"for f-getfl and f-setfl") +(defun unix-open (path flags mode) + _N"Unix-open opens the file whose pathname is specified by PATH + for reading and/or writing as specified by the FLAGS argument. + Returns an integer file descriptor. + The flags argument can be: + + o_rdonly Read-only flag. + o_wronly Write-only flag. + o_rdwr Read-and-write flag. + o_append Append flag. + o_creat Create-if-nonexistant flag. + o_trunc Truncate-to-size-0 flag. + o_excl Error if the file already exists + o_noctty Don't assign controlling tty + o_ndelay Non-blocking I/O + o_sync Synchronous I/O + o_async Asynchronous I/O + + If the o_creat flag is specified, then the file is created with + a permission of argument MODE if the file doesn't exist." + (declare (type unix-pathname path) + (type fixnum flags) + (type unix-file-mode mode)) + (int-syscall ("open64" c-string int int) (%name->file path) flags mode)) + +;;; asm/errno.h (eval-when (compile eval)
(defparameter *compiler-unix-errors* nil) @@ -241,97 +221,135 @@
)
-(defmacro def-enum (inc cur &rest names) - (flet ((defform (name) - (prog1 (when name `(defconstant ,name ,cur)) - (setf cur (funcall inc cur 1))))) - `(progn ,@(mapcar #'defform names)))) - -;;;; Memory-mapped files +(def-unix-error ESUCCESS 0 _N"Successful") +(def-unix-error EPERM 1 _N"Operation not permitted") +(def-unix-error ENOENT 2 _N"No such file or directory") +(def-unix-error ESRCH 3 _N"No such process") +(def-unix-error EINTR 4 _N"Interrupted system call") +(def-unix-error EIO 5 _N"I/O error") +(def-unix-error ENXIO 6 _N"No such device or address") +(def-unix-error E2BIG 7 _N"Arg list too long") +(def-unix-error ENOEXEC 8 _N"Exec format error") +(def-unix-error EBADF 9 _N"Bad file number") +(def-unix-error ECHILD 10 _N"No children") +(def-unix-error EAGAIN 11 _N"Try again") +(def-unix-error ENOMEM 12 _N"Out of memory") +(def-unix-error EACCES 13 _N"Permission denied") +(def-unix-error EFAULT 14 _N"Bad address") +(def-unix-error ENOTBLK 15 _N"Block device required") +(def-unix-error EBUSY 16 _N"Device or resource busy") +(def-unix-error EEXIST 17 _N"File exists") +(def-unix-error EXDEV 18 _N"Cross-device link") +(def-unix-error ENODEV 19 _N"No such device") +(def-unix-error ENOTDIR 20 _N"Not a director") +(def-unix-error EISDIR 21 _N"Is a directory") +(def-unix-error EINVAL 22 _N"Invalid argument") +(def-unix-error ENFILE 23 _N"File table overflow") +(def-unix-error EMFILE 24 _N"Too many open files") +(def-unix-error ENOTTY 25 _N"Not a typewriter") +(def-unix-error ETXTBSY 26 _N"Text file busy") +(def-unix-error EFBIG 27 _N"File too large") +(def-unix-error ENOSPC 28 _N"No space left on device") +(def-unix-error ESPIPE 29 _N"Illegal seek") +(def-unix-error EROFS 30 _N"Read-only file system") +(def-unix-error EMLINK 31 _N"Too many links") +(def-unix-error EPIPE 32 _N"Broken pipe") +;;; +;;; Math +(def-unix-error EDOM 33 _N"Math argument out of domain") +(def-unix-error ERANGE 34 _N"Math result not representable") +;;; +(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")
-(defconstant +null+ (sys:int-sap 0)) - -(defconstant prot_read 1) -(defconstant prot_write 2) -(defconstant prot_exec 4) -(defconstant prot_none 0) - -(defconstant map_shared 1) -(defconstant map_private 2) -(defconstant map_fixed 16) -(defconstant map_anonymous 32) - -(defconstant ms_async 1) -(defconstant ms_sync 4) -(defconstant ms_invalidate 2) - -;; The return value from mmap that means mmap failed. -(defconstant map_failed (int-sap (1- (ash 1 vm:word-bits)))) - -(defun unix-mmap (addr length prot flags fd offset) - (declare (type (or null system-area-pointer) addr) - (type (unsigned-byte 32) length) - (type (integer 1 7) prot) - (type (unsigned-byte 32) flags) - (type (or null unix-fd) fd) - (type (signed-byte 32) offset)) - ;; Can't use syscall, because the address that is returned could be - ;; "negative". Hence we explicitly check for mmap returning - ;; MAP_FAILED. - (let ((result - (alien-funcall (extern-alien "mmap" (function system-area-pointer - system-area-pointer - size-t int int int off-t)) - (or addr +null+) length prot flags (or fd -1) offset))) - (if (sap= result map_failed) - (values nil (unix-errno)) - (values result 0)))) - -(defun unix-munmap (addr length) - (declare (type system-area-pointer addr) - (type (unsigned-byte 32) length)) - (syscall ("munmap" system-area-pointer size-t) t addr length)) - -(defun unix-msync (addr length flags) - (declare (type system-area-pointer addr) - (type (unsigned-byte 32) length) - (type (signed-byte 32) flags)) - (syscall ("msync" system-area-pointer size-t int) t addr length flags)) - -(defun unix-mprotect (addr length prot) - (declare (type system-area-pointer addr) - (type (unsigned-byte 32) length) - (type (integer 1 7) prot)) - (syscall ("mprotect" system-area-pointer size-t int) - t addr length prot)) - -;;;; Lisp types used by syscalls. - -(deftype unix-pathname () 'simple-string) -(deftype unix-fd () `(integer 0 ,most-positive-fixnum)) - -(deftype unix-file-mode () '(unsigned-byte 32)) -(deftype unix-pid () '(unsigned-byte 32)) -(deftype unix-uid () '(unsigned-byte 32)) -(deftype unix-gid () '(unsigned-byte 32)) - - -;;;; User and group database structures: <pwd.h> and <grp.h> - -(defstruct user-info - (name "" :type string) - (password "" :type string) - (uid 0 :type unix-uid) - (gid 0 :type unix-gid) - (gecos "" :type string) - (dir "" :type string) - (shell "" :type string)) - -(defstruct group-info - (name "" :type string) - (password "" :type string) - (gid 0 :type unix-gid) - (members nil :type list)) ; list of logins as strings +;;; And now for something completely different ... +(emit-unix-errors)
(def-alien-type nil (struct passwd @@ -343,14 +361,6 @@ (pw-dir (* char)) ; user's home directory (pw-shell (* char)))) ; user's login shell
-(def-alien-type nil - (struct group - (gr-name (* char)) ; name of the group - (gr-passwd (* char)) ; encrypted group password - (gr-gid gid-t) ; numerical group ID - (gr-mem (* (* char))))) ; vector of pointers to member names - - ;;;; System calls.
(def-alien-routine ("os_get_errno" unix-get-errno) int) @@ -393,213 +403,261 @@ (defmacro int-syscall ((name &rest arg-types) &rest args) `(syscall (,name ,@arg-types) (values result 0) ,@args))
-;;; From stdio.h - -;;; Unix-rename accepts two files names and renames the first to the second. - -(defun unix-rename (name1 name2) - _N"Unix-rename renames the file with string name1 to the string - name2. NIL and an error code is returned if an error occured." - (declare (type unix-pathname name1 name2)) - (void-syscall ("rename" c-string c-string) - (%name->file name1) (%name->file name2))) - -;;; From sys/types.h -;;; and -;;; gnu/types.h +;;; Unix-write accepts a file descriptor, a buffer, an offset, and the +;;; length to write. It attempts to write len bytes to the device +;;; associated with fd from the the buffer starting at offset. It returns +;;; the actual number of bytes written.
-(defconstant +max-s-long+ 2147483647) -(defconstant +max-u-long+ 4294967295) +(defun unix-write (fd buf offset len) + _N"Unix-write attempts to write a character buffer (buf) of length + len to the file described by the file descriptor fd. NIL and an + error is returned if the call is unsuccessful." + (declare (type unix-fd fd) + (type (unsigned-byte 32) offset len)) + (int-syscall ("write" int (* char) int) + fd + (with-alien ((ptr (* char) (etypecase buf + ((simple-array * (*)) + (vector-sap buf)) + (system-area-pointer + buf)))) + (addr (deref ptr offset))) + len))
-(def-alien-type quad-t #+alpha long #-alpha (array long 2)) -(def-alien-type uquad-t #+alpha unsigned-long - #-alpha (array unsigned-long 2)) -(def-alien-type qaddr-t (* quad-t)) -(def-alien-type daddr-t int) -(def-alien-type caddr-t (* char)) -(def-alien-type swblk-t long) -(def-alien-type size-t #-alpha unsigned-int #+alpha long) -(def-alien-type time-t long) -(def-alien-type clock-t long) -(def-alien-type uid-t unsigned-int) -(def-alien-type ssize-t #-alpha int #+alpha long) -(def-alien-type key-t int) -(def-alien-type int8-t char) -(def-alien-type u-int8-t unsigned-char) -(def-alien-type int16-t short) -(def-alien-type u-int16-t unsigned-short) -(def-alien-type int32-t int) -(def-alien-type u-int32-t unsigned-int) -(def-alien-type int64-t (signed 64)) -(def-alien-type u-int64-t (unsigned 64)) -(def-alien-type register-t #-alpha int #+alpha long) +(defun unix-pipe () + _N"Unix-pipe sets up a unix-piping mechanism consisting of + an input pipe and an output pipe. Unix-Pipe returns two + values: if no error occurred the first value is the pipe + to be read from and the second is can be written to. If + an error occurred the first value is NIL and the second + the unix error code." + (with-alien ((fds (array int 2))) + (syscall ("pipe" (* int)) + (values (deref fds 0) (deref fds 1)) + (cast fds (* int)))))
-(def-alien-type dev-t #-amd64 uquad-t #+amd64 u-int64-t) -(def-alien-type uid-t unsigned-int) -(def-alien-type gid-t unsigned-int) -(def-alien-type ino-t #-amd64 u-int32-t #+amd64 u-int64-t) -(def-alien-type ino64-t u-int64-t) -(def-alien-type mode-t u-int32-t) -(def-alien-type nlink-t #-amd64 unsigned-int #+amd64 u-int64-t) -(def-alien-type off-t int64-t) -(def-alien-type blkcnt-t u-int64-t) -(def-alien-type fsblkcnt-t u-int64-t) -(def-alien-type fsfilcnt-t u-int64-t) -(def-alien-type pid-t int) -;(def-alien-type ssize-t #-alpha int #+alpha long) +;;; UNIX-READ accepts a file descriptor, a buffer, and the length to read. +;;; It attempts to read len bytes from the device associated with fd +;;; and store them into the buffer. It returns the actual number of +;;; bytes read.
-(def-alien-type fsid-t (array int 2)) +(defun unix-read (fd buf len) + _N"UNIX-READ attempts to read from the file described by fd into + the buffer buf until it is full. Len is the length of the buffer. + The number of bytes actually read is returned or NIL and an error + number if an error occured." + (declare (type unix-fd fd) + (type (unsigned-byte 32) len)) + #+gencgc + ;; With gencgc, the collector tries to keep raw objects like strings + ;; in separate pages that are not write-protected. However, this + ;; isn't always true. Thus, BUF will sometimes be write-protected + ;; and the kernel doesn't like writing to write-protected pages. So + ;; go through and touch each page to give the segv handler a chance + ;; to unprotect the pages. (This is taken from unix.lisp.) + (without-gcing + (let* ((page-size (get-page-size)) + (1-page-size (1- page-size)) + (sap (etypecase buf + (system-area-pointer buf) + (vector (vector-sap buf)))) + (end (sap+ sap len))) + (declare (type (and fixnum unsigned-byte) page-size 1-page-size) + (type system-area-pointer sap end) + (optimize (speed 3) (safety 0))) + ;; Touch the beginning of every page + (do ((sap (int-sap (logand (sap-int sap) + (logxor 1-page-size (ldb (byte 32 0) -1)))) + (sap+ sap page-size))) + ((sap>= sap end)) + (declare (type system-area-pointer sap)) + (setf (sap-ref-8 sap 0) (sap-ref-8 sap 0))))) + (int-syscall ("read" int (* char) int) fd buf len))
-(def-alien-type fd-mask #-alpha unsigned-long #+alpha unsigned-int) +;;; Unix-getpagesize returns the number of bytes in the system page.
-(defconstant fd-setsize 1024) -(defconstant nfdbits 32) - -(def-alien-type nil - (struct fd-set - (fds-bits (array fd-mask #.(/ fd-setsize nfdbits))))) +(defun unix-getpagesize () + _N"Unix-getpagesize returns the number of bytes in a system page." + (int-syscall ("getpagesize")))
-(def-alien-type key-t int) +;;; sys/stat.h
-(def-alien-type ipc-pid-t unsigned-short) +(defmacro extract-stat-results (buf) + `(values T + #+(or alpha amd64) + (slot ,buf 'st-dev) + #-(or alpha amd64) + (+ (deref (slot ,buf 'st-dev) 0) + (* (+ +max-u-long+ 1) + (deref (slot ,buf 'st-dev) 1))) ;;; let's hope this works.. + (slot ,buf 'st-ino) + (slot ,buf 'st-mode) + (slot ,buf 'st-nlink) + (slot ,buf 'st-uid) + (slot ,buf 'st-gid) + #+(or alpha amd64) + (slot ,buf 'st-rdev) + #-(or alpha amd64) + (+ (deref (slot ,buf 'st-rdev) 0) + (* (+ +max-u-long+ 1) + (deref (slot ,buf 'st-rdev) 1))) ;;; let's hope this works.. + (slot ,buf 'st-size) + (slot ,buf 'st-atime) + (slot ,buf 'st-mtime) + (slot ,buf 'st-ctime) + (slot ,buf 'st-blksize) + (slot ,buf 'st-blocks)))
-;;; direntry.h +;;; bits/stat.h
(def-alien-type nil - (struct dirent - #+glibc2.1 - (d-ino ino-t) ; inode number of entry - #-glibc2.1 - (d-ino ino64-t) ; inode number of entry - (d-off off-t) ; offset of next disk directory entry - (d-reclen unsigned-short) ; length of this record - (d_type unsigned-char) - (d-name (array char 256)))) ; name must be no longer than this -;;; dirent.h - -;;; Operations on Unix Directories. - -(export '(open-dir read-dir close-dir)) + (struct stat + (st-dev dev-t) + #-(or alpha amd64) (st-pad1 unsigned-short) + (st-ino ino-t) + #+alpha (st-pad1 unsigned-int) + #-amd64 (st-mode mode-t) + (st-nlink nlink-t) + #+amd64 (st-mode mode-t) + (st-uid uid-t) + (st-gid gid-t) + (st-rdev dev-t) + #-alpha (st-pad2 unsigned-short) + (st-size off-t) + #-alpha (st-blksize unsigned-long) + #-alpha (st-blocks blkcnt-t) + (st-atime time-t) + #-alpha (unused-1 unsigned-long) + (st-mtime time-t) + #-alpha (unused-2 unsigned-long) + (st-ctime time-t) + #+alpha (st-blocks int) + #+alpha (st-pad2 unsigned-int) + #+alpha (st-blksize unsigned-int) + #+alpha (st-flags unsigned-int) + #+alpha (st-gen unsigned-int) + #+alpha (st-pad3 unsigned-int) + #+alpha (unused-1 unsigned-long) + #+alpha (unused-2 unsigned-long) + (unused-3 unsigned-long) + (unused-4 unsigned-long) + #-alpha (unused-5 unsigned-long)))
-(defstruct (%directory - (:constructor make-directory) - (:conc-name directory-) - (:print-function %print-directory)) - name - (dir-struct (required-argument) :type system-area-pointer)) - -(defun %print-directory (dir stream depth) - (declare (ignore depth)) - (format stream "#<Directory ~S>" (directory-name dir))) +(defun unix-stat (name) + _N"UNIX-STAT retrieves information about the specified + file returning them in the form of multiple values. + See the UNIX Programmer's Manual for a description + of the values returned. If the call fails, then NIL + and an error number is returned instead." + (declare (type unix-pathname name)) + (when (string= name "") + (setf name ".")) + (with-alien ((buf (struct stat))) + (syscall ("stat64" c-string (* (struct stat))) + (extract-stat-results buf) + (%name->file name) (addr buf))))
-(defun open-dir (pathname) - (declare (type unix-pathname pathname)) - (when (string= pathname "") - (setf pathname ".")) - (let ((kind (unix-file-kind pathname))) - (case kind - (:directory - (let ((dir-struct - (alien-funcall (extern-alien "opendir" - (function system-area-pointer - c-string)) - (%name->file pathname)))) - (if (zerop (sap-int dir-struct)) - (values nil (unix-errno)) - (make-directory :name pathname :dir-struct dir-struct)))) - ((nil) - (values nil enoent)) - (t - (values nil enotdir))))) +(defun unix-fstat (fd) + _N"UNIX-FSTAT is similar to UNIX-STAT except the file is specified + by the file descriptor FD." + (declare (type unix-fd fd)) + (with-alien ((buf (struct stat))) + (syscall ("fstat64" int (* (struct stat))) + (extract-stat-results buf) + fd (addr buf))))
-(defun read-dir (dir) - (declare (type %directory dir)) - (let ((daddr (alien-funcall (extern-alien "readdir64" - (function system-area-pointer - system-area-pointer)) - (directory-dir-struct dir)))) - (declare (type system-area-pointer daddr)) - (if (zerop (sap-int daddr)) - nil - (with-alien ((dirent (* (struct dirent)) daddr)) - (values (%file->name (cast (slot dirent 'd-name) c-string)) - (slot dirent 'd-ino)))))) +(defun unix-lstat (name) + _N"UNIX-LSTAT is similar to UNIX-STAT except the specified + file must be a symbolic link." + (declare (type unix-pathname name)) + (with-alien ((buf (struct stat))) + (syscall ("lstat64" c-string (* (struct stat))) + (extract-stat-results buf) + (%name->file name) (addr buf))))
-(defun close-dir (dir) - (declare (type %directory dir)) - (alien-funcall (extern-alien "closedir" - (function void system-area-pointer)) - (directory-dir-struct dir)) - nil) +;; Encoding of the file mode.
-;;; dlfcn.h -> in foreign.lisp +(defconstant s-ifmt #o0170000 _N"These bits determine file type.")
-;;; fcntl.h -;;; -;;; POSIX Standard: 6.5 File Control Operations <fcntl.h> +;; File types.
-(defconstant r_ok 4 _N"Test for read permission") -(defconstant w_ok 2 _N"Test for write permission") -(defconstant x_ok 1 _N"Test for execute permission") -(defconstant f_ok 0 _N"Test for presence of file") +(defconstant s-ififo #o0010000 _N"FIFO") +(defconstant s-ifchr #o0020000 _N"Character device") +(defconstant s-ifdir #o0040000 _N"Directory") +(defconstant s-ifblk #o0060000 _N"Block device") +(defconstant s-ifreg #o0100000 _N"Regular file")
-(defun unix-fcntl (fd cmd arg) - _N"Unix-fcntl manipulates file descriptors accoridng to the - argument CMD which can be one of the following: +;; These don't actually exist on System V, but having them doesn't hurt.
- F-DUPFD Duplicate a file descriptor. - F-GETFD Get file descriptor flags. - F-SETFD Set file descriptor flags. - F-GETFL Get file flags. - F-SETFL Set file flags. - F-GETOWN Get owner. - F-SETOWN Set owner. +(defconstant s-iflnk #o0120000 _N"Symbolic link.") +(defconstant s-ifsock #o0140000 _N"Socket.") +(defun unix-file-kind (name &optional check-for-links) + _N"Returns either :file, :directory, :link, :special, or NIL." + (declare (simple-string name)) + (multiple-value-bind (res dev ino mode) + (if check-for-links + (unix-lstat name) + (unix-stat name)) + (declare (type (or fixnum null) mode) + (ignore dev ino)) + (when res + (let ((kind (logand mode s-ifmt))) + (cond ((eql kind s-ifdir) :directory) + ((eql kind s-ifreg) :file) + ((eql kind s-iflnk) :link) + (t :special))))))
- The flags that can be specified for F-SETFL are: +(defun unix-maybe-prepend-current-directory (name) + (declare (simple-string name)) + (if (and (> (length name) 0) (char= (schar name 0) #/)) + name + (multiple-value-bind (win dir) (unix-current-directory) + (if win + (concatenate 'simple-string dir "/" name) + name))))
- FNDELAY Non-blocking reads. - FAPPEND Append on each write. - FASYNC Signal pgrp when data ready. - FCREAT Create if nonexistant. - FTRUNC Truncate to zero length. - FEXCL Error if already created. - " - (declare (type unix-fd fd) - (type (unsigned-byte 32) cmd) - (type (unsigned-byte 32) arg)) - (int-syscall ("fcntl" int unsigned-int unsigned-int) fd cmd arg)) +;; Values for the second argument to access.
-(defun unix-open (path flags mode) - _N"Unix-open opens the file whose pathname is specified by PATH - for reading and/or writing as specified by the FLAGS argument. - Returns an integer file descriptor. - The flags argument can be: +;;; Unix-access accepts a path and a mode. It returns two values the +;;; first is T if the file is accessible and NIL otherwise. The second +;;; only has meaning in the second case and is the unix errno value.
- o_rdonly Read-only flag. - o_wronly Write-only flag. - o_rdwr Read-and-write flag. - o_append Append flag. - o_creat Create-if-nonexistant flag. - o_trunc Truncate-to-size-0 flag. - o_excl Error if the file already exists - o_noctty Don't assign controlling tty - o_ndelay Non-blocking I/O - o_sync Synchronous I/O - o_async Asynchronous I/O +(defun unix-access (path mode) + _N"Given a file path (a string) and one of four constant modes, + unix-access returns T if the file is accessible with that + mode and NIL if not. It also returns an errno value with + NIL which determines why the file was not accessible.
- If the o_creat flag is specified, then the file is created with - a permission of argument MODE if the file doesn't exist." + The access modes are: + r_ok Read permission. + w_ok Write permission. + x_ok Execute permission. + f_ok Presence of file." (declare (type unix-pathname path) - (type fixnum flags) - (type unix-file-mode mode)) - (int-syscall ("open64" c-string int int) (%name->file path) flags mode)) + (type (mod 8) mode)) + (void-syscall ("access" c-string int) (%name->file path) mode))
-(defun unix-getdtablesize () - _N"Unix-getdtablesize returns the maximum size of the file descriptor - table. (i.e. the maximum number of descriptors that can exist at - one time.)" - (int-syscall ("getdtablesize"))) +(defconstant l_set 0 _N"set the file pointer") +(defconstant l_incr 1 _N"increment the file pointer") +(defconstant l_xtnd 2 _N"extend the file size") + +(defun unix-lseek (fd offset whence) + _N"UNIX-LSEEK accepts a file descriptor and moves the file pointer ahead + a certain OFFSET for that file. WHENCE can be any of the following:
+ l_set Set the file pointer. + l_incr Increment the file pointer. + l_xtnd Extend the file size. + " + (declare (type unix-fd fd) + (type (signed-byte 64) offset) + (type (integer 0 2) whence)) + (let ((result (alien-funcall + (extern-alien "lseek64" (function off-t int off-t int)) + fd offset whence))) + (if (minusp result) + (values nil (unix-errno)) + (values result 0)))) ;;; Unix-close accepts a file descriptor and attempts to close the file ;;; associated with it.
@@ -625,1511 +683,912 @@ (type unix-file-mode mode)) (int-syscall ("creat64" c-string int) (%name->file name) mode))
-;;; fcntlbits.h - -(defconstant o_read o_rdonly _N"Open for reading") -(defconstant o_write o_wronly _N"Open for writing") - -(defconstant o_rdonly 0 _N"Read-only flag.") -(defconstant o_wronly 1 _N"Write-only flag.") -(defconstant o_rdwr 2 _N"Read-write flag.") -(defconstant o_accmode 3 _N"Access mode mask.") - -#-alpha -(progn - (defconstant o_creat #o100 _N"Create if nonexistant flag. (not fcntl)") - (defconstant o_excl #o200 _N"Error if already exists. (not fcntl)") - (defconstant o_noctty #o400 _N"Don't assign controlling tty. (not fcntl)") - (defconstant o_trunc #o1000 _N"Truncate flag. (not fcntl)") - (defconstant o_append #o2000 _N"Append flag.") - (defconstant o_ndelay #o4000 _N"Non-blocking I/O") - (defconstant o_nonblock #o4000 _N"Non-blocking I/O") - (defconstant o_ndelay o_nonblock) - (defconstant o_sync #o10000 _N"Synchronous writes (on ext2)") - (defconstant o_fsync o_sync) - (defconstant o_async #o20000 _N"Asynchronous I/O")) -#+alpha -(progn - (defconstant o_creat #o1000 _N"Create if nonexistant flag. (not fcntl)") - (defconstant o_trunc #o2000 _N"Truncate flag. (not fcntl)") - (defconstant o_excl #o4000 _N"Error if already exists. (not fcntl)") - (defconstant o_noctty #o10000 _N"Don't assign controlling tty. (not fcntl)") - (defconstant o_nonblock #o4 _N"Non-blocking I/O") - (defconstant o_append #o10 _N"Append flag.") - (defconstant o_ndelay o_nonblock) - (defconstant o_sync #o40000 _N"Synchronous writes (on ext2)") - (defconstant o_fsync o_sync) - (defconstant o_async #o20000 _N"Asynchronous I/O")) - -(defconstant f-dupfd 0 _N"Duplicate a file descriptor") -(defconstant f-getfd 1 _N"Get file desc. flags") -(defconstant f-setfd 2 _N"Set file desc. flags") -(defconstant f-getfl 3 _N"Get file flags") -(defconstant f-setfl 4 _N"Set file flags") - -#-alpha -(progn - (defconstant f-getlk 5 _N"Get lock") - (defconstant f-setlk 6 _N"Set lock") - (defconstant f-setlkw 7 _N"Set lock, wait for release") - (defconstant f-setown 8 _N"Set owner (for sockets)") - (defconstant f-getown 9 _N"Get owner (for sockets)")) -#+alpha -(progn - (defconstant f-getlk 7 _N"Get lock") - (defconstant f-setlk 8 _N"Set lock") - (defconstant f-setlkw 9 _N"Set lock, wait for release") - (defconstant f-setown 5 _N"Set owner (for sockets)") - (defconstant f-getown 6 _N"Get owner (for sockets)")) - - - -(defconstant F-CLOEXEC 1 _N"for f-getfl and f-setfl") - -#-alpha -(progn - (defconstant F-RDLCK 0 _N"for fcntl and lockf") - (defconstant F-WRLCK 1 _N"for fcntl and lockf") - (defconstant F-UNLCK 2 _N"for fcntl and lockf") - (defconstant F-EXLCK 4 _N"old bsd flock (depricated)") - (defconstant F-SHLCK 8 _N"old bsd flock (depricated)")) -#+alpha -(progn - (defconstant F-RDLCK 1 _N"for fcntl and lockf") - (defconstant F-WRLCK 2 _N"for fcntl and lockf") - (defconstant F-UNLCK 8 _N"for fcntl and lockf") - (defconstant F-EXLCK 16 _N"old bsd flock (depricated)") - (defconstant F-SHLCK 32 _N"old bsd flock (depricated)")) +(defun unix-resolve-links (pathname) + _N"Returns the pathname with all symbolic links resolved." + (declare (simple-string pathname)) + (let ((len (length pathname)) + (pending pathname)) + (declare (fixnum len) (simple-string pending)) + (if (zerop len) + pathname + (let ((result (make-string 100 :initial-element (code-char 0))) + (fill-ptr 0) + (name-start 0)) + (loop + (let* ((name-end (or (position #/ pending :start name-start) len)) + (new-fill-ptr (+ fill-ptr (- name-end name-start)))) + ;; grow the result string, if necessary. the ">=" (instead of + ;; using ">") allows for the trailing "/" if we find this + ;; component is a directory. + (when (>= new-fill-ptr (length result)) + (let ((longer (make-string (* 3 (length result)) + :initial-element (code-char 0)))) + (replace longer result :end1 fill-ptr) + (setq result longer))) + (replace result pending + :start1 fill-ptr + :end1 new-fill-ptr + :start2 name-start + :end2 name-end) + (let ((kind (unix-file-kind (if (zerop name-end) "/" result) t))) + (unless kind (return nil)) + (cond ((eq kind :link) + (multiple-value-bind (link err) (unix-readlink result) + (unless link + (error (intl:gettext "Error reading link ~S: ~S") + (subseq result 0 fill-ptr) + (get-unix-error-msg err))) + (cond ((or (zerop (length link)) + (char/= (schar link 0) #/)) + ;; It's a relative link + (fill result (code-char 0) + :start fill-ptr + :end new-fill-ptr)) + ((string= result "/../" :end1 4) + ;; It's across the super-root. + (let ((slash (or (position #/ result :start 4) + 0))) + (fill result (code-char 0) + :start slash + :end new-fill-ptr) + (setf fill-ptr slash))) + (t + ;; It's absolute. + (and (> (length link) 0) + (char= (schar link 0) #/)) + (fill result (code-char 0) :end new-fill-ptr) + (setf fill-ptr 0))) + (setf pending + (if (= name-end len) + link + (concatenate 'simple-string + link + (subseq pending name-end)))) + (setf len (length pending)) + (setf name-start 0))) + ((= name-end len) + (when (eq kind :directory) + (setf (schar result new-fill-ptr) #/) + (incf new-fill-ptr)) + (return (subseq result 0 new-fill-ptr))) + ((eq kind :directory) + (setf (schar result new-fill-ptr) #/) + (setf fill-ptr (1+ new-fill-ptr)) + (setf name-start (1+ name-end))) + (t + (return nil))))))))))
-(defconstant F-LOCK-SH 1 _N"Shared lock for bsd flock") -(defconstant F-LOCK-EX 2 _N"Exclusive lock for bsd flock") -(defconstant F-LOCK-NB 4 _N"Don't block. Combine with F-LOCK-SH or F-LOCK-EX") -(defconstant F-LOCK-UN 8 _N"Remove lock for bsd flock") +(defun unix-simplify-pathname (src) + (declare (simple-string src)) + (let* ((src-len (length src)) + (dst (make-string src-len)) + (dst-len 0) + (dots 0) + (last-slash nil)) + (macrolet ((deposit (char) + `(progn + (setf (schar dst dst-len) ,char) + (incf dst-len)))) + (dotimes (src-index src-len) + (let ((char (schar src src-index))) + (cond ((char= char #.) + (when dots + (incf dots)) + (deposit char)) + ((char= char #/) + (case dots + (0 + ;; Either ``/...' or ``...//...' + (unless last-slash + (setf last-slash dst-len) + (deposit char))) + (1 + ;; Either ``./...'' or ``..././...'' + (decf dst-len)) + (2 + ;; We've found .. + (cond + ((and last-slash (not (zerop last-slash))) + ;; There is something before this .. + (let ((prev-prev-slash + (position #/ dst :end last-slash :from-end t))) + (cond ((and (= (+ (or prev-prev-slash 0) 2) + last-slash) + (char= (schar dst (- last-slash 2)) #.) + (char= (schar dst (1- last-slash)) #.)) + ;; The something before this .. is another .. + (deposit char) + (setf last-slash dst-len)) + (t + ;; The something is some random dir. + (setf dst-len + (if prev-prev-slash + (1+ prev-prev-slash) + 0)) + (setf last-slash prev-prev-slash))))) + (t + ;; There is nothing before this .., so we need to keep it + (setf last-slash dst-len) + (deposit char)))) + (t + ;; Something other than a dot between slashes. + (setf last-slash dst-len) + (deposit char))) + (setf dots 0)) + (t + (setf dots nil) + (setf (schar dst dst-len) char) + (incf dst-len)))))) + (when (and last-slash (not (zerop last-slash))) + (case dots + (1 + ;; We've got ``foobar/.'' + (decf dst-len)) + (2 + ;; We've got ``foobar/..'' + (unless (and (>= last-slash 2) + (char= (schar dst (1- last-slash)) #.) + (char= (schar dst (- last-slash 2)) #.) + (or (= last-slash 2) + (char= (schar dst (- last-slash 3)) #/))) + (let ((prev-prev-slash + (position #/ dst :end last-slash :from-end t))) + (if prev-prev-slash + (setf dst-len (1+ prev-prev-slash)) + (return-from unix-simplify-pathname "./"))))))) + (cond ((zerop dst-len) + "./") + ((= dst-len src-len) + dst) + (t + (subseq dst 0 dst-len)))))
-(def-alien-type nil - (struct flock - (l-type short) - (l-whence short) - (l-start off-t) - (l-len off-t) - (l-pid pid-t))) +(defun unix-gethostname () + _N"Unix-gethostname returns the name of the host machine as a string." + (with-alien ((buf (array char 256))) + (syscall* ("gethostname" (* char) int) + (cast buf c-string) + (cast buf (* char)) 256)))
-;;; Define some more compatibility macros to be backward compatible with -;;; BSD systems which did not managed to hide these kernel macros. +;;; Unix-dup returns a duplicate copy of the existing file-descriptor +;;; passed as an argument.
-(defconstant FAPPEND o_append _N"depricated stuff") -(defconstant FFSYNC o_fsync _N"depricated stuff") -(defconstant FASYNC o_async _N"depricated stuff") -(defconstant FNONBLOCK o_nonblock _N"depricated stuff") -(defconstant FNDELAY o_ndelay _N"depricated stuff") +(defun unix-dup (fd) + _N"Unix-dup duplicates an existing file descriptor (given as the + argument) and return it. If FD is not a valid file descriptor, NIL + and an error number are returned." + (declare (type unix-fd fd)) + (int-syscall ("dup" int) fd))
+;;; Unix-dup2 makes the second file-descriptor describe the same file +;;; as the first. If the second file-descriptor points to an open +;;; file, it is first closed. In any case, the second should have a +;;; value which is a valid file-descriptor.
-;;; grp.h +(defun unix-dup2 (fd1 fd2) + _N"Unix-dup2 duplicates an existing file descriptor just as unix-dup + does only the new value of the duplicate descriptor may be requested + through the second argument. If a file already exists with the + requested descriptor number, it will be closed and the number + assigned to the duplicate." + (declare (type unix-fd fd1 fd2)) + (void-syscall ("dup2" int int) fd1 fd2))
-;;; POSIX Standard: 9.2.1 Group Database Access <grp.h> +;;; Unix-exit terminates a program.
-#+(or) -(defun unix-setgrend () - _N"Rewind the group-file stream." - (void-syscall ("setgrend"))) +(defun unix-exit (&optional (code 0)) + _N"Unix-exit terminates the current process with an optional + error code. If successful, the call doesn't return. If + unsuccessful, the call returns NIL and an error number." + (declare (type (signed-byte 32) code)) + (void-syscall ("exit" int) code))
-#+(or) -(defun unix-endgrent () - _N"Close the group-file stream." - (void-syscall ("endgrent"))) +(def-alien-routine ("getuid" unix-getuid) int + _N"Unix-getuid returns the real user-id associated with the + current process.")
-#+(or) -(defun unix-getgrent () - _N"Read an entry from the group-file stream, opening it if necessary." - - (let ((result (alien-funcall (extern-alien "getgrent" - (function (* (struct group))))))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) +;;; Unix-chdir accepts a directory name and makes that the +;;; current working directory.
-;;; ioctl-types.h +(defun unix-chdir (path) + _N"Given a file path string, unix-chdir changes the current working + directory to the one specified." + (declare (type unix-pathname path)) + (void-syscall ("chdir" c-string) (%name->file path)))
-(def-alien-type nil - (struct winsize - (ws-row unsigned-short) ; rows, in characters - (ws-col unsigned-short) ; columns, in characters - (ws-xpixel unsigned-short) ; horizontal size, pixels - (ws-ypixel unsigned-short))) ; veritical size, pixels +;;; Unix-chmod accepts a path and a mode and changes the mode to the new mode.
-(defconstant +NCC+ 8 - _N"Size of control character vector.") +(defun unix-chmod (path mode) + _N"Given a file path string and a constant mode, unix-chmod changes the + permission mode for that file to the one specified. The new mode + can be created by logically OR'ing the following:
-(def-alien-type nil - (struct termio - (c-iflag unsigned-int) ; input mode flags - (c-oflag unsigned-int) ; output mode flags - (c-cflag unsigned-int) ; control mode flags - (c-lflag unsigned-int) ; local mode flags - (c-line unsigned-char) ; line discipline - (c-cc (array unsigned-char #.+NCC+)))) ; control characters - -;;; modem lines -(defconstant tiocm-le 1) -(defconstant tiocm-dtr 2) -(defconstant tiocm-rts 4) -(defconstant tiocm-st 8) -(defconstant tiocm-sr #x10) -(defconstant tiocm-cts #x20) -(defconstant tiocm-car #x40) -(defconstant tiocm-rng #x80) -(defconstant tiocm-dsr #x100) -(defconstant tiocm-cd tiocm-car) -(defconstant tiocm-ri #x80) - -;;; ioctl (fd, TIOCSERGETLSR, &result) where result may be as below - -;;; line disciplines -(defconstant N-TTY 0) -(defconstant N-SLIP 1) -(defconstant N-MOUSE 2) -(defconstant N-PPP 3) -(defconstant N-STRIP 4) -(defconstant N-AX25 5) - - -;;; ioctls.h - -;;; Routing table calls. -(defconstant siocaddrt #x890B) ;; add routing table entry -(defconstant siocdelrt #x890C) ;; delete routing table entry -(defconstant siocrtmsg #x890D) ;; call to routing system - -;;; Socket configuration controls. -(defconstant siocgifname #x8910) ;; get iface name -(defconstant siocsiflink #x8911) ;; set iface channel -(defconstant siocgifconf #x8912) ;; get iface list -(defconstant siocgifflags #x8913) ;; get flags -(defconstant siocsifflags #x8914) ;; set flags -(defconstant siocgifaddr #x8915) ;; get PA address -(defconstant siocsifaddr #x8916) ;; set PA address -(defconstant siocgifdstaddr #x8917 ) ;; get remote PA address -(defconstant siocsifdstaddr #x8918 ) ;; set remote PA address -(defconstant siocgifbrdaddr #x8919 ) ;; get broadcast PA address -(defconstant siocsifbrdaddr #x891a ) ;; set broadcast PA address -(defconstant siocgifnetmask #x891b ) ;; get network PA mask -(defconstant siocsifnetmask #x891c ) ;; set network PA mask -(defconstant siocgifmetric #x891d ) ;; get metric -(defconstant siocsifmetric #x891e ) ;; set metric -(defconstant siocgifmem #x891f ) ;; get memory address (BSD) -(defconstant siocsifmem #x8920 ) ;; set memory address (BSD) -(defconstant siocgifmtu #x8921 ) ;; get MTU size -(defconstant siocsifmtu #x8922 ) ;; set MTU size -(defconstant siocsifhwaddr #x8924 ) ;; set hardware address -(defconstant siocgifencap #x8925 ) ;; get/set encapsulations -(defconstant siocsifencap #x8926) -(defconstant siocgifhwaddr #x8927 ) ;; Get hardware address -(defconstant siocgifslave #x8929 ) ;; Driver slaving support -(defconstant siocsifslave #x8930) -(defconstant siocaddmulti #x8931 ) ;; Multicast address lists -(defconstant siocdelmulti #x8932) -(defconstant siocgifindex #x8933 ) ;; name -> if_index mapping -(defconstant siogifindex SIOCGIFINDEX ) ;; misprint compatibility :-) -(defconstant siocsifpflags #x8934 ) ;; set/get extended flags set -(defconstant siocgifpflags #x8935) -(defconstant siocdifaddr #x8936 ) ;; delete PA address -(defconstant siocsifhwbroadcast #x8937 ) ;; set hardware broadcast addr -(defconstant siocgifcount #x8938 ) ;; get number of devices - -(defconstant siocgifbr #x8940 ) ;; Bridging support -(defconstant siocsifbr #x8941 ) ;; Set bridging options - -(defconstant siocgiftxqlen #x8942 ) ;; Get the tx queue length -(defconstant siocsiftxqlen #x8943 ) ;; Set the tx queue length - - -;;; ARP cache control calls. -;; 0x8950 - 0x8952 * obsolete calls, don't re-use -(defconstant siocdarp #x8953 ) ;; delete ARP table entry -(defconstant siocgarp #x8954 ) ;; get ARP table entry -(defconstant siocsarp #x8955 ) ;; set ARP table entry - -;;; RARP cache control calls. -(defconstant siocdrarp #x8960 ) ;; delete RARP table entry -(defconstant siocgrarp #x8961 ) ;; get RARP table entry -(defconstant siocsrarp #x8962 ) ;; set RARP table entry - -;;; Driver configuration calls - -(defconstant siocgifmap #x8970 ) ;; Get device parameters -(defconstant siocsifmap #x8971 ) ;; Set device parameters - -;;; DLCI configuration calls - -(defconstant siocadddlci #x8980 ) ;; Create new DLCI device -(defconstant siocdeldlci #x8981 ) ;; Delete DLCI device - -;;; Device private ioctl calls. - -;; These 16 ioctls are available to devices via the do_ioctl() device -;; vector. Each device should include this file and redefine these -;; names as their own. Because these are device dependent it is a good -;; idea _NOT_ to issue them to random objects and hope. - -(defconstant siocdevprivate #x89F0 ) ;; to 89FF - - -;;; netdb.h - -;; All data returned by the network data base library are supplied in -;; host order and returned in network order (suitable for use in -;; system calls). - -;;; Absolute file name for network data base files. -(defconstant path-hequiv "/etc/hosts.equiv") -(defconstant path-hosts "/etc/hosts") -(defconstant path-networks "/etc/networks") -(defconstant path-nsswitch_conf "/etc/nsswitch.conf") -(defconstant path-protocols "/etc/protocols") -(defconstant path-services "/etc/services") - - -;;; Possible values left in `h_errno'. -(defconstant netdb-internal -1 _N"See errno.") -(defconstant netdb-success 0 _N"No problem.") -(defconstant host-not-found 1 _N"Authoritative Answer Host not found.") -(defconstant try-again 2 _N"Non-Authoritative Host not found,or SERVERFAIL.") -(defconstant no-recovery 3 _N"Non recoverable errors, FORMERR, REFUSED, NOTIMP.") -(defconstant no-data 4 "Valid name, no data record of requested type.") -(defconstant no-address no-data "No address, look for MX record.") - -;;; Description of data base entry for a single host. + setuidexec Set user ID on execution. + setgidexec Set group ID on execution. + savetext Save text image after execution. + readown Read by owner. + writeown Write by owner. + execown Execute (search directory) by owner. + readgrp Read by group. + writegrp Write by group. + execgrp Execute (search directory) by group. + readoth Read by others. + writeoth Write by others. + execoth Execute (search directory) by others.
-(def-alien-type nil - (struct hostent - (h-name c-string) ; Official name of host. - (h-aliases (* c-string)) ; Alias list. - (h-addrtype int) ; Host address type. - (h_length int) ; Length of address. - (h-addr-list (* c-string)))) ; List of addresses from name server. - -#+(or) -(defun unix-sethostent (stay-open) - _N"Open host data base files and mark them as staying open even after -a later search if STAY_OPEN is non-zero." - (void-syscall ("sethostent" int) stay-open)) - -#+(or) -(defun unix-endhostent () - _N"Close host data base files and clear `stay open' flag." - (void-syscall ("endhostent"))) - -#+(or) -(defun unix-gethostent () - _N"Get next entry from host data base file. Open data base if -necessary." - (let ((result (alien-funcall (extern-alien "gethostent" - (function (* (struct hostent))))))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-gethostbyaddr(addr length type) - _N"Return entry from host data base which address match ADDR with -length LEN and type TYPE." - (let ((result (alien-funcall (extern-alien "gethostbyaddr" - (function (* (struct hostent)) - c-string int int)) - addr len type))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-gethostbyname (name) - _N"Return entry from host data base for host with NAME." - (let ((result (alien-funcall (extern-alien "gethostbyname" - (function (* (struct hostent)) - c-string)) - name))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-gethostbyname2 (name af) - _N"Return entry from host data base for host with NAME. AF must be - set to the address type which as `AF_INET' for IPv4 or `AF_INET6' - for IPv6." - (let ((result (alien-funcall (extern-alien "gethostbyname2" - (function (* (struct hostent)) - c-string int)) - name af))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) + Thus #o444 and (logior unix:readown unix:readgrp unix:readoth) + are equivalent for 'mode. The octal-base is familar to Unix users. + + It returns T on successfully completion; NIL and an error number + otherwise." + (declare (type unix-pathname path) + (type unix-file-mode mode)) + (void-syscall ("chmod" c-string int) (%name->file path) mode))
-;; Description of data base entry for a single network. NOTE: here a -;; poor assumption is made. The network number is expected to fit -;; into an unsigned long int variable. +;;; Unix-fchmod accepts a file descriptor ("fd") and a file protection mode +;;; ("mode") and changes the protection of the file described by "fd" to +;;; "mode".
-(def-alien-type nil - (struct netent - (n-name c-string) ; Official name of network. - (n-aliases (* c-string)) ; Alias list. - (n-addrtype int) ; Net address type. - (n-net unsigned-long))) ; Network number. - -#+(or) -(defun unix-setnetent (stay-open) - _N"Open network data base files and mark them as staying open even - after a later search if STAY_OPEN is non-zero." - (void-syscall ("setnetent" int) stay-open)) - - -#+(or) -(defun unix-endnetent () - _N"Close network data base files and clear `stay open' flag." - (void-syscall ("endnetent"))) - - -#+(or) -(defun unix-getnetent () - _N"Get next entry from network data base file. Open data base if - necessary." - (let ((result (alien-funcall (extern-alien "getnetent" - (function (* (struct netent))))))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - - -#+(or) -(defun unix-getnetbyaddr (net type) - _N"Return entry from network data base which address match NET and - type TYPE." - (let ((result (alien-funcall (extern-alien "getnetbyaddr" - (function (* (struct netent)) - unsigned-long int)) - net type))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-getnetbyname (name) - _N"Return entry from network data base for network with NAME." - (let ((result (alien-funcall (extern-alien "getnetbyname" - (function (* (struct netent)) - c-string)) - name))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -;; Description of data base entry for a single service. -(def-alien-type nil - (struct servent - (s-name c-string) ; Official service name. - (s-aliases (* c-string)) ; Alias list. - (s-port int) ; Port number. - (s-proto c-string))) ; Protocol to use. - -#+(or) -(defun unix-setservent (stay-open) - _N"Open service data base files and mark them as staying open even - after a later search if STAY_OPEN is non-zero." - (void-syscall ("setservent" int) stay-open)) - -#+(or) -(defun unix-endservent (stay-open) - _N"Close service data base files and clear `stay open' flag." - (void-syscall ("endservent"))) - - -#+(or) -(defun unix-getservent () - _N"Get next entry from service data base file. Open data base if - necessary." - (let ((result (alien-funcall (extern-alien "getservent" - (function (* (struct servent))))))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-getservbyname (name proto) - _N"Return entry from network data base for network with NAME and - protocol PROTO." - (let ((result (alien-funcall (extern-alien "getservbyname" - (function (* (struct netent)) - c-string (* char))) - name proto))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-getservbyport (port proto) - _N"Return entry from service data base which matches port PORT and - protocol PROTO." - (let ((result (alien-funcall (extern-alien "getservbyport" - (function (* (struct netent)) - int (* char))) - port proto))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -;; Description of data base entry for a single service. +(defun unix-fchmod (fd mode) + _N"Given an integer file descriptor and a mode (the same as those + used for unix-chmod), unix-fchmod changes the permission mode + for that file to the one specified. T is returned if the call + was successful." + (declare (type unix-fd fd) + (type unix-file-mode mode)) + (void-syscall ("fchmod" int int) fd mode))
-(def-alien-type nil - (struct protoent - (p-name c-string) ; Official protocol name. - (p-aliases (* c-string)) ; Alias list. - (p-proto int))) ; Protocol number. - -#+(or) -(defun unix-setprotoent (stay-open) - _N"Open protocol data base files and mark them as staying open even - after a later search if STAY_OPEN is non-zero." - (void-syscall ("setprotoent" int) stay-open)) - -#+(or) -(defun unix-endprotoent () - _N"Close protocol data base files and clear `stay open' flag." - (void-syscall ("endprotoent"))) - -#+(or) -(defun unix-getprotoent () - _N"Get next entry from protocol data base file. Open data base if - necessary." - (let ((result (alien-funcall (extern-alien "getprotoent" - (function (* (struct protoent))))))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-getprotobyname (name) - _N"Return entry from protocol data base for network with NAME." - (let ((result (alien-funcall (extern-alien "getprotobyname" - (function (* (struct protoent)) - c-string)) - name))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-getprotobynumber (proto) - _N"Return entry from protocol data base which number is PROTO." - (let ((result (alien-funcall (extern-alien "getprotobynumber" - (function (* (struct protoent)) - int)) - proto))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-setnetgrent (netgroup) - _N"Establish network group NETGROUP for enumeration." - (int-syscall ("setservent" c-string) netgroup)) - -#+(or) -(defun unix-endnetgrent () - _N"Free all space allocated by previous `setnetgrent' call." - (void-syscall ("endnetgrent"))) - -#+(or) -(defun unix-getnetgrent (hostp userp domainp) - _N"Get next member of netgroup established by last `setnetgrent' call - and return pointers to elements in HOSTP, USERP, and DOMAINP." - (int-syscall ("getnetgrent" (* c-string) (* c-string) (* c-string)) - hostp userp domainp)) - -#+(or) -(defun unix-innetgr (netgroup host user domain) - _N"Test whether NETGROUP contains the triple (HOST,USER,DOMAIN)." - (int-syscall ("innetgr" c-string c-string c-string c-string) - netgroup host user domain)) +(defun unix-readlink (path) + _N"Unix-readlink invokes the readlink system call on the file name + specified by the simple string path. It returns up to two values: + the contents of the symbolic link if the call is successful, or + NIL and the Unix error number." + (declare (type unix-pathname path)) + (with-alien ((buf (array char 1024))) + (syscall ("readlink" c-string (* char) int) + (let ((string (make-string result))) + #-unicode + (kernel:copy-from-system-area + (alien-sap buf) 0 + string (* vm:vector-data-offset vm:word-bits) + (* result vm:byte-bits)) + #+unicode + (let ((sap (alien-sap buf))) + (dotimes (k result) + (setf (aref string k) (code-char (sap-ref-8 sap k))))) + (%file->name string)) + (%name->file path) (cast buf (* char)) 1024)))
-(def-alien-type nil - (struct addrinfo - (ai-flags int) ; Input flags. - (ai-family int) ; Protocol family for socket. - (ai-socktype int) ; Socket type. - (ai-protocol int) ; Protocol for socket. - (ai-addrlen int) ; Length of socket address. - (ai-addr (* (struct sockaddr))) - ; Socket address for socket. - (ai-cononname c-string) - ; Canonical name for service location. - (ai-net (* (struct addrinfo))))) ; Pointer to next in list. - -;; Possible values for `ai_flags' field in `addrinfo' structure. - -(defconstant ai_passive 1 _N"Socket address is intended for `bind'.") -(defconstant ai_canonname 2 _N"Request for canonical name.") - -;; Error values for `getaddrinfo' function. -(defconstant eai_badflags -1 _N"Invalid value for `ai_flags' field.") -(defconstant eai_noname -2 _N"NAME or SERVICE is unknown.") -(defconstant eai_again -3 _N"Temporary failure in name resolution.") -(defconstant eai_fail -4 _N"Non-recoverable failure in name res.") -(defconstant eai_nodata -5 _N"No address associated with NAME.") -(defconstant eai_family -6 _N"ai_family not supported.") -(defconstant eai_socktype -7 _N"ai_socktype not supported.") -(defconstant eai_service -8 _N"SERVICE not supported for ai_socktype.") -(defconstant eai_addrfamily -9 _N"Address family for NAME not supported.") -(defconstant eai_memory -10 _N"Memory allocation failure.") -(defconstant eai_system -11 _N"System error returned in errno.") - - -#+(or) -(defun unix-getaddrinfo (name service req pai) - _N"Translate name of a service location and/or a service name to set of - socket addresses." - (int-syscall ("getaddrinfo" c-string c-string (* (struct addrinfo)) - (* (* struct addrinfo))) - name service req pai)) - - -#+(or) -(defun unix-freeaddrinfo (ai) - _N"Free `addrinfo' structure AI including associated storage." - (void-syscall ("freeaddrinfo" (* struct addrinfo)) - ai)) +;;; Unix-unlink accepts a name and deletes the directory entry for that +;;; name and the file if this is the last link.
+(defun unix-unlink (name) + _N"Unix-unlink removes the directory entry for the named file. + NIL and an error code is returned if the call fails." + (declare (type unix-pathname name)) + (void-syscall ("unlink" c-string) (%name->file name)))
-;;; pty.h +;;; fcntl.h +;;; +;;; POSIX Standard: 6.5 File Control Operations <fcntl.h>
-(defun unix-openpty (name termp winp) - _N"Create pseudo tty master slave pair with NAME and set terminal - attributes according to TERMP and WINP and return handles for both - ends in AMASTER and ASLAVE." - (with-alien ((amaster int) - (aslave int)) - (values - (int-syscall ("openpty" (* int) (* int) c-string (* (struct termios)) - (* (struct winsize))) - (addr amaster) (addr aslave) name termp winp) - amaster aslave))) +(defconstant r_ok 4 _N"Test for read permission") +(defconstant w_ok 2 _N"Test for write permission") +(defconstant x_ok 1 _N"Test for execute permission") +(defconstant f_ok 0 _N"Test for presence of file")
-#+(or) -(defun unix-forkpty (amaster name termp winp) - _N"Create child process and establish the slave pseudo terminal as the - child's controlling terminal." - (int-syscall ("forkpty" (* int) c-string (* (struct termios)) - (* (struct winsize))) - amaster name termp winp)) - - -;; POSIX Standard: 9.2.2 User Database Access <pwd.h> - -#+(or) -(defun unix-setpwent () - _N"Rewind the password-file stream." - (void-syscall ("setpwent"))) - -#+(or) -(defun unix-endpwent () - _N"Close the password-file stream." - (void-syscall ("endpwent"))) - -#+(or) -(defun unix-getpwent () - _N"Read an entry from the password-file stream, opening it if necessary." - (let ((result (alien-funcall (extern-alien "getpwent" - (function (* (struct passwd))))))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) +(defun unix-fcntl (fd cmd arg) + _N"Unix-fcntl manipulates file descriptors accoridng to the + argument CMD which can be one of the following:
-;;; resourcebits.h + F-DUPFD Duplicate a file descriptor. + F-GETFD Get file descriptor flags. + F-SETFD Set file descriptor flags. + F-GETFL Get file flags. + F-SETFL Set file flags. + F-GETOWN Get owner. + F-SETOWN Set owner.
-(def-alien-type nil - (struct rlimit - (rlim-cur long) ; current (soft) limit - (rlim-max long))); maximum value for rlim-cur + The flags that can be specified for F-SETFL are:
-(defconstant rusage_self 0 _N"The calling process.") -(defconstant rusage_children -1 _N"Terminated child processes.") -(defconstant rusage_both -2) + FNDELAY Non-blocking reads. + FAPPEND Append on each write. + FASYNC Signal pgrp when data ready. + FCREAT Create if nonexistant. + FTRUNC Truncate to zero length. + FEXCL Error if already created. + " + (declare (type unix-fd fd) + (type (unsigned-byte 32) cmd) + (type (unsigned-byte 32) arg)) + (int-syscall ("fcntl" int unsigned-int unsigned-int) fd cmd arg))
-(def-alien-type nil - (struct rusage - (ru-utime (struct timeval)) ; user time used - (ru-stime (struct timeval)) ; system time used. - (ru-maxrss long) ; Maximum resident set size (in kilobytes) - (ru-ixrss long) ; integral shared memory size - (ru-idrss long) ; integral unshared data " - (ru-isrss long) ; integral unshared stack " - (ru-minflt long) ; page reclaims - (ru-majflt long) ; page faults - (ru-nswap long) ; swaps - (ru-inblock long) ; block input operations - (ru-oublock long) ; block output operations - (ru-msgsnd long) ; messages sent - (ru-msgrcv long) ; messages received - (ru-nsignals long) ; signals received - (ru-nvcsw long) ; voluntary context switches - (ru-nivcsw long))) ; involuntary " +;;;; Memory-mapped files
-;; Priority limits. +(defconstant +null+ (sys:int-sap 0))
-(defconstant prio-min -20 _N"Minimum priority a process can have") -(defconstant prio-max 20 _N"Maximum priority a process can have") +(defconstant prot_read 1) +(defconstant prot_write 2) +(defconstant prot_exec 4) +(defconstant prot_none 0)
+(defconstant map_shared 1) +(defconstant map_private 2) +(defconstant map_fixed 16) +(defconstant map_anonymous 32)
-;;; The type of the WHICH argument to `getpriority' and `setpriority', -;;; indicating what flavor of entity the WHO argument specifies. +(defconstant ms_async 1) +(defconstant ms_sync 4) +(defconstant ms_invalidate 2)
-(defconstant priority-process 0 _N"WHO is a process ID") -(defconstant priority-pgrp 1 _N"WHO is a process group ID") -(defconstant priority-user 2 _N"WHO is a user ID") +;; The return value from mmap that means mmap failed. +(defconstant map_failed (int-sap (1- (ash 1 vm:word-bits))))
-;;; sched.h +(defun unix-mmap (addr length prot flags fd offset) + (declare (type (or null system-area-pointer) addr) + (type (unsigned-byte 32) length) + (type (integer 1 7) prot) + (type (unsigned-byte 32) flags) + (type (or null unix-fd) fd) + (type (signed-byte 32) offset)) + ;; Can't use syscall, because the address that is returned could be + ;; "negative". Hence we explicitly check for mmap returning + ;; MAP_FAILED. + (let ((result + (alien-funcall (extern-alien "mmap" (function system-area-pointer + system-area-pointer + size-t int int int off-t)) + (or addr +null+) length prot flags (or fd -1) offset))) + (if (sap= result map_failed) + (values nil (unix-errno)) + (values result 0))))
-#+(or) -(defun unix-sched_setparam (pid param) - _N"Rewind the password-file stream." - (int-syscall ("sched_setparam" pid-t (struct psched-param)) - pid param)) +(defun unix-munmap (addr length) + (declare (type system-area-pointer addr) + (type (unsigned-byte 32) length)) + (syscall ("munmap" system-area-pointer size-t) t addr length))
-#+(or) -(defun unix-sched_getparam (pid param) - _N"Rewind the password-file stream." - (int-syscall ("sched_getparam" pid-t (struct psched-param)) - pid param)) +(defun unix-msync (addr length flags) + (declare (type system-area-pointer addr) + (type (unsigned-byte 32) length) + (type (signed-byte 32) flags)) + (syscall ("msync" system-area-pointer size-t int) t addr length flags))
+;;; Unix-rename accepts two files names and renames the first to the second.
-#+(or) -(defun unix-sched_setscheduler (pid policy param) - _N"Set scheduling algorithm and/or parameters for a process." - (int-syscall ("sched_setscheduler" pid-t int (struct psched-param)) - pid policy param)) +(defun unix-rename (name1 name2) + _N"Unix-rename renames the file with string name1 to the string + name2. NIL and an error code is returned if an error occured." + (declare (type unix-pathname name1 name2)) + (void-syscall ("rename" c-string c-string) + (%name->file name1) (%name->file name2)))
-#+(or) -(defun unix-sched_getscheduler (pid) - _N"Retrieve scheduling algorithm for a particular purpose." - (int-syscall ("sched_getscheduler" pid-t) - pid)) +;;; Unix-rmdir accepts a name and removes the associated directory.
-(defun unix-sched-yield () - _N"Retrieve scheduling algorithm for a particular purpose." - (int-syscall ("sched_yield"))) +(defun unix-rmdir (name) + _N"Unix-rmdir attempts to remove the directory name. NIL and + an error number is returned if an error occured." + (declare (type unix-pathname name)) + (void-syscall ("rmdir" c-string) (%name->file name)))
-#+(or) -(defun unix-sched_get_priority_max (algorithm) - _N"Get maximum priority value for a scheduler." - (int-syscall ("sched_get_priority_max" int) - algorithm)) +(def-alien-type fd-mask #-alpha unsigned-long #+alpha unsigned-int)
-#+(or) -(defun unix-sched_get_priority_min (algorithm) - _N"Get minimum priority value for a scheduler." - (int-syscall ("sched_get_priority_min" int) - algorithm)) +(defconstant fd-setsize 1024) +(defconstant nfdbits 32) + +(def-alien-type nil + (struct fd-set + (fds-bits (array fd-mask #.(/ fd-setsize nfdbits)))))
+;; not checked for linux... +(defmacro fd-clr (offset fd-set) + (let ((word (gensym)) + (bit (gensym))) + `(multiple-value-bind (,word ,bit) (floor ,offset nfdbits) + (setf (deref (slot ,fd-set 'fds-bits) ,word) + (logand (deref (slot ,fd-set 'fds-bits) ,word) + (32bit-logical-not + (truly-the (unsigned-byte 32) (ash 1 ,bit))))))))
+;; not checked for linux... +(defmacro fd-isset (offset fd-set) + (let ((word (gensym)) + (bit (gensym))) + `(multiple-value-bind (,word ,bit) (floor ,offset nfdbits) + (logbitp ,bit (deref (slot ,fd-set 'fds-bits) ,word)))))
-#+(or) -(defun unix-sched_rr_get_interval (pid t) - _N"Get the SCHED_RR interval for the named process." - (int-syscall ("sched_rr_get_interval" pid-t (* (struct timespec))) - pid t)) +;; not checked for linux... +(defmacro fd-set (offset fd-set) + (let ((word (gensym)) + (bit (gensym))) + `(multiple-value-bind (,word ,bit) (floor ,offset nfdbits) + (setf (deref (slot ,fd-set 'fds-bits) ,word) + (logior (truly-the (unsigned-byte 32) (ash 1 ,bit)) + (deref (slot ,fd-set 'fds-bits) ,word))))))
-;;; schedbits.h +;; not checked for linux... +(defmacro fd-zero (fd-set) + `(progn + ,@(loop for index upfrom 0 below (/ fd-setsize nfdbits) + collect `(setf (deref (slot ,fd-set 'fds-bits) ,index) 0))))
-(defconstant scheduler-other 0) -(defconstant scheduler-fifo 1) -(defconstant scheduler-rr 2) +;;; TTY ioctl commands.
+(eval-when (compile load eval)
-;; Data structure to describe a process' schedulability. +(defconstant iocparm-mask #x3fff) +(defconstant ioc_void #x00000000) +(defconstant ioc_out #x40000000) +(defconstant ioc_in #x80000000) +(defconstant ioc_inout (logior ioc_in ioc_out))
-(def-alien-type nil - (struct sched_param - (sched-priority int))) +(defmacro define-ioctl-command (name dev cmd &optional arg parm-type) + _N"Define an ioctl command. If the optional ARG and PARM-TYPE are given + then ioctl argument size and direction are included as for ioctls defined + by _IO, _IOR, _IOW, or _IOWR. If DEV is a character then the ioctl type + is the characters code, else DEV may be an integer giving the type." + (let* ((type (if (characterp dev) + (char-code dev) + dev)) + (code (logior (ash type 8) cmd))) + (when arg + (setf code `(logior (ash (logand (alien-size ,arg :bytes) ,iocparm-mask) + 16) + ,code))) + (when parm-type + (let ((dir (ecase parm-type + (:void ioc_void) + (:in ioc_in) + (:out ioc_out) + (:inout ioc_inout)))) + (setf code `(logior ,dir ,code)))) + `(eval-when (eval load compile) + (defconstant ,name ,code)))) +)
-;; Cloning flags. -(defconstant csignal #x000000ff _N"Signal mask to be sent at exit.") -(defconstant clone_vm #x00000100 _N"Set if VM shared between processes.") -(defconstant clone_fs #x00000200 _N"Set if fs info shared between processes") -(defconstant clone_files #x00000400 _N"Set if open files shared between processe") -(defconstant clone_sighand #x00000800 _N"Set if signal handlers shared.") -(defconstant clone_pid #x00001000 _N"Set if pid shared.") +;;; TTY ioctl commands.
+(define-ioctl-command TIOCGWINSZ #\T #x13) +(define-ioctl-command TIOCSWINSZ #\T #x14) +(define-ioctl-command TIOCNOTTY #\T #x22) +(define-ioctl-command TIOCSPGRP #\T #x10) +(define-ioctl-command TIOCGPGRP #\T #x0F)
-;;; shadow.h +;;; File ioctl commands. +(define-ioctl-command FIONREAD #\T #x1B)
-;; Structure of the password file. +;;; ioctl-types.h
(def-alien-type nil - (struct spwd - (sp-namp c-string) ; Login name. - (sp-pwdp c-string) ; Encrypted password. - (sp-lstchg long) ; Date of last change. - (sp-min long) ; Minimum number of days between changes. - (sp-max long) ; Maximum number of days between changes. - (sp-warn long) ; Number of days to warn user to change the password. - (sp-inact long) ; Number of days the account may be inactive. - (sp-expire long) ; Number of days since 1970-01-01 until account expires. - (sp-flags long))) ; Reserved. - -#+(or) -(defun unix-setspent () - _N"Open database for reading." - (void-syscall ("setspent"))) - -#+(or) -(defun unix-endspent () - _N"Close database." - (void-syscall ("endspent"))) - -#+(or) -(defun unix-getspent () - _N"Get next entry from database, perhaps after opening the file." - (let ((result (alien-funcall (extern-alien "getspent" - (function (* (struct spwd))))))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-getspnam (name) - _N"Get shadow entry matching NAME." - (let ((result (alien-funcall (extern-alien "getspnam" - (function (* (struct spwd)) - c-string)) - name))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -#+(or) -(defun unix-sgetspent (string) - _N"Read shadow entry from STRING." - (let ((result (alien-funcall (extern-alien "sgetspent" - (function (* (struct spwd)) - c-string)) - string))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) - -;; - -#+(or) -(defun unix-lckpwdf () - _N"Protect password file against multi writers." - (void-syscall ("lckpwdf"))) + (struct winsize + (ws-row unsigned-short) ; rows, in characters + (ws-col unsigned-short) ; columns, in characters + (ws-xpixel unsigned-short) ; horizontal size, pixels + (ws-ypixel unsigned-short))) ; veritical size, pixels
+(defconstant f-getfl 3 _N"Get file flags") +(defconstant f-setfl 4 _N"Set file flags")
-#+(or) -(defun unix-ulckpwdf () - _N"Unlock password file." - (void-syscall ("ulckpwdf"))) +;;; Define some more compatibility macros to be backward compatible with +;;; BSD systems which did not managed to hide these kernel macros.
-;;; bits/stat.h - -(def-alien-type nil - (struct stat - (st-dev dev-t) - #-(or alpha amd64) (st-pad1 unsigned-short) - (st-ino ino-t) - #+alpha (st-pad1 unsigned-int) - #-amd64 (st-mode mode-t) - (st-nlink nlink-t) - #+amd64 (st-mode mode-t) - (st-uid uid-t) - (st-gid gid-t) - (st-rdev dev-t) - #-alpha (st-pad2 unsigned-short) - (st-size off-t) - #-alpha (st-blksize unsigned-long) - #-alpha (st-blocks blkcnt-t) - (st-atime time-t) - #-alpha (unused-1 unsigned-long) - (st-mtime time-t) - #-alpha (unused-2 unsigned-long) - (st-ctime time-t) - #+alpha (st-blocks int) - #+alpha (st-pad2 unsigned-int) - #+alpha (st-blksize unsigned-int) - #+alpha (st-flags unsigned-int) - #+alpha (st-gen unsigned-int) - #+alpha (st-pad3 unsigned-int) - #+alpha (unused-1 unsigned-long) - #+alpha (unused-2 unsigned-long) - (unused-3 unsigned-long) - (unused-4 unsigned-long) - #-alpha (unused-5 unsigned-long))) - -;; Encoding of the file mode. +(defconstant FAPPEND o_append _N"depricated stuff") +(defconstant FFSYNC o_fsync _N"depricated stuff") +(defconstant FASYNC o_async _N"depricated stuff") +(defconstant FNONBLOCK o_nonblock _N"depricated stuff") +(defconstant FNDELAY o_ndelay _N"depricated stuff")
-(defconstant s-ifmt #o0170000 _N"These bits determine file type.") +(defun unix-mprotect (addr length prot) + (declare (type system-area-pointer addr) + (type (unsigned-byte 32) length) + (type (integer 1 7) prot)) + (syscall ("mprotect" system-area-pointer size-t int) + t addr length prot)) + +;;;; Lisp types used by syscalls.
-;; File types. +(deftype unix-pathname () 'simple-string) +(deftype unix-fd () `(integer 0 ,most-positive-fixnum))
-(defconstant s-ififo #o0010000 _N"FIFO") -(defconstant s-ifchr #o0020000 _N"Character device") -(defconstant s-ifdir #o0040000 _N"Directory") -(defconstant s-ifblk #o0060000 _N"Block device") -(defconstant s-ifreg #o0100000 _N"Regular file") +(deftype unix-file-mode () '(unsigned-byte 32)) +(deftype unix-pid () '(unsigned-byte 32)) +(deftype unix-uid () '(unsigned-byte 32)) +(deftype unix-gid () '(unsigned-byte 32))
-;; These don't actually exist on System V, but having them doesn't hurt. +;;; Operations on Unix Directories.
-(defconstant s-iflnk #o0120000 _N"Symbolic link.") -(defconstant s-ifsock #o0140000 _N"Socket.") +;;; direntry.h
-;; Protection bits. +(def-alien-type nil + (struct dirent + #+glibc2.1 + (d-ino ino-t) ; inode number of entry + #-glibc2.1 + (d-ino ino64-t) ; inode number of entry + (d-off off-t) ; offset of next disk directory entry + (d-reclen unsigned-short) ; length of this record + (d_type unsigned-char) + (d-name (array char 256)))) ; name must be no longer than this
-(defconstant s-isuid #o0004000 _N"Set user ID on execution.") -(defconstant s-isgid #o0002000 _N"Set group ID on execution.") -(defconstant s-isvtx #o0001000 _N"Save swapped text after use (sticky).") -(defconstant s-iread #o0000400 _N"Read by owner") -(defconstant s-iwrite #o0000200 _N"Write by owner.") -(defconstant s-iexec #o0000100 _N"Execute by owner.") +(export '(open-dir read-dir close-dir))
-;;; statfsbuf.h +(defstruct (%directory + (:constructor make-directory) + (:conc-name directory-) + (:print-function %print-directory)) + name + (dir-struct (required-argument) :type system-area-pointer))
-(def-alien-type nil - (struct statfs - (f-type int) - (f-bsize int) - (f-blocks fsblkcnt-t) - (f-bfree fsblkcnt-t) - (f-bavail fsblkcnt-t) - (f-files fsfilcnt-t) - (f-ffree fsfilcnt-t) - (f-fsid fsid-t) - (f-namelen int) - (f-spare (array int 6)))) +(defun %print-directory (dir stream depth) + (declare (ignore depth)) + (format stream "#<Directory ~S>" (directory-name dir)))
+(defun open-dir (pathname) + (declare (type unix-pathname pathname)) + (when (string= pathname "") + (setf pathname ".")) + (let ((kind (unix-file-kind pathname))) + (case kind + (:directory + (let ((dir-struct + (alien-funcall (extern-alien "opendir" + (function system-area-pointer + c-string)) + (%name->file pathname)))) + (if (zerop (sap-int dir-struct)) + (values nil (unix-errno)) + (make-directory :name pathname :dir-struct dir-struct)))) + ((nil) + (values nil enoent)) + (t + (values nil enotdir)))))
-;;; termbits.h +(defun read-dir (dir) + (declare (type %directory dir)) + (let ((daddr (alien-funcall (extern-alien "readdir64" + (function system-area-pointer + system-area-pointer)) + (directory-dir-struct dir)))) + (declare (type system-area-pointer daddr)) + (if (zerop (sap-int daddr)) + nil + (with-alien ((dirent (* (struct dirent)) daddr)) + (values (%file->name (cast (slot dirent 'd-name) c-string)) + (slot dirent 'd-ino))))))
-(def-alien-type cc-t unsigned-char) -(def-alien-type speed-t unsigned-int) -(def-alien-type tcflag-t unsigned-int) +(defun close-dir (dir) + (declare (type %directory dir)) + (alien-funcall (extern-alien "closedir" + (function void system-area-pointer)) + (directory-dir-struct dir)) + nil)
-(defconstant +NCCS+ 32 - _N"Size of control character vector.") +(defconstant rusage_self 0 _N"The calling process.") +(defconstant rusage_children -1 _N"Terminated child processes.") +(defconstant rusage_both -2)
(def-alien-type nil - (struct termios - (c-iflag tcflag-t) - (c-oflag tcflag-t) - (c-cflag tcflag-t) - (c-lflag tcflag-t) - (c-line cc-t) - (c-cc (array cc-t #.+NCCS+)) - (c-ispeed speed-t) - (c-ospeed speed-t))) + (struct rusage + (ru-utime (struct timeval)) ; user time used + (ru-stime (struct timeval)) ; system time used. + (ru-maxrss long) ; Maximum resident set size (in kilobytes) + (ru-ixrss long) ; integral shared memory size + (ru-idrss long) ; integral unshared data " + (ru-isrss long) ; integral unshared stack " + (ru-minflt long) ; page reclaims + (ru-majflt long) ; page faults + (ru-nswap long) ; swaps + (ru-inblock long) ; block input operations + (ru-oublock long) ; block output operations + (ru-msgsnd long) ; messages sent + (ru-msgrcv long) ; messages received + (ru-nsignals long) ; signals received + (ru-nvcsw long) ; voluntary context switches + (ru-nivcsw long)))
-;; c_cc characters +(declaim (inline unix-fast-getrusage)) +(defun unix-fast-getrusage (who) + _N"Like call getrusage, but return only the system and user time, and returns + the seconds and microseconds as separate values." + (declare (values (member t) + (unsigned-byte 31) (mod 1000000) + (unsigned-byte 31) (mod 1000000))) + (with-alien ((usage (struct rusage))) + (syscall* ("getrusage" int (* (struct rusage))) + (values t + (slot (slot usage 'ru-utime) 'tv-sec) + (slot (slot usage 'ru-utime) 'tv-usec) + (slot (slot usage 'ru-stime) 'tv-sec) + (slot (slot usage 'ru-stime) 'tv-usec)) + who (addr usage))))
-(def-enum + 0 vintr vquit verase - vkill veof vtime - vmin vswtc vstart - vstop vsusp veol - vreprint vdiscard vwerase - vlnext veol2) -(defvar vdsusp vsusp) +(defun unix-getrusage (who) + _N"Unix-getrusage returns information about the resource usage + of the process specified by who. Who can be either the + current process (rusage_self) or all of the terminated + child processes (rusage_children). NIL and an error number + is returned if the call fails." + (with-alien ((usage (struct rusage))) + (syscall ("getrusage" int (* (struct rusage))) + (values t + (+ (* (slot (slot usage 'ru-utime) 'tv-sec) 1000000) + (slot (slot usage 'ru-utime) 'tv-usec)) + (+ (* (slot (slot usage 'ru-stime) 'tv-sec) 1000000) + (slot (slot usage 'ru-stime) 'tv-usec)) + (slot usage 'ru-maxrss) + (slot usage 'ru-ixrss) + (slot usage 'ru-idrss) + (slot usage 'ru-isrss) + (slot usage 'ru-minflt) + (slot usage 'ru-majflt) + (slot usage 'ru-nswap) + (slot usage 'ru-inblock) + (slot usage 'ru-oublock) + (slot usage 'ru-msgsnd) + (slot usage 'ru-msgrcv) + (slot usage 'ru-nsignals) + (slot usage 'ru-nvcsw) + (slot usage 'ru-nivcsw)) + who (addr usage))))
-(def-enum + 0 tciflush tcoflush tcioflush) +;;;; Socket support.
-(def-enum + 0 tcsanow tcsadrain tcsaflush) +;;; Looks a bit naked.
-;; c_iflag bits -(def-enum ash 1 tty-ignbrk tty-brkint tty-ignpar tty-parmrk tty-inpck - tty-istrip tty-inlcr tty-igncr tty-icrnl tty-iuclc - tty-ixon tty-ixany tty-ixoff - tty-imaxbel) +(def-alien-routine ("socket" unix-socket) int + (domain int) + (type int) + (protocol int))
-;; c_oflag bits -(def-enum ash 1 tty-opost tty-olcuc tty-onlcr tty-ocrnl tty-onocr - tty-onlret tty-ofill tty-ofdel tty-nldly) +(def-alien-routine ("connect" unix-connect) int + (socket int) + (sockaddr (* t)) + (len int))
-(defconstant tty-nl0 0) -(defconstant tty-nl1 #o400) - -(defconstant tty-crdly #o0003000) -(defconstant tty-cr0 #o0000000) -(defconstant tty-cr1 #o0001000) -(defconstant tty-cr2 #o0002000) -(defconstant tty-cr3 #o0003000) -(defconstant tty-tabdly #o0014000) -(defconstant tty-tab0 #o0000000) -(defconstant tty-tab1 #o0004000) -(defconstant tty-tab2 #o0010000) -(defconstant tty-tab3 #o0014000) -(defconstant tty-xtabs #o0014000) -(defconstant tty-bsdly #o0020000) -(defconstant tty-bs0 #o0000000) -(defconstant tty-bs1 #o0020000) -(defconstant tty-vtdly #o0040000) -(defconstant tty-vt0 #o0000000) -(defconstant tty-vt1 #o0040000) -(defconstant tty-ffdly #o0100000) -(defconstant tty-ff0 #o0000000) -(defconstant tty-ff1 #o0100000) - -;; c-cflag bit meaning -(defconstant tty-cbaud #o0010017) -(defconstant tty-b0 #o0000000) ;; hang up -(defconstant tty-b50 #o0000001) -(defconstant tty-b75 #o0000002) -(defconstant tty-b110 #o0000003) -(defconstant tty-b134 #o0000004) -(defconstant tty-b150 #o0000005) -(defconstant tty-b200 #o0000006) -(defconstant tty-b300 #o0000007) -(defconstant tty-b600 #o0000010) -(defconstant tty-b1200 #o0000011) -(defconstant tty-b1800 #o0000012) -(defconstant tty-b2400 #o0000013) -(defconstant tty-b4800 #o0000014) -(defconstant tty-b9600 #o0000015) -(defconstant tty-b19200 #o0000016) -(defconstant tty-b38400 #o0000017) -(defconstant tty-exta tty-b19200) -(defconstant tty-extb tty-b38400) -(defconstant tty-csize #o0000060) -(defconstant tty-cs5 #o0000000) -(defconstant tty-cs6 #o0000020) -(defconstant tty-cs7 #o0000040) -(defconstant tty-cs8 #o0000060) -(defconstant tty-cstopb #o0000100) -(defconstant tty-cread #o0000200) -(defconstant tty-parenb #o0000400) -(defconstant tty-parodd #o0001000) -(defconstant tty-hupcl #o0002000) -(defconstant tty-clocal #o0004000) -(defconstant tty-cbaudex #o0010000) -(defconstant tty-b57600 #o0010001) -(defconstant tty-b115200 #o0010002) -(defconstant tty-b230400 #o0010003) -(defconstant tty-b460800 #o0010004) -(defconstant tty-cibaud #o002003600000) ; input baud rate (not used) -(defconstant tty-crtscts #o020000000000) ;flow control +(def-alien-routine ("bind" unix-bind) int + (socket int) + (sockaddr (* t)) + (len int))
-;; c_lflag bits -(def-enum ash 1 tty-isig tty-icanon tty-xcase tty-echo tty-echoe - tty-echok tty-echonl tty-noflsh - tty-tostop tty-echoctl tty-echoprt - tty-echoke tty-flusho - tty-pendin tty-iexten) +(def-alien-routine ("listen" unix-listen) int + (socket int) + (backlog int))
-;;; tcflow() and TCXONC use these -(def-enum + 0 tty-tcooff tty-tcoon tty-tcioff tty-tcion) +(def-alien-routine ("accept" unix-accept) int + (socket int) + (sockaddr (* t)) + (len int :in-out))
-;; tcflush() and TCFLSH use these */ -(def-enum + 0 tty-tciflush tty-tcoflush tty-tcioflush) +(def-alien-routine ("recv" unix-recv) int + (fd int) + (buffer c-string) + (length int) + (flags int))
-;; tcsetattr uses these -(def-enum + 0 tty-tcsanow tty-tcsadrain tty-tcsaflush) +(def-alien-routine ("send" unix-send) int + (fd int) + (buffer c-string) + (length int) + (flags int))
-;;; termios.h - -(defun unix-cfgetospeed (termios) - _N"Get terminal output speed." - (multiple-value-bind (speed errno) - (int-syscall ("cfgetospeed" (* (struct termios))) termios) - (if speed - (values (svref terminal-speeds speed) 0) - (values speed errno)))) +(def-alien-routine ("getpeername" unix-getpeername) int + (socket int) + (sockaddr (* t)) + (len (* unsigned)))
-(defun unix-cfsetospeed (termios speed) - _N"Set terminal output speed." - (let ((baud (or (position speed terminal-speeds) - (error _"Bogus baud rate ~S" speed)))) - (void-syscall ("cfsetospeed" (* (struct termios)) int) termios baud))) +(def-alien-routine ("getsockname" unix-getsockname) int + (socket int) + (sockaddr (* t)) + (len (* unsigned)))
-(defun unix-cfgetispeed (termios) - _N"Get terminal input speed." - (multiple-value-bind (speed errno) - (int-syscall ("cfgetispeed" (* (struct termios))) termios) - (if speed - (values (svref terminal-speeds speed) 0) - (values speed errno)))) +(def-alien-routine ("getsockopt" unix-getsockopt) int + (socket int) + (level int) + (optname int) + (optval (* t)) + (optlen unsigned :in-out))
-(defun unix-cfsetispeed (termios speed) - _N"Set terminal input speed." - (let ((baud (or (position speed terminal-speeds) - (error _"Bogus baud rate ~S" speed)))) - (void-syscall ("cfsetispeed" (* (struct termios)) int) termios baud))) +(def-alien-routine ("setsockopt" unix-setsockopt) int + (socket int) + (level int) + (optname int) + (optval (* t)) + (optlen unsigned))
-(defun unix-tcgetattr (fd termios) - _N"Get terminal attributes." - (declare (type unix-fd fd)) - (void-syscall ("tcgetattr" int (* (struct termios))) fd termios)) +;; Datagram support
-(defun unix-tcsetattr (fd opt termios) - _N"Set terminal attributes." - (declare (type unix-fd fd)) - (void-syscall ("tcsetattr" int int (* (struct termios))) fd opt termios)) +(def-alien-routine ("recvfrom" unix-recvfrom) int + (fd int) + (buffer c-string) + (length int) + (flags int) + (sockaddr (* t)) + (len int :in-out))
-(defun unix-tcsendbreak (fd duration) - _N"Send break" - (declare (type unix-fd fd)) - (void-syscall ("tcsendbreak" int int) fd duration)) +(def-alien-routine ("sendto" unix-sendto) int + (fd int) + (buffer c-string) + (length int) + (flags int) + (sockaddr (* t)) + (len int))
-(defun unix-tcdrain (fd) - _N"Wait for output for finish" - (declare (type unix-fd fd)) - (void-syscall ("tcdrain" int) fd)) +(def-alien-routine ("shutdown" unix-shutdown) int + (socket int) + (level int))
-(defun unix-tcflush (fd selector) - _N"See tcflush(3)" - (declare (type unix-fd fd)) - (void-syscall ("tcflush" int int) fd selector)) +;;; sys/select.h
-(defun unix-tcflow (fd action) - _N"Flow control" - (declare (type unix-fd fd)) - (void-syscall ("tcflow" int int) fd action)) +;;; UNIX-FAST-SELECT -- public. +;;; +(defmacro unix-fast-select (num-descriptors + read-fds write-fds exception-fds + timeout-secs &optional (timeout-usecs 0)) + _N"Perform the UNIX select(2) system call." + (declare (type (integer 0 #.FD-SETSIZE) num-descriptors) + (type (or (alien (* (struct fd-set))) null) + read-fds write-fds exception-fds) + (type (or null (unsigned-byte 31)) timeout-secs) + (type (unsigned-byte 31) timeout-usecs) + (optimize (speed 3) (safety 0) (inhibit-warnings 3))) + `(let ((timeout-secs ,timeout-secs)) + (with-alien ((tv (struct timeval))) + (when timeout-secs + (setf (slot tv 'tv-sec) timeout-secs) + (setf (slot tv 'tv-usec) ,timeout-usecs)) + (int-syscall ("select" int (* (struct fd-set)) (* (struct fd-set)) + (* (struct fd-set)) (* (struct timeval))) + ,num-descriptors ,read-fds ,write-fds ,exception-fds + (if timeout-secs (alien-sap (addr tv)) (int-sap 0))))))
-;;; timebits.h
-;; A time value that is accurate to the nearest -;; microsecond but also has a range of years. -(def-alien-type nil - (struct timeval - (tv-sec time-t) ; seconds - (tv-usec time-t))) ; and microseconds +;;; Unix-select accepts sets of file descriptors and waits for an event +;;; to happen on one of them or to time out.
-;;; unistd.h - -(defun sub-unix-execve (program arg-list env-list) - (let ((argv nil) - (argv-bytes 0) - (envp nil) - (envp-bytes 0) - result error-code) - (unwind-protect - (progn - ;; Blast the stuff into the proper format - (multiple-value-setq - (argv argv-bytes) - (string-list-to-c-strvec arg-list)) - (multiple-value-setq - (envp envp-bytes) - (string-list-to-c-strvec env-list)) - ;; - ;; Now do the system call - (multiple-value-setq - (result error-code) - (int-syscall ("execve" - c-string system-area-pointer system-area-pointer) - program argv envp))) - ;; - ;; Deallocate memory - (when argv - (system:deallocate-system-memory argv argv-bytes)) - (when envp - (system:deallocate-system-memory envp envp-bytes))) - (values result error-code))) - -;;;; UNIX-EXECVE - -(defun unix-execve (program &optional arg-list - (environment *environment-list*)) - _N"Executes the Unix execve system call. If the system call suceeds, lisp - will no longer be running in this process. If the system call fails this - function returns two values: NIL and an error code. Arg-list should be a - list of simple-strings which are passed as arguments to the exec'ed program. - Environment should be an a-list mapping symbols to simple-strings which this - function bashes together to form the environment for the exec'ed program." - (check-type program simple-string) - (let ((env-list (let ((envlist nil)) - (dolist (cons environment) - (push (if (cdr cons) - (concatenate 'simple-string - (string (car cons)) "=" - (cdr cons)) - (car cons)) - envlist)) - envlist))) - (sub-unix-execve (%name->file program) arg-list env-list))) - - -(defmacro round-bytes-to-words (n) - `(logand (the fixnum (+ (the fixnum ,n) 3)) (lognot 3))) +(defmacro num-to-fd-set (fdset num) + `(if (fixnump ,num) + (progn + (setf (deref (slot ,fdset 'fds-bits) 0) ,num) + ,@(loop for index upfrom 1 below (/ fd-setsize nfdbits) + collect `(setf (deref (slot ,fdset 'fds-bits) ,index) 0))) + (progn + ,@(loop for index upfrom 0 below (/ fd-setsize nfdbits) + collect `(setf (deref (slot ,fdset 'fds-bits) ,index) + (ldb (byte nfdbits ,(* index nfdbits)) ,num))))))
-;; Values for the second argument to access. +(defmacro fd-set-to-num (nfds fdset) + `(if (<= ,nfds nfdbits) + (deref (slot ,fdset 'fds-bits) 0) + (+ ,@(loop for index upfrom 0 below (/ fd-setsize nfdbits) + collect `(ash (deref (slot ,fdset 'fds-bits) ,index) + ,(* index nfdbits))))))
-;;; Unix-access accepts a path and a mode. It returns two values the -;;; first is T if the file is accessible and NIL otherwise. The second -;;; only has meaning in the second case and is the unix errno value. +(defun unix-select (nfds rdfds wrfds xpfds to-secs &optional (to-usecs 0)) + _N"Unix-select examines the sets of descriptors passed as arguments + to see if they are ready for reading and writing. See the UNIX + Programmers Manual for more information." + (declare (type (integer 0 #.FD-SETSIZE) nfds) + (type unsigned-byte rdfds wrfds xpfds) + (type (or (unsigned-byte 31) null) to-secs) + (type (unsigned-byte 31) to-usecs) + (optimize (speed 3) (safety 0) (inhibit-warnings 3))) + (with-alien ((tv (struct timeval)) + (rdf (struct fd-set)) + (wrf (struct fd-set)) + (xpf (struct fd-set))) + (when to-secs + (setf (slot tv 'tv-sec) to-secs) + (setf (slot tv 'tv-usec) to-usecs)) + (num-to-fd-set rdf rdfds) + (num-to-fd-set wrf wrfds) + (num-to-fd-set xpf xpfds) + (macrolet ((frob (lispvar alienvar) + `(if (zerop ,lispvar) + (int-sap 0) + (alien-sap (addr ,alienvar))))) + (syscall ("select" int (* (struct fd-set)) (* (struct fd-set)) + (* (struct fd-set)) (* (struct timeval))) + (values result + (fd-set-to-num nfds rdf) + (fd-set-to-num nfds wrf) + (fd-set-to-num nfds xpf)) + nfds (frob rdfds rdf) (frob wrfds wrf) (frob xpfds xpf) + (if to-secs (alien-sap (addr tv)) (int-sap 0))))))
-(defun unix-access (path mode) - _N"Given a file path (a string) and one of four constant modes, - unix-access returns T if the file is accessible with that - mode and NIL if not. It also returns an errno value with - NIL which determines why the file was not accessible. +(defun unix-symlink (name1 name2) + _N"Unix-symlink creates a symbolic link named name2 to the file + named name1. NIL and an error number is returned if the call + is unsuccessful." + (declare (type unix-pathname name1 name2)) + (void-syscall ("symlink" c-string c-string) + (%name->file name1) (%name->file name2)))
- The access modes are: - r_ok Read permission. - w_ok Write permission. - x_ok Execute permission. - f_ok Presence of file." - (declare (type unix-pathname path) - (type (mod 8) mode)) - (void-syscall ("access" c-string int) (%name->file path) mode)) +(def-alien-routine ("gethostid" unix-gethostid) unsigned-long + _N"Unix-gethostid returns a 32-bit integer which provides unique + identification for the host machine.")
-(defconstant l_set 0 _N"set the file pointer") -(defconstant l_incr 1 _N"increment the file pointer") -(defconstant l_xtnd 2 _N"extend the file size") +(def-alien-routine ("getpid" unix-getpid) int + _N"Unix-getpid returns the process-id of the current process.")
-(defun unix-lseek (fd offset whence) - _N"UNIX-LSEEK accepts a file descriptor and moves the file pointer ahead - a certain OFFSET for that file. WHENCE can be any of the following: +;;;; User and group database structures: <pwd.h> and <grp.h> +(defstruct user-info + (name "" :type string) + (password "" :type string) + (uid 0 :type unix-uid) + (gid 0 :type unix-gid) + (gecos "" :type string) + (dir "" :type string) + (shell "" :type string))
- l_set Set the file pointer. - l_incr Increment the file pointer. - l_xtnd Extend the file size. - " - (declare (type unix-fd fd) - (type (signed-byte 64) offset) - (type (integer 0 2) whence)) - (let ((result (alien-funcall - (extern-alien "lseek64" (function off-t int off-t int)) - fd offset whence))) - (if (minusp result) - (values nil (unix-errno)) - (values result 0)))) +(defun unix-getpwuid (uid) + _N"Return a USER-INFO structure for the user identified by UID, or NIL if not found." + (declare (type unix-uid uid)) + (with-alien ((buf (array c-call:char 1024)) + (user-info (struct passwd)) + (result (* (struct passwd)))) + (let ((returned + (alien-funcall + (extern-alien "getpwuid_r" + (function c-call:int + c-call:unsigned-int + (* (struct passwd)) + (* c-call:char) + c-call:unsigned-int + (* (* (struct passwd))))) + uid + (addr user-info) + (cast buf (* c-call:char)) + 1024 + (addr result)))) + (when (zerop returned) + (make-user-info + :name (string (cast (slot result 'pw-name) c-call:c-string)) + :password (string (cast (slot result 'pw-passwd) c-call:c-string)) + :uid (slot result 'pw-uid) + :gid (slot result 'pw-gid) + :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) + :dir (string (cast (slot result 'pw-dir) c-call:c-string)) + :shell (string (cast (slot result 'pw-shell) c-call:c-string)))))))
+(declaim (inline unix-gettimeofday)) +(defun unix-gettimeofday () + _N"If it works, unix-gettimeofday returns 5 values: T, the seconds and + microseconds of the current time of day, the timezone (in minutes west + of Greenwich), and a daylight-savings flag. If it doesn't work, it + returns NIL and the errno." + (with-alien ((tv (struct timeval)) + (tz (struct timezone))) + (syscall* ("gettimeofday" (* (struct timeval)) + (* (struct timezone))) + (values T + (slot tv 'tv-sec) + (slot tv 'tv-usec) + (slot tz 'tz-minuteswest) + (slot tz 'tz-dsttime)) + (addr tv) + (addr tz))))
-;;; UNIX-READ accepts a file descriptor, a buffer, and the length to read. -;;; It attempts to read len bytes from the device associated with fd -;;; and store them into the buffer. It returns the actual number of -;;; bytes read. +;;; Unix-utimes changes the accessed and updated times on UNIX +;;; files. The first argument is the filename (a string) and +;;; the second argument is a list of the 4 times- accessed and +;;; updated seconds and microseconds.
-(defun unix-read (fd buf len) - _N"UNIX-READ attempts to read from the file described by fd into - the buffer buf until it is full. Len is the length of the buffer. - The number of bytes actually read is returned or NIL and an error - number if an error occured." - (declare (type unix-fd fd) - (type (unsigned-byte 32) len)) - #+gencgc - ;; With gencgc, the collector tries to keep raw objects like strings - ;; in separate pages that are not write-protected. However, this - ;; isn't always true. Thus, BUF will sometimes be write-protected - ;; and the kernel doesn't like writing to write-protected pages. So - ;; go through and touch each page to give the segv handler a chance - ;; to unprotect the pages. (This is taken from unix.lisp.) - (without-gcing - (let* ((page-size (get-page-size)) - (1-page-size (1- page-size)) - (sap (etypecase buf - (system-area-pointer buf) - (vector (vector-sap buf)))) - (end (sap+ sap len))) - (declare (type (and fixnum unsigned-byte) page-size 1-page-size) - (type system-area-pointer sap end) - (optimize (speed 3) (safety 0))) - ;; Touch the beginning of every page - (do ((sap (int-sap (logand (sap-int sap) - (logxor 1-page-size (ldb (byte 32 0) -1)))) - (sap+ sap page-size))) - ((sap>= sap end)) - (declare (type system-area-pointer sap)) - (setf (sap-ref-8 sap 0) (sap-ref-8 sap 0))))) - (int-syscall ("read" int (* char) int) fd buf len)) - - -;;; Unix-write accepts a file descriptor, a buffer, an offset, and the -;;; length to write. It attempts to write len bytes to the device -;;; associated with fd from the the buffer starting at offset. It returns -;;; the actual number of bytes written. - -(defun unix-write (fd buf offset len) - _N"Unix-write attempts to write a character buffer (buf) of length - len to the file described by the file descriptor fd. NIL and an - error is returned if the call is unsuccessful." - (declare (type unix-fd fd) - (type (unsigned-byte 32) offset len)) - (int-syscall ("write" int (* char) int) - fd - (with-alien ((ptr (* char) (etypecase buf - ((simple-array * (*)) - (vector-sap buf)) - (system-area-pointer - buf)))) - (addr (deref ptr offset))) - len)) - -(defun unix-pipe () - _N"Unix-pipe sets up a unix-piping mechanism consisting of - an input pipe and an output pipe. Unix-Pipe returns two - values: if no error occurred the first value is the pipe - to be read from and the second is can be written to. If - an error occurred the first value is NIL and the second - the unix error code." - (with-alien ((fds (array int 2))) - (syscall ("pipe" (* int)) - (values (deref fds 0) (deref fds 1)) - (cast fds (* int))))) - - -(defun unix-chown (path uid gid) - _N"Given a file path, an integer user-id, and an integer group-id, - unix-chown changes the owner of the file and the group of the - file to those specified. Either the owner or the group may be - left unchanged by specifying them as -1. Note: Permission will - fail if the caller is not the superuser." - (declare (type unix-pathname path) - (type (or unix-uid (integer -1 -1)) uid) - (type (or unix-gid (integer -1 -1)) gid)) - (void-syscall ("chown" c-string int int) (%name->file path) uid gid)) - -;;; Unix-fchown is exactly the same as unix-chown except that the file -;;; is specified by a file-descriptor ("fd") instead of a pathname. - -(defun unix-fchown (fd uid gid) - _N"Unix-fchown is like unix-chown, except that it accepts an integer - file descriptor instead of a file path name." - (declare (type unix-fd fd) - (type (or unix-uid (integer -1 -1)) uid) - (type (or unix-gid (integer -1 -1)) gid)) - (void-syscall ("fchown" int int int) fd uid gid)) - -;;; Unix-chdir accepts a directory name and makes that the -;;; current working directory. - -(defun unix-chdir (path) - _N"Given a file path string, unix-chdir changes the current working - directory to the one specified." - (declare (type unix-pathname path)) - (void-syscall ("chdir" c-string) (%name->file path))) - -(defun unix-current-directory () - _N"Put the absolute pathname of the current working directory in BUF. - If successful, return BUF. If not, put an error message in - BUF and return NULL. BUF should be at least PATH_MAX bytes long." - ;; 5120 is some randomly selected maximum size for the buffer for getcwd. - (with-alien ((buf (array c-call:char 5120))) - (let ((result (alien-funcall - (extern-alien "getcwd" - (function (* c-call:char) - (* c-call:char) c-call:int)) - (cast buf (* c-call:char)) - 5120))) - - (values (not (zerop (sap-int (alien-sap result)))) - (%file->name (cast buf c-call:c-string)))))) - - -;;; Unix-dup returns a duplicate copy of the existing file-descriptor -;;; passed as an argument. - -(defun unix-dup (fd) - _N"Unix-dup duplicates an existing file descriptor (given as the - argument) and return it. If FD is not a valid file descriptor, NIL - and an error number are returned." - (declare (type unix-fd fd)) - (int-syscall ("dup" int) fd)) - -;;; Unix-dup2 makes the second file-descriptor describe the same file -;;; as the first. If the second file-descriptor points to an open -;;; file, it is first closed. In any case, the second should have a -;;; value which is a valid file-descriptor. - -(defun unix-dup2 (fd1 fd2) - _N"Unix-dup2 duplicates an existing file descriptor just as unix-dup - does only the new value of the duplicate descriptor may be requested - through the second argument. If a file already exists with the - requested descriptor number, it will be closed and the number - assigned to the duplicate." - (declare (type unix-fd fd1 fd2)) - (void-syscall ("dup2" int int) fd1 fd2)) - -;;; Unix-exit terminates a program. - -(defun unix-exit (&optional (code 0)) - _N"Unix-exit terminates the current process with an optional - error code. If successful, the call doesn't return. If - unsuccessful, the call returns NIL and an error number." - (declare (type (signed-byte 32) code)) - (void-syscall ("exit" int) code)) - -#+(or) -(defun unix-pathconf (path name) - _N"Get file-specific configuration information about PATH." - (int-syscall ("pathconf" c-string int) (%name->file path) name)) - -#+(or) -(defun unix-sysconf (name) - _N"Get the value of the system variable NAME." - (int-syscall ("sysconf" int) name)) - -#+(or) -(defun unix-confstr (name) - _N"Get the value of the string-valued system variable NAME." - (with-alien ((buf (array char 1024))) - (values (not (zerop (alien-funcall (extern-alien "confstr" - (function int - c-string - size-t)) - name buf 1024))) - (cast buf c-string)))) - - -(def-alien-routine ("getpid" unix-getpid) int - _N"Unix-getpid returns the process-id of the current process.") - -(def-alien-routine ("getppid" unix-getppid) int - _N"Unix-getppid returns the process-id of the parent of the current process.") - -;;; Unix-getpgrp returns the group-id associated with the -;;; current process. - -(defun unix-getpgrp () - _N"Unix-getpgrp returns the group-id of the calling process." - (int-syscall ("getpgrp"))) - -;;; Unix-setpgid sets the group-id of the process specified by -;;; "pid" to the value of "pgrp". The process must either have -;;; the same effective user-id or be a super-user process. - -;;; setpgrp(int int)[freebsd] is identical to setpgid and is retained -;;; for backward compatibility. setpgrp(void)[solaris] is being phased -;;; out in favor of setsid(). - -(defun unix-setpgrp (pid pgrp) - _N"Unix-setpgrp sets the process group on the process pid to - pgrp. NIL and an error number are returned upon failure." - (void-syscall ("setpgid" int int) pid pgrp)) - -(defun unix-setpgid (pid pgrp) - _N"Unix-setpgid sets the process group of the process pid to - pgrp. If pgid is equal to pid, the process becomes a process - group leader. NIL and an error number are returned upon failure." - (void-syscall ("setpgid" int int) pid pgrp)) - -#+(or) -(defun unix-setsid () - _N"Create a new session with the calling process as its leader. - The process group IDs of the session and the calling process - are set to the process ID of the calling process, which is returned." - (void-syscall ( "setsid"))) - -#+(or) -(defun unix-getsid () - _N"Return the session ID of the given process." - (int-syscall ( "getsid"))) - -(def-alien-routine ("getuid" unix-getuid) int - _N"Unix-getuid returns the real user-id associated with the - current process.") - -#+(or) -(def-alien-routine ("geteuid" unix-getuid) int - _N"Get the effective user ID of the calling process.") - -(def-alien-routine ("getgid" unix-getgid) int - _N"Unix-getgid returns the real group-id of the current process.") - -(def-alien-routine ("getegid" unix-getegid) int - _N"Unix-getegid returns the effective group-id of the current process.") - -;/* If SIZE is zero, return the number of supplementary groups -; the calling process is in. Otherwise, fill in the group IDs -; of its supplementary groups in LIST and return the number written. */ -;extern int getgroups __P ((int __size, __gid_t __list[])); - -#+(or) -(defun unix-group-member (gid) - _N"Return nonzero iff the calling process is in group GID." - (int-syscall ( "group-member" gid-t) gid)) - - -(defun unix-setuid (uid) - _N"Set the user ID of the calling process to UID. - If the calling process is the super-user, set the real - and effective user IDs, and the saved set-user-ID to UID; - if not, the effective user ID is set to UID." - (int-syscall ("setuid" uid-t) uid)) - -;;; Unix-setreuid sets the real and effective user-id's of the current -;;; process to the arguments "ruid" and "euid", respectively. Usage is -;;; restricted for anyone but the super-user. Setting either "ruid" or -;;; "euid" to -1 makes the system use the current id instead. - -(defun unix-setreuid (ruid euid) - _N"Unix-setreuid sets the real and effective user-id's of the current - process to the specified ones. NIL and an error number is returned - if the call fails." - (void-syscall ("setreuid" int int) ruid euid)) - -(defun unix-setgid (gid) - _N"Set the group ID of the calling process to GID. - If the calling process is the super-user, set the real - and effective group IDs, and the saved set-group-ID to GID; - if not, the effective group ID is set to GID." - (int-syscall ("setgid" gid-t) gid)) - - -;;; Unix-setregid sets the real and effective group-id's of the current -;;; process to the arguments "rgid" and "egid", respectively. Usage is -;;; restricted for anyone but the super-user. Setting either "rgid" or -;;; "egid" to -1 makes the system use the current id instead. - -(defun unix-setregid (rgid egid) - _N"Unix-setregid sets the real and effective group-id's of the current - process process to the specified ones. NIL and an error number is - returned if the call fails." - (void-syscall ("setregid" int int) rgid egid)) - -(defun unix-fork () - _N"Executes the unix fork system call. Returns 0 in the child and the pid - of the child in the parent if it works, or NIL and an error number if it - doesn't work." - (int-syscall ("fork"))) - -;; Environment maninpulation; man getenv(3) -(def-alien-routine ("getenv" unix-getenv) c-call:c-string - (name c-call:c-string) - _N"Get the value of the environment variable named Name. If no such - variable exists, Nil is returned.") - -(def-alien-routine ("setenv" unix-setenv) c-call:int - (name c-call:c-string) - (value c-call:c-string) - (overwrite c-call:int) - _N"Adds the environment variable named Name to the environment with - the given Value if Name does not already exist. If Name does exist, - the value is changed to Value if Overwrite is non-zero. Otherwise, - the value is not changed.") - -(def-alien-routine ("putenv" unix-putenv) c-call:int - (name c-call:c-string) - _N"Adds or changes the environment. Name-value must be a string of - the form "name=value". If the name does not exist, it is added. - If name does exist, the value is updated to the given value.") - -(def-alien-routine ("unsetenv" unix-unsetenv) c-call:int - (name c-call:c-string) - _N"Removes the variable Name from the environment") +(defun unix-utimes (file atime-sec atime-usec mtime-sec mtime-usec) + _N"Unix-utimes sets the 'last-accessed' and 'last-updated' + times on a specified file. NIL and an error number is + returned if the call is unsuccessful." + (declare (type unix-pathname file) + (type (alien unsigned-long) + atime-sec atime-usec + mtime-sec mtime-usec)) + (with-alien ((tvp (array (struct timeval) 2))) + (setf (slot (deref tvp 0) 'tv-sec) atime-sec) + (setf (slot (deref tvp 0) 'tv-usec) atime-usec) + (setf (slot (deref tvp 1) 'tv-sec) mtime-sec) + (setf (slot (deref tvp 1) 'tv-usec) mtime-usec) + (void-syscall ("utimes" c-string (* (struct timeval))) + file + (cast tvp (* (struct timeval))))))
(def-alien-routine ("ttyname" unix-ttyname) c-string (fd int)) @@ -2139,127 +1598,19 @@ length LEN and type TYPE." associated with it is a terminal." (fd int))
-;;; Unix-link creates a hard link from name2 to name1. - -(defun unix-link (name1 name2) - _N"Unix-link creates a hard link from the file with name1 to the - file with name2." - (declare (type unix-pathname name1 name2)) - (void-syscall ("link" c-string c-string) - (%name->file name1) (%name->file name2))) - -(defun unix-symlink (name1 name2) - _N"Unix-symlink creates a symbolic link named name2 to the file - named name1. NIL and an error number is returned if the call - is unsuccessful." - (declare (type unix-pathname name1 name2)) - (void-syscall ("symlink" c-string c-string) - (%name->file name1) (%name->file name2))) - -(defun unix-readlink (path) - _N"Unix-readlink invokes the readlink system call on the file name - specified by the simple string path. It returns up to two values: - the contents of the symbolic link if the call is successful, or - NIL and the Unix error number." - (declare (type unix-pathname path)) - (with-alien ((buf (array char 1024))) - (syscall ("readlink" c-string (* char) int) - (let ((string (make-string result))) - #-unicode - (kernel:copy-from-system-area - (alien-sap buf) 0 - string (* vm:vector-data-offset vm:word-bits) - (* result vm:byte-bits)) - #+unicode - (let ((sap (alien-sap buf))) - (dotimes (k result) - (setf (aref string k) (code-char (sap-ref-8 sap k))))) - (%file->name string)) - (%name->file path) (cast buf (* char)) 1024))) - -;;; Unix-unlink accepts a name and deletes the directory entry for that -;;; name and the file if this is the last link. - -(defun unix-unlink (name) - _N"Unix-unlink removes the directory entry for the named file. - NIL and an error code is returned if the call fails." - (declare (type unix-pathname name)) - (void-syscall ("unlink" c-string) (%name->file name))) - -;;; Unix-rmdir accepts a name and removes the associated directory. - -(defun unix-rmdir (name) - _N"Unix-rmdir attempts to remove the directory name. NIL and - an error number is returned if an error occured." - (declare (type unix-pathname name)) - (void-syscall ("rmdir" c-string) (%name->file name))) +;;; pty.h
-(defun tcgetpgrp (fd) - _N"Get the tty-process-group for the unix file-descriptor FD." - (alien:with-alien ((alien-pgrp c-call:int)) - (multiple-value-bind (ok err) - (unix-ioctl fd - tiocgpgrp - (alien:alien-sap (alien:addr alien-pgrp))) - (if ok - (values alien-pgrp nil) - (values nil err))))) - -(defun tty-process-group (&optional fd) - _N"Get the tty-process-group for the unix file-descriptor FD. If not supplied, - FD defaults to /dev/tty." - (if fd - (tcgetpgrp fd) - (multiple-value-bind (tty-fd errno) - (unix-open "/dev/tty" o_rdwr 0) - (cond (tty-fd - (multiple-value-prog1 - (tcgetpgrp tty-fd) - (unix-close tty-fd))) - (t - (values nil errno)))))) - -(defun tcsetpgrp (fd pgrp) - _N"Set the tty-process-group for the unix file-descriptor FD to PGRP." - (alien:with-alien ((alien-pgrp c-call:int pgrp)) - (unix-ioctl fd - tiocspgrp - (alien:alien-sap (alien:addr alien-pgrp))))) - -(defun %set-tty-process-group (pgrp &optional fd) - _N"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not - supplied, FD defaults to /dev/tty." - (let ((old-sigs - (unix-sigblock - (sigmask :sigttou :sigttin :sigtstp :sigchld)))) - (declare (type (unsigned-byte 32) old-sigs)) - (unwind-protect - (if fd - (tcsetpgrp fd pgrp) - (multiple-value-bind (tty-fd errno) - (unix-open "/dev/tty" o_rdwr 0) - (cond (tty-fd - (multiple-value-prog1 - (tcsetpgrp tty-fd pgrp) - (unix-close tty-fd))) - (t - (values nil errno))))) - (unix-sigsetmask old-sigs)))) - -(defsetf tty-process-group (&optional fd) (pgrp) - _N"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not - supplied, FD defaults to /dev/tty." - `(%set-tty-process-group ,pgrp ,fd)) - -#+(or) -(defun unix-getlogin () - _N"Return the login name of the user." - (let ((result (alien-funcall (extern-alien "getlogin" - (function c-string))))) - (declare (type system-area-pointer result)) - (if (zerop (sap-int result)) - nil - result))) +(defun unix-openpty (name termp winp) + _N"Create pseudo tty master slave pair with NAME and set terminal + attributes according to TERMP and WINP and return handles for both + ends in AMASTER and ASLAVE." + (with-alien ((amaster int) + (aslave int)) + (values + (int-syscall ("openpty" (* int) (* int) c-string (* (struct termios)) + (* (struct winsize))) + (addr amaster) (addr aslave) name termp winp) + amaster aslave)))
(def-alien-type nil (struct utsname @@ -2284,1516 +1635,190 @@ length LEN and type TYPE." (cast (slot utsname 'domainname) c-string)) (addr utsname))))
-(defun unix-gethostname () - _N"Unix-gethostname returns the name of the host machine as a string." - (with-alien ((buf (array char 256))) - (syscall* ("gethostname" (* char) int) - (cast buf c-string) - (cast buf (* char)) 256))) - -#+(or) -(defun unix-sethostname (name len) - (int-syscall ("sethostname" c-string size-t) name len)) - -#+(or) -(defun unix-sethostid (id) - (int-syscall ("sethostid" long) id)) - -#+(or) -(defun unix-getdomainname (name len) - (int-syscall ("getdomainname" c-string size-t) name len)) +;;; sys/ioctl.h
-#+(or) -(defun unix-setdomainname (name len) - (int-syscall ("setdomainname" c-string size-t) name len)) +(defun unix-ioctl (fd cmd arg) + _N"Unix-ioctl performs a variety of operations on open i/o + descriptors. See the UNIX Programmer's Manual for more + information." + (declare (type unix-fd fd) + (type (unsigned-byte 32) cmd)) + (int-syscall ("ioctl" int unsigned-int (* char)) fd cmd arg))
-;;; Unix-fsync writes the core-image of the file described by "fd" to -;;; permanent storage (i.e. disk).
-(defun unix-fsync (fd) - _N"Unix-fsync writes the core image of the file described by - fd to disk." - (declare (type unix-fd fd)) - (void-syscall ("fsync" int) fd)) +;;; Unix-mkdir accepts a name and a mode and attempts to create the +;;; corresponding directory with mode mode.
+(defun unix-mkdir (name mode) + _N"Unix-mkdir creates a new directory with the specified name and mode. + (Same as those for unix-chmod.) It returns T upon success, otherwise + NIL and an error number." + (declare (type unix-pathname name) + (type unix-file-mode mode)) + (void-syscall ("mkdir" c-string int) (%name->file name) mode))
-#+(or) -(defun unix-vhangup () - _N"Revoke access permissions to all processes currently communicating - with the control terminal, and then send a SIGHUP signal to the process - group of the control terminal." - (int-syscall ("vhangup"))) - -#+(or) -(defun unix-revoke (file) - _N"Revoke the access of all descriptors currently open on FILE." - (int-syscall ("revoke" c-string) (%name->file file))) - - -#+(or) -(defun unix-chroot (path) - _N"Make PATH be the root directory (the starting point for absolute paths). - This call is restricted to the super-user." - (int-syscall ("chroot" c-string) (%name->file path))) - -(def-alien-routine ("gethostid" unix-gethostid) unsigned-long - _N"Unix-gethostid returns a 32-bit integer which provides unique - identification for the host machine.") - -;;; Unix-sync writes all information in core memory which has been modified -;;; to permanent storage (i.e. disk). - -(defun unix-sync () - _N"Unix-sync writes all information in core memory which has been - modified to disk. It returns NIL and an error code if an error - occured." - (void-syscall ("sync"))) - -;;; Unix-getpagesize returns the number of bytes in the system page. - -(defun unix-getpagesize () - _N"Unix-getpagesize returns the number of bytes in a system page." - (int-syscall ("getpagesize"))) - -;;; Unix-truncate accepts a file name and a new length. The file is -;;; truncated to the new length. - -(defun unix-truncate (name length) - _N"Unix-truncate truncates the named file to the length (in - bytes) specified by LENGTH. NIL and an error number is returned - if the call is unsuccessful." - (declare (type unix-pathname name) - (type (unsigned-byte 64) length)) - (void-syscall ("truncate64" c-string off-t) (%name->file name) length)) - -(defun unix-ftruncate (fd length) - _N"Unix-ftruncate is similar to unix-truncate except that the first - argument is a file descriptor rather than a file name." - (declare (type unix-fd fd) - (type (unsigned-byte 64) length)) - (void-syscall ("ftruncate64" int off-t) fd length)) - -#+(or) -(defun unix-getdtablesize () - _N"Return the maximum number of file descriptors - the current process could possibly have." - (int-syscall ("getdtablesize"))) - -(defconstant f_ulock 0 _N"Unlock a locked region") -(defconstant f_lock 1 _N"Lock a region for exclusive use") -(defconstant f_tlock 2 _N"Test and lock a region for exclusive use") -(defconstant f_test 3 _N"Test a region for othwer processes locks") - -(defun unix-lockf (fd cmd length) - _N"Unix-locks can lock, unlock and test files according to the cmd - which can be one of the following: - - f_ulock Unlock a locked region - f_lock Lock a region for exclusive use - f_tlock Test and lock a region for exclusive use - f_test Test a region for othwer processes locks - - The lock is for a region from the current location for a length - of length. - - This is a simpler version of the interface provided by unix-fcntl. - " - (declare (type unix-fd fd) - (type (unsigned-byte 64) length) - (type (integer 0 3) cmd)) - (int-syscall ("lockf64" int int off-t) fd cmd length)) - -;;; utime.h - -;; Structure describing file times. +;;; timebits.h
+;; A time value that is accurate to the nearest +;; microsecond but also has a range of years. (def-alien-type nil - (struct utimbuf - (actime time-t) ; Access time. - (modtime time-t))) ; Modification time. - -;;; Unix-utimes changes the accessed and updated times on UNIX -;;; files. The first argument is the filename (a string) and -;;; the second argument is a list of the 4 times- accessed and -;;; updated seconds and microseconds. + (struct timeval + (tv-sec time-t) ; seconds + (tv-usec time-t))) ; and microseconds
-(defun unix-utimes (file atime-sec atime-usec mtime-sec mtime-usec) - _N"Unix-utimes sets the 'last-accessed' and 'last-updated' - times on a specified file. NIL and an error number is - returned if the call is unsuccessful." - (declare (type unix-pathname file) - (type (alien unsigned-long) - atime-sec atime-usec - mtime-sec mtime-usec)) - (with-alien ((tvp (array (struct timeval) 2))) - (setf (slot (deref tvp 0) 'tv-sec) atime-sec) - (setf (slot (deref tvp 0) 'tv-usec) atime-usec) - (setf (slot (deref tvp 1) 'tv-sec) mtime-sec) - (setf (slot (deref tvp 1) 'tv-usec) mtime-usec) - (void-syscall ("utimes" c-string (* (struct timeval))) - file - (cast tvp (* (struct timeval)))))) -;;; waitflags.h +;;; sys/time.h
-;; Bits in the third argument to `waitpid'. +;; Structure crudely representing a timezone. +;; This is obsolete and should never be used. +(def-alien-type nil + (struct timezone + (tz-minuteswest int) ; minutes west of Greenwich + (tz-dsttime int))) ; type of dst correction
-(defconstant waitpid-wnohang 1 _N"Don't block waiting.") -(defconstant waitpid-wuntranced 2 _N"Report status of stopped children.") +;; Type of the second argument to `getitimer' and +;; the second and third arguments `setitimer'. +(def-alien-type nil + (struct itimerval + (it-interval (struct timeval)) ; timer interval + (it-value (struct timeval)))) ; current value
-(defconstant waitpid-wclone #x80000000 _N"Wait for cloned process.") +(defconstant ITIMER-REAL 0) +(defconstant ITIMER-VIRTUAL 1) +(defconstant ITIMER-PROF 2)
-;;; sys/ioctl.h +(defun unix-getitimer (which) + _N"Unix-getitimer returns the INTERVAL and VALUE slots of one of + three system timers (:real :virtual or :profile). On success, + unix-getitimer returns 5 values, + T, it-interval-secs, it-interval-usec, it-value-secs, it-value-usec." + (declare (type (member :real :virtual :profile) which) + (values t + (unsigned-byte 29)(mod 1000000) + (unsigned-byte 29)(mod 1000000))) + (let ((which (ecase which + (:real ITIMER-REAL) + (:virtual ITIMER-VIRTUAL) + (:profile ITIMER-PROF)))) + (with-alien ((itv (struct itimerval))) + (syscall* ("getitimer" int (* (struct itimerval))) + (values T + (slot (slot itv 'it-interval) 'tv-sec) + (slot (slot itv 'it-interval) 'tv-usec) + (slot (slot itv 'it-value) 'tv-sec) + (slot (slot itv 'it-value) 'tv-usec)) + which (alien-sap (addr itv))))))
-(defun unix-ioctl (fd cmd arg) - _N"Unix-ioctl performs a variety of operations on open i/o - descriptors. See the UNIX Programmer's Manual for more - information." - (declare (type unix-fd fd) - (type (unsigned-byte 32) cmd)) - (int-syscall ("ioctl" int unsigned-int (* char)) fd cmd arg)) +(defun unix-setitimer (which int-secs int-usec val-secs val-usec) + _N" Unix-setitimer sets the INTERVAL and VALUE slots of one of + three system timers (:real :virtual or :profile). A SIGALRM signal + will be delivered VALUE <seconds+microseconds> from now. INTERVAL, + when non-zero, is <seconds+microseconds> to be loaded each time + the timer expires. Setting INTERVAL and VALUE to zero disables + the timer. See the Unix man page for more details. On success, + unix-setitimer returns the old contents of the INTERVAL and VALUE + slots as in unix-getitimer." + (declare (type (member :real :virtual :profile) which) + (type (unsigned-byte 29) int-secs val-secs) + (type (integer 0 (1000000)) int-usec val-usec) + (values t + (unsigned-byte 29)(mod 1000000) + (unsigned-byte 29)(mod 1000000))) + (let ((which (ecase which + (:real ITIMER-REAL) + (:virtual ITIMER-VIRTUAL) + (:profile ITIMER-PROF)))) + (with-alien ((itvn (struct itimerval)) + (itvo (struct itimerval))) + (setf (slot (slot itvn 'it-interval) 'tv-sec ) int-secs + (slot (slot itvn 'it-interval) 'tv-usec) int-usec + (slot (slot itvn 'it-value ) 'tv-sec ) val-secs + (slot (slot itvn 'it-value ) 'tv-usec) val-usec) + (syscall* ("setitimer" int (* (struct timeval))(* (struct timeval))) + (values T + (slot (slot itvo 'it-interval) 'tv-sec) + (slot (slot itvo 'it-interval) 'tv-usec) + (slot (slot itvo 'it-value) 'tv-sec) + (slot (slot itvo 'it-value) 'tv-usec)) + which (alien-sap (addr itvn))(alien-sap (addr itvo))))))
+ +;;; termbits.h
-;;; sys/fsuid.h +(def-alien-type cc-t unsigned-char) +(def-alien-type speed-t unsigned-int) +(def-alien-type tcflag-t unsigned-int)
-#+(or) -(defun unix-setfsuid (uid) - _N"Change uid used for file access control to UID, without affecting - other priveledges (such as who can send signals at the process)." - (int-syscall ("setfsuid" uid-t) uid)) +(defconstant +NCCS+ 32 + _N"Size of control character vector.")
-#+(or) -(defun unix-setfsgid (gid) - _N"Change gid used for file access control to GID, without affecting - other priveledges (such as who can send signals at the process)." - (int-syscall ("setfsgid" gid-t) gid)) +(def-alien-type nil + (struct termios + (c-iflag tcflag-t) + (c-oflag tcflag-t) + (c-cflag tcflag-t) + (c-lflag tcflag-t) + (c-line cc-t) + (c-cc (array cc-t #.+NCCS+)) + (c-ispeed speed-t) + (c-ospeed speed-t)))
-;;; sys/poll.h +;; c_cc characters
-;; Data structure describing a polling request. +(defmacro def-enum (inc cur &rest names) + (flet ((defform (name) + (prog1 (when name `(defconstant ,name ,cur)) + (setf cur (funcall inc cur 1))))) + `(progn ,@(mapcar #'defform names))))
-(def-alien-type nil - (struct pollfd - (fd int) ; File descriptor to poll. - (events short) ; Types of events poller cares about. - (revents short))) ; Types of events that actually occurred. - -;; Event types that can be polled for. These bits may be set in `events' -;; to indicate the interesting event types; they will appear in `revents' -;; to indicate the status of the file descriptor. - -(defconstant POLLIN #o1 _N"There is data to read.") -(defconstant POLLPRI #o2 _N"There is urgent data to read.") -(defconstant POLLOUT #o4 _N"Writing now will not block.") - -;; Event types always implicitly polled for. These bits need not be set in -;;`events', but they will appear in `revents' to indicate the status of -;; the file descriptor. */ - - -(defconstant POLLERR #o10 _N"Error condition.") -(defconstant POLLHUP #o20 _N"Hung up.") -(defconstant POLLNVAL #o40 _N"Invalid polling request.") - - -(defconstant +npollfile+ 30 _N"Canonical number of polling requests to read -in at a time in poll.") - -#+(or) -(defun unix-poll (fds nfds timeout) - _N" Poll the file descriptors described by the NFDS structures starting at - FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for - an event to occur; if TIMEOUT is -1, block until an event occurs. - Returns the number of file descriptors with events, zero if timed out, - or -1 for errors." - (int-syscall ("poll" (* (struct pollfd)) long int) - fds nfds timeout)) - -;;; sys/resource.h - -(defun unix-getrlimit (resource) - _N"Get the soft and hard limits for RESOURCE." - (with-alien ((rlimits (struct rlimit))) - (syscall ("getrlimit" int (* (struct rlimit))) - (values t - (slot rlimits 'rlim-cur) - (slot rlimits 'rlim-max)) - resource (addr rlimits)))) - -(defun unix-setrlimit (resource current maximum) - _N"Set the current soft and hard maximum limits for RESOURCE. - Only the super-user can increase hard limits." - (with-alien ((rlimits (struct rlimit))) - (setf (slot rlimits 'rlim-cur) current) - (setf (slot rlimits 'rlim-max) maximum) - (void-syscall ("setrlimit" int (* (struct rlimit))) - resource (addr rlimits)))) +(def-enum + 0 vintr vquit verase + vkill veof vtime + vmin vswtc vstart + vstop vsusp veol + vreprint vdiscard vwerase + vlnext veol2) +(defvar vdsusp vsusp)
-(declaim (inline unix-fast-getrusage)) -(defun unix-fast-getrusage (who) - _N"Like call getrusage, but return only the system and user time, and returns - the seconds and microseconds as separate values." - (declare (values (member t) - (unsigned-byte 31) (mod 1000000) - (unsigned-byte 31) (mod 1000000))) - (with-alien ((usage (struct rusage))) - (syscall* ("getrusage" int (* (struct rusage))) - (values t - (slot (slot usage 'ru-utime) 'tv-sec) - (slot (slot usage 'ru-utime) 'tv-usec) - (slot (slot usage 'ru-stime) 'tv-sec) - (slot (slot usage 'ru-stime) 'tv-usec)) - who (addr usage)))) +(def-enum + 0 tcsanow tcsadrain tcsaflush)
-(defun unix-getrusage (who) - _N"Unix-getrusage returns information about the resource usage - of the process specified by who. Who can be either the - current process (rusage_self) or all of the terminated - child processes (rusage_children). NIL and an error number - is returned if the call fails." - (with-alien ((usage (struct rusage))) - (syscall ("getrusage" int (* (struct rusage))) - (values t - (+ (* (slot (slot usage 'ru-utime) 'tv-sec) 1000000) - (slot (slot usage 'ru-utime) 'tv-usec)) - (+ (* (slot (slot usage 'ru-stime) 'tv-sec) 1000000) - (slot (slot usage 'ru-stime) 'tv-usec)) - (slot usage 'ru-maxrss) - (slot usage 'ru-ixrss) - (slot usage 'ru-idrss) - (slot usage 'ru-isrss) - (slot usage 'ru-minflt) - (slot usage 'ru-majflt) - (slot usage 'ru-nswap) - (slot usage 'ru-inblock) - (slot usage 'ru-oublock) - (slot usage 'ru-msgsnd) - (slot usage 'ru-msgrcv) - (slot usage 'ru-nsignals) - (slot usage 'ru-nvcsw) - (slot usage 'ru-nivcsw)) - who (addr usage)))) +;; c_iflag bits +(def-enum ash 1 tty-ignbrk tty-brkint tty-ignpar tty-parmrk tty-inpck + tty-istrip tty-inlcr tty-igncr tty-icrnl tty-iuclc + tty-ixon tty-ixany tty-ixoff + tty-imaxbel)
-#+(or) -(defun unix-ulimit (cmd newlimit) - _N"Function depends on CMD: - 1 = Return the limit on the size of a file, in units of 512 bytes. - 2 = Set the limit on the size of a file to NEWLIMIT. Only the - super-user can increase the limit. - 3 = Return the maximum possible address of the data segment. - 4 = Return the maximum number of files that the calling process can open. - Returns -1 on errors." - (int-syscall ("ulimit" int long) cmd newlimit)) - -#+(or) -(defun unix-getpriority (which who) - _N"Return the highest priority of any process specified by WHICH and WHO - (see above); if WHO is zero, the current process, process group, or user - (as specified by WHO) is used. A lower priority number means higher - priority. Priorities range from PRIO_MIN to PRIO_MAX (above)." - (int-syscall ("getpriority" int int) - which who)) - -#+(or) -(defun unix-setpriority (which who) - _N"Set the priority of all processes specified by WHICH and WHO (see above) - to PRIO. Returns 0 on success, -1 on errors." - (int-syscall ("setpriority" int int) - which who)) - -;;; sys/socket.h +;; c_oflag bits +(def-enum ash 1 tty-opost tty-olcuc tty-onlcr tty-ocrnl tty-onocr + tty-onlret tty-ofill tty-ofdel tty-nldly)
-;;;; Socket support. +;; c_lflag bits +(def-enum ash 1 tty-isig tty-icanon tty-xcase tty-echo tty-echoe + tty-echok tty-echonl tty-noflsh + tty-tostop tty-echoctl tty-echoprt + tty-echoke tty-flusho + tty-pendin tty-iexten)
-;;; Looks a bit naked. +(defun unix-tcgetattr (fd termios) + _N"Get terminal attributes." + (declare (type unix-fd fd)) + (void-syscall ("tcgetattr" int (* (struct termios))) fd termios))
-(def-alien-routine ("socket" unix-socket) int - (domain int) - (type int) - (protocol int)) +(defun unix-tcsetattr (fd opt termios) + _N"Set terminal attributes." + (declare (type unix-fd fd)) + (void-syscall ("tcsetattr" int int (* (struct termios))) fd opt termios))
-(def-alien-routine ("connect" unix-connect) int - (socket int) - (sockaddr (* t)) - (len int)) +(defconstant writeown #o200 _N"Write by owner")
-(def-alien-routine ("bind" unix-bind) int - (socket int) - (sockaddr (* t)) - (len int)) +;;; termios.h
-(def-alien-routine ("listen" unix-listen) int - (socket int) - (backlog int)) +(defconstant terminal-speeds + '#(0 50 75 110 134 150 200 300 600 1200 1800 2400 + 4800 9600 19200 38400 57600 115200 230400))
-(def-alien-routine ("accept" unix-accept) int - (socket int) - (sockaddr (* t)) - (len int :in-out)) - -(def-alien-routine ("recv" unix-recv) int - (fd int) - (buffer c-string) - (length int) - (flags int)) - -(def-alien-routine ("send" unix-send) int - (fd int) - (buffer c-string) - (length int) - (flags int)) - -(def-alien-routine ("getpeername" unix-getpeername) int - (socket int) - (sockaddr (* t)) - (len (* unsigned))) - -(def-alien-routine ("getsockname" unix-getsockname) int - (socket int) - (sockaddr (* t)) - (len (* unsigned))) - -(def-alien-routine ("getsockopt" unix-getsockopt) int - (socket int) - (level int) - (optname int) - (optval (* t)) - (optlen unsigned :in-out)) - -(def-alien-routine ("setsockopt" unix-setsockopt) int - (socket int) - (level int) - (optname int) - (optval (* t)) - (optlen unsigned)) - -;; Datagram support - -(def-alien-routine ("recvfrom" unix-recvfrom) int - (fd int) - (buffer c-string) - (length int) - (flags int) - (sockaddr (* t)) - (len int :in-out)) - -(def-alien-routine ("sendto" unix-sendto) int - (fd int) - (buffer c-string) - (length int) - (flags int) - (sockaddr (* t)) - (len int)) - -(def-alien-routine ("shutdown" unix-shutdown) int - (socket int) - (level int)) - -;;; sys/select.h - -;;; UNIX-FAST-SELECT -- public. -;;; -(defmacro unix-fast-select (num-descriptors - read-fds write-fds exception-fds - timeout-secs &optional (timeout-usecs 0)) - _N"Perform the UNIX select(2) system call." - (declare (type (integer 0 #.FD-SETSIZE) num-descriptors) - (type (or (alien (* (struct fd-set))) null) - read-fds write-fds exception-fds) - (type (or null (unsigned-byte 31)) timeout-secs) - (type (unsigned-byte 31) timeout-usecs) - (optimize (speed 3) (safety 0) (inhibit-warnings 3))) - `(let ((timeout-secs ,timeout-secs)) - (with-alien ((tv (struct timeval))) - (when timeout-secs - (setf (slot tv 'tv-sec) timeout-secs) - (setf (slot tv 'tv-usec) ,timeout-usecs)) - (int-syscall ("select" int (* (struct fd-set)) (* (struct fd-set)) - (* (struct fd-set)) (* (struct timeval))) - ,num-descriptors ,read-fds ,write-fds ,exception-fds - (if timeout-secs (alien-sap (addr tv)) (int-sap 0)))))) - - -;;; Unix-select accepts sets of file descriptors and waits for an event -;;; to happen on one of them or to time out. - -(defmacro num-to-fd-set (fdset num) - `(if (fixnump ,num) - (progn - (setf (deref (slot ,fdset 'fds-bits) 0) ,num) - ,@(loop for index upfrom 1 below (/ fd-setsize nfdbits) - collect `(setf (deref (slot ,fdset 'fds-bits) ,index) 0))) - (progn - ,@(loop for index upfrom 0 below (/ fd-setsize nfdbits) - collect `(setf (deref (slot ,fdset 'fds-bits) ,index) - (ldb (byte nfdbits ,(* index nfdbits)) ,num)))))) - -(defmacro fd-set-to-num (nfds fdset) - `(if (<= ,nfds nfdbits) - (deref (slot ,fdset 'fds-bits) 0) - (+ ,@(loop for index upfrom 0 below (/ fd-setsize nfdbits) - collect `(ash (deref (slot ,fdset 'fds-bits) ,index) - ,(* index nfdbits)))))) - -(defun unix-select (nfds rdfds wrfds xpfds to-secs &optional (to-usecs 0)) - _N"Unix-select examines the sets of descriptors passed as arguments - to see if they are ready for reading and writing. See the UNIX - Programmers Manual for more information." - (declare (type (integer 0 #.FD-SETSIZE) nfds) - (type unsigned-byte rdfds wrfds xpfds) - (type (or (unsigned-byte 31) null) to-secs) - (type (unsigned-byte 31) to-usecs) - (optimize (speed 3) (safety 0) (inhibit-warnings 3))) - (with-alien ((tv (struct timeval)) - (rdf (struct fd-set)) - (wrf (struct fd-set)) - (xpf (struct fd-set))) - (when to-secs - (setf (slot tv 'tv-sec) to-secs) - (setf (slot tv 'tv-usec) to-usecs)) - (num-to-fd-set rdf rdfds) - (num-to-fd-set wrf wrfds) - (num-to-fd-set xpf xpfds) - (macrolet ((frob (lispvar alienvar) - `(if (zerop ,lispvar) - (int-sap 0) - (alien-sap (addr ,alienvar))))) - (syscall ("select" int (* (struct fd-set)) (* (struct fd-set)) - (* (struct fd-set)) (* (struct timeval))) - (values result - (fd-set-to-num nfds rdf) - (fd-set-to-num nfds wrf) - (fd-set-to-num nfds xpf)) - nfds (frob rdfds rdf) (frob wrfds wrf) (frob xpfds xpf) - (if to-secs (alien-sap (addr tv)) (int-sap 0)))))) - -;;; sys/stat.h - -(defmacro extract-stat-results (buf) - `(values T - #+(or alpha amd64) - (slot ,buf 'st-dev) - #-(or alpha amd64) - (+ (deref (slot ,buf 'st-dev) 0) - (* (+ +max-u-long+ 1) - (deref (slot ,buf 'st-dev) 1))) ;;; let's hope this works.. - (slot ,buf 'st-ino) - (slot ,buf 'st-mode) - (slot ,buf 'st-nlink) - (slot ,buf 'st-uid) - (slot ,buf 'st-gid) - #+(or alpha amd64) - (slot ,buf 'st-rdev) - #-(or alpha amd64) - (+ (deref (slot ,buf 'st-rdev) 0) - (* (+ +max-u-long+ 1) - (deref (slot ,buf 'st-rdev) 1))) ;;; let's hope this works.. - (slot ,buf 'st-size) - (slot ,buf 'st-atime) - (slot ,buf 'st-mtime) - (slot ,buf 'st-ctime) - (slot ,buf 'st-blksize) - (slot ,buf 'st-blocks))) - -(defun unix-stat (name) - _N"UNIX-STAT retrieves information about the specified - file returning them in the form of multiple values. - See the UNIX Programmer's Manual for a description - of the values returned. If the call fails, then NIL - and an error number is returned instead." - (declare (type unix-pathname name)) - (when (string= name "") - (setf name ".")) - (with-alien ((buf (struct stat))) - (syscall ("stat64" c-string (* (struct stat))) - (extract-stat-results buf) - (%name->file name) (addr buf)))) - -(defun unix-fstat (fd) - _N"UNIX-FSTAT is similar to UNIX-STAT except the file is specified - by the file descriptor FD." - (declare (type unix-fd fd)) - (with-alien ((buf (struct stat))) - (syscall ("fstat64" int (* (struct stat))) - (extract-stat-results buf) - fd (addr buf)))) - -(defun unix-lstat (name) - _N"UNIX-LSTAT is similar to UNIX-STAT except the specified - file must be a symbolic link." - (declare (type unix-pathname name)) - (with-alien ((buf (struct stat))) - (syscall ("lstat64" c-string (* (struct stat))) - (extract-stat-results buf) - (%name->file name) (addr buf)))) - -;;; Unix-chmod accepts a path and a mode and changes the mode to the new mode. - -(defun unix-chmod (path mode) - _N"Given a file path string and a constant mode, unix-chmod changes the - permission mode for that file to the one specified. The new mode - can be created by logically OR'ing the following: - - setuidexec Set user ID on execution. - setgidexec Set group ID on execution. - savetext Save text image after execution. - readown Read by owner. - writeown Write by owner. - execown Execute (search directory) by owner. - readgrp Read by group. - writegrp Write by group. - execgrp Execute (search directory) by group. - readoth Read by others. - writeoth Write by others. - execoth Execute (search directory) by others. - - Thus #o444 and (logior unix:readown unix:readgrp unix:readoth) - are equivalent for 'mode. The octal-base is familar to Unix users. - - It returns T on successfully completion; NIL and an error number - otherwise." - (declare (type unix-pathname path) - (type unix-file-mode mode)) - (void-syscall ("chmod" c-string int) (%name->file path) mode)) - -;;; Unix-fchmod accepts a file descriptor ("fd") and a file protection mode -;;; ("mode") and changes the protection of the file described by "fd" to -;;; "mode". - -(defun unix-fchmod (fd mode) - _N"Given an integer file descriptor and a mode (the same as those - used for unix-chmod), unix-fchmod changes the permission mode - for that file to the one specified. T is returned if the call - was successful." - (declare (type unix-fd fd) - (type unix-file-mode mode)) - (void-syscall ("fchmod" int int) fd mode)) - - -(defun unix-umask (mask) - _N"Set the file creation mask of the current process to MASK, - and return the old creation mask." - (int-syscall ("umask" mode-t) mask)) - -;;; Unix-mkdir accepts a name and a mode and attempts to create the -;;; corresponding directory with mode mode. - -(defun unix-mkdir (name mode) - _N"Unix-mkdir creates a new directory with the specified name and mode. - (Same as those for unix-chmod.) It returns T upon success, otherwise - NIL and an error number." - (declare (type unix-pathname name) - (type unix-file-mode mode)) - (void-syscall ("mkdir" c-string int) (%name->file name) mode)) - -#+(or) -(defun unix-makedev (path mode dev) - _N"Create a device file named PATH, with permission and special bits MODE - and device number DEV (which can be constructed from major and minor - device numbers with the `makedev' macro above)." - (declare (type unix-pathname path) - (type unix-file-mode mode)) - (void-syscall ("makedev" c-string mode-t dev-t) (%name->file name) mode dev)) - - -#+(or) -(defun unix-fifo (name mode) - _N"Create a new FIFO named PATH, with permission bits MODE." - (declare (type unix-pathname name) - (type unix-file-mode mode)) - (void-syscall ("mkfifo" c-string int) (%name->file name) mode)) - -;;; sys/statfs.h - -#+(or) -(defun unix-statfs (file buf) - _N"Return information about the filesystem on which FILE resides." - (int-syscall ("statfs64" c-string (* (struct statfs))) - (%name->file file) buf)) - -;;; sys/swap.h - -#+(or) -(defun unix-swapon (path flags) - _N"Make the block special device PATH available to the system for swapping. - This call is restricted to the super-user." - (int-syscall ("swapon" c-string int) (%name->file path) flags)) - -#+(or) -(defun unix-swapoff (path) - _N"Make the block special device PATH unavailable to the system for swapping. - This call is restricted to the super-user." - (int-syscall ("swapoff" c-string) (%name->file path))) - -;;; sys/sysctl.h - -#+(or) -(defun unix-sysctl (name nlen oldval oldlenp newval newlen) - _N"Read or write system parameters." - (int-syscall ("sysctl" int int (* void) (* void) (* void) size-t) - name nlen oldval oldlenp newval newlen)) - -;;; time.h - -;; POSIX.4 structure for a time value. This is like a `struct timeval' but -;; has nanoseconds instead of microseconds. - -(def-alien-type nil - (struct timespec - (tv-sec long) ;Seconds - (tv-nsec long))) ;Nanoseconds - -;; Used by other time functions. - -(def-alien-type nil - (struct tm - (tm-sec int) ; Seconds. [0-60] (1 leap second) - (tm-min int) ; Minutes. [0-59] - (tm-hour int) ; Hours. [0-23] - (tm-mday int) ; Day. [1-31] - (tm-mon int) ; Month. [0-11] - (tm-year int) ; Year - 1900. - (tm-wday int) ; Day of week. [0-6] - (tm-yday int) ; Days in year.[0-365] - (tm-isdst int) ; DST. [-1/0/1] - (tm-gmtoff long) ; Seconds east of UTC. - (tm-zone c-string))) ; Timezone abbreviation. - -#+(or) -(defun unix-clock () - _N"Time used by the program so far (user time + system time). - The result / CLOCKS_PER_SECOND is program time in seconds." - (int-syscall ("clock"))) - -#+(or) -(defun unix-time (timer) - _N"Return the current time and put it in *TIMER if TIMER is not NULL." - (int-syscall ("time" time-t) timer)) - -;; Requires call to tzset() in main. - -(def-alien-variable ("daylight" unix-daylight) int) -(def-alien-variable ("timezone" unix-timezone) time-t) -;(def-alien-variable ("altzone" unix-altzone) time-t) doesn't exist -(def-alien-variable ("tzname" unix-tzname) (array c-string 2)) - -(def-alien-routine get-timezone c-call:void - (when c-call:long :in) - (minutes-west c-call:int :out) - (daylight-savings-p alien:boolean :out)) - -(defun unix-get-minutes-west (secs) - (multiple-value-bind (ignore minutes dst) (get-timezone secs) - (declare (ignore ignore) (ignore dst)) - (values minutes))) - -(defun unix-get-timezone (secs) - (multiple-value-bind (ignore minutes dst) (get-timezone secs) - (declare (ignore ignore) (ignore minutes)) - (values (deref unix-tzname (if dst 1 0))))) - -;;; sys/time.h - -;; Structure crudely representing a timezone. -;; This is obsolete and should never be used. -(def-alien-type nil - (struct timezone - (tz-minuteswest int) ; minutes west of Greenwich - (tz-dsttime int))) ; type of dst correction - - -(declaim (inline unix-gettimeofday)) -(defun unix-gettimeofday () - _N"If it works, unix-gettimeofday returns 5 values: T, the seconds and - microseconds of the current time of day, the timezone (in minutes west - of Greenwich), and a daylight-savings flag. If it doesn't work, it - returns NIL and the errno." - (with-alien ((tv (struct timeval)) - (tz (struct timezone))) - (syscall* ("gettimeofday" (* (struct timeval)) - (* (struct timezone))) - (values T - (slot tv 'tv-sec) - (slot tv 'tv-usec) - (slot tz 'tz-minuteswest) - (slot tz 'tz-dsttime)) - (addr tv) - (addr tz)))) - - -;/* Set the current time of day and timezone information. -; This call is restricted to the super-user. */ -;extern int __settimeofday __P ((__const struct timeval *__tv, -; __const struct timezone *__tz)); -;extern int settimeofday __P ((__const struct timeval *__tv, -; __const struct timezone *__tz)); - -;/* Adjust the current time of day by the amount in DELTA. -; If OLDDELTA is not NULL, it is filled in with the amount -; of time adjustment remaining to be done from the last `adjtime' call. -; This call is restricted to the super-user. */ -;extern int __adjtime __P ((__const struct timeval *__delta, -; struct timeval *__olddelta)); -;extern int adjtime __P ((__const struct timeval *__delta, -; struct timeval *__olddelta)); - - -;; Type of the second argument to `getitimer' and -;; the second and third arguments `setitimer'. -(def-alien-type nil - (struct itimerval - (it-interval (struct timeval)) ; timer interval - (it-value (struct timeval)))) ; current value - -(defconstant ITIMER-REAL 0) -(defconstant ITIMER-VIRTUAL 1) -(defconstant ITIMER-PROF 2) - -(defun unix-getitimer (which) - _N"Unix-getitimer returns the INTERVAL and VALUE slots of one of - three system timers (:real :virtual or :profile). On success, - unix-getitimer returns 5 values, - T, it-interval-secs, it-interval-usec, it-value-secs, it-value-usec." - (declare (type (member :real :virtual :profile) which) - (values t - (unsigned-byte 29)(mod 1000000) - (unsigned-byte 29)(mod 1000000))) - (let ((which (ecase which - (:real ITIMER-REAL) - (:virtual ITIMER-VIRTUAL) - (:profile ITIMER-PROF)))) - (with-alien ((itv (struct itimerval))) - (syscall* ("getitimer" int (* (struct itimerval))) - (values T - (slot (slot itv 'it-interval) 'tv-sec) - (slot (slot itv 'it-interval) 'tv-usec) - (slot (slot itv 'it-value) 'tv-sec) - (slot (slot itv 'it-value) 'tv-usec)) - which (alien-sap (addr itv)))))) - -(defun unix-setitimer (which int-secs int-usec val-secs val-usec) - _N" Unix-setitimer sets the INTERVAL and VALUE slots of one of - three system timers (:real :virtual or :profile). A SIGALRM signal - will be delivered VALUE <seconds+microseconds> from now. INTERVAL, - when non-zero, is <seconds+microseconds> to be loaded each time - the timer expires. Setting INTERVAL and VALUE to zero disables - the timer. See the Unix man page for more details. On success, - unix-setitimer returns the old contents of the INTERVAL and VALUE - slots as in unix-getitimer." - (declare (type (member :real :virtual :profile) which) - (type (unsigned-byte 29) int-secs val-secs) - (type (integer 0 (1000000)) int-usec val-usec) - (values t - (unsigned-byte 29)(mod 1000000) - (unsigned-byte 29)(mod 1000000))) - (let ((which (ecase which - (:real ITIMER-REAL) - (:virtual ITIMER-VIRTUAL) - (:profile ITIMER-PROF)))) - (with-alien ((itvn (struct itimerval)) - (itvo (struct itimerval))) - (setf (slot (slot itvn 'it-interval) 'tv-sec ) int-secs - (slot (slot itvn 'it-interval) 'tv-usec) int-usec - (slot (slot itvn 'it-value ) 'tv-sec ) val-secs - (slot (slot itvn 'it-value ) 'tv-usec) val-usec) - (syscall* ("setitimer" int (* (struct timeval))(* (struct timeval))) - (values T - (slot (slot itvo 'it-interval) 'tv-sec) - (slot (slot itvo 'it-interval) 'tv-usec) - (slot (slot itvo 'it-value) 'tv-sec) - (slot (slot itvo 'it-value) 'tv-usec)) - which (alien-sap (addr itvn))(alien-sap (addr itvo)))))) - -;;; sys/timeb.h - -;; Structure returned by the `ftime' function. - -(def-alien-type nil - (struct timeb - (time time-t) ; Seconds since epoch, as from `time'. - (millitm short) ; Additional milliseconds. - (timezone int) ; Minutes west of GMT. - (dstflag short))) ; Nonzero if Daylight Savings Time used. - -#+(or) -(defun unix-fstime (timebuf) - _N"Fill in TIMEBUF with information about the current time." - (int-syscall ("ftime" (* (struct timeb))) timebuf)) - - -;;; sys/times.h - -;; Structure describing CPU time used by a process and its children. - -(def-alien-type nil - (struct tms - (tms-utime clock-t) ; User CPU time. - (tms-stime clock-t) ; System CPU time. - (tms-cutime clock-t) ; User CPU time of dead children. - (tms-cstime clock-t))) ; System CPU time of dead children. - -#+(or) -(defun unix-times (buffer) - _N"Store the CPU time used by this process and all its - dead children (and their dead children) in BUFFER. - Return the elapsed real time, or (clock_t) -1 for errors. - All times are in CLK_TCKths of a second." - (int-syscall ("times" (* (struct tms))) buffer)) - -;;; sys/wait.h - -#+(or) -(defun unix-wait (status) - _N"Wait for a child to die. When one does, put its status in *STAT_LOC - and return its process ID. For errors, return (pid_t) -1." - (int-syscall ("wait" (* int)) status)) - -#+(or) -(defun unix-waitpid (pid status options) - _N"Wait for a child matching PID to die. - If PID is greater than 0, match any process whose process ID is PID. - If PID is (pid_t) -1, match any process. - If PID is (pid_t) 0, match any process with the - same process group as the current process. - If PID is less than -1, match any process whose - process group is the absolute value of PID. - If the WNOHANG bit is set in OPTIONS, and that child - is not already dead, return (pid_t) 0. If successful, - return PID and store the dead child's status in STAT_LOC. - Return (pid_t) -1 for errors. If the WUNTRACED bit is - set in OPTIONS, return status for stopped children; otherwise don't." - (int-syscall ("waitpit" pid-t (* int) int) - pid status options)) - -;;; asm/errno.h - -(def-unix-error ESUCCESS 0 _N"Successful") -(def-unix-error EPERM 1 _N"Operation not permitted") -(def-unix-error ENOENT 2 _N"No such file or directory") -(def-unix-error ESRCH 3 _N"No such process") -(def-unix-error EINTR 4 _N"Interrupted system call") -(def-unix-error EIO 5 _N"I/O error") -(def-unix-error ENXIO 6 _N"No such device or address") -(def-unix-error E2BIG 7 _N"Arg list too long") -(def-unix-error ENOEXEC 8 _N"Exec format error") -(def-unix-error EBADF 9 _N"Bad file number") -(def-unix-error ECHILD 10 _N"No children") -(def-unix-error EAGAIN 11 _N"Try again") -(def-unix-error ENOMEM 12 _N"Out of memory") -(def-unix-error EACCES 13 _N"Permission denied") -(def-unix-error EFAULT 14 _N"Bad address") -(def-unix-error ENOTBLK 15 _N"Block device required") -(def-unix-error EBUSY 16 _N"Device or resource busy") -(def-unix-error EEXIST 17 _N"File exists") -(def-unix-error EXDEV 18 _N"Cross-device link") -(def-unix-error ENODEV 19 _N"No such device") -(def-unix-error ENOTDIR 20 _N"Not a director") -(def-unix-error EISDIR 21 _N"Is a directory") -(def-unix-error EINVAL 22 _N"Invalid argument") -(def-unix-error ENFILE 23 _N"File table overflow") -(def-unix-error EMFILE 24 _N"Too many open files") -(def-unix-error ENOTTY 25 _N"Not a typewriter") -(def-unix-error ETXTBSY 26 _N"Text file busy") -(def-unix-error EFBIG 27 _N"File too large") -(def-unix-error ENOSPC 28 _N"No space left on device") -(def-unix-error ESPIPE 29 _N"Illegal seek") -(def-unix-error EROFS 30 _N"Read-only file system") -(def-unix-error EMLINK 31 _N"Too many links") -(def-unix-error EPIPE 32 _N"Broken pipe") -;;; -;;; Math -(def-unix-error EDOM 33 _N"Math argument out of domain") -(def-unix-error ERANGE 34 _N"Math result not representable") -;;; -(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) - -;;; the ioctl's. -;;; -;;; I've deleted all the stuff that wasn't in the header files. -;;; This is what survived. - -;; 0x54 is just a magic number to make these relatively unique ('T') - -(eval-when (compile load eval) - -(defconstant iocparm-mask #x3fff) -(defconstant ioc_void #x00000000) -(defconstant ioc_out #x40000000) -(defconstant ioc_in #x80000000) -(defconstant ioc_inout (logior ioc_in ioc_out)) - -(defmacro define-ioctl-command (name dev cmd &optional arg parm-type) - _N"Define an ioctl command. If the optional ARG and PARM-TYPE are given - then ioctl argument size and direction are included as for ioctls defined - by _IO, _IOR, _IOW, or _IOWR. If DEV is a character then the ioctl type - is the characters code, else DEV may be an integer giving the type." - (let* ((type (if (characterp dev) - (char-code dev) - dev)) - (code (logior (ash type 8) cmd))) - (when arg - (setf code `(logior (ash (logand (alien-size ,arg :bytes) ,iocparm-mask) - 16) - ,code))) - (when parm-type - (let ((dir (ecase parm-type - (:void ioc_void) - (:in ioc_in) - (:out ioc_out) - (:inout ioc_inout)))) - (setf code `(logior ,dir ,code)))) - `(eval-when (eval load compile) - (defconstant ,name ,code)))) - -) - -;;; TTY ioctl commands. - -(define-ioctl-command TIOCGWINSZ #\T #x13) -(define-ioctl-command TIOCSWINSZ #\T #x14) -(define-ioctl-command TIOCNOTTY #\T #x22) -(define-ioctl-command TIOCSPGRP #\T #x10) -(define-ioctl-command TIOCGPGRP #\T #x0F) - -;;; File ioctl commands. -(define-ioctl-command FIONREAD #\T #x1B) - -;;; asm/sockios.h - -;;; Socket options. - -(define-ioctl-command SIOCSPGRP #x89 #x02) - -(defun siocspgrp (fd pgrp) - _N"Set the socket process-group for the unix file-descriptor FD to PGRP." - (alien:with-alien ((alien-pgrp c-call:int pgrp)) - (unix-ioctl fd - siocspgrp - (alien:alien-sap (alien:addr alien-pgrp))))) - -;;; A few random constants and functions - -(defconstant setuidexec #o4000 _N"Set user ID on execution") -(defconstant setgidexec #o2000 _N"Set group ID on execution") -(defconstant savetext #o1000 _N"Save text image after execution") -(defconstant readown #o400 _N"Read by owner") -(defconstant writeown #o200 _N"Write by owner") -(defconstant execown #o100 _N"Execute (search directory) by owner") -(defconstant readgrp #o40 _N"Read by group") -(defconstant writegrp #o20 _N"Write by group") -(defconstant execgrp #o10 _N"Execute (search directory) by group") -(defconstant readoth #o4 _N"Read by others") -(defconstant writeoth #o2 _N"Write by others") -(defconstant execoth #o1 _N"Execute (search directory) by others") - -(defconstant terminal-speeds - '#(0 50 75 110 134 150 200 300 600 1200 1800 2400 - 4800 9600 19200 38400 57600 115200 230400)) - -;;;; Support routines for dealing with unix pathnames. - -(export '(unix-file-kind unix-maybe-prepend-current-directory - unix-resolve-links unix-simplify-pathname)) - -(defun unix-file-kind (name &optional check-for-links) - _N"Returns either :file, :directory, :link, :special, or NIL." - (declare (simple-string name)) - (multiple-value-bind (res dev ino mode) - (if check-for-links - (unix-lstat name) - (unix-stat name)) - (declare (type (or fixnum null) mode) - (ignore dev ino)) - (when res - (let ((kind (logand mode s-ifmt))) - (cond ((eql kind s-ifdir) :directory) - ((eql kind s-ifreg) :file) - ((eql kind s-iflnk) :link) - (t :special)))))) - -(defun unix-maybe-prepend-current-directory (name) - (declare (simple-string name)) - (if (and (> (length name) 0) (char= (schar name 0) #/)) - name - (multiple-value-bind (win dir) (unix-current-directory) - (if win - (concatenate 'simple-string dir "/" name) - name)))) - -(defun unix-resolve-links (pathname) - _N"Returns the pathname with all symbolic links resolved." - (declare (simple-string pathname)) - (let ((len (length pathname)) - (pending pathname)) - (declare (fixnum len) (simple-string pending)) - (if (zerop len) - pathname - (let ((result (make-string 100 :initial-element (code-char 0))) - (fill-ptr 0) - (name-start 0)) - (loop - (let* ((name-end (or (position #/ pending :start name-start) len)) - (new-fill-ptr (+ fill-ptr (- name-end name-start)))) - ;; grow the result string, if necessary. the ">=" (instead of - ;; using ">") allows for the trailing "/" if we find this - ;; component is a directory. - (when (>= new-fill-ptr (length result)) - (let ((longer (make-string (* 3 (length result)) - :initial-element (code-char 0)))) - (replace longer result :end1 fill-ptr) - (setq result longer))) - (replace result pending - :start1 fill-ptr - :end1 new-fill-ptr - :start2 name-start - :end2 name-end) - (let ((kind (unix-file-kind (if (zerop name-end) "/" result) t))) - (unless kind (return nil)) - (cond ((eq kind :link) - (multiple-value-bind (link err) (unix-readlink result) - (unless link - (error (intl:gettext "Error reading link ~S: ~S") - (subseq result 0 fill-ptr) - (get-unix-error-msg err))) - (cond ((or (zerop (length link)) - (char/= (schar link 0) #/)) - ;; It's a relative link - (fill result (code-char 0) - :start fill-ptr - :end new-fill-ptr)) - ((string= result "/../" :end1 4) - ;; It's across the super-root. - (let ((slash (or (position #/ result :start 4) - 0))) - (fill result (code-char 0) - :start slash - :end new-fill-ptr) - (setf fill-ptr slash))) - (t - ;; It's absolute. - (and (> (length link) 0) - (char= (schar link 0) #/)) - (fill result (code-char 0) :end new-fill-ptr) - (setf fill-ptr 0))) - (setf pending - (if (= name-end len) - link - (concatenate 'simple-string - link - (subseq pending name-end)))) - (setf len (length pending)) - (setf name-start 0))) - ((= name-end len) - (when (eq kind :directory) - (setf (schar result new-fill-ptr) #/) - (incf new-fill-ptr)) - (return (subseq result 0 new-fill-ptr))) - ((eq kind :directory) - (setf (schar result new-fill-ptr) #/) - (setf fill-ptr (1+ new-fill-ptr)) - (setf name-start (1+ name-end))) - (t - (return nil)))))))))) - -(defun unix-simplify-pathname (src) - (declare (simple-string src)) - (let* ((src-len (length src)) - (dst (make-string src-len)) - (dst-len 0) - (dots 0) - (last-slash nil)) - (macrolet ((deposit (char) - `(progn - (setf (schar dst dst-len) ,char) - (incf dst-len)))) - (dotimes (src-index src-len) - (let ((char (schar src src-index))) - (cond ((char= char #.) - (when dots - (incf dots)) - (deposit char)) - ((char= char #/) - (case dots - (0 - ;; Either ``/...' or ``...//...' - (unless last-slash - (setf last-slash dst-len) - (deposit char))) - (1 - ;; Either ``./...'' or ``..././...'' - (decf dst-len)) - (2 - ;; We've found .. - (cond - ((and last-slash (not (zerop last-slash))) - ;; There is something before this .. - (let ((prev-prev-slash - (position #/ dst :end last-slash :from-end t))) - (cond ((and (= (+ (or prev-prev-slash 0) 2) - last-slash) - (char= (schar dst (- last-slash 2)) #.) - (char= (schar dst (1- last-slash)) #.)) - ;; The something before this .. is another .. - (deposit char) - (setf last-slash dst-len)) - (t - ;; The something is some random dir. - (setf dst-len - (if prev-prev-slash - (1+ prev-prev-slash) - 0)) - (setf last-slash prev-prev-slash))))) - (t - ;; There is nothing before this .., so we need to keep it - (setf last-slash dst-len) - (deposit char)))) - (t - ;; Something other than a dot between slashes. - (setf last-slash dst-len) - (deposit char))) - (setf dots 0)) - (t - (setf dots nil) - (setf (schar dst dst-len) char) - (incf dst-len)))))) - (when (and last-slash (not (zerop last-slash))) - (case dots - (1 - ;; We've got ``foobar/.'' - (decf dst-len)) - (2 - ;; We've got ``foobar/..'' - (unless (and (>= last-slash 2) - (char= (schar dst (1- last-slash)) #.) - (char= (schar dst (- last-slash 2)) #.) - (or (= last-slash 2) - (char= (schar dst (- last-slash 3)) #/))) - (let ((prev-prev-slash - (position #/ dst :end last-slash :from-end t))) - (if prev-prev-slash - (setf dst-len (1+ prev-prev-slash)) - (return-from unix-simplify-pathname "./"))))))) - (cond ((zerop dst-len) - "./") - ((= dst-len src-len) - dst) - (t - (subseq dst 0 dst-len))))) - -;;; -;;; STRING-LIST-TO-C-STRVEC -- Internal -;;; -;;; STRING-LIST-TO-C-STRVEC is a function which takes a list of -;;; simple-strings and constructs a C-style string vector (strvec) -- -;;; a null-terminated array of pointers to null-terminated strings. -;;; This function returns two values: a sap and a byte count. When the -;;; memory is no longer needed it should be deallocated with -;;; vm_deallocate. -;;; -(defun string-list-to-c-strvec (string-list) - ;; - ;; Make a pass over string-list to calculate the amount of memory - ;; needed to hold the strvec. - (let ((string-bytes 0) - (vec-bytes (* 4 (1+ (length string-list))))) - (declare (fixnum string-bytes vec-bytes)) - (dolist (s string-list) - (check-type s simple-string) - (incf string-bytes (round-bytes-to-words (1+ (length s))))) - ;; - ;; Now allocate the memory and fill it in. - (let* ((total-bytes (+ string-bytes vec-bytes)) - (vec-sap (system:allocate-system-memory total-bytes)) - (string-sap (sap+ vec-sap vec-bytes)) - (i 0)) - (declare (type (and unsigned-byte fixnum) total-bytes i) - (type system:system-area-pointer vec-sap string-sap)) - (dolist (s string-list) - (declare (simple-string s)) - (let ((n (length s))) - ;; - ;; Blast the string into place - #-unicode - (kernel:copy-to-system-area (the simple-string s) - (* vm:vector-data-offset vm:word-bits) - string-sap 0 - (* (1+ n) vm:byte-bits)) - #+unicode - (progn - ;; FIXME: Do we need to apply some kind of transformation - ;; to convert Lisp unicode strings to C strings? Utf-8? - (dotimes (k n) - (setf (sap-ref-8 string-sap k) - (logand #xff (char-code (aref s k))))) - (setf (sap-ref-8 string-sap n) 0)) - ;; - ;; Blast the pointer to the string into place - (setf (sap-ref-sap vec-sap i) string-sap) - (setf string-sap (sap+ string-sap (round-bytes-to-words (1+ n)))) - (incf i 4))) - ;; Blast in last null pointer - (setf (sap-ref-sap vec-sap i) (int-sap 0)) - (values vec-sap total-bytes)))) - -;;; Stuff not yet found in the header files... -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Abandon all hope who enters here... - - -;; not checked for linux... -(defmacro fd-set (offset fd-set) - (let ((word (gensym)) - (bit (gensym))) - `(multiple-value-bind (,word ,bit) (floor ,offset nfdbits) - (setf (deref (slot ,fd-set 'fds-bits) ,word) - (logior (truly-the (unsigned-byte 32) (ash 1 ,bit)) - (deref (slot ,fd-set 'fds-bits) ,word)))))) - -;; not checked for linux... -(defmacro fd-clr (offset fd-set) - (let ((word (gensym)) - (bit (gensym))) - `(multiple-value-bind (,word ,bit) (floor ,offset nfdbits) - (setf (deref (slot ,fd-set 'fds-bits) ,word) - (logand (deref (slot ,fd-set 'fds-bits) ,word) - (32bit-logical-not - (truly-the (unsigned-byte 32) (ash 1 ,bit)))))))) - -;; not checked for linux... -(defmacro fd-isset (offset fd-set) - (let ((word (gensym)) - (bit (gensym))) - `(multiple-value-bind (,word ,bit) (floor ,offset nfdbits) - (logbitp ,bit (deref (slot ,fd-set 'fds-bits) ,word))))) - -;; not checked for linux... -(defmacro fd-zero (fd-set) - `(progn - ,@(loop for index upfrom 0 below (/ fd-setsize nfdbits) - collect `(setf (deref (slot ,fd-set 'fds-bits) ,index) 0)))) - - - - -;;;; User and group database access, POSIX Standard 9.2.2 - -(defun unix-getpwnam (login) - _N"Return a USER-INFO structure for the user identified by LOGIN, or NIL if not found." - (declare (type simple-string login)) - (with-alien ((buf (array c-call:char 1024)) - (user-info (struct passwd)) - (result (* (struct passwd)))) - (let ((returned - (alien-funcall - (extern-alien "getpwnam_r" - (function c-call:int - c-call:c-string - (* (struct passwd)) - (* c-call:char) - c-call:unsigned-int - (* (* (struct passwd))))) - login - (addr user-info) - (cast buf (* c-call:char)) - 1024 - (addr result)))) - (when (zerop returned) - (make-user-info - :name (string (cast (slot result 'pw-name) c-call:c-string)) - :password (string (cast (slot result 'pw-passwd) c-call:c-string)) - :uid (slot result 'pw-uid) - :gid (slot result 'pw-gid) - :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) - :dir (string (cast (slot result 'pw-dir) c-call:c-string)) - :shell (string (cast (slot result 'pw-shell) c-call:c-string))))))) - -(defun unix-getpwuid (uid) - _N"Return a USER-INFO structure for the user identified by UID, or NIL if not found." - (declare (type unix-uid uid)) - (with-alien ((buf (array c-call:char 1024)) - (user-info (struct passwd)) - (result (* (struct passwd)))) - (let ((returned - (alien-funcall - (extern-alien "getpwuid_r" - (function c-call:int - c-call:unsigned-int - (* (struct passwd)) - (* c-call:char) - c-call:unsigned-int - (* (* (struct passwd))))) - uid - (addr user-info) - (cast buf (* c-call:char)) - 1024 - (addr result)))) - (when (zerop returned) - (make-user-info - :name (string (cast (slot result 'pw-name) c-call:c-string)) - :password (string (cast (slot result 'pw-passwd) c-call:c-string)) - :uid (slot result 'pw-uid) - :gid (slot result 'pw-gid) - :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) - :dir (string (cast (slot result 'pw-dir) c-call:c-string)) - :shell (string (cast (slot result 'pw-shell) c-call:c-string))))))) - -(defun unix-getgrnam (name) - _N"Return a GROUP-INFO structure for the group identified by NAME, or NIL if not found." - (declare (type simple-string name)) - (with-alien ((buf (array c-call:char 2048)) - (group-info (struct group)) - (result (* (struct group)))) - (let ((returned - (alien-funcall - (extern-alien "getgrnam_r" - (function c-call:int - c-call:c-string - (* (struct group)) - (* c-call:char) - c-call:unsigned-int - (* (* (struct group))))) - name - (addr group-info) - (cast buf (* c-call:char)) - 2048 - (addr result)))) - (when (zerop returned) - (make-group-info - :name (string (cast (slot result 'gr-name) c-call:c-string)) - :password (string (cast (slot result 'gr-passwd) c-call:c-string)) - :gid (slot result 'gr-gid) - :members (loop :with members = (slot result 'gr-mem) - :for i :from 0 - :for member = (deref members i) - :until (zerop (sap-int (alien-sap member))) - :collect (string (cast member c-call:c-string)))))))) - -(defun unix-getgrgid (gid) - _N"Return a GROUP-INFO structure for the group identified by GID, or NIL if not found." - (declare (type unix-gid gid)) - (with-alien ((buf (array c-call:char 2048)) - (group-info (struct group)) - (result (* (struct group)))) - (let ((returned - (alien-funcall - (extern-alien "getgrgid_r" - (function c-call:int - c-call:unsigned-int - (* (struct group)) - (* c-call:char) - c-call:unsigned-int - (* (* (struct group))))) - gid - (addr group-info) - (cast buf (* c-call:char)) - 2048 - (addr result)))) - (when (zerop returned) - (make-group-info - :name (string (cast (slot result 'gr-name) c-call:c-string)) - :password (string (cast (slot result 'gr-passwd) c-call:c-string)) - :gid (slot result 'gr-gid) - :members (loop :with members = (slot result 'gr-mem) - :for i :from 0 - :for member = (deref members i) - :until (zerop (sap-int (alien-sap member))) - :collect (string (cast member c-call:c-string)))))))) - - -;; EOF +(defun unix-cfgetospeed (termios) + _N"Get terminal output speed." + (multiple-value-bind (speed errno) + (int-syscall ("cfgetospeed" (* (struct termios))) termios) + (if speed + (values (svref terminal-speeds speed) 0) + (values speed errno))))
===================================== src/code/unix.lisp ===================================== --- a/src/code/unix.lisp +++ b/src/code/unix.lisp @@ -9,15 +9,15 @@ ;;; ;;; ********************************************************************** ;;; -;;; This file contains the UNIX low-level support. +;;; This file contains the UNIX low-level support, just enough to run +;;; CMUCL. ;;; (in-package "UNIX") -(use-package "ALIEN") -(use-package "C-CALL") -(use-package "SYSTEM") -(use-package "EXT") + (intl:textdomain "cmucl-unix")
+(pushnew :unix *features*) + ;; Check the G_BROKEN_FILENAMES environment variable; if set the encoding ;; is locale-dependent...else use :utf-8 on Unicode Lisps. On 8 bit Lisps ;; it must be set to :iso8859-1 (or left as NIL), making files with @@ -25,172 +25,7 @@ ;; Must be set to NIL initially to enable building Lisp! (defvar *filename-encoding* nil)
-(export '(daddr-t caddr-t ino-t swblk-t size-t time-t dev-t off-t uid-t gid-t - timeval tv-sec tv-usec timezone tz-minuteswest tz-dsttime - itimerval it-interval it-value tchars t-intrc t-quitc t-startc - t-stopc t-eofc t-brkc ltchars t-suspc t-dsuspc t-rprntc t-flushc - t-werasc t-lnextc sgttyb sg-ispeed sg-ospeed sg-erase sg-kill - sg-flags winsize ws-row ws-col ws-xpixel ws-ypixel - direct d-off d-ino d-reclen #-(or linux svr4) d-namlen d-name - stat st-dev st-mode st-nlink st-uid st-gid st-rdev st-size - st-atime st-mtime st-ctime st-blksize st-blocks - s-ifmt s-ifdir s-ifchr s-ifblk s-ifreg s-iflnk s-ifsock - s-isuid s-isgid s-isvtx s-iread s-iwrite s-iexec - ruseage ru-utime ru-stime ru-maxrss ru-ixrss ru-idrss - ru-isrss ru-minflt ru-majflt ru-nswap ru-inblock ru-oublock - ru-msgsnd ru-msgrcv ru-nsignals ru-nvcsw ru-nivcsw - rlimit rlim-cur rlim-max sc-onstack sc-mask sc-pc - - unix-errno get-unix-error-msg - - prot_read prot_write prot_exec prot_none - map_shared map_private map_fixed map_anonymous - ms_async ms_sync ms_invalidate - unix-mmap unix-munmap unix-msync - unix-mprotect - - unix-pathname unix-file-mode unix-fd unix-pid unix-uid unix-gid - unix-setitimer unix-getitimer - unix-access r_ok w_ok x_ok f_ok unix-chdir unix-chmod setuidexec - setgidexec savetext readown writeown execown readgrp writegrp - execgrp readoth writeoth execoth unix-fchmod unix-chown unix-fchown - unix-getdtablesize unix-close unix-creat unix-dup unix-dup2 - unix-fcntl f-dupfd f-getfd f-setfd f-getfl f-setfl f-getown f-setown - fndelay fappend fasync fcreat ftrunc fexcl unix-link unix-lseek - l_set l_incr l_xtnd unix-mkdir unix-open o_rdonly o_wronly o_rdwr - #+(or hpux svr4 bsd linux) o_ndelay - #+(or hpux svr4 bsd linux) o_noctty #+(or hpux svr4 bsd) o_nonblock - o_append o_creat o_trunc o_excl unix-pipe unix-read unix-readlink - unix-rename unix-rmdir unix-fast-select fd-setsize fd-set fd-clr - fd-isset fd-zero unix-select unix-sync unix-fsync unix-truncate - unix-ftruncate unix-symlink - #+(and sparc svr4) unix-times - unix-unlink unix-write unix-ioctl - tcsetpgrp tcgetpgrp tty-process-group - terminal-speeds tty-raw tty-crmod tty-echo tty-lcase - #-hpux tty-cbreak #-(or hpux linux) tty-tandem - #+(or hpux svr4 linux bsd) termios - #+(or hpux svr4 linux bsd) c-lflag - #+(or hpux svr4 linux bsd) c-iflag - #+(or hpux svr4 linux bsd) c-oflag - #+(or hpux svr4 linux bsd) tty-icrnl - #+(or hpux svr4 linux) tty-ocrnl - #+(or hpux svr4 bsd) vdsusp #+(or hpux svr4 linux bsd) veof - #+(or hpux svr4 linux bsd) vintr - #+(or hpux svr4 linux bsd) vquit - #+(or hpux svr4 linux bsd) vstart - #+(or hpux svr4 linux bsd) vstop - #+(or hpux svr4 linux bsd) vsusp - #+(or hpux svr4 linux bsd) c-cflag - #+(or hpux svr4 linux bsd) c-cc - #+(or bsd osf1) c-ispeed - #+(or bsd osf1) c-ospeed - #+(or hpux svr4 linux bsd) tty-icanon - #+(or hpux svr4 linux bsd) vmin - #+(or hpux svr4 linux bsd) vtime - #+(or hpux svr4 linux bsd) tty-ixon - #+(or hpux svr4 linux bsd) tcsanow - #+(or hpux svr4 linux bsd) tcsadrain - #+(or hpux svr4 linux bsd) tciflush - #+(or hpux svr4 linux bsd) tcoflush - #+(or hpux svr4 linux bsd) tcioflush - #+(or hpux svr4 linux bsd) tcsaflush - #+(or hpux svr4 linux bsd) unix-tcgetattr - #+(or hpux svr4 linux bsd) unix-tcsetattr - #+(or hpux svr4 bsd) unix-cfgetospeed - #+(or hpux svr4 bsd) unix-cfsetospeed - #+(or hpux svr4 bsd) unix-cfgetispeed - #+(or hpux svr4 bsd) unix-cfsetispeed - #+(or hpux svr4 linux bsd) tty-ignbrk - #+(or hpux svr4 linux bsd) tty-brkint - #+(or hpux svr4 linux bsd) tty-ignpar - #+(or hpux svr4 linux bsd) tty-parmrk - #+(or hpux svr4 linux bsd) tty-inpck - #+(or hpux svr4 linux bsd) tty-istrip - #+(or hpux svr4 linux bsd) tty-inlcr - #+(or hpux svr4 linux bsd) tty-igncr - #+(or hpux svr4 linux) tty-iuclc - #+(or hpux svr4 linux bsd) tty-ixany - #+(or hpux svr4 linux bsd) tty-ixoff - #+hpux tty-ienqak - #+(or hpux irix solaris linux bsd) tty-imaxbel - #+(or hpux svr4 linux bsd) tty-opost - #+(or hpux svr4 linux) tty-olcuc - #+(or hpux svr4 linux bsd) tty-onlcr - #+(or hpux svr4 linux) tty-onocr - #+(or hpux svr4 linux) tty-onlret - #+(or hpux svr4 linux) tty-ofill - #+(or hpux svr4 linux) tty-ofdel - #+(or hpux svr4 linux bsd) tty-isig - #+(or hpux svr4 linux) tty-xcase - #+(or hpux svr4 linux bsd) tty-echoe - #+(or hpux svr4 linux bsd) tty-echok - #+(or hpux svr4 linux bsd) tty-echonl - #+(or hpux svr4 linux bsd) tty-noflsh - #+(or hpux svr4 linux bsd) tty-iexten - #+(or hpux svr4 linux bsd) tty-tostop - #+(or hpux irix solaris linux bsd) tty-echoctl - #+(or hpux irix solaris linux bsd) tty-echoprt - #+(or hpux irix solaris linux bsd) tty-echoke - #+(or hpux irix solaris) tty-defecho - #+(or hpux irix solaris bsd) tty-flusho - #+(or hpux irix solaris linux bsd) tty-pendin - #+(or hpux svr4 linux bsd) tty-cstopb - #+(or hpux svr4 linux bsd) tty-cread - #+(or hpux svr4 linux bsd) tty-parenb - #+(or hpux svr4 linux bsd) tty-parodd - #+(or hpux svr4 linux bsd) tty-hupcl - #+(or hpux svr4 linux bsd) tty-clocal - #+(or irix solaris) rcv1en - #+(or irix solaris) xmt1en - #+(or hpux irix solaris) tty-loblk - #+(or hpux svr4 linux bsd) vintr - #+(or hpux svr4 linux bsd) verase - #+(or hpux svr4 linux bsd) vkill - #+(or hpux svr4 linux bsd) veol - #+(or hpux irix solaris linux bsd) veol2 - #+(or hpux irix solaris) tty-cbaud - #+(or hpux svr4 bsd) tty-csize #+(or hpux svr4 bsd) tty-cs5 - #+(or hpux svr4 bsd) tty-cs6 #+(or hpux svr4 bsd) tty-cs7 - #+(or hpux svr4 bsd) tty-cs8 - #+(or hpux svr4 bsd) unix-tcsendbreak - #+(or hpux svr4 bsd) unix-tcdrain - #+(or hpux svr4 bsd) unix-tcflush - #+(or hpux svr4 bsd) unix-tcflow - - TIOCGETP TIOCSETP TIOCFLUSH TIOCSETC TIOCGETC TIOCSLTC - TIOCGLTC TIOCNOTTY TIOCSPGRP TIOCGPGRP TIOCGWINSZ TIOCSWINSZ - TIOCSIGSEND - - KBDCGET KBDCSET KBDCRESET KBDCRST KBDCSSTD KBDSGET KBDGCLICK - KBDSCLICK FIONREAD #+(or hpux bsd) siocspgrp - unix-exit unix-stat unix-lstat unix-fstat - unix-getrusage unix-fast-getrusage rusage_self rusage_children - unix-gettimeofday - #-hpux unix-utimes #-(or svr4 hpux) unix-setreuid - #-(or svr4 hpux) unix-setregid - unix-getpid unix-getppid - #+(or svr4 bsd)unix-setpgid - unix-getgid unix-getegid unix-getpgrp unix-setpgrp unix-getuid - unix-getpagesize unix-gethostname unix-gethostid unix-fork - unix-getenv unix-setenv unix-putenv unix-unsetenv - unix-current-directory unix-isatty unix-ttyname unix-execve - unix-socket unix-connect unix-bind unix-listen unix-accept - unix-recv unix-send unix-getpeername unix-getsockname - unix-getsockopt unix-setsockopt unix-openpty - - unix-recvfrom unix-sendto unix-shutdown - - unix-getpwnam unix-getpwuid unix-getgrnam unix-getgrgid - user-info user-info-name user-info-password user-info-uid - user-info-gid user-info-gecos user-info-dir user-info-shell - group-info group-info-name group-info-gid group-info-members - - unix-uname)) - -(pushnew :unix *features*) - -(eval-when (:compile-toplevel) +(eval-when (:compile-toplevel :load-toplevel :execute) (defmacro %name->file (string) `(if *filename-encoding* (string-encode ,string *filename-encoding*) @@ -203,24 +38,15 @@ ;;;; Common machine independent structures.
-;;; From sys/types.h - (def-alien-type int64-t (signed 64)) -(def-alien-type u-int64-t (unsigned 64)) - -(def-alien-type daddr-t - #-(or linux alpha) long - #+(or linux alpha) int)
-(def-alien-type caddr-t (* char)) +(def-alien-type u-int64-t (unsigned 64))
(def-alien-type ino-t #+netbsd u-int64-t #+alpha unsigned-int #-(or alpha netbsd) unsigned-long)
-(def-alien-type swblk-t long) - (def-alien-type size-t #-(or linux alpha) long #+linux unsigned-int @@ -262,55 +88,11 @@ (def-alien-type uid-t unsigned-long) (def-alien-type gid-t unsigned-long))
-;;; Large file support for Solaris. Define some of the 64-bit types -;;; we need. Unlike unix-glibc's large file support, Solaris's -;;; version is a little simpler because all of the 64-bit versions of -;;; the functions actually exist as functions. So instead of calling -;;; the 32-bit versions of the functions, we call the 64-bit versions. -;;; -;;; These functions are: creat64, open64, truncate64, ftruncate64, -;;; stat64, lstat64, fstat64, readdir64. -;;; -;;; There are also some new structures for large file support: -;;; dirent64, stat64. -;;; -;;; FIXME: We should abstract this better, but I (rtoy) don't have any -;;; other system to test this out on, so it's a Solaris hack for now. -#+solaris -(progn - (deftype file-offset64 () '(signed-byte 64)) - (def-alien-type off64-t int64-t) - (def-alien-type ino64-t u-int64-t) - (def-alien-type blkcnt64-t u-int64-t)) - (def-alien-type mode-t #-(or alpha svr4) unsigned-short #+alpha unsigned-int #+svr4 unsigned-long)
-(def-alien-type nlink-t - #-(or svr4 netbsd) unsigned-short - #+netbsd unsigned-long - #+svr4 unsigned-long) - -(defconstant FD-SETSIZE - #-(or hpux alpha linux FreeBSD) 256 - #+hpux 2048 #+alpha 4096 #+(or linux FreeBSD) 1024) - -;; not checked for linux... -(def-alien-type nil - (struct fd-set - (fds-bits (array #-alpha unsigned-long #+alpha int #.(/ fd-setsize 32))))) - -;; not checked for linux... -(defmacro fd-set (offset fd-set) - (let ((word (gensym)) - (bit (gensym))) - `(multiple-value-bind (,word ,bit) (floor ,offset 32) - (setf (deref (slot ,fd-set 'fds-bits) ,word) - (logior (truly-the (unsigned-byte 32) (ash 1 ,bit)) - (deref (slot ,fd-set 'fds-bits) ,word)))))) - ;; not checked for linux... (defmacro fd-clr (offset fd-set) (let ((word (gensym)) @@ -328,38 +110,25 @@ `(multiple-value-bind (,word ,bit) (floor ,offset 32) (logbitp ,bit (deref (slot ,fd-set 'fds-bits) ,word)))))
-;; not checked for linux... -(defmacro fd-zero (fd-set) - `(progn - ,@(loop for index upfrom 0 below (/ fd-setsize 32) - collect `(setf (deref (slot ,fd-set 'fds-bits) ,index) 0)))) +(def-alien-type nlink-t + #-(or svr4 netbsd) unsigned-short + #+netbsd unsigned-long + #+svr4 unsigned-long) + +(defconstant fd-setsize + #-(or hpux alpha linux FreeBSD) 256 + #+hpux 2048 #+alpha 4096 #+(or linux FreeBSD) 1024)
-;;; From sys/time.h +;; not checked for linux... +(def-alien-type nil + (struct fd-set + (fds-bits (array #-alpha unsigned-long #+alpha int #.(/ fd-setsize 32)))))
(def-alien-type nil (struct timeval (tv-sec #-linux time-t #+linux int) ; seconds (tv-usec int))) ; and microseconds
-(def-alien-type nil - (struct timezone - (tz-minuteswest int) ; minutes west of Greenwich - (tz-dsttime ; type of dst correction - #-linux (enum nil :none :usa :aust :wet :met :eet :can) - #+linux int))) - -(def-alien-type nil - (struct itimerval - (it-interval (struct timeval)) ; timer interval - (it-value (struct timeval)))) ; current value - -#+(or linux svr4) -; High-res time. Actually posix definition under svr4 name. -(def-alien-type nil - (struct timestruc-t - (tv-sec time-t) - (tv-nsec long))) - #+(or linux BSD) (def-alien-type nil (struct timespec-t @@ -388,7 +157,6 @@ #-linux (t-werasc char) ; word erase (t-lnextc char))) ; literal next character
- (def-alien-type nil (struct sgttyb #+linux (sg-flags #+mach short #-mach int) ; mode flags @@ -408,932 +176,413 @@ (ws-xpixel unsigned-short) ; horizontal size, pixels (ws-ypixel unsigned-short))) ; veritical size, pixels
+ +;;;; System calls.
-;;; From sys/termios.h - -;;; NOTE: There is both a termio (SYSV) and termios (POSIX) -;;; structure with similar but incompatible definitions. It may be that -;;; the non-BSD variant of termios below is really a termio but I (pw) -;;; can't verify. The BSD variant uses the Posix termios def. Some systems -;;; (Ultrix and OSF1) seem to support both if used independently. -;;; The 17f version of this seems a bit confused wrt the conditionals. -;;; Please check these defs for your system. - -;;; TSM: from what I can tell looking at the 17f definition, my guess is that it -;;; was originally a termio for sunos (nonsolaris) (because it had the c-line -;;; member for sunos only), and then was mutated into the termios definition for -;;; later systems. The definition here is definitely not an IRIX termio because -;;; it doesn't have c-line. In any case, the functions tcgetattr, etc., -;;; definitely take a termios, and termios seems to be the more standard -;;; standard now, so my suggestion is to just go with termios and forget about -;;; termio. Note the SVID says NCCS not NCC for the constant here, so I've -;;; changed it (which means you need to bootstrap it to avoid a reader error). - -;;; On top of all that, SGI decided to change the termios structure on irix -;;; 6.[34] (but NOT 6.2), left the old routines named the same in the library, -;;; but introduced static functions in termios.h to redirect new calls to the -;;; new library--which means it's important not to #include termios.h before -;;; undefineds.h when building lisp. - -(defconstant +NCCS+ - #+hpux 16 - #+irix 23 - #+(or linux solaris) 19 - #+(or bsd osf1) 20 - #+(and sunos (not svr4)) 17 - _N"Size of control character vector.") +(defmacro %syscall ((name (&rest arg-types) result-type) + success-form &rest args) + `(let* ((fn (extern-alien ,name (function ,result-type ,@arg-types))) + (result (alien-funcall fn ,@args))) + (if (eql -1 result) + (values nil (unix-errno)) + ,success-form)))
-(def-alien-type nil - (struct termios - (c-iflag unsigned-int) - (c-oflag unsigned-int) - (c-cflag unsigned-int) - (c-lflag unsigned-int) - #+(or linux hpux (and sunos (not svr4))) - (c-reserved #-(or linux (and sunos (not svr4))) unsigned-int - #+(or linux (and sunos (not svr4))) unsigned-char) - (c-cc (array unsigned-char #.+NCCS+)) - #+(or bsd osf1) (c-ispeed unsigned-int) - #+(or bsd osf1) (c-ospeed unsigned-int))) +(defmacro syscall ((name &rest arg-types) success-form &rest args) + `(%syscall (,name (,@arg-types) int) ,success-form ,@args))
-;;; From sys/dir.h +;;; Like syscall, but if it fails, signal an error instead of returing error +;;; codes. Should only be used for syscalls that will never really get an +;;; error. ;;; -;;; (For Solaris, this is not struct direct, but struct dirent!) -#-bsd -(def-alien-type nil - (struct direct - #+(and sunos (not svr4)) (d-off long) ; offset of next disk directory entry - (d-ino ino-t); inode number of entry - #+(or linux svr4) (d-off long) - (d-reclen unsigned-short) ; length of this record - #-(or linux svr4) - (d-namlen unsigned-short) ; length of string in d-name - (d-name (array char 256)))) ; name must be no longer than this +(defmacro syscall* ((name &rest arg-types) success-form &rest args) + `(let ((result (alien-funcall (extern-alien ,name (function int ,@arg-types)) + ,@args))) + (if (eql -1 result) + (error _"Syscall ~A failed: ~A" ,name (get-unix-error-msg)) + ,success-form)))
-#+(and bsd (not netbsd)) -(def-alien-type nil - (struct direct - (d-fileno unsigned-long) - (d-reclen unsigned-short) - (d-type unsigned-char) - (d-namlen unsigned-char) ; length of string in d-name - (d-name (array char 256)))) ; name must be no longer than this +(defmacro void-syscall ((name &rest arg-types) &rest args) + `(syscall (,name ,@arg-types) (values t 0) ,@args))
-#+netbsd -(def-alien-type nil - (struct direct - (d-fileno ino-t) - (d-reclen unsigned-short) - (d-namlen unsigned-short) - (d-type unsigned-char) - (d-name (array char 512)))) +(defmacro int-syscall ((name &rest arg-types) &rest args) + `(syscall (,name ,@arg-types) (values result 0) ,@args))
-;;; The 64-bit version of struct dirent. -#+solaris -(def-alien-type nil - (struct dirent64 - (d-ino ino64-t); inode number of entry - (d-off off64-t) ; offset of next disk directory entry - (d-reclen unsigned-short) ; length of this record - (d-name (array char 256)))) ; name must be no longer than this +(defmacro off-t-syscall ((name arg-types) &rest args) + `(%syscall (,name ,arg-types off-t) (values result 0) ,@args))
+ +;;; Operations on Unix Directories.
-;;; From sys/stat.h -;; oh boy, in linux-> 2 stat(s)!! +(export '(open-dir read-dir close-dir))
-#-(or svr4 bsd linux) ; eg hpux and alpha -(def-alien-type nil - (struct stat - (st-dev dev-t) - (st-ino ino-t) - (st-mode mode-t) - (st-nlink nlink-t) - (st-uid uid-t) - (st-gid gid-t) - (st-rdev dev-t) - (st-size off-t) - (st-atime time-t) - (st-spare1 int) - (st-mtime time-t) - (st-spare2 int) - (st-ctime time-t) - (st-spare3 int) - (st-blksize #-alpha long #+alpha unsigned-int) - (st-blocks #-alpha long #+alpha int) - (st-spare4 (array long 2)))) +(defstruct (%directory + (:conc-name directory-) + (:constructor make-directory) + (:print-function %print-directory)) + name + (dir-struct (required-argument) :type system-area-pointer))
-#+(and bsd (not netbsd)) -(def-alien-type nil - (struct stat - (st-dev dev-t) - (st-ino ino-t) - (st-mode mode-t) - (st-nlink nlink-t) - (st-uid uid-t) - (st-gid gid-t) - (st-rdev dev-t) - (st-atime (struct timespec-t)) - (st-mtime (struct timespec-t)) - (st-ctime (struct timespec-t)) - (st-size off-t) - (st-blocks off-t) - (st-blksize unsigned-long) - (st-flags unsigned-long) - (st-gen unsigned-long) - (st-lspare long) - (st-qspare (array long 4)))) +(defun %print-directory (dir stream depth) + (declare (ignore depth)) + (format stream "#<Directory ~S>" (directory-name dir)))
-#+netbsd -(def-alien-type nil - (struct stat - (st-dev dev-t) - (st-mode mode-t) - (st-ino ino-t) - (st-nlink nlink-t) - (st-uid uid-t) - (st-gid gid-t) - (st-rdev dev-t) - (st-atime (struct timespec-t)) - (st-mtime (struct timespec-t)) - (st-ctime (struct timespec-t)) - (st-birthtime (struct timespec-t)) - (st-size off-t) - (st-blocks off-t) - (st-blksize long) - (st-flags unsigned-long) - (st-gen unsigned-long) - (st-spare (array unsigned-long 2)))) +(defun open-dir (pathname) + (declare (type unix-pathname pathname)) + (when (string= pathname "") + (setf pathname ".")) + (let ((kind (unix-file-kind pathname))) + (case kind + (:directory + (let ((dir-struct + (alien-funcall (extern-alien "opendir" + (function system-area-pointer + c-string)) + (%name->file pathname)))) + (if (zerop (sap-int dir-struct)) + (values nil (unix-errno)) + (make-directory :name pathname :dir-struct dir-struct)))) + ((nil) + (values nil enoent)) + (t + (values nil enotdir)))))
-#+(or linux svr4) -(def-alien-type nil - (struct stat - (st-dev dev-t) - (st-pad1 #-linux (array long 3) #+linux unsigned-short) - (st-ino ino-t) - (st-mode #-linux unsigned-long #+linux unsigned-short) - (st-nlink #-linux short #+linux unsigned-short) - (st-uid #-linux uid-t #+linux unsigned-short) - (st-gid #-linux gid-t #+linux unsigned-short) - (st-rdev dev-t) - (st-pad2 #-linux (array long 2) #+linux unsigned-short) - (st-size off-t) - #-linux (st-pad3 long) - #+linux (st-blksize unsigned-long) - #+linux (st-blocks unsigned-long) - #-linux (st-atime (struct timestruc-t)) - #+linux (st-atime unsigned-long) - #+linux (unused-1 unsigned-long) - #-linux (st-mtime (struct timestruc-t)) - #+linux (st-mtime unsigned-long) - #+linux (unused-2 unsigned-long) - #-linux (st-ctime (struct timestruc-t)) - #+linux (st-ctime unsigned-long) - #+linux (unused-3 unsigned-long) - #+linux (unused-4 unsigned-long) - #+linux (unused-5 unsigned-long) - #-linux(st-blksize long) - #-linux (st-blocks long) - #-linux (st-fstype (array char 16)) - #-linux (st-pad4 (array long 8)))) +#-(and bsd (not solaris)) +(defun read-dir (dir) + (declare (type %directory dir)) + (let ((daddr (alien-funcall (extern-alien "readdir" + (function system-area-pointer + system-area-pointer)) + (directory-dir-struct dir)))) + (declare (type system-area-pointer daddr)) + (if (zerop (sap-int daddr)) + nil + (with-alien ((direct (* (struct direct)) daddr)) + #-(or linux svr4) + (let ((nlen (slot direct 'd-namlen)) + (ino (slot direct 'd-ino))) + (declare (type (unsigned-byte 16) nlen)) + (let ((string (make-string nlen))) + #-unicode + (kernel:copy-from-system-area + (alien-sap (addr (slot direct 'd-name))) 0 + string (* vm:vector-data-offset vm:word-bits) + (* nlen vm:byte-bits)) + #+unicode + (let ((sap (alien-sap (addr (slot direct 'd-name))))) + (dotimes (k nlen) + (setf (aref string k) + (code-char (sap-ref-8 sap k))))) + (values (%file->name string) ino))) + #+(or linux svr4) + (values (%file->name (cast (slot direct 'd-name) c-string)) + (slot direct 'd-ino))))))
-;;; 64-bit stat for Solaris +;;; 64-bit readdir for Solaris #+solaris -(def-alien-type nil - (struct stat64 - (st-dev dev-t) - (st-pad1 (array long 3)) ; Pad so ino is 64-bit aligned - (st-ino ino64-t) - (st-mode unsigned-long) - (st-nlink short) - (st-uid uid-t) - (st-gid gid-t) - (st-rdev dev-t) - (st-pad2 (array long 3)) ; Pad so size is 64-bit aligned - (st-size off64-t) - (st-atime (struct timestruc-t)) - (st-mtime (struct timestruc-t)) - (st-ctime (struct timestruc-t)) - (st-blksize long) - (st-pad3 (array long 1)) ; Pad so blocks is 64-bit aligned - (st-blocks blkcnt64-t) - (st-fstype (array char 16)) - (st-pad4 (array long 8)))) +(defun read-dir (dir) + (declare (type %directory dir)) + (let ((daddr (alien-funcall (extern-alien "readdir64" + (function system-area-pointer + system-area-pointer)) + (directory-dir-struct dir)))) + (declare (type system-area-pointer daddr)) + (if (zerop (sap-int daddr)) + nil + (with-alien ((direct (* (struct dirent64)) daddr)) + #-(or linux svr4) + (let ((nlen (slot direct 'd-namlen)) + (ino (slot direct 'd-ino))) + (declare (type (unsigned-byte 16) nlen)) + (let ((string (make-string nlen))) + #-unicode + (kernel:copy-from-system-area + (alien-sap (addr (slot direct 'd-name))) 0 + string (* vm:vector-data-offset vm:word-bits) + (* nlen vm:byte-bits)) + #+unicode + (let ((sap (alien-sap (addr (slot direct 'd-name))))) + (dotimes (k nlen) + (setf (aref string k) + (code-char (sap-ref-8 sap k))))) + (values (%file->name string) ino))) + #+(or linux svr4) + (values (%file->name (cast (slot direct 'd-name) c-string)) + (slot direct 'd-ino))))))
-(defconstant s-ifmt #o0170000) -(defconstant s-ifdir #o0040000) -(defconstant s-ifchr #o0020000) -#+linux (defconstant s-ififo #x0010000) -(defconstant s-ifblk #o0060000) -(defconstant s-ifreg #o0100000) -(defconstant s-iflnk #o0120000) -(defconstant s-ifsock #o0140000) -(defconstant s-isuid #o0004000) -(defconstant s-isgid #o0002000) -(defconstant s-isvtx #o0001000) -(defconstant s-iread #o0000400) -(defconstant s-iwrite #o0000200) -(defconstant s-iexec #o0000100) +#+(and bsd (not solaris)) +(defun read-dir (dir) + (declare (type %directory dir)) + (let ((daddr (alien-funcall (extern-alien "readdir" + (function system-area-pointer + system-area-pointer)) + (directory-dir-struct dir)))) + (declare (type system-area-pointer daddr)) + (if (zerop (sap-int daddr)) + nil + (with-alien ((direct (* (struct direct)) daddr)) + (let ((nlen (slot direct 'd-namlen)) + (fino (slot direct 'd-fileno))) + (declare (type (unsigned-byte #+netbsd 16 #-netbsd 8) nlen) + (type (unsigned-byte #+netbsd 64 #-netbsd 32) fino)) + (let ((string (make-string nlen))) + #-unicode + (kernel:copy-from-system-area + (alien-sap (addr (slot direct 'd-name))) 0 + string (* vm:vector-data-offset vm:word-bits) + (* nlen vm:byte-bits)) + #+unicode + (let ((sap (alien-sap (addr (slot direct 'd-name))))) + (dotimes (k nlen) + (setf (aref string k) + (code-char (sap-ref-8 sap k))))) + (values (%file->name string) fino)))))))
-;;; From sys/resource.h
-(def-alien-type nil - (struct rusage - (ru-utime (struct timeval)) ; user time used - (ru-stime (struct timeval)) ; system time used. - (ru-maxrss long) - (ru-ixrss long) ; integral sharded memory size - (ru-idrss long) ; integral unsharded data " - (ru-isrss long) ; integral unsharded stack " - (ru-minflt long) ; page reclaims - (ru-majflt long) ; page faults - (ru-nswap long) ; swaps - (ru-inblock long) ; block input operations - (ru-oublock long) ; block output operations - (ru-msgsnd long) ; messages sent - (ru-msgrcv long) ; messages received - (ru-nsignals long) ; signals received - (ru-nvcsw long) ; voluntary context switches - (ru-nivcsw long))) ; involuntary " +(defun close-dir (dir) + (declare (type %directory dir)) + (alien-funcall (extern-alien "closedir" + (function void system-area-pointer)) + (directory-dir-struct dir)) + nil)
-(def-alien-type nil - (struct rlimit - (rlim-cur #-(or linux alpha) int #+linux long #+alpha unsigned-int) ; current (soft) limit - (rlim-max #-(or linux alpha) int #+linux long #+alpha unsigned-int))); maximum value for rlim-cur
+;; Use getcwd instead of getwd. But what should we do if the path +;; won't fit? Try again with a larger size? We don't do that right +;; now. +(defun unix-current-directory () + ;; 5120 is some randomly selected maximum size for the buffer for getcwd. + (with-alien ((buf (array c-call:char 5120))) + (let ((result + (alien-funcall + (extern-alien "getcwd" + (function (* c-call:char) + (* c-call:char) c-call:int)) + (cast buf (* c-call:char)) + 5120))) + + (values (not (zerop + (sap-int (alien-sap result)))) + (%file->name (cast buf c-call:c-string))))))
- -;;;; Errno stuff. +;;; Unix-access accepts a path and a mode. It returns two values the +;;; first is T if the file is accessible and NIL otherwise. The second +;;; only has meaning in the second case and is the unix errno value.
-(eval-when (compile eval) +(defconstant r_ok 4 _N"Test for read permission") +(defconstant w_ok 2 _N"Test for write permission") +(defconstant x_ok 1 _N"Test for execute permission") +(defconstant f_ok 0 _N"Test for presence of file")
-(defparameter *compiler-unix-errors* nil) +(defun unix-access (path mode) + _N"Given a file path (a string) and one of four constant modes, + unix-access returns T if the file is accessible with that + mode and NIL if not. It also returns an errno value with + NIL which determines why the file was not accessible.
-(defmacro def-unix-error (name number description) - `(progn - (eval-when (compile eval) - (push (cons ,number ,description) *compiler-unix-errors*)) - (defconstant ,name ,number ,description) - (export ',name))) + The access modes are: + r_ok Read permission. + w_ok Write permission. + x_ok Execute permission. + f_ok Presence of file." + (declare (type unix-pathname path) + (type (mod 8) mode)) + (void-syscall ("access" c-string int) (%name->file path) mode))
-(defmacro emit-unix-errors () - (let* ((max (apply #'max (mapcar #'car *compiler-unix-errors*))) - (array (make-array (1+ max) :initial-element nil))) - (dolist (error *compiler-unix-errors*) - (setf (svref array (car error)) (cdr error))) - `(progn - (defvar *unix-errors* ',array) - (declaim (simple-vector *unix-errors*))))) +;;; Unix-chdir accepts a directory name and makes that the +;;; current working directory.
-) ;eval-when +(defun unix-chdir (path) + _N"Given a file path string, unix-chdir changes the current working + directory to the one specified." + (declare (type unix-pathname path)) + (void-syscall ("chdir" c-string) (%name->file path)))
-;;; -;;; From <errno.h> -;;; -(def-unix-error ESUCCESS 0 _N"Successful") -(def-unix-error EPERM 1 _N"Operation not permitted") -(def-unix-error ENOENT 2 _N"No such file or directory") -(def-unix-error ESRCH 3 _N"No such process") -(def-unix-error EINTR 4 _N"Interrupted system call") -(def-unix-error EIO 5 _N"I/O error") -(def-unix-error ENXIO 6 _N"Device not configured") -(def-unix-error E2BIG 7 _N"Arg list too long") -(def-unix-error ENOEXEC 8 _N"Exec format error") -(def-unix-error EBADF 9 _N"Bad file descriptor") -(def-unix-error ECHILD 10 _N"No child process") -#+bsd(def-unix-error EDEADLK 11 _N"Resource deadlock avoided") -#-bsd(def-unix-error EAGAIN 11 #-linux _N"No more processes" #+linux _N"Try again") -(def-unix-error ENOMEM 12 _N"Out of memory") -(def-unix-error EACCES 13 _N"Permission denied") -(def-unix-error EFAULT 14 _N"Bad address") -(def-unix-error ENOTBLK 15 _N"Block device required") -(def-unix-error EBUSY 16 _N"Device or resource busy") -(def-unix-error EEXIST 17 _N"File exists") -(def-unix-error EXDEV 18 _N"Cross-device link") -(def-unix-error ENODEV 19 _N"No such device") -(def-unix-error ENOTDIR 20 _N"Not a director") -(def-unix-error EISDIR 21 _N"Is a directory") -(def-unix-error EINVAL 22 _N"Invalid argument") -(def-unix-error ENFILE 23 _N"File table overflow") -(def-unix-error EMFILE 24 _N"Too many open files") -(def-unix-error ENOTTY 25 _N"Inappropriate ioctl for device") -(def-unix-error ETXTBSY 26 _N"Text file busy") -(def-unix-error EFBIG 27 _N"File too large") -(def-unix-error ENOSPC 28 _N"No space left on device") -(def-unix-error ESPIPE 29 _N"Illegal seek") -(def-unix-error EROFS 30 _N"Read-only file system") -(def-unix-error EMLINK 31 _N"Too many links") -(def-unix-error EPIPE 32 _N"Broken pipe") -;;; -;;; Math -(def-unix-error EDOM 33 _N"Numerical argument out of domain") -(def-unix-error ERANGE 34 #-linux _N"Result too large" #+linux _N"Math result not representable") -;;; -#-(or linux svr4) +;;; Unix-chmod accepts a path and a mode and changes the mode to the new mode. + +(defconstant setuidexec #o4000 _N"Set user ID on execution") +(defconstant setgidexec #o2000 _N"Set group ID on execution") +(defconstant savetext #o1000 _N"Save text image after execution") +(defconstant readown #o400 _N"Read by owner") +(defconstant writeown #o200 _N"Write by owner") +(defconstant execown #o100 _N"Execute (search directory) by owner") +(defconstant readgrp #o40 _N"Read by group") +(defconstant writegrp #o20 _N"Write by group") +(defconstant execgrp #o10 _N"Execute (search directory) by group") +(defconstant readoth #o4 _N"Read by others") +(defconstant writeoth #o2 _N"Write by others") +(defconstant execoth #o1 _N"Execute (search directory) by others") + +(defun unix-chmod (path mode) + _N"Given a file path string and a constant mode, unix-chmod changes the + permission mode for that file to the one specified. The new mode + can be created by logically OR'ing the following: + + setuidexec Set user ID on execution. + setgidexec Set group ID on execution. + savetext Save text image after execution. + readown Read by owner. + writeown Write by owner. + execown Execute (search directory) by owner. + readgrp Read by group. + writegrp Write by group. + execgrp Execute (search directory) by group. + readoth Read by others. + writeoth Write by others. + execoth Execute (search directory) by others. + + Thus #o444 and (logior unix:readown unix:readgrp unix:readoth) + are equivalent for 'mode. The octal-base is familar to Unix users. + + It returns T on successfully completion; NIL and an error number + otherwise." + (declare (type unix-pathname path) + (type unix-file-mode mode)) + (void-syscall ("chmod" c-string int) (%name->file path) mode)) + +;;; Unix-fchmod accepts a file descriptor ("fd") and a file protection mode +;;; ("mode") and changes the protection of the file described by "fd" to +;;; "mode". + +(defun unix-fchmod (fd mode) + _N"Given an integer file descriptor and a mode (the same as those + used for unix-chmod), unix-fchmod changes the permission mode + for that file to the one specified. T is returned if the call + was successful." + (declare (type unix-fd fd) + (type unix-file-mode mode)) + (void-syscall ("fchmod" int int) fd mode)) + +;;; Unix-lseek accepts a file descriptor, an offset, and whence value. + +(defconstant l_set 0 _N"set the file pointer") +(defconstant l_incr 1 _N"increment the file pointer") +(defconstant l_xtnd 2 _N"extend the file size") + +(defun unix-lseek (fd offset whence) + _N"Unix-lseek accepts a file descriptor and moves the file pointer ahead + a certain offset for that file. Whence can be any of the following: + + l_set Set the file pointer. + l_incr Increment the file pointer. + l_xtnd Extend the file size. + _N" + (declare (type unix-fd fd) + (type file-offset offset) + (type (integer 0 2) whence)) + (off-t-syscall ("lseek" (int off-t int)) fd offset whence)) + +;;; Unix-mkdir accepts a name and a mode and attempts to create the +;;; corresponding directory with mode mode. + +(defun unix-mkdir (name mode) + _N"Unix-mkdir creates a new directory with the specified name and mode. + (Same as those for unix-chmod.) It returns T upon success, otherwise + NIL and an error number." + (declare (type unix-pathname name) + (type unix-file-mode mode)) + (void-syscall ("mkdir" c-string int) (%name->file name) mode)) + +;;; Unix-unlink accepts a name and deletes the directory entry for that +;;; name and the file if this is the last link. + +(defun unix-unlink (name) + _N"Unix-unlink removes the directory entry for the named file. + NIL and an error code is returned if the call fails." + (declare (type unix-pathname name)) + (void-syscall ("unlink" c-string) (%name->file name))) + +;;; Unix-open accepts a pathname (a simple string), flags, and mode and +;;; attempts to open file with name pathname. + +(defconstant o_rdonly 0 _N"Read-only flag.") +(defconstant o_wronly 1 _N"Write-only flag.") +(defconstant o_rdwr 2 _N"Read-write flag.") +#+(or hpux linux svr4) +(defconstant o_ndelay #-linux 4 #+linux #o4000 _N"Non-blocking I/O") +(defconstant o_append #-linux #o10 #+linux #o2000 _N"Append flag.") +#+(or hpux svr4 linux) (progn -;;; non-blocking and interrupt i/o -(def-unix-error EWOULDBLOCK 35 _N"Operation would block") -#-bsd(def-unix-error EDEADLK 35 _N"Operation would block") ; Ditto -#+bsd(def-unix-error EAGAIN 35 _N"Resource temporarily unavailable") -(def-unix-error EINPROGRESS 36 _N"Operation now in progress") -(def-unix-error EALREADY 37 _N"Operation already in progress") -;;; -;;; ipc/network software -(def-unix-error ENOTSOCK 38 _N"Socket operation on non-socket") -(def-unix-error EDESTADDRREQ 39 _N"Destination address required") -(def-unix-error EMSGSIZE 40 _N"Message too long") -(def-unix-error EPROTOTYPE 41 _N"Protocol wrong type for socket") -(def-unix-error ENOPROTOOPT 42 _N"Protocol not available") -(def-unix-error EPROTONOSUPPORT 43 _N"Protocol not supported") -(def-unix-error ESOCKTNOSUPPORT 44 _N"Socket type not supported") -(def-unix-error EOPNOTSUPP 45 _N"Operation not supported on socket") -(def-unix-error EPFNOSUPPORT 46 _N"Protocol family not supported") -(def-unix-error EAFNOSUPPORT 47 _N"Address family not supported by protocol family") -(def-unix-error EADDRINUSE 48 _N"Address already in use") -(def-unix-error EADDRNOTAVAIL 49 _N"Can't assign requested address") -;;; -;;; operational errors -(def-unix-error ENETDOWN 50 _N"Network is down") -(def-unix-error ENETUNREACH 51 _N"Network is unreachable") -(def-unix-error ENETRESET 52 _N"Network dropped connection on reset") -(def-unix-error ECONNABORTED 53 _N"Software caused connection abort") -(def-unix-error ECONNRESET 54 _N"Connection reset by peer") -(def-unix-error ENOBUFS 55 _N"No buffer space available") -(def-unix-error EISCONN 56 _N"Socket is already connected") -(def-unix-error ENOTCONN 57 _N"Socket is not connected") -(def-unix-error ESHUTDOWN 58 _N"Can't send after socket shutdown") -(def-unix-error ETOOMANYREFS 59 _N"Too many references: can't splice") -(def-unix-error ETIMEDOUT 60 _N"Connection timed out") -(def-unix-error ECONNREFUSED 61 _N"Connection refused") -;;; -(def-unix-error ELOOP 62 _N"Too many levels of symbolic links") -(def-unix-error ENAMETOOLONG 63 _N"File name too long") -;;; -(def-unix-error EHOSTDOWN 64 _N"Host is down") -(def-unix-error EHOSTUNREACH 65 _N"No route to host") -(def-unix-error ENOTEMPTY 66 _N"Directory not empty") -;;; -;;; quotas & resource -(def-unix-error EPROCLIM 67 _N"Too many processes") -(def-unix-error EUSERS 68 _N"Too many users") -(def-unix-error EDQUOT 69 _N"Disc quota exceeded") -;;; -;;; CMU RFS -(def-unix-error ELOCAL 126 _N"namei should continue locally") -(def-unix-error EREMOTE 127 _N"namei was handled remotely") -;;; -;;; VICE -(def-unix-error EVICEERR 70 _N"Remote file system error _N") -(def-unix-error EVICEOP 71 _N"syscall was handled by Vice") -) -#+svr4 + (defconstant o_creat #-linux #o400 #+linux #o100 _N"Create if nonexistant flag.") + (defconstant o_trunc #o1000 _N"Truncate flag.") + (defconstant o_excl #-linux #o2000 #+linux #o200 _N"Error if already exists.") + (defconstant o_noctty #+linux #o400 #+hpux #o400000 #+(or irix solaris) #x800 + _N"Don't assign controlling tty")) +#+(or hpux svr4 BSD) +(defconstant o_nonblock #+hpux #o200000 #+(or irix solaris) #x80 #+BSD #x04 + _N"Non-blocking mode") +#+BSD +(defconstant o_ndelay o_nonblock) ; compatibility +#+linux (progn -(def-unix-error ENOMSG 35 _N"No message of desired type") -(def-unix-error EIDRM 36 _N"Identifier removed") -(def-unix-error ECHRNG 37 _N"Channel number out of range") -(def-unix-error EL2NSYNC 38 _N"Level 2 not synchronized") -(def-unix-error EL3HLT 39 _N"Level 3 halted") -(def-unix-error EL3RST 40 _N"Level 3 reset") -(def-unix-error ELNRNG 41 _N"Link number out of range") -(def-unix-error EUNATCH 42 _N"Protocol driver not attached") -(def-unix-error ENOCSI 43 _N"No CSI structure available") -(def-unix-error EL2HLT 44 _N"Level 2 halted") -(def-unix-error EDEADLK 45 _N"Deadlock situation detected/avoided") -(def-unix-error ENOLCK 46 _N"No record locks available") -(def-unix-error ECANCELED 47 _N"Error 47") -(def-unix-error ENOTSUP 48 _N"Error 48") -(def-unix-error EBADE 50 _N"Bad exchange descriptor") -(def-unix-error EBADR 51 _N"Bad request descriptor") -(def-unix-error EXFULL 52 _N"Message tables full") -(def-unix-error ENOANO 53 _N"Anode table overflow") -(def-unix-error EBADRQC 54 _N"Bad request code") -(def-unix-error EBADSLT 55 _N"Invalid slot") -(def-unix-error EDEADLOCK 56 _N"File locking deadlock") -(def-unix-error EBFONT 57 _N"Bad font file format") -(def-unix-error ENOSTR 60 _N"Not a stream device") -(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 stream 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 74 _N"Multihop attempted") -(def-unix-error EBADMSG 77 _N"Not a data message") -(def-unix-error ENAMETOOLONG 78 _N"File name too long") -(def-unix-error EOVERFLOW 79 _N"Value too large for defined data type") -(def-unix-error ENOTUNIQ 80 _N"Name not unique on network") -(def-unix-error EBADFD 81 _N"File descriptor in bad state") -(def-unix-error EREMCHG 82 _N"Remote address changed") -(def-unix-error ELIBACC 83 _N"Can not access a needed shared library") -(def-unix-error ELIBBAD 84 _N"Accessing a corrupted shared library") -(def-unix-error ELIBSCN 85 _N".lib section in a.out corrupted") -(def-unix-error ELIBMAX 86 _N"Attempting to link in more shared libraries than system limit") -(def-unix-error ELIBEXEC 87 _N"Can not exec a shared library directly") -(def-unix-error EILSEQ 88 _N"Error 88") -(def-unix-error ENOSYS 89 _N"Operation not applicable") -(def-unix-error ELOOP 90 _N"Number of symbolic links encountered during path name traversal exceeds MAXSYMLINKS") -(def-unix-error ERESTART 91 _N"Error 91") -(def-unix-error ESTRPIPE 92 _N"Error 92") -(def-unix-error ENOTEMPTY 93 _N"Directory not empty") -(def-unix-error EUSERS 94 _N"Too many users") -(def-unix-error ENOTSOCK 95 _N"Socket operation on non-socket") -(def-unix-error EDESTADDRREQ 96 _N"Destination address required") -(def-unix-error EMSGSIZE 97 _N"Message too long") -(def-unix-error EPROTOTYPE 98 _N"Protocol wrong type for socket") -(def-unix-error ENOPROTOOPT 99 _N"Option not supported by protocol") -(def-unix-error EPROTONOSUPPORT 120 _N"Protocol not supported") -(def-unix-error ESOCKTNOSUPPORT 121 _N"Socket type not supported") -(def-unix-error EOPNOTSUPP 122 _N"Operation not supported on transport endpoint") -(def-unix-error EPFNOSUPPORT 123 _N"Protocol family not supported") -(def-unix-error EAFNOSUPPORT 124 _N"Address family not supported by protocol family") -(def-unix-error EADDRINUSE 125 _N"Address already in use") -(def-unix-error EADDRNOTAVAIL 126 _N"Cannot assign requested address") -(def-unix-error ENETDOWN 127 _N"Network is down") -(def-unix-error ENETUNREACH 128 _N"Network is unreachable") -(def-unix-error ENETRESET 129 _N"Network dropped connection because of reset") -(def-unix-error ECONNABORTED 130 _N"Software caused connection abort") -(def-unix-error ECONNRESET 131 _N"Connection reset by peer") -(def-unix-error ENOBUFS 132 _N"No buffer space available") -(def-unix-error EISCONN 133 _N"Transport endpoint is already connected") -(def-unix-error ENOTCONN 134 _N"Transport endpoint is not connected") -(def-unix-error ESHUTDOWN 143 _N"Cannot send after socket shutdown") -(def-unix-error ETOOMANYREFS 144 _N"Too many references: cannot splice") -(def-unix-error ETIMEDOUT 145 _N"Connection timed out") -(def-unix-error ECONNREFUSED 146 _N"Connection refused") -(def-unix-error EHOSTDOWN 147 _N"Host is down") -(def-unix-error EHOSTUNREACH 148 _N"No route to host") -(def-unix-error EWOULDBLOCK 11 _N"Resource temporarily unavailable") -(def-unix-error EALREADY 149 _N"Operation already in progress") -(def-unix-error EINPROGRESS 150 _N"Operation now in progress") -(def-unix-error ESTALE 151 _N"Stale NFS file handle") -) -#+linux + (defconstant o_sync #o10000 _N"Synchronous writes (on ext2)")) + +#-(or hpux svr4 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") -) + (defconstant o_creat #o1000 _N"Create if nonexistant flag.") + (defconstant o_trunc #o2000 _N"Truncate flag.") + (defconstant o_excl #o4000 _N"Error if already exists."))
-;;; -;;; And now for something completely different ... -(emit-unix-errors) +(defun unix-open (path flags mode) + _N"Unix-open opens the file whose pathname is specified by path + for reading and/or writing as specified by the flags argument. + The flags argument can be:
-(def-alien-routine ("os_get_errno" unix-get-errno) int) -(def-alien-routine ("os_set_errno" unix-set-errno) int (newvalue int)) -(defun unix-errno () (unix-get-errno)) -(defun (setf unix-errno) (newvalue) (unix-set-errno newvalue)) + o_rdonly Read-only flag. + o_wronly Write-only flag. + o_rdwr Read-and-write flag. + o_append Append flag. + o_creat Create-if-nonexistant flag. + o_trunc Truncate-to-size-0 flag.
-;;; GET-UNIX-ERROR-MSG -- public. -;;; -(defun get-unix-error-msg (&optional (error-number (unix-errno))) - _N"Returns a string describing the error number which was returned by a - UNIX system call." - (declare (type integer error-number)) - (if (array-in-bounds-p *unix-errors* error-number) - (svref *unix-errors* error-number) - (format nil _"Unknown error [~d]" error-number))) + If the o_creat flag is specified, then the file is created with + a permission of argument mode if the file doesn't exist. An + integer file descriptor is returned by unix-open." + (declare (type unix-pathname path) + (type fixnum flags) + (type unix-file-mode mode)) + (int-syscall (#+solaris "open64" #-solaris "open" c-string int int) + (%name->file path) flags mode))
- -;;;; Lisp types used by syscalls. +;;; Unix-close accepts a file descriptor and attempts to close the file +;;; associated with it.
-(deftype unix-pathname () 'simple-string) -(deftype unix-fd () `(integer 0 ,most-positive-fixnum)) +(defun unix-close (fd) + _N"Unix-close takes an integer file descriptor as an argument and + closes the file associated with it. T is returned upon successful + completion, otherwise NIL and an error number." + (declare (type unix-fd fd)) + (void-syscall ("close" int) fd))
-(deftype unix-file-mode () '(unsigned-byte 32)) -(deftype unix-pid () '(unsigned-byte 32)) -(deftype unix-uid () '(unsigned-byte 32)) -(deftype unix-gid () '(unsigned-byte 32)) +;;; Unix-creat accepts a file name and a mode. It creates a new file +;;; with name and sets it mode to mode (as for chmod).
+(defun unix-creat (name mode) + _N"Unix-creat accepts a file name and a mode (same as those for + unix-chmod) and creates a file by that name with the specified + permission mode. It returns a file descriptor on success, + or NIL and an error number otherwise.
- -;;;; User and group database structures + This interface is made obsolete by UNIX-OPEN." + + (declare (type unix-pathname name) + (type unix-file-mode mode)) + (int-syscall (#+solaris "creat64" #-solaris "creat" c-string int) + (%name->file name) mode))
-(defstruct user-info - (name "" :type string) - (password "" :type string) - (uid 0 :type unix-uid) - (gid 0 :type unix-gid) - #+solaris (age "" :type string) - #+solaris (comment "" :type string) - #+freebsd (change -1 :type fixnum) - (gecos "" :type string) - (dir "" :type string) - (shell "" :type string)) +;;; Unix-read accepts a file descriptor, a buffer, and the length to read. +;;; It attempts to read len bytes from the device associated with fd +;;; and store them into the buffer. It returns the actual number of +;;; bytes read.
-(defstruct group-info - (name "" :type string) - (password "" :type string) - (gid 0 :type unix-gid) - (members nil :type list)) ; list of logins as strings +;;; Unix-dup returns a duplicate copy of the existing file-descriptor +;;; passed as an argument.
-;; see <pwd.h> -#+solaris -(def-alien-type nil - (struct passwd - (pw-name (* char)) ; user's login name - (pw-passwd (* char)) ; no longer used - (pw-uid uid-t) ; user id - (pw-gid gid-t) ; group id - (pw-age (* char)) ; password age (not used) - (pw-comment (* char)) ; not used - (pw-gecos (* char)) ; typically user's full name - (pw-dir (* char)) ; user's home directory - (pw-shell (* char)))) ; user's login shell - -#+bsd -(def-alien-type nil - (struct passwd - (pw-name (* char)) ; user's login name - (pw-passwd (* char)) ; no longer used - (pw-uid uid-t) ; user id - (pw-gid gid-t) ; group id - (pw-change int) ; password change time - (pw-class (* char)) ; user access class - (pw-gecos (* char)) ; typically user's full name - (pw-dir (* char)) ; user's home directory - (pw-shell (* char)) ; user's login shell - (pw-expire int) ; account expiration - #+(or freebsd darwin) - (pw-fields int))) ; internal - -;; see <grp.h> -(def-alien-type nil - (struct group - (gr-name (* char)) ; name of the group - (gr-passwd (* char)) ; encrypted group password - (gr-gid gid-t) ; numerical group ID - (gr-mem (* (* char))))) ; vector of pointers to member names - - -;;;; System calls. - -(defmacro %syscall ((name (&rest arg-types) result-type) - success-form &rest args) - `(let* ((fn (extern-alien ,name (function ,result-type ,@arg-types))) - (result (alien-funcall fn ,@args))) - (if (eql -1 result) - (values nil (unix-errno)) - ,success-form))) - -(defmacro syscall ((name &rest arg-types) success-form &rest args) - `(%syscall (,name (,@arg-types) int) ,success-form ,@args)) - -;;; Like syscall, but if it fails, signal an error instead of returing error -;;; codes. Should only be used for syscalls that will never really get an -;;; error. -;;; -(defmacro syscall* ((name &rest arg-types) success-form &rest args) - `(let ((result (alien-funcall (extern-alien ,name (function int ,@arg-types)) - ,@args))) - (if (eql -1 result) - (error _"Syscall ~A failed: ~A" ,name (get-unix-error-msg)) - ,success-form))) - -(defmacro void-syscall ((name &rest arg-types) &rest args) - `(syscall (,name ,@arg-types) (values t 0) ,@args)) - -(defmacro int-syscall ((name &rest arg-types) &rest args) - `(syscall (,name ,@arg-types) (values result 0) ,@args)) - -(defmacro off-t-syscall ((name arg-types) &rest args) - `(%syscall (,name ,arg-types off-t) (values result 0) ,@args)) - - -;;;; Memory-mapped files - -(defconstant +null+ (sys:int-sap 0)) - -(defconstant prot_read 1) ; Readable -(defconstant prot_write 2) ; Writable -(defconstant prot_exec 4) ; Executable -(defconstant prot_none 0) ; No access - -(defconstant map_shared 1) ; Changes are shared -(defconstant map_private 2) ; Changes are private -(defconstant map_fixed 16) ; Fixed, user-defined address -(defconstant map_noreserve #x40) ; Don't reserve swap space -(defconstant map_anonymous - #+solaris #x100 ; Solaris - #+linux 32 ; Linux - #+bsd #x1000) - -(defconstant ms_async 1) -(defconstant ms_sync 4) -(defconstant ms_invalidate 2) - -;; The return value from mmap that means mmap failed. -(defconstant map_failed (int-sap (1- (ash 1 vm:word-bits)))) - -(defun unix-mmap (addr length prot flags fd offset) - (declare (type (or null system-area-pointer) addr) - (type (unsigned-byte 32) length) - (type (integer 1 7) prot) - (type (unsigned-byte 32) flags) - (type (or null unix-fd) fd) - (type file-offset offset)) - ;; Can't use syscall, because the address that is returned could be - ;; "negative". Hence we explicitly check for mmap returning - ;; MAP_FAILED. - (let ((result - (alien-funcall (extern-alien "mmap" (function system-area-pointer - system-area-pointer - size-t int int int off-t)) - (or addr +null+) length prot flags (or fd -1) offset))) - (if (sap= result map_failed) - (values nil (unix-errno)) - (values result 0)))) - -(defun unix-munmap (addr length) - (declare (type system-area-pointer addr) - (type (unsigned-byte 32) length)) - (syscall ("munmap" system-area-pointer size-t) t addr length)) - -(defun unix-mprotect (addr length prot) - (declare (type system-area-pointer addr) - (type (unsigned-byte 32) length) - (type (integer 1 7) prot)) - (syscall ("mprotect" system-area-pointer size-t int) - t addr length prot)) - -(defun unix-setuid (uid) - _N"Set the user ID of the calling process to UID. - If the calling process is the super-user, set the real - and effective user IDs, and the saved set-user-ID to UID; - if not, the effective user ID is set to UID." - (int-syscall ("setuid" uid-t) uid)) - -(defun unix-setgid (gid) - _N"Set the group ID of the calling process to GID. - If the calling process is the super-user, set the real - and effective group IDs, and the saved set-group-ID to GID; - if not, the effective group ID is set to GID." - (int-syscall ("setgid" gid-t) gid)) - - - -(defun unix-msync (addr length flags) - (declare (type system-area-pointer addr) - (type (unsigned-byte 32) length) - (type (signed-byte 32) flags)) - (syscall ("msync" system-area-pointer size-t int) t addr length flags)) - -;;; Unix-access accepts a path and a mode. It returns two values the -;;; first is T if the file is accessible and NIL otherwise. The second -;;; only has meaning in the second case and is the unix errno value. - -(defconstant r_ok 4 _N"Test for read permission") -(defconstant w_ok 2 _N"Test for write permission") -(defconstant x_ok 1 _N"Test for execute permission") -(defconstant f_ok 0 _N"Test for presence of file") - -(defun unix-access (path mode) - _N"Given a file path (a string) and one of four constant modes, - unix-access returns T if the file is accessible with that - mode and NIL if not. It also returns an errno value with - NIL which determines why the file was not accessible. - - The access modes are: - r_ok Read permission. - w_ok Write permission. - x_ok Execute permission. - f_ok Presence of file." - (declare (type unix-pathname path) - (type (mod 8) mode)) - (void-syscall ("access" c-string int) (%name->file path) mode)) - -;;; Unix-chdir accepts a directory name and makes that the -;;; current working directory. - -(defun unix-chdir (path) - _N"Given a file path string, unix-chdir changes the current working - directory to the one specified." - (declare (type unix-pathname path)) - (void-syscall ("chdir" c-string) (%name->file path))) - -;;; Unix-chmod accepts a path and a mode and changes the mode to the new mode. - -(defconstant setuidexec #o4000 _N"Set user ID on execution") -(defconstant setgidexec #o2000 _N"Set group ID on execution") -(defconstant savetext #o1000 _N"Save text image after execution") -(defconstant readown #o400 _N"Read by owner") -(defconstant writeown #o200 _N"Write by owner") -(defconstant execown #o100 _N"Execute (search directory) by owner") -(defconstant readgrp #o40 _N"Read by group") -(defconstant writegrp #o20 _N"Write by group") -(defconstant execgrp #o10 _N"Execute (search directory) by group") -(defconstant readoth #o4 _N"Read by others") -(defconstant writeoth #o2 _N"Write by others") -(defconstant execoth #o1 _N"Execute (search directory) by others") - -(defun unix-chmod (path mode) - _N"Given a file path string and a constant mode, unix-chmod changes the - permission mode for that file to the one specified. The new mode - can be created by logically OR'ing the following: - - setuidexec Set user ID on execution. - setgidexec Set group ID on execution. - savetext Save text image after execution. - readown Read by owner. - writeown Write by owner. - execown Execute (search directory) by owner. - readgrp Read by group. - writegrp Write by group. - execgrp Execute (search directory) by group. - readoth Read by others. - writeoth Write by others. - execoth Execute (search directory) by others. - - Thus #o444 and (logior unix:readown unix:readgrp unix:readoth) - are equivalent for 'mode. The octal-base is familar to Unix users. - - It returns T on successfully completion; NIL and an error number - otherwise." - (declare (type unix-pathname path) - (type unix-file-mode mode)) - (void-syscall ("chmod" c-string int) (%name->file path) mode)) - -;;; Unix-fchmod accepts a file descriptor ("fd") and a file protection mode -;;; ("mode") and changes the protection of the file described by "fd" to -;;; "mode". - -(defun unix-fchmod (fd mode) - _N"Given an integer file descriptor and a mode (the same as those - used for unix-chmod), unix-fchmod changes the permission mode - for that file to the one specified. T is returned if the call - was successful." - (declare (type unix-fd fd) - (type unix-file-mode mode)) - (void-syscall ("fchmod" int int) fd mode)) - -(defun unix-chown (path uid gid) - _N"Given a file path, an integer user-id, and an integer group-id, - unix-chown changes the owner of the file and the group of the - file to those specified. Either the owner or the group may be - left unchanged by specifying them as -1. Note: Permission will - fail if the caller is not the superuser." - (declare (type unix-pathname path) - (type (or unix-uid (integer -1 -1)) uid) - (type (or unix-gid (integer -1 -1)) gid)) - (void-syscall ("chown" c-string int int) (%name->file path) uid gid)) - -;;; Unix-fchown is exactly the same as unix-chown except that the file -;;; is specified by a file-descriptor ("fd") instead of a pathname. - -(defun unix-fchown (fd uid gid) - _N"Unix-fchown is like unix-chown, except that it accepts an integer - file descriptor instead of a file path name." - (declare (type unix-fd fd) - (type (or unix-uid (integer -1 -1)) uid) - (type (or unix-gid (integer -1 -1)) gid)) - (void-syscall ("fchown" int int int) fd uid gid)) - -;;; Returns the maximum size (i.e. the number of array elements -;;; of the file descriptor table. - -(defun unix-getdtablesize () - _N"Unix-getdtablesize returns the maximum size of the file descriptor - table. (i.e. the maximum number of descriptors that can exist at - one time.)" - (int-syscall ("getdtablesize"))) - -;;; Unix-close accepts a file descriptor and attempts to close the file -;;; associated with it. - -(defun unix-close (fd) - _N"Unix-close takes an integer file descriptor as an argument and - closes the file associated with it. T is returned upon successful - completion, otherwise NIL and an error number." - (declare (type unix-fd fd)) - (void-syscall ("close" int) fd)) - -;;; Unix-creat accepts a file name and a mode. It creates a new file -;;; with name and sets it mode to mode (as for chmod). - -(defun unix-creat (name mode) - _N"Unix-creat accepts a file name and a mode (same as those for - unix-chmod) and creates a file by that name with the specified - permission mode. It returns a file descriptor on success, - or NIL and an error number otherwise. - - This interface is made obsolete by UNIX-OPEN." - - (declare (type unix-pathname name) - (type unix-file-mode mode)) - (int-syscall (#+solaris "creat64" #-solaris "creat" c-string int) - (%name->file name) mode)) - -;;; Unix-dup returns a duplicate copy of the existing file-descriptor -;;; passed as an argument. - -(defun unix-dup (fd) - _N"Unix-dup duplicates an existing file descriptor (given as the - argument) and return it. If FD is not a valid file descriptor, NIL - and an error number are returned." - (declare (type unix-fd fd)) - (int-syscall ("dup" int) fd)) - -;;; Unix-dup2 makes the second file-descriptor describe the same file -;;; as the first. If the second file-descriptor points to an open -;;; file, it is first closed. In any case, the second should have a -;;; value which is a valid file-descriptor. - -(defun unix-dup2 (fd1 fd2) - _N"Unix-dup2 duplicates an existing file descriptor just as unix-dup - does only the new value of the duplicate descriptor may be requested - through the second argument. If a file already exists with the - requested descriptor number, it will be closed and the number - assigned to the duplicate." - (declare (type unix-fd fd1 fd2)) - (void-syscall ("dup2" int int) fd1 fd2)) +(defun unix-dup (fd) + _N"Unix-dup duplicates an existing file descriptor (given as the + argument) and return it. If FD is not a valid file descriptor, NIL + and an error number are returned." + (declare (type unix-fd fd)) + (int-syscall ("dup" int) fd))
;;; Unix-fcntl takes a file descriptor, an integer command ;;; number, and optional command arguments. It performs @@ -1404,134 +653,17 @@ (type (unsigned-byte 32) arg)) (int-syscall ("fcntl" int unsigned-int unsigned-int) fd cmd arg))
-;;; Unix-link creates a hard link from name2 to name1. - -(defun unix-link (name1 name2) - _N"Unix-link creates a hard link from the file with name1 to the - file with name2." - (declare (type unix-pathname name1 name2)) - (void-syscall ("link" c-string c-string) - (%name->file name1) (%name->file name2))) - -;;; Unix-lseek accepts a file descriptor, an offset, and whence value. - -(defconstant l_set 0 _N"set the file pointer") -(defconstant l_incr 1 _N"increment the file pointer") -(defconstant l_xtnd 2 _N"extend the file size") - -#-solaris -(defun unix-lseek (fd offset whence) - _N"Unix-lseek accepts a file descriptor and moves the file pointer ahead - a certain offset for that file. Whence can be any of the following: - - l_set Set the file pointer. - l_incr Increment the file pointer. - l_xtnd Extend the file size. - _N" - (declare (type unix-fd fd) - (type file-offset offset) - (type (integer 0 2) whence)) - (off-t-syscall ("lseek" (int off-t int)) fd offset whence)) - -#+solaris -(defun unix-lseek (fd offset whence) - _N"Unix-lseek accepts a file descriptor and moves the file pointer ahead - a certain offset for that file. Whence can be any of the following: - - l_set Set the file pointer. - l_incr Increment the file pointer. - l_xtnd Extend the file size. - _N" - (declare (type unix-fd fd) - (type file-offset64 offset) - (type (integer 0 2) whence)) - (let ((result (alien-funcall - (extern-alien "lseek64" (function off64-t int off64-t int)) - fd offset whence))) - (if (minusp result) - (progn - (values nil (unix-errno))) - (values result 0)))) - -;;; Unix-mkdir accepts a name and a mode and attempts to create the -;;; corresponding directory with mode mode. - -(defun unix-mkdir (name mode) - _N"Unix-mkdir creates a new directory with the specified name and mode. - (Same as those for unix-chmod.) It returns T upon success, otherwise - NIL and an error number." - (declare (type unix-pathname name) - (type unix-file-mode mode)) - (void-syscall ("mkdir" c-string int) (%name->file name) mode)) - -;;; Unix-open accepts a pathname (a simple string), flags, and mode and -;;; attempts to open file with name pathname. - -(defconstant o_rdonly 0 _N"Read-only flag.") -(defconstant o_wronly 1 _N"Write-only flag.") -(defconstant o_rdwr 2 _N"Read-write flag.") -#+(or hpux linux svr4) -(defconstant o_ndelay #-linux 4 #+linux #o4000 _N"Non-blocking I/O") -(defconstant o_append #-linux #o10 #+linux #o2000 _N"Append flag.") -#+(or hpux svr4 linux) -(progn - (defconstant o_creat #-linux #o400 #+linux #o100 _N"Create if nonexistant flag.") - (defconstant o_trunc #o1000 _N"Truncate flag.") - (defconstant o_excl #-linux #o2000 #+linux #o200 _N"Error if already exists.") - (defconstant o_noctty #+linux #o400 #+hpux #o400000 #+(or irix solaris) #x800 - _N"Don't assign controlling tty")) -#+(or hpux svr4 BSD) -(defconstant o_nonblock #+hpux #o200000 #+(or irix solaris) #x80 #+BSD #x04 - _N"Non-blocking mode") -#+BSD -(defconstant o_ndelay o_nonblock) ; compatibility -#+linux -(progn - (defconstant o_sync #o10000 _N"Synchronous writes (on ext2)")) - -#-(or hpux svr4 linux) -(progn - (defconstant o_creat #o1000 _N"Create if nonexistant flag.") - (defconstant o_trunc #o2000 _N"Truncate flag.") - (defconstant o_excl #o4000 _N"Error if already exists.")) - -(defun unix-open (path flags mode) - _N"Unix-open opens the file whose pathname is specified by path - for reading and/or writing as specified by the flags argument. - The flags argument can be: - - o_rdonly Read-only flag. - o_wronly Write-only flag. - o_rdwr Read-and-write flag. - o_append Append flag. - o_creat Create-if-nonexistant flag. - o_trunc Truncate-to-size-0 flag. - - If the o_creat flag is specified, then the file is created with - a permission of argument mode if the file doesn't exist. An - integer file descriptor is returned by unix-open." - (declare (type unix-pathname path) - (type fixnum flags) - (type unix-file-mode mode)) - (int-syscall (#+solaris "open64" #-solaris "open" c-string int int) - (%name->file path) flags mode)) - -(defun unix-pipe () - _N"Unix-pipe sets up a unix-piping mechanism consisting of - an input pipe and an output pipe. Unix-Pipe returns two - values: if no error occurred the first value is the pipe - to be read from and the second is can be written to. If - an error occurred the first value is NIL and the second - the unix error code." - (with-alien ((fds (array int 2))) - (syscall ("pipe" (* int)) - (values (deref fds 0) (deref fds 1)) - (cast fds (* int))))) - -;;; Unix-read accepts a file descriptor, a buffer, and the length to read. -;;; It attempts to read len bytes from the device associated with fd -;;; and store them into the buffer. It returns the actual number of -;;; bytes read. +(defun unix-pipe () + _N"Unix-pipe sets up a unix-piping mechanism consisting of + an input pipe and an output pipe. Unix-Pipe returns two + values: if no error occurred the first value is the pipe + to be read from and the second is can be written to. If + an error occurred the first value is NIL and the second + the unix error code." + (with-alien ((fds (array int 2))) + (syscall ("pipe" (* int)) + (values (deref fds 0) (deref fds 1)) + (cast fds (* int)))))
(defun unix-read (fd buf len) _N"Unix-read attempts to read from the file described by fd into @@ -1613,143 +745,6 @@ (declare (type unix-pathname name)) (void-syscall ("rmdir" c-string) (%name->file name)))
- -;;; UNIX-FAST-SELECT -- public. -;;; -(defmacro unix-fast-select (num-descriptors - read-fds write-fds exception-fds - timeout-secs &optional (timeout-usecs 0)) - _N"Perform the UNIX select(2) system call. - (declare (type (integer 0 #.FD-SETSIZE) num-descriptors) - (type (or (alien (* (struct fd-set))) null) - read-fds write-fds exception-fds) - (type (or null (unsigned-byte 31)) timeout-secs) - (type (unsigned-byte 31) timeout-usecs) - (optimize (speed 3) (safety 0) (inhibit-warnings 3)))" - `(let ((timeout-secs ,timeout-secs)) - (with-alien ((tv (struct timeval))) - (when timeout-secs - (setf (slot tv 'tv-sec) timeout-secs) - (setf (slot tv 'tv-usec) ,timeout-usecs)) - (int-syscall (#-netbsd "select" #+netbsd "__select50" int (* (struct fd-set)) (* (struct fd-set)) - (* (struct fd-set)) (* (struct timeval))) - ,num-descriptors ,read-fds ,write-fds ,exception-fds - (if timeout-secs (alien-sap (addr tv)) (int-sap 0)))))) - - -;;; Unix-select accepts sets of file descriptors and waits for an event -;;; to happen on one of them or to time out. - -(defmacro num-to-fd-set (fdset num) - `(if (fixnump ,num) - (progn - (setf (deref (slot ,fdset 'fds-bits) 0) ,num) - ,@(loop for index upfrom 1 below (/ fd-setsize 32) - collect `(setf (deref (slot ,fdset 'fds-bits) ,index) 0))) - (progn - ,@(loop for index upfrom 0 below (/ fd-setsize 32) - collect `(setf (deref (slot ,fdset 'fds-bits) ,index) - (ldb (byte 32 ,(* index 32)) ,num)))))) - -(defmacro fd-set-to-num (nfds fdset) - `(if (<= ,nfds 32) - (deref (slot ,fdset 'fds-bits) 0) - (+ ,@(loop for index upfrom 0 below (/ fd-setsize 32) - collect `(ash (deref (slot ,fdset 'fds-bits) ,index) - ,(* index 32)))))) - -(defun unix-select (nfds rdfds wrfds xpfds to-secs &optional (to-usecs 0)) - _N"Unix-select examines the sets of descriptors passed as arguments - to see if they are ready for reading and writing. See the UNIX - Programmers Manual for more information." - (declare (type (integer 0 #.FD-SETSIZE) nfds) - (type unsigned-byte rdfds wrfds xpfds) - (type (or (unsigned-byte 31) null) to-secs) - (type (unsigned-byte 31) to-usecs) - (optimize (speed 3) (safety 0) (inhibit-warnings 3))) - (with-alien ((tv (struct timeval)) - (rdf (struct fd-set)) - (wrf (struct fd-set)) - (xpf (struct fd-set))) - (when to-secs - (setf (slot tv 'tv-sec) to-secs) - (setf (slot tv 'tv-usec) to-usecs)) - (num-to-fd-set rdf rdfds) - (num-to-fd-set wrf wrfds) - (num-to-fd-set xpf xpfds) - (macrolet ((frob (lispvar alienvar) - `(if (zerop ,lispvar) - (int-sap 0) - (alien-sap (addr ,alienvar))))) - (syscall (#-netbsd "select" #+netbsd "__select50" int (* (struct fd-set)) (* (struct fd-set)) - (* (struct fd-set)) (* (struct timeval))) - (values result - (fd-set-to-num nfds rdf) - (fd-set-to-num nfds wrf) - (fd-set-to-num nfds xpf)) - nfds (frob rdfds rdf) (frob wrfds wrf) (frob xpfds xpf) - (if to-secs (alien-sap (addr tv)) (int-sap 0)))))) - - -;;; Unix-sync writes all information in core memory which has been modified -;;; to permanent storage (i.e. disk). - -(defun unix-sync () - _N"Unix-sync writes all information in core memory which has been - modified to disk. It returns NIL and an error code if an error - occured." - (void-syscall ("sync"))) - -;;; Unix-fsync writes the core-image of the file described by "fd" to -;;; permanent storage (i.e. disk). - -(defun unix-fsync (fd) - _N"Unix-fsync writes the core image of the file described by - fd to disk." - (declare (type unix-fd fd)) - (void-syscall ("fsync" int) fd)) - -;;; Unix-truncate accepts a file name and a new length. The file is -;;; truncated to the new length. - -(defun unix-truncate (name len) - _N"Unix-truncate truncates the named file to the length (in - bytes) specified by len. NIL and an error number is returned - if the call is unsuccessful." - (declare (type unix-pathname name) - (type (unsigned-byte #+solaris 64 #-solaris 32) len)) - #-(and bsd x86) - (void-syscall (#+solaris "truncate64" #-solaris "truncate" c-string int) name len) - #+(and bsd x86) - (void-syscall ("truncate" c-string unsigned-long unsigned-long) name len 0)) - -(defun unix-ftruncate (fd len) - _N"Unix-ftruncate is similar to unix-truncate except that the first - argument is a file descriptor rather than a file name." - (declare (type unix-fd fd) - (type (unsigned-byte #+solaris 64 #-solaris 32) len)) - #-(and bsd x86) - (void-syscall (#+solaris "ftruncate64" #-solaris "ftruncate" int int) fd len) - #+(and bsd x86) - (void-syscall ("ftruncate" int unsigned-long unsigned-long) fd len 0)) - -(defun unix-symlink (name1 name2) - _N"Unix-symlink creates a symbolic link named name2 to the file - named name1. NIL and an error number is returned if the call - is unsuccessful." - (declare (type unix-pathname name1 name2)) - (void-syscall ("symlink" c-string c-string) - (%name->file name1) (%name->file name2))) - -;;; Unix-unlink accepts a name and deletes the directory entry for that -;;; name and the file if this is the last link. - -(defun unix-unlink (name) - _N"Unix-unlink removes the directory entry for the named file. - NIL and an error code is returned if the call fails." - (declare (type unix-pathname name)) - (void-syscall ("unlink" c-string) (%name->file name))) - ;;; Unix-write accepts a file descriptor, a buffer, an offset, and the ;;; length to write. It attempts to write len bytes to the device ;;; associated with fd from the buffer starting at offset. It returns @@ -1981,165 +976,52 @@ (type (unsigned-byte 32) cmd)) (int-syscall ("ioctl" int unsigned-int (* char)) fd cmd arg))
-#+(or svr4 hpux bsd linux) -(progn - (defun unix-tcgetattr (fd termios) - _N"Get terminal attributes." - (declare (type unix-fd fd)) - (void-syscall ("tcgetattr" int (* (struct termios))) fd termios)) - - (defun unix-tcsetattr (fd opt termios) - _N"Set terminal attributes." - (declare (type unix-fd fd)) - (void-syscall ("tcsetattr" int int (* (struct termios))) fd opt termios)) - - ;; XXX rest of functions in this progn probably are present in linux, but - ;; not verified. - #-bsd - (defun unix-cfgetospeed (termios) - _N"Get terminal output speed." - (multiple-value-bind (speed errno) - (int-syscall ("cfgetospeed" (* (struct termios))) termios) - (if speed - (values (svref terminal-speeds speed) 0) - (values speed errno)))) - - #+bsd - (defun unix-cfgetospeed (termios) - _N"Get terminal output speed." - (int-syscall ("cfgetospeed" (* (struct termios))) termios)) - - #-bsd - (defun unix-cfsetospeed (termios speed) - _N"Set terminal output speed." - (let ((baud (or (position speed terminal-speeds) - (error _"Bogus baud rate ~S" speed)))) - (void-syscall ("cfsetospeed" (* (struct termios)) int) termios baud))) - - #+bsd - (defun unix-cfsetospeed (termios speed) - _N"Set terminal output speed." - (void-syscall ("cfsetospeed" (* (struct termios)) int) termios speed)) - - #-bsd - (defun unix-cfgetispeed (termios) - _N"Get terminal input speed." - (multiple-value-bind (speed errno) - (int-syscall ("cfgetispeed" (* (struct termios))) termios) - (if speed - (values (svref terminal-speeds speed) 0) - (values speed errno)))) - - #+bsd - (defun unix-cfgetispeed (termios) - _N"Get terminal input speed." - (int-syscall ("cfgetispeed" (* (struct termios))) termios)) - - #-bsd - (defun unix-cfsetispeed (termios speed) - _N"Set terminal input speed." - (let ((baud (or (position speed terminal-speeds) - (error _"Bogus baud rate ~S" speed)))) - (void-syscall ("cfsetispeed" (* (struct termios)) int) termios baud))) - - #+bsd - (defun unix-cfsetispeed (termios speed) - _N"Set terminal input speed." - (void-syscall ("cfsetispeed" (* (struct termios)) int) termios speed)) - - (defun unix-tcsendbreak (fd duration) - _N"Send break" - (declare (type unix-fd fd)) - (void-syscall ("tcsendbreak" int int) fd duration)) - - (defun unix-tcdrain (fd) - _N"Wait for output for finish" - (declare (type unix-fd fd)) - (void-syscall ("tcdrain" int) fd)) - - (defun unix-tcflush (fd selector) - _N"See tcflush(3)" - (declare (type unix-fd fd)) - (void-syscall ("tcflush" int int) fd selector)) - - (defun unix-tcflow (fd action) - _N"Flow control" - (declare (type unix-fd fd)) - (void-syscall ("tcflow" int int) fd action))) - -(defun tcsetpgrp (fd pgrp) - _N"Set the tty-process-group for the unix file-descriptor FD to PGRP." - (alien:with-alien ((alien-pgrp c-call:int pgrp)) - (unix-ioctl fd - tiocspgrp - (alien:alien-sap (alien:addr alien-pgrp))))) - -(defun tcgetpgrp (fd) - _N"Get the tty-process-group for the unix file-descriptor FD." - (alien:with-alien ((alien-pgrp c-call:int)) - (multiple-value-bind (ok err) - (unix-ioctl fd - tiocgpgrp - (alien:alien-sap (alien:addr alien-pgrp))) - (if ok - (values alien-pgrp nil) - (values nil err))))) - -(defun tty-process-group (&optional fd) - _N"Get the tty-process-group for the unix file-descriptor FD. If not supplied, - FD defaults to /dev/tty." - (if fd - (tcgetpgrp fd) - (multiple-value-bind (tty-fd errno) - (unix-open "/dev/tty" o_rdwr 0) - (cond (tty-fd - (multiple-value-prog1 - (tcgetpgrp tty-fd) - (unix-close tty-fd))) - (t - (values nil errno)))))) - -(defun %set-tty-process-group (pgrp &optional fd) - _N"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not - supplied, FD defaults to /dev/tty." - (let ((old-sigs - (unix-sigblock - (sigmask :sigttou :sigttin :sigtstp :sigchld)))) - (declare (type (unsigned-byte 32) old-sigs)) - (unwind-protect - (if fd - (tcsetpgrp fd pgrp) - (multiple-value-bind (tty-fd errno) - (unix-open "/dev/tty" o_rdwr 0) - (cond (tty-fd - (multiple-value-prog1 - (tcsetpgrp tty-fd pgrp) - (unix-close tty-fd))) - (t - (values nil errno))))) - (unix-sigsetmask old-sigs)))) - -(defsetf tty-process-group (&optional fd) (pgrp) - _N"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not - supplied, FD defaults to /dev/tty." - `(%set-tty-process-group ,pgrp ,fd)) +(defun unix-tcgetattr (fd termios) + _N"Get terminal attributes." + (declare (type unix-fd fd)) + (void-syscall ("tcgetattr" int (* (struct termios))) fd termios))
+(defun unix-tcsetattr (fd opt termios) + _N"Set terminal attributes." + (declare (type unix-fd fd)) + (void-syscall ("tcsetattr" int int (* (struct termios))) fd opt termios))
-;;; Socket options. +;; XXX rest of functions in this progn probably are present in linux, but +;; not verified. +#-bsd +(defun unix-cfgetospeed (termios) + _N"Get terminal output speed." + (multiple-value-bind (speed errno) + (int-syscall ("cfgetospeed" (* (struct termios))) termios) + (if speed + (values (svref terminal-speeds speed) 0) + (values speed errno))))
-#+(or hpux bsd) -(define-ioctl-command SIOCSPGRP #\s 8 int :in) +#+bsd +(defun unix-cfgetospeed (termios) + _N"Get terminal output speed." + (int-syscall ("cfgetospeed" (* (struct termios))) termios))
-#+linux -(define-ioctl-command SIOCSPGRP #\s #x8904 int :in) +(def-alien-routine ("getuid" unix-getuid) int + _N"Unix-getuid returns the real user-id associated with the + current process.")
-#+(or hpux bsd linux) -(defun siocspgrp (fd pgrp) - _N"Set the socket process-group for the unix file-descriptor FD to PGRP." - (alien:with-alien ((alien-pgrp c-call:int pgrp)) - (unix-ioctl fd - siocspgrp - (alien:alien-sap (alien:addr alien-pgrp))))) +;;; Unix-getpagesize returns the number of bytes in the system page. + +(defun unix-getpagesize () + _N"Unix-getpagesize returns the number of bytes in a system page." + (int-syscall ("getpagesize"))) + +(defun unix-gethostname () + _N"Unix-gethostname returns the name of the host machine as a string." + (with-alien ((buf (array char 256))) + (syscall* ("gethostname" (* char) int) + (cast buf c-string) + (cast buf (* char)) 256))) + +(def-alien-routine ("gethostid" unix-gethostid) unsigned-long + _N"Unix-gethostid returns a 32-bit integer which provides unique + identification for the host machine.")
;;; Unix-exit terminates a program.
@@ -2150,14 +1032,227 @@ (declare (type (signed-byte 32) code)) (void-syscall ("exit" int) code))
-;;; STAT and friends. +;;; From sys/termios.h
-(defmacro extract-stat-results (buf) - `(values T - (slot ,buf 'st-dev) - (slot ,buf 'st-ino) - (slot ,buf 'st-mode) - (slot ,buf 'st-nlink) +;;; NOTE: There is both a termio (SYSV) and termios (POSIX) +;;; structure with similar but incompatible definitions. It may be that +;;; the non-BSD variant of termios below is really a termio but I (pw) +;;; can't verify. The BSD variant uses the Posix termios def. Some systems +;;; (Ultrix and OSF1) seem to support both if used independently. +;;; The 17f version of this seems a bit confused wrt the conditionals. +;;; Please check these defs for your system. + +;;; TSM: from what I can tell looking at the 17f definition, my guess is that it +;;; was originally a termio for sunos (nonsolaris) (because it had the c-line +;;; member for sunos only), and then was mutated into the termios definition for +;;; later systems. The definition here is definitely not an IRIX termio because +;;; it doesn't have c-line. In any case, the functions tcgetattr, etc., +;;; definitely take a termios, and termios seems to be the more standard +;;; standard now, so my suggestion is to just go with termios and forget about +;;; termio. Note the SVID says NCCS not NCC for the constant here, so I've +;;; changed it (which means you need to bootstrap it to avoid a reader error). + +;;; On top of all that, SGI decided to change the termios structure on irix +;;; 6.[34] (but NOT 6.2), left the old routines named the same in the library, +;;; but introduced static functions in termios.h to redirect new calls to the +;;; new library--which means it's important not to #include termios.h before +;;; undefineds.h when building lisp. + +(defconstant +NCCS+ + #+hpux 16 + #+irix 23 + #+(or linux solaris) 19 + #+(or bsd osf1) 20 + #+(and sunos (not svr4)) 17 + _N"Size of control character vector.") + +(def-alien-type nil + (struct termios + (c-iflag unsigned-int) + (c-oflag unsigned-int) + (c-cflag unsigned-int) + (c-lflag unsigned-int) + #+(or linux hpux (and sunos (not svr4))) + (c-reserved #-(or linux (and sunos (not svr4))) unsigned-int + #+(or linux (and sunos (not svr4))) unsigned-char) + (c-cc (array unsigned-char #.+NCCS+)) + #+(or bsd osf1) (c-ispeed unsigned-int) + #+(or bsd osf1) (c-ospeed unsigned-int))) + +;;; From sys/dir.h +;;; +;;; (For Solaris, this is not struct direct, but struct dirent!) +#-bsd +(def-alien-type nil + (struct direct + #+(and sunos (not svr4)) (d-off long) ; offset of next disk directory entry + (d-ino ino-t); inode number of entry + #+(or linux svr4) (d-off long) + (d-reclen unsigned-short) ; length of this record + #-(or linux svr4) + (d-namlen unsigned-short) ; length of string in d-name + (d-name (array char 256)))) ; name must be no longer than this + +#+(and bsd (not netbsd)) +(def-alien-type nil + (struct direct + (d-fileno unsigned-long) + (d-reclen unsigned-short) + (d-type unsigned-char) + (d-namlen unsigned-char) ; length of string in d-name + (d-name (array char 256)))) ; name must be no longer than this + +#+netbsd +(def-alien-type nil + (struct direct + (d-fileno ino-t) + (d-reclen unsigned-short) + (d-namlen unsigned-short) + (d-type unsigned-char) + (d-name (array char 512)))) + +#+(or linux svr4) +; High-res time. Actually posix definition under svr4 name. +(def-alien-type nil + (struct timestruc-t + (tv-sec time-t) + (tv-nsec long))) + + +;;; Large file support for Solaris. Define some of the 64-bit types +;;; we need. Unlike unix-glibc's large file support, Solaris's +;;; version is a little simpler because all of the 64-bit versions of +;;; the functions actually exist as functions. So instead of calling +;;; the 32-bit versions of the functions, we call the 64-bit versions. +;;; +;;; These functions are: creat64, open64, truncate64, ftruncate64, +;;; stat64, lstat64, fstat64, readdir64. +;;; +;;; There are also some new structures for large file support: +;;; dirent64, stat64. +;;; +;;; FIXME: We should abstract this better, but I (rtoy) don't have any +;;; other system to test this out on, so it's a Solaris hack for now. +#+solaris +(progn + (deftype file-offset64 () '(signed-byte 64)) + (def-alien-type off64-t int64-t) + (def-alien-type ino64-t u-int64-t) + (def-alien-type blkcnt64-t u-int64-t)) + +;;; The 64-bit version of struct dirent. +#+solaris +(def-alien-type nil + (struct dirent64 + (d-ino ino64-t); inode number of entry + (d-off off64-t) ; offset of next disk directory entry + (d-reclen unsigned-short) ; length of this record + (d-name (array char 256)))) ; name must be no longer than this + + +#+(and bsd (not netbsd)) +(def-alien-type nil + (struct stat + (st-dev dev-t) + (st-ino ino-t) + (st-mode mode-t) + (st-nlink nlink-t) + (st-uid uid-t) + (st-gid gid-t) + (st-rdev dev-t) + (st-atime (struct timespec-t)) + (st-mtime (struct timespec-t)) + (st-ctime (struct timespec-t)) + (st-size off-t) + (st-blocks off-t) + (st-blksize unsigned-long) + (st-flags unsigned-long) + (st-gen unsigned-long) + (st-lspare long) + (st-qspare (array long 4)))) + +#+(or linux svr4) +(def-alien-type nil + (struct stat + (st-dev dev-t) + (st-pad1 #-linux (array long 3) #+linux unsigned-short) + (st-ino ino-t) + (st-mode #-linux unsigned-long #+linux unsigned-short) + (st-nlink #-linux short #+linux unsigned-short) + (st-uid #-linux uid-t #+linux unsigned-short) + (st-gid #-linux gid-t #+linux unsigned-short) + (st-rdev dev-t) + (st-pad2 #-linux (array long 2) #+linux unsigned-short) + (st-size off-t) + #-linux (st-pad3 long) + #+linux (st-blksize unsigned-long) + #+linux (st-blocks unsigned-long) + #-linux (st-atime (struct timestruc-t)) + #+linux (st-atime unsigned-long) + #+linux (unused-1 unsigned-long) + #-linux (st-mtime (struct timestruc-t)) + #+linux (st-mtime unsigned-long) + #+linux (unused-2 unsigned-long) + #-linux (st-ctime (struct timestruc-t)) + #+linux (st-ctime unsigned-long) + #+linux (unused-3 unsigned-long) + #+linux (unused-4 unsigned-long) + #+linux (unused-5 unsigned-long) + #-linux(st-blksize long) + #-linux (st-blocks long) + #-linux (st-fstype (array char 16)) + #-linux (st-pad4 (array long 8)))) + +;;; 64-bit stat for Solaris +#+solaris +(def-alien-type nil + (struct stat64 + (st-dev dev-t) + (st-pad1 (array long 3)) ; Pad so ino is 64-bit aligned + (st-ino ino64-t) + (st-mode unsigned-long) + (st-nlink short) + (st-uid uid-t) + (st-gid gid-t) + (st-rdev dev-t) + (st-pad2 (array long 3)) ; Pad so size is 64-bit aligned + (st-size off64-t) + (st-atime (struct timestruc-t)) + (st-mtime (struct timestruc-t)) + (st-ctime (struct timestruc-t)) + (st-blksize long) + (st-pad3 (array long 1)) ; Pad so blocks is 64-bit aligned + (st-blocks blkcnt64-t) + (st-fstype (array char 16)) + (st-pad4 (array long 8)))) + +#+netbsd +(def-alien-type nil + (struct stat + (st-dev dev-t) + (st-mode mode-t) + (st-ino ino-t) + (st-nlink nlink-t) + (st-uid uid-t) + (st-gid gid-t) + (st-rdev dev-t) + (st-atime (struct timespec-t)) + (st-mtime (struct timespec-t)) + (st-ctime (struct timespec-t)) + (st-birthtime (struct timespec-t)) + (st-size off-t) + (st-blocks off-t) + (st-blksize long) + (st-flags unsigned-long) + (st-gen unsigned-long) + (st-spare (array unsigned-long 2)))) + +(defmacro extract-stat-results (buf) + `(values T + (slot ,buf 'st-dev) + (slot ,buf 'st-ino) + (slot ,buf 'st-mode) + (slot ,buf 'st-nlink) (slot ,buf 'st-uid) (slot ,buf 'st-gid) (slot ,buf 'st-rdev) @@ -2246,6 +1341,24 @@ fd (addr buf)))) )
+(def-alien-type nil + (struct rusage + (ru-utime (struct timeval)) ; user time used + (ru-stime (struct timeval)) ; system time used. + (ru-maxrss long) + (ru-ixrss long) ; integral sharded memory size + (ru-idrss long) ; integral unsharded data " + (ru-isrss long) ; integral unsharded stack " + (ru-minflt long) ; page reclaims + (ru-majflt long) ; page faults + (ru-nswap long) ; swaps + (ru-inblock long) ; block input operations + (ru-oublock long) ; block output operations + (ru-msgsnd long) ; messages sent + (ru-msgrcv long) ; messages received + (ru-nsignals long) ; signals received + (ru-nvcsw long) ; voluntary context switches + (ru-nivcsw long))) ; involuntary "
(defconstant rusage_self 0 _N"The calling process.") (defconstant rusage_children -1 _N"Terminated child processes.") @@ -2295,706 +1408,695 @@ (slot usage 'ru-nivcsw)) who (addr usage))))
-;;; Getrusage is not provided in the C library on Solaris 2.4, and is -;;; rather slow on later versions so the "times" system call is -;;; provided. -#+(and sparc svr4) -(progn -(def-alien-type nil - (struct tms - (tms-utime #-alpha long #+alpha int) ; user time used - (tms-stime #-alpha long #+alpha int) ; system time used. - (tms-cutime #-alpha long #+alpha int) ; user time, children - (tms-cstime #-alpha long #+alpha int))) ; system time, children +;;;; Support routines for dealing with unix pathnames.
-(declaim (inline unix-times)) -(defun unix-times () - _N"Unix-times returns information about the cpu time usage of the process - and its children." - (with-alien ((usage (struct tms))) - (alien-funcall (extern-alien "times" (function int (* (struct tms)))) - (addr usage)) - (values t - (slot usage 'tms-utime) - (slot usage 'tms-stime) - (slot usage 'tms-cutime) - (slot usage 'tms-cstime)))) -) ; end progn +(defconstant s-ifmt #o0170000) +(defconstant s-ifdir #o0040000) +(defconstant s-ifchr #o0020000) +#+linux (defconstant s-ififo #x0010000) +(defconstant s-ifblk #o0060000) +(defconstant s-ifreg #o0100000) +(defconstant s-iflnk #o0120000) +(defconstant s-ifsock #o0140000) +(defconstant s-isuid #o0004000) +(defconstant s-isgid #o0002000) +(defconstant s-isvtx #o0001000) +(defconstant s-iread #o0000400) +(defconstant s-iwrite #o0000200) +(defconstant s-iexec #o0000100)
-;; Requires call to tzset() in main. -;; Don't use this now: we -#+(or linux svr4) +(defun unix-file-kind (name &optional check-for-links) + _N"Returns either :file, :directory, :link, :special, or NIL." + (declare (simple-string name)) + (multiple-value-bind (res dev ino mode) + (if check-for-links + (unix-lstat name) + (unix-stat name)) + (declare (type (or fixnum null) mode) + (ignore dev ino)) + (when res + (let ((kind (logand mode s-ifmt))) + (cond ((eql kind s-ifdir) :directory) + ((eql kind s-ifreg) :file) + ((eql kind s-iflnk) :link) + (t :special)))))) + +(defun unix-maybe-prepend-current-directory (name) + (declare (simple-string name)) + (if (and (> (length name) 0) (char= (schar name 0) #/)) + name + (multiple-value-bind (win dir) (unix-current-directory) + (if win + (concatenate 'simple-string dir "/" name) + name)))) + +(defun unix-resolve-links (pathname) + _N"Returns the pathname with all symbolic links resolved." + (declare (simple-string pathname)) + (let ((len (length pathname)) + (pending pathname)) + (declare (fixnum len) (simple-string pending)) + (if (zerop len) + pathname + (let ((result (make-string 100 :initial-element (code-char 0))) + (fill-ptr 0) + (name-start 0)) + (loop + (let* ((name-end (or (position #/ pending :start name-start) len)) + (new-fill-ptr (+ fill-ptr (- name-end name-start)))) + ;; grow the result string, if necessary. the ">=" (instead of + ;; using ">") allows for the trailing "/" if we find this + ;; component is a directory. + (when (>= new-fill-ptr (length result)) + (let ((longer (make-string (* 3 (length result)) + :initial-element (code-char 0)))) + (replace longer result :end1 fill-ptr) + (setq result longer))) + (replace result pending + :start1 fill-ptr + :end1 new-fill-ptr + :start2 name-start + :end2 name-end) + (let ((kind (unix-file-kind (if (zerop name-end) "/" result) t))) + (unless kind (return nil)) + (cond ((eq kind :link) + (multiple-value-bind (link err) (unix-readlink result) + (unless link + (error (intl:gettext "Error reading link ~S: ~S") + (subseq result 0 fill-ptr) + (get-unix-error-msg err))) + (cond ((or (zerop (length link)) + (char/= (schar link 0) #/)) + ;; It's a relative link + (fill result (code-char 0) + :start fill-ptr + :end new-fill-ptr)) + ((string= result "/../" :end1 4) + ;; It's across the super-root. + (let ((slash (or (position #/ result :start 4) + 0))) + (fill result (code-char 0) + :start slash + :end new-fill-ptr) + (setf fill-ptr slash))) + (t + ;; It's absolute. + (and (> (length link) 0) + (char= (schar link 0) #/)) + (fill result (code-char 0) :end new-fill-ptr) + (setf fill-ptr 0))) + (setf pending + (if (= name-end len) + link + (concatenate 'simple-string + link + (subseq pending name-end)))) + (setf len (length pending)) + (setf name-start 0))) + ((= name-end len) + (when (eq kind :directory) + (setf (schar result new-fill-ptr) #/) + (incf new-fill-ptr)) + (return (subseq result 0 new-fill-ptr))) + ((eq kind :directory) + (setf (schar result new-fill-ptr) #/) + (setf fill-ptr (1+ new-fill-ptr)) + (setf name-start (1+ name-end))) + (t + (return nil)))))))))) + +(defun unix-simplify-pathname (src) + (declare (simple-string src)) + (let* ((src-len (length src)) + (dst (make-string src-len)) + (dst-len 0) + (dots 0) + (last-slash nil)) + (macrolet ((deposit (char) + `(progn + (setf (schar dst dst-len) ,char) + (incf dst-len)))) + (dotimes (src-index src-len) + (let ((char (schar src src-index))) + (cond ((char= char #.) + (when dots + (incf dots)) + (deposit char)) + ((char= char #/) + (case dots + (0 + ;; Either ``/...' or ``...//...' + (unless last-slash + (setf last-slash dst-len) + (deposit char))) + (1 + ;; Either ``./...'' or ``..././...'' + (decf dst-len)) + (2 + ;; We've found .. + (cond + ((and last-slash (not (zerop last-slash))) + ;; There is something before this .. + (let ((prev-prev-slash + (position #/ dst :end last-slash :from-end t))) + (cond ((and (= (+ (or prev-prev-slash 0) 2) + last-slash) + (char= (schar dst (- last-slash 2)) #.) + (char= (schar dst (1- last-slash)) #.)) + ;; The something before this .. is another .. + (deposit char) + (setf last-slash dst-len)) + (t + ;; The something is some random dir. + (setf dst-len + (if prev-prev-slash + (1+ prev-prev-slash) + 0)) + (setf last-slash prev-prev-slash))))) + (t + ;; There is nothing before this .., so we need to keep it + (setf last-slash dst-len) + (deposit char)))) + (t + ;; Something other than a dot between slashes. + (setf last-slash dst-len) + (deposit char))) + (setf dots 0)) + (t + (setf dots nil) + (setf (schar dst dst-len) char) + (incf dst-len)))))) + (when (and last-slash (not (zerop last-slash))) + (case dots + (1 + ;; We've got ``foobar/.'' + (decf dst-len)) + (2 + ;; We've got ``foobar/..'' + (unless (and (>= last-slash 2) + (char= (schar dst (1- last-slash)) #.) + (char= (schar dst (- last-slash 2)) #.) + (or (= last-slash 2) + (char= (schar dst (- last-slash 3)) #/))) + (let ((prev-prev-slash + (position #/ dst :end last-slash :from-end t))) + (if prev-prev-slash + (setf dst-len (1+ prev-prev-slash)) + (return-from unix-simplify-pathname "./"))))))) + (cond ((zerop dst-len) + "./") + ((= dst-len src-len) + dst) + (t + (subseq dst 0 dst-len))))) + +;;;; Errno stuff. + +(eval-when (compile eval) + +(defparameter *compiler-unix-errors* nil) + +(defmacro def-unix-error (name number description) + `(progn + (eval-when (compile eval) + (push (cons ,number ,description) *compiler-unix-errors*)) + (defconstant ,name ,number ,description) + (export ',name))) + +(defmacro emit-unix-errors () + (let* ((max (apply #'max (mapcar #'car *compiler-unix-errors*))) + (array (make-array (1+ max) :initial-element nil))) + (dolist (error *compiler-unix-errors*) + (setf (svref array (car error)) (cdr error))) + `(progn + (defvar *unix-errors* ',array) + (declaim (simple-vector *unix-errors*))))) + +) ;eval-when + +;;; +;;; From <errno.h> +;;; +(def-unix-error ESUCCESS 0 _N"Successful") +(def-unix-error EPERM 1 _N"Operation not permitted") +(def-unix-error ENOENT 2 _N"No such file or directory") +(def-unix-error ESRCH 3 _N"No such process") +(def-unix-error EINTR 4 _N"Interrupted system call") +(def-unix-error EIO 5 _N"I/O error") +(def-unix-error ENXIO 6 _N"Device not configured") +(def-unix-error E2BIG 7 _N"Arg list too long") +(def-unix-error ENOEXEC 8 _N"Exec format error") +(def-unix-error EBADF 9 _N"Bad file descriptor") +(def-unix-error ECHILD 10 _N"No child process") +#+bsd(def-unix-error EDEADLK 11 _N"Resource deadlock avoided") +#-bsd(def-unix-error EAGAIN 11 #-linux _N"No more processes" #+linux _N"Try again") +(def-unix-error ENOMEM 12 _N"Out of memory") +(def-unix-error EACCES 13 _N"Permission denied") +(def-unix-error EFAULT 14 _N"Bad address") +(def-unix-error ENOTBLK 15 _N"Block device required") +(def-unix-error EBUSY 16 _N"Device or resource busy") +(def-unix-error EEXIST 17 _N"File exists") +(def-unix-error EXDEV 18 _N"Cross-device link") +(def-unix-error ENODEV 19 _N"No such device") +(def-unix-error ENOTDIR 20 _N"Not a director") +(def-unix-error EISDIR 21 _N"Is a directory") +(def-unix-error EINVAL 22 _N"Invalid argument") +(def-unix-error ENFILE 23 _N"File table overflow") +(def-unix-error EMFILE 24 _N"Too many open files") +(def-unix-error ENOTTY 25 _N"Inappropriate ioctl for device") +(def-unix-error ETXTBSY 26 _N"Text file busy") +(def-unix-error EFBIG 27 _N"File too large") +(def-unix-error ENOSPC 28 _N"No space left on device") +(def-unix-error ESPIPE 29 _N"Illegal seek") +(def-unix-error EROFS 30 _N"Read-only file system") +(def-unix-error EMLINK 31 _N"Too many links") +(def-unix-error EPIPE 32 _N"Broken pipe") +;;; +;;; Math +(def-unix-error EDOM 33 _N"Numerical argument out of domain") +(def-unix-error ERANGE 34 #-linux _N"Result too large" #+linux _N"Math result not representable") +;;; +#-(or linux svr4) (progn - (def-alien-variable ("daylight" unix-daylight) int) - (def-alien-variable ("timezone" unix-timezone) time-t) - (def-alien-variable ("altzone" unix-altzone) time-t) - #-irix (def-alien-variable ("tzname" unix-tzname) (array c-string 2)) - #+irix (defvar unix-tzname-addr nil) - #+irix (pushnew #'(lambda () (setq unix-tzname-addr nil)) - ext:*after-save-initializations*) - #+irix (declaim (notinline fakeout-compiler)) - #+irix (defun fakeout-compiler (name dst) - (unless unix-tzname-addr - (setf unix-tzname-addr (system:foreign-symbol-address - name - :flavor :data))) - (deref (sap-alien unix-tzname-addr (array c-string 2)) dst)) - (def-alien-routine get-timezone c-call:void - (when c-call:long :in) - (minutes-west c-call:int :out) - (daylight-savings-p alien:boolean :out)) - (defun unix-get-minutes-west (secs) - (multiple-value-bind (ignore minutes dst) (get-timezone secs) - (declare (ignore ignore) (ignore dst)) - (values minutes)) - ) - (defun unix-get-timezone (secs) - (multiple-value-bind (ignore minutes dst) (get-timezone secs) - (declare (ignore ignore) (ignore minutes)) - (values #-irix (deref unix-tzname (if dst 1 0)) - #+irix (fakeout-compiler "tzname" (if dst 1 0))) - ) ) +;;; non-blocking and interrupt i/o +(def-unix-error EWOULDBLOCK 35 _N"Operation would block") +#-bsd(def-unix-error EDEADLK 35 _N"Operation would block") ; Ditto +#+bsd(def-unix-error EAGAIN 35 _N"Resource temporarily unavailable") +(def-unix-error EINPROGRESS 36 _N"Operation now in progress") +(def-unix-error EALREADY 37 _N"Operation already in progress") +;;; +;;; ipc/network software +(def-unix-error ENOTSOCK 38 _N"Socket operation on non-socket") +(def-unix-error EDESTADDRREQ 39 _N"Destination address required") +(def-unix-error EMSGSIZE 40 _N"Message too long") +(def-unix-error EPROTOTYPE 41 _N"Protocol wrong type for socket") +(def-unix-error ENOPROTOOPT 42 _N"Protocol not available") +(def-unix-error EPROTONOSUPPORT 43 _N"Protocol not supported") +(def-unix-error ESOCKTNOSUPPORT 44 _N"Socket type not supported") +(def-unix-error EOPNOTSUPP 45 _N"Operation not supported on socket") +(def-unix-error EPFNOSUPPORT 46 _N"Protocol family not supported") +(def-unix-error EAFNOSUPPORT 47 _N"Address family not supported by protocol family") +(def-unix-error EADDRINUSE 48 _N"Address already in use") +(def-unix-error EADDRNOTAVAIL 49 _N"Can't assign requested address") +;;; +;;; operational errors +(def-unix-error ENETDOWN 50 _N"Network is down") +(def-unix-error ENETUNREACH 51 _N"Network is unreachable") +(def-unix-error ENETRESET 52 _N"Network dropped connection on reset") +(def-unix-error ECONNABORTED 53 _N"Software caused connection abort") +(def-unix-error ECONNRESET 54 _N"Connection reset by peer") +(def-unix-error ENOBUFS 55 _N"No buffer space available") +(def-unix-error EISCONN 56 _N"Socket is already connected") +(def-unix-error ENOTCONN 57 _N"Socket is not connected") +(def-unix-error ESHUTDOWN 58 _N"Can't send after socket shutdown") +(def-unix-error ETOOMANYREFS 59 _N"Too many references: can't splice") +(def-unix-error ETIMEDOUT 60 _N"Connection timed out") +(def-unix-error ECONNREFUSED 61 _N"Connection refused") +;;; +(def-unix-error ELOOP 62 _N"Too many levels of symbolic links") +(def-unix-error ENAMETOOLONG 63 _N"File name too long") +;;; +(def-unix-error EHOSTDOWN 64 _N"Host is down") +(def-unix-error EHOSTUNREACH 65 _N"No route to host") +(def-unix-error ENOTEMPTY 66 _N"Directory not empty") +;;; +;;; quotas & resource +(def-unix-error EPROCLIM 67 _N"Too many processes") +(def-unix-error EUSERS 68 _N"Too many users") +(def-unix-error EDQUOT 69 _N"Disc quota exceeded") +;;; +;;; CMU RFS +(def-unix-error ELOCAL 126 _N"namei should continue locally") +(def-unix-error EREMOTE 127 _N"namei was handled remotely") +;;; +;;; VICE +(def-unix-error EVICEERR 70 _N"Remote file system error _N") +(def-unix-error EVICEOP 71 _N"syscall was handled by Vice") +) +#+svr4 +(progn +(def-unix-error ENOMSG 35 _N"No message of desired type") +(def-unix-error EIDRM 36 _N"Identifier removed") +(def-unix-error ECHRNG 37 _N"Channel number out of range") +(def-unix-error EL2NSYNC 38 _N"Level 2 not synchronized") +(def-unix-error EL3HLT 39 _N"Level 3 halted") +(def-unix-error EL3RST 40 _N"Level 3 reset") +(def-unix-error ELNRNG 41 _N"Link number out of range") +(def-unix-error EUNATCH 42 _N"Protocol driver not attached") +(def-unix-error ENOCSI 43 _N"No CSI structure available") +(def-unix-error EL2HLT 44 _N"Level 2 halted") +(def-unix-error EDEADLK 45 _N"Deadlock situation detected/avoided") +(def-unix-error ENOLCK 46 _N"No record locks available") +(def-unix-error ECANCELED 47 _N"Error 47") +(def-unix-error ENOTSUP 48 _N"Error 48") +(def-unix-error EBADE 50 _N"Bad exchange descriptor") +(def-unix-error EBADR 51 _N"Bad request descriptor") +(def-unix-error EXFULL 52 _N"Message tables full") +(def-unix-error ENOANO 53 _N"Anode table overflow") +(def-unix-error EBADRQC 54 _N"Bad request code") +(def-unix-error EBADSLT 55 _N"Invalid slot") +(def-unix-error EDEADLOCK 56 _N"File locking deadlock") +(def-unix-error EBFONT 57 _N"Bad font file format") +(def-unix-error ENOSTR 60 _N"Not a stream device") +(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 stream 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 74 _N"Multihop attempted") +(def-unix-error EBADMSG 77 _N"Not a data message") +(def-unix-error ENAMETOOLONG 78 _N"File name too long") +(def-unix-error EOVERFLOW 79 _N"Value too large for defined data type") +(def-unix-error ENOTUNIQ 80 _N"Name not unique on network") +(def-unix-error EBADFD 81 _N"File descriptor in bad state") +(def-unix-error EREMCHG 82 _N"Remote address changed") +(def-unix-error ELIBACC 83 _N"Can not access a needed shared library") +(def-unix-error ELIBBAD 84 _N"Accessing a corrupted shared library") +(def-unix-error ELIBSCN 85 _N".lib section in a.out corrupted") +(def-unix-error ELIBMAX 86 _N"Attempting to link in more shared libraries than system limit") +(def-unix-error ELIBEXEC 87 _N"Can not exec a shared library directly") +(def-unix-error EILSEQ 88 _N"Error 88") +(def-unix-error ENOSYS 89 _N"Operation not applicable") +(def-unix-error ELOOP 90 _N"Number of symbolic links encountered during path name traversal exceeds MAXSYMLINKS") +(def-unix-error ERESTART 91 _N"Error 91") +(def-unix-error ESTRPIPE 92 _N"Error 92") +(def-unix-error ENOTEMPTY 93 _N"Directory not empty") +(def-unix-error EUSERS 94 _N"Too many users") +(def-unix-error ENOTSOCK 95 _N"Socket operation on non-socket") +(def-unix-error EDESTADDRREQ 96 _N"Destination address required") +(def-unix-error EMSGSIZE 97 _N"Message too long") +(def-unix-error EPROTOTYPE 98 _N"Protocol wrong type for socket") +(def-unix-error ENOPROTOOPT 99 _N"Option not supported by protocol") +(def-unix-error EPROTONOSUPPORT 120 _N"Protocol not supported") +(def-unix-error ESOCKTNOSUPPORT 121 _N"Socket type not supported") +(def-unix-error EOPNOTSUPP 122 _N"Operation not supported on transport endpoint") +(def-unix-error EPFNOSUPPORT 123 _N"Protocol family not supported") +(def-unix-error EAFNOSUPPORT 124 _N"Address family not supported by protocol family") +(def-unix-error EADDRINUSE 125 _N"Address already in use") +(def-unix-error EADDRNOTAVAIL 126 _N"Cannot assign requested address") +(def-unix-error ENETDOWN 127 _N"Network is down") +(def-unix-error ENETUNREACH 128 _N"Network is unreachable") +(def-unix-error ENETRESET 129 _N"Network dropped connection because of reset") +(def-unix-error ECONNABORTED 130 _N"Software caused connection abort") +(def-unix-error ECONNRESET 131 _N"Connection reset by peer") +(def-unix-error ENOBUFS 132 _N"No buffer space available") +(def-unix-error EISCONN 133 _N"Transport endpoint is already connected") +(def-unix-error ENOTCONN 134 _N"Transport endpoint is not connected") +(def-unix-error ESHUTDOWN 143 _N"Cannot send after socket shutdown") +(def-unix-error ETOOMANYREFS 144 _N"Too many references: cannot splice") +(def-unix-error ETIMEDOUT 145 _N"Connection timed out") +(def-unix-error ECONNREFUSED 146 _N"Connection refused") +(def-unix-error EHOSTDOWN 147 _N"Host is down") +(def-unix-error EHOSTUNREACH 148 _N"No route to host") +(def-unix-error EWOULDBLOCK 11 _N"Resource temporarily unavailable") +(def-unix-error EALREADY 149 _N"Operation already in progress") +(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") ) -(declaim (inline unix-gettimeofday)) -(defun unix-gettimeofday () - _N"If it works, unix-gettimeofday returns 5 values: T, the seconds and - microseconds of the current time of day, the timezone (in minutes west - of Greenwich), and a daylight-savings flag. If it doesn't work, it - returns NIL and the errno." - (with-alien ((tv (struct timeval)) - #-(or svr4 netbsd) (tz (struct timezone))) - (syscall* (#-netbsd "gettimeofday" - #+netbsd "__gettimeofday50" - (* (struct timeval)) #-svr4 (* (struct timezone))) - (values T - (slot tv 'tv-sec) - (slot tv 'tv-usec) - #-(or svr4 netbsd) (slot tz 'tz-minuteswest) - #+svr4 (unix-get-minutes-west (slot tv 'tv-sec)) - #-(or svr4 netbsd) (slot tz 'tz-dsttime) - #+svr4 (unix-get-timezone (slot tv 'tv-sec)) - ) - (addr tv) - #-(or svr4 netbsd) (addr tz) #+netbsd nil))) - -;;; Unix-utimes changes the accessed and updated times on UNIX -;;; files. The first argument is the filename (a string) and -;;; the second argument is a list of the 4 times- accessed and -;;; updated seconds and microseconds. - -#-hpux -(defun unix-utimes (file atime-sec atime-usec mtime-sec mtime-usec) - _N"Unix-utimes sets the 'last-accessed' and 'last-updated' - times on a specified file. NIL and an error number is - returned if the call is unsuccessful." - (declare (type unix-pathname file) - (type (alien unsigned-long) - atime-sec atime-usec - mtime-sec mtime-usec)) - (with-alien ((tvp (array (struct timeval) 2))) - (setf (slot (deref tvp 0) 'tv-sec) atime-sec) - (setf (slot (deref tvp 0) 'tv-usec) atime-usec) - (setf (slot (deref tvp 1) 'tv-sec) mtime-sec) - (setf (slot (deref tvp 1) 'tv-usec) mtime-usec) - (void-syscall (#-netbsd "utimes" #+netbsd "__utimes50" c-string (* (struct timeval))) - file - (cast tvp (* (struct timeval)))))) - -;;; Unix-setreuid sets the real and effective user-id's of the current -;;; process to the arguments "ruid" and "euid", respectively. Usage is -;;; restricted for anyone but the super-user. Setting either "ruid" or -;;; "euid" to -1 makes the system use the current id instead. - -#-(or svr4 hpux) -(defun unix-setreuid (ruid euid) - _N"Unix-setreuid sets the real and effective user-id's of the current - process to the specified ones. NIL and an error number is returned - if the call fails." - (void-syscall ("setreuid" int int) ruid euid)) - -;;; Unix-setregid sets the real and effective group-id's of the current -;;; process to the arguments "rgid" and "egid", respectively. Usage is -;;; restricted for anyone but the super-user. Setting either "rgid" or -;;; "egid" to -1 makes the system use the current id instead. - -#-(or svr4 hpux) -(defun unix-setregid (rgid egid) - _N"Unix-setregid sets the real and effective group-id's of the current - process process to the specified ones. NIL and an error number is - returned if the call fails." - (void-syscall ("setregid" int int) rgid egid)) - -(def-alien-routine ("getpid" unix-getpid) int - _N"Unix-getpid returns the process-id of the current process.") - -(def-alien-routine ("getppid" unix-getppid) int - _N"Unix-getppid returns the process-id of the parent of the current process.") - -(def-alien-routine ("getgid" unix-getgid) int - _N"Unix-getgid returns the real group-id of the current process.") - -(def-alien-routine ("getegid" unix-getegid) int - _N"Unix-getegid returns the effective group-id of the current process.") - -;;; Unix-getpgrp returns the group-id associated with the -;;; current process. - -(defun unix-getpgrp () - _N"Unix-getpgrp returns the group-id of the calling process." - (int-syscall ("getpgrp"))) - -;;; Unix-setpgid sets the group-id of the process specified by -;;; "pid" to the value of "pgrp". The process must either have -;;; the same effective user-id or be a super-user process. - -;;; setpgrp(int int)[freebsd] is identical to setpgid and is retained -;;; for backward compatibility. setpgrp(void)[solaris] is being phased -;;; out in favor of setsid(). - -(defun unix-setpgrp (pid pgrp) - _N"Unix-setpgrp sets the process group on the process pid to - pgrp. NIL and an error number are returned upon failure." - (void-syscall (#-svr4 "setpgrp" #+svr4 "setpgid" int int) pid pgrp)) - -(defun unix-setpgid (pid pgrp) - _N"Unix-setpgid sets the process group of the process pid to - pgrp. If pgid is equal to pid, the process becomes a process - group leader. NIL and an error number are returned upon failure." - (void-syscall ("setpgid" int int) pid pgrp)) - -(def-alien-routine ("getuid" unix-getuid) int - _N"Unix-getuid returns the real user-id associated with the - current process.") - -;;; Unix-getpagesize returns the number of bytes in the system page. - -(defun unix-getpagesize () - _N"Unix-getpagesize returns the number of bytes in a system page." - (int-syscall ("getpagesize"))) - -(defun unix-gethostname () - _N"Unix-gethostname returns the name of the host machine as a string." - (with-alien ((buf (array char 256))) - (syscall* ("gethostname" (* char) int) - (cast buf c-string) - (cast buf (* char)) 256))) - -(def-alien-routine ("gethostid" unix-gethostid) unsigned-long - _N"Unix-gethostid returns a 32-bit integer which provides unique - identification for the host machine.") - -(defun unix-fork () - _N"Executes the unix fork system call. Returns 0 in the child and the pid - of the child in the parent if it works, or NIL and an error number if it - doesn't work." - (int-syscall ("fork"))) - -;; Environment manipulation; man getenv(3) -(def-alien-routine ("getenv" unix-getenv) c-call:c-string - (name c-call:c-string) - _N"Get the value of the environment variable named Name. If no such - variable exists, Nil is returned.") - -;; This doesn't exist in Solaris 8 but does exist in Solaris 10. -(def-alien-routine ("setenv" unix-setenv) c-call:int - (name c-call:c-string) - (value c-call:c-string) - (overwrite c-call:int) - _N"Adds the environment variable named Name to the environment with - the given Value if Name does not already exist. If Name does exist, - the value is changed to Value if Overwrite is non-zero. Otherwise, - the value is not changed.") - - -(def-alien-routine ("putenv" unix-putenv) c-call:int - (name-value c-call:c-string) - _N"Adds or changes the environment. Name-value must be a string of - the form "name=value". If the name does not exist, it is added. - If name does exist, the value is updated to the given value.") - -;; This doesn't exist in Solaris 8 but does exist in Solaris 10. -(def-alien-routine ("unsetenv" unix-unsetenv) c-call:int - (name c-call:c-string) - _N"Removes the variable Name from the environment") - - -;;; Operations on Unix Directories. - -(export '(open-dir read-dir close-dir)) - -(defstruct (%directory - (:conc-name directory-) - (:constructor make-directory) - (:print-function %print-directory)) - name - (dir-struct (required-argument) :type system-area-pointer)) - -(defun %print-directory (dir stream depth) - (declare (ignore depth)) - (format stream "#<Directory ~S>" (directory-name dir))) - -(defun open-dir (pathname) - (declare (type unix-pathname pathname)) - (when (string= pathname "") - (setf pathname ".")) - (let ((kind (unix-file-kind pathname))) - (case kind - (:directory - (let ((dir-struct - (alien-funcall (extern-alien "opendir" - (function system-area-pointer - c-string)) - (%name->file pathname)))) - (if (zerop (sap-int dir-struct)) - (values nil (unix-errno)) - (make-directory :name pathname :dir-struct dir-struct)))) - ((nil) - (values nil enoent)) - (t - (values nil enotdir))))) - -#-(and bsd (not solaris)) -(defun read-dir (dir) - (declare (type %directory dir)) - (let ((daddr (alien-funcall (extern-alien "readdir" - (function system-area-pointer - system-area-pointer)) - (directory-dir-struct dir)))) - (declare (type system-area-pointer daddr)) - (if (zerop (sap-int daddr)) - nil - (with-alien ((direct (* (struct direct)) daddr)) - #-(or linux svr4) - (let ((nlen (slot direct 'd-namlen)) - (ino (slot direct 'd-ino))) - (declare (type (unsigned-byte 16) nlen)) - (let ((string (make-string nlen))) - #-unicode - (kernel:copy-from-system-area - (alien-sap (addr (slot direct 'd-name))) 0 - string (* vm:vector-data-offset vm:word-bits) - (* nlen vm:byte-bits)) - #+unicode - (let ((sap (alien-sap (addr (slot direct 'd-name))))) - (dotimes (k nlen) - (setf (aref string k) - (code-char (sap-ref-8 sap k))))) - (values (%file->name string) ino))) - #+(or linux svr4) - (values (%file->name (cast (slot direct 'd-name) c-string)) - (slot direct 'd-ino)))))) - -;;; 64-bit readdir for Solaris -#+solaris -(defun read-dir (dir) - (declare (type %directory dir)) - (let ((daddr (alien-funcall (extern-alien "readdir64" - (function system-area-pointer - system-area-pointer)) - (directory-dir-struct dir)))) - (declare (type system-area-pointer daddr)) - (if (zerop (sap-int daddr)) - nil - (with-alien ((direct (* (struct dirent64)) daddr)) - #-(or linux svr4) - (let ((nlen (slot direct 'd-namlen)) - (ino (slot direct 'd-ino))) - (declare (type (unsigned-byte 16) nlen)) - (let ((string (make-string nlen))) - #-unicode - (kernel:copy-from-system-area - (alien-sap (addr (slot direct 'd-name))) 0 - string (* vm:vector-data-offset vm:word-bits) - (* nlen vm:byte-bits)) - #+unicode - (let ((sap (alien-sap (addr (slot direct 'd-name))))) - (dotimes (k nlen) - (setf (aref string k) - (code-char (sap-ref-8 sap k))))) - (values (%file->name string) ino))) - #+(or linux svr4) - (values (%file->name (cast (slot direct 'd-name) c-string)) - (slot direct 'd-ino))))))
-#+(and bsd (not solaris)) -(defun read-dir (dir) - (declare (type %directory dir)) - (let ((daddr (alien-funcall (extern-alien "readdir" - (function system-area-pointer - system-area-pointer)) - (directory-dir-struct dir)))) - (declare (type system-area-pointer daddr)) - (if (zerop (sap-int daddr)) - nil - (with-alien ((direct (* (struct direct)) daddr)) - (let ((nlen (slot direct 'd-namlen)) - (fino (slot direct 'd-fileno))) - (declare (type (unsigned-byte #+netbsd 16 #-netbsd 8) nlen) - (type (unsigned-byte #+netbsd 64 #-netbsd 32) fino)) - (let ((string (make-string nlen))) - #-unicode - (kernel:copy-from-system-area - (alien-sap (addr (slot direct 'd-name))) 0 - string (* vm:vector-data-offset vm:word-bits) - (* nlen vm:byte-bits)) - #+unicode - (let ((sap (alien-sap (addr (slot direct 'd-name))))) - (dotimes (k nlen) - (setf (aref string k) - (code-char (sap-ref-8 sap k))))) - (values (%file->name string) fino))))))) +;;; +;;; 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)) +(defun unix-errno () (unix-get-errno))
-(defun close-dir (dir) - (declare (type %directory dir)) - (alien-funcall (extern-alien "closedir" - (function void system-area-pointer)) - (directory-dir-struct dir)) - nil) +;;; GET-UNIX-ERROR-MSG -- public. +;;; +(defun get-unix-error-msg (&optional (error-number (unix-errno))) + _N"Returns a string describing the error number which was returned by a + UNIX system call." + (declare (type integer error-number)) + (if (array-in-bounds-p *unix-errors* error-number) + (svref *unix-errors* error-number) + (format nil _"Unknown error [~d]" error-number)))
+ +;;;; Lisp types used by syscalls.
-;; Use getcwd instead of getwd. But what should we do if the path -;; won't fit? Try again with a larger size? We don't do that right -;; now. -(defun unix-current-directory () - ;; 5120 is some randomly selected maximum size for the buffer for getcwd. - (with-alien ((buf (array c-call:char 5120))) - (let ((result - (alien-funcall - (extern-alien "getcwd" - (function (* c-call:char) - (* c-call:char) c-call:int)) - (cast buf (* c-call:char)) - 5120))) - - (values (not (zerop - (sap-int (alien-sap result)))) - (%file->name (cast buf c-call:c-string)))))) +(deftype unix-pathname () 'simple-string) +(deftype unix-fd () `(integer 0 ,most-positive-fixnum))
+(deftype unix-file-mode () '(unsigned-byte 32)) +(deftype unix-uid () '(unsigned-byte 32)) +(deftype unix-gid () '(unsigned-byte 32))
- -;;;; Support routines for dealing with unix pathnames.
-(export '(unix-file-kind unix-maybe-prepend-current-directory - unix-resolve-links unix-simplify-pathname)) +;;; UNIX-FAST-SELECT -- public. +;;; +(defmacro unix-fast-select (num-descriptors + read-fds write-fds exception-fds + timeout-secs &optional (timeout-usecs 0)) + _N"Perform the UNIX select(2) system call. + (declare (type (integer 0 #.FD-SETSIZE) num-descriptors) + (type (or (alien (* (struct fd-set))) null) + read-fds write-fds exception-fds) + (type (or null (unsigned-byte 31)) timeout-secs) + (type (unsigned-byte 31) timeout-usecs) + (optimize (speed 3) (safety 0) (inhibit-warnings 3)))" + `(let ((timeout-secs ,timeout-secs)) + (with-alien ((tv (struct timeval))) + (when timeout-secs + (setf (slot tv 'tv-sec) timeout-secs) + (setf (slot tv 'tv-usec) ,timeout-usecs)) + (int-syscall (#-netbsd "select" #+netbsd "__select50" int (* (struct fd-set)) (* (struct fd-set)) + (* (struct fd-set)) (* (struct timeval))) + ,num-descriptors ,read-fds ,write-fds ,exception-fds + (if timeout-secs (alien-sap (addr tv)) (int-sap 0))))))
-(defun unix-file-kind (name &optional check-for-links) - _N"Returns either :file, :directory, :link, :special, or NIL." - (declare (simple-string name)) - (multiple-value-bind (res dev ino mode) - (if check-for-links - (unix-lstat name) - (unix-stat name)) - (declare (type (or fixnum null) mode) - (ignore dev ino)) - (when res - (let ((kind (logand mode s-ifmt))) - (cond ((eql kind s-ifdir) :directory) - ((eql kind s-ifreg) :file) - ((eql kind s-iflnk) :link) - (t :special)))))) +;;; Unix-select accepts sets of file descriptors and waits for an event +;;; to happen on one of them or to time out.
-(defun unix-maybe-prepend-current-directory (name) - (declare (simple-string name)) - (if (and (> (length name) 0) (char= (schar name 0) #/)) - name - (multiple-value-bind (win dir) (unix-current-directory) - (if win - (concatenate 'simple-string dir "/" name) - name)))) +(defmacro num-to-fd-set (fdset num) + `(if (fixnump ,num) + (progn + (setf (deref (slot ,fdset 'fds-bits) 0) ,num) + ,@(loop for index upfrom 1 below (/ fd-setsize 32) + collect `(setf (deref (slot ,fdset 'fds-bits) ,index) 0))) + (progn + ,@(loop for index upfrom 0 below (/ fd-setsize 32) + collect `(setf (deref (slot ,fdset 'fds-bits) ,index) + (ldb (byte 32 ,(* index 32)) ,num))))))
-(defun unix-resolve-links (pathname) - _N"Returns the pathname with all symbolic links resolved." - (declare (simple-string pathname)) - (let ((len (length pathname)) - (pending pathname)) - (declare (fixnum len) (simple-string pending)) - (if (zerop len) - pathname - (let ((result (make-string 100 :initial-element (code-char 0))) - (fill-ptr 0) - (name-start 0)) - (loop - (let* ((name-end (or (position #/ pending :start name-start) len)) - (new-fill-ptr (+ fill-ptr (- name-end name-start)))) - ;; grow the result string, if necessary. the ">=" (instead of - ;; using ">") allows for the trailing "/" if we find this - ;; component is a directory. - (when (>= new-fill-ptr (length result)) - (let ((longer (make-string (* 3 (length result)) - :initial-element (code-char 0)))) - (replace longer result :end1 fill-ptr) - (setq result longer))) - (replace result pending - :start1 fill-ptr - :end1 new-fill-ptr - :start2 name-start - :end2 name-end) - (let ((kind (unix-file-kind (if (zerop name-end) "/" result) t))) - (unless kind (return nil)) - (cond ((eq kind :link) - (multiple-value-bind (link err) (unix-readlink result) - (unless link - (error (intl:gettext "Error reading link ~S: ~S") - (subseq result 0 fill-ptr) - (get-unix-error-msg err))) - (cond ((or (zerop (length link)) - (char/= (schar link 0) #/)) - ;; It's a relative link - (fill result (code-char 0) - :start fill-ptr - :end new-fill-ptr)) - ((string= result "/../" :end1 4) - ;; It's across the super-root. - (let ((slash (or (position #/ result :start 4) - 0))) - (fill result (code-char 0) - :start slash - :end new-fill-ptr) - (setf fill-ptr slash))) - (t - ;; It's absolute. - (and (> (length link) 0) - (char= (schar link 0) #/)) - (fill result (code-char 0) :end new-fill-ptr) - (setf fill-ptr 0))) - (setf pending - (if (= name-end len) - link - (concatenate 'simple-string - link - (subseq pending name-end)))) - (setf len (length pending)) - (setf name-start 0))) - ((= name-end len) - (when (eq kind :directory) - (setf (schar result new-fill-ptr) #/) - (incf new-fill-ptr)) - (return (subseq result 0 new-fill-ptr))) - ((eq kind :directory) - (setf (schar result new-fill-ptr) #/) - (setf fill-ptr (1+ new-fill-ptr)) - (setf name-start (1+ name-end))) - (t - (return nil)))))))))) +(defmacro fd-set-to-num (nfds fdset) + `(if (<= ,nfds 32) + (deref (slot ,fdset 'fds-bits) 0) + (+ ,@(loop for index upfrom 0 below (/ fd-setsize 32) + collect `(ash (deref (slot ,fdset 'fds-bits) ,index) + ,(* index 32))))))
-(defun unix-simplify-pathname (src) - (declare (simple-string src)) - (let* ((src-len (length src)) - (dst (make-string src-len)) - (dst-len 0) - (dots 0) - (last-slash nil)) - (macrolet ((deposit (char) - `(progn - (setf (schar dst dst-len) ,char) - (incf dst-len)))) - (dotimes (src-index src-len) - (let ((char (schar src src-index))) - (cond ((char= char #.) - (when dots - (incf dots)) - (deposit char)) - ((char= char #/) - (case dots - (0 - ;; Either ``/...' or ``...//...' - (unless last-slash - (setf last-slash dst-len) - (deposit char))) - (1 - ;; Either ``./...'' or ``..././...'' - (decf dst-len)) - (2 - ;; We've found .. - (cond - ((and last-slash (not (zerop last-slash))) - ;; There is something before this .. - (let ((prev-prev-slash - (position #/ dst :end last-slash :from-end t))) - (cond ((and (= (+ (or prev-prev-slash 0) 2) - last-slash) - (char= (schar dst (- last-slash 2)) #.) - (char= (schar dst (1- last-slash)) #.)) - ;; The something before this .. is another .. - (deposit char) - (setf last-slash dst-len)) - (t - ;; The something is some random dir. - (setf dst-len - (if prev-prev-slash - (1+ prev-prev-slash) - 0)) - (setf last-slash prev-prev-slash))))) - (t - ;; There is nothing before this .., so we need to keep it - (setf last-slash dst-len) - (deposit char)))) - (t - ;; Something other than a dot between slashes. - (setf last-slash dst-len) - (deposit char))) - (setf dots 0)) - (t - (setf dots nil) - (setf (schar dst dst-len) char) - (incf dst-len)))))) - (when (and last-slash (not (zerop last-slash))) - (case dots - (1 - ;; We've got ``foobar/.'' - (decf dst-len)) - (2 - ;; We've got ``foobar/..'' - (unless (and (>= last-slash 2) - (char= (schar dst (1- last-slash)) #.) - (char= (schar dst (- last-slash 2)) #.) - (or (= last-slash 2) - (char= (schar dst (- last-slash 3)) #/))) - (let ((prev-prev-slash - (position #/ dst :end last-slash :from-end t))) - (if prev-prev-slash - (setf dst-len (1+ prev-prev-slash)) - (return-from unix-simplify-pathname "./"))))))) - (cond ((zerop dst-len) - "./") - ((= dst-len src-len) - dst) - (t - (subseq dst 0 dst-len))))) +;; not checked for linux... +(defmacro fd-set (offset fd-set) + (let ((word (gensym)) + (bit (gensym))) + `(multiple-value-bind (,word ,bit) (floor ,offset 32) + (setf (deref (slot ,fd-set 'fds-bits) ,word) + (logior (truly-the (unsigned-byte 32) (ash 1 ,bit)) + (deref (slot ,fd-set 'fds-bits) ,word))))))
- -;;;; Other random routines. +;; not checked for linux... +(defmacro fd-zero (fd-set) + `(progn + ,@(loop for index upfrom 0 below (/ fd-setsize 32) + collect `(setf (deref (slot ,fd-set 'fds-bits) ,index) 0))))
-(def-alien-routine ("isatty" unix-isatty) boolean - _N"Accepts a Unix file descriptor and returns T if the device - associated with it is a terminal." - (fd int)) +(defun unix-select (nfds rdfds wrfds xpfds to-secs &optional (to-usecs 0)) + _N"Unix-select examines the sets of descriptors passed as arguments + to see if they are ready for reading and writing. See the UNIX + Programmers Manual for more information." + (declare (type (integer 0 #.FD-SETSIZE) nfds) + (type unsigned-byte rdfds wrfds xpfds) + (type (or (unsigned-byte 31) null) to-secs) + (type (unsigned-byte 31) to-usecs) + (optimize (speed 3) (safety 0) (inhibit-warnings 3))) + (with-alien ((tv (struct timeval)) + (rdf (struct fd-set)) + (wrf (struct fd-set)) + (xpf (struct fd-set))) + (when to-secs + (setf (slot tv 'tv-sec) to-secs) + (setf (slot tv 'tv-usec) to-usecs)) + (num-to-fd-set rdf rdfds) + (num-to-fd-set wrf wrfds) + (num-to-fd-set xpf xpfds) + (macrolet ((frob (lispvar alienvar) + `(if (zerop ,lispvar) + (int-sap 0) + (alien-sap (addr ,alienvar))))) + (syscall (#-netbsd "select" #+netbsd "__select50" int (* (struct fd-set)) (* (struct fd-set)) + (* (struct fd-set)) (* (struct timeval))) + (values result + (fd-set-to-num nfds rdf) + (fd-set-to-num nfds wrf) + (fd-set-to-num nfds xpf)) + nfds (frob rdfds rdf) (frob wrfds wrf) (frob xpfds xpf) + (if to-secs (alien-sap (addr tv)) (int-sap 0))))))
-(def-alien-routine ("ttyname" unix-ttyname) c-string - (fd int)) +(defun unix-symlink (name1 name2) + _N"Unix-symlink creates a symbolic link named name2 to the file + named name1. NIL and an error number is returned if the call + is unsuccessful." + (declare (type unix-pathname name1 name2)) + (void-syscall ("symlink" c-string c-string) + (%name->file name1) (%name->file name2)))
-(def-alien-routine ("openpty" unix-openpty) int - (amaster int :out) - (aslave int :out) - (name c-string) - (termp (* (struct termios))) - (winp (* (struct winsize)))) +(def-alien-type nil + (struct timeval + (tv-sec #-linux time-t #+linux int) ; seconds + (tv-usec int))) ; and microseconds + +(def-alien-type nil + (struct timezone + (tz-minuteswest int) ; minutes west of Greenwich + (tz-dsttime ; type of dst correction + #-linux (enum nil :none :usa :aust :wet :met :eet :can) + #+linux int)))
+(declaim (inline unix-gettimeofday)) +(defun unix-gettimeofday () + _N"If it works, unix-gettimeofday returns 5 values: T, the seconds and + microseconds of the current time of day, the timezone (in minutes west + of Greenwich), and a daylight-savings flag. If it doesn't work, it + returns NIL and the errno." + (with-alien ((tv (struct timeval)) + #-(or svr4 netbsd) (tz (struct timezone))) + (syscall* (#-netbsd "gettimeofday" + #+netbsd "__gettimeofday50" + (* (struct timeval)) #-svr4 (* (struct timezone))) + (values T + (slot tv 'tv-sec) + (slot tv 'tv-usec) + #-(or svr4 netbsd) (slot tz 'tz-minuteswest) + #+svr4 (unix-get-minutes-west (slot tv 'tv-sec)) + #-(or svr4 netbsd) (slot tz 'tz-dsttime) + #+svr4 (unix-get-timezone (slot tv 'tv-sec)) + ) + (addr tv) + #-(or svr4 netbsd) (addr tz) #+netbsd nil)))
- -;;;; UNIX-EXECVE - -(defun unix-execve (program &optional arg-list - (environment *environment-list*)) - _N"Executes the Unix execve system call. If the system call suceeds, lisp - will no longer be running in this process. If the system call fails this - function returns two values: NIL and an error code. Arg-list should be a - list of simple-strings which are passed as arguments to the exec'ed program. - Environment should be an a-list mapping symbols to simple-strings which this - function bashes together to form the environment for the exec'ed program." - (check-type program simple-string) - (let ((env-list (let ((envlist nil)) - (dolist (cons environment) - (push (if (cdr cons) - (concatenate 'simple-string - (string (car cons)) "=" - (cdr cons)) - (car cons)) - envlist)) - envlist))) - (sub-unix-execve (%name->file program) arg-list env-list))) - - -(defmacro round-bytes-to-words (n) - `(logand (the fixnum (+ (the fixnum ,n) 3)) (lognot 3))) +;;; Unix-utimes changes the accessed and updated times on UNIX +;;; files. The first argument is the filename (a string) and +;;; the second argument is a list of the 4 times- accessed and +;;; updated seconds and microseconds.
-;;; -;;; STRING-LIST-TO-C-STRVEC -- Internal -;;; -;;; STRING-LIST-TO-C-STRVEC is a function which takes a list of -;;; simple-strings and constructs a C-style string vector (strvec) -- -;;; a null-terminated array of pointers to null-terminated strings. -;;; This function returns two values: a sap and a byte count. When the -;;; memory is no longer needed it should be deallocated with -;;; vm_deallocate. -;;; -(defun string-list-to-c-strvec (string-list) - ;; - ;; Make a pass over string-list to calculate the amount of memory - ;; needed to hold the strvec. - (let ((string-bytes 0) - (vec-bytes (* 4 (1+ (length string-list))))) - (declare (fixnum string-bytes vec-bytes)) - (dolist (s string-list) - (check-type s simple-string) - (incf string-bytes (round-bytes-to-words (1+ (length s))))) - ;; - ;; Now allocate the memory and fill it in. - (let* ((total-bytes (+ string-bytes vec-bytes)) - (vec-sap (system:allocate-system-memory total-bytes)) - (string-sap (sap+ vec-sap vec-bytes)) - (i 0)) - (declare (type (and unsigned-byte fixnum) total-bytes i) - (type system:system-area-pointer vec-sap string-sap)) - (dolist (s string-list) - (declare (simple-string s)) - (let ((n (length s))) - ;; - ;; Blast the string into place - #-unicode - (kernel:copy-to-system-area (the simple-string s) - (* vm:vector-data-offset vm:word-bits) - string-sap 0 - (* (1+ n) vm:byte-bits)) - #+unicode - (progn - ;; FIXME: Do we need to apply some kind of transformation - ;; to convert Lisp unicode strings to C strings? Utf-8? - (dotimes (k n) - (setf (sap-ref-8 string-sap k) - (logand #xff (char-code (aref s k))))) - (setf (sap-ref-8 string-sap n) 0)) - - ;; - ;; Blast the pointer to the string into place - (setf (sap-ref-sap vec-sap i) string-sap) - (setf string-sap (sap+ string-sap (round-bytes-to-words (1+ n)))) - (incf i 4))) - ;; Blast in last null pointer - (setf (sap-ref-sap vec-sap i) (int-sap 0)) - (values vec-sap total-bytes)))) - -(defun sub-unix-execve (program arg-list env-list) - (let ((argv nil) - (argv-bytes 0) - (envp nil) - (envp-bytes 0) - result error-code) - (unwind-protect - (progn - ;; Blast the stuff into the proper format - (multiple-value-setq - (argv argv-bytes) - (string-list-to-c-strvec arg-list)) - (multiple-value-setq - (envp envp-bytes) - (string-list-to-c-strvec env-list)) - ;; - ;; Now do the system call - (multiple-value-setq - (result error-code) - (int-syscall ("execve" - c-string system-area-pointer system-area-pointer) - program argv envp))) - ;; - ;; Deallocate memory - (when argv - (system:deallocate-system-memory argv argv-bytes)) - (when envp - (system:deallocate-system-memory envp envp-bytes))) - (values result error-code))) +#-hpux +(defun unix-utimes (file atime-sec atime-usec mtime-sec mtime-usec) + _N"Unix-utimes sets the 'last-accessed' and 'last-updated' + times on a specified file. NIL and an error number is + returned if the call is unsuccessful." + (declare (type unix-pathname file) + (type (alien unsigned-long) + atime-sec atime-usec + mtime-sec mtime-usec)) + (with-alien ((tvp (array (struct timeval) 2))) + (setf (slot (deref tvp 0) 'tv-sec) atime-sec) + (setf (slot (deref tvp 0) 'tv-usec) atime-usec) + (setf (slot (deref tvp 1) 'tv-sec) mtime-sec) + (setf (slot (deref tvp 1) 'tv-usec) mtime-usec) + (void-syscall (#-netbsd "utimes" #+netbsd "__utimes50" c-string (* (struct timeval))) + file + (cast tvp (* (struct timeval))))))
+(def-alien-routine ("getpid" unix-getpid) int + _N"Unix-getpid returns the process-id of the current process.")
;;;; Socket support. @@ -3061,88 +2163,190 @@
;; Datagram support
-(defun unix-recvfrom (fd buffer length flags sockaddr len) - (with-alien ((l c-call:int len)) - (values - (alien-funcall (extern-alien "recvfrom" - (function c-call:int - c-call:int - system-area-pointer - c-call:int - c-call:int - (* t) - (* c-call:int))) - fd - (system:vector-sap buffer) - length - flags - sockaddr - (addr l)) - l))) +(defun unix-recvfrom (fd buffer length flags sockaddr len) + (with-alien ((l c-call:int len)) + (values + (alien-funcall (extern-alien "recvfrom" + (function c-call:int + c-call:int + system-area-pointer + c-call:int + c-call:int + (* t) + (* c-call:int))) + fd + (system:vector-sap buffer) + length + flags + sockaddr + (addr l)) + l))) + +#-unicode +(def-alien-routine ("sendto" unix-sendto) int + (fd int) + (buffer c-string) + (length int) + (flags int) + (sockaddr (* t)) + (len int)) + +(defun unix-sendto (fd buffer length flags sockaddr len) + (alien-funcall (extern-alien "sendto" + (function c-call:int + c-call:int + system-area-pointer + c-call:int + c-call:int + (* t) + c-call:int)) + fd + (system:vector-sap buffer) + length + flags + sockaddr + len)) + +(def-alien-routine ("shutdown" unix-shutdown) int + (socket int) + (level int)) + + +;;;; Memory-mapped files + +(defconstant +null+ (sys:int-sap 0)) + +(defconstant prot_read 1) ; Readable +(defconstant prot_write 2) ; Writable +(defconstant prot_exec 4) ; Executable +(defconstant prot_none 0) ; No access + +(defconstant map_shared 1) ; Changes are shared +(defconstant map_private 2) ; Changes are private +(defconstant map_fixed 16) ; Fixed, user-defined address +(defconstant map_noreserve #x40) ; Don't reserve swap space +(defconstant map_anonymous + #+solaris #x100 ; Solaris + #+linux 32 ; Linux + #+bsd #x1000) + +(defconstant ms_async 1) +(defconstant ms_sync 4) +(defconstant ms_invalidate 2) + +;; The return value from mmap that means mmap failed. +(defconstant map_failed (int-sap (1- (ash 1 vm:word-bits)))) + +(defun unix-mmap (addr length prot flags fd offset) + (declare (type (or null system-area-pointer) addr) + (type (unsigned-byte 32) length) + (type (integer 1 7) prot) + (type (unsigned-byte 32) flags) + (type (or null unix-fd) fd) + (type file-offset offset)) + ;; Can't use syscall, because the address that is returned could be + ;; "negative". Hence we explicitly check for mmap returning + ;; MAP_FAILED. + (let ((result + (alien-funcall (extern-alien "mmap" (function system-area-pointer + system-area-pointer + size-t int int int off-t)) + (or addr +null+) length prot flags (or fd -1) offset))) + (if (sap= result map_failed) + (values nil (unix-errno)) + (values result 0)))) + +(defun unix-munmap (addr length) + (declare (type system-area-pointer addr) + (type (unsigned-byte 32) length)) + (syscall ("munmap" system-area-pointer size-t) t addr length)) + +(defun unix-mprotect (addr length prot) + (declare (type system-area-pointer addr) + (type (unsigned-byte 32) length) + (type (integer 1 7) prot)) + (syscall ("mprotect" system-area-pointer size-t int) + t addr length prot)) + +(defun unix-msync (addr length flags) + (declare (type system-area-pointer addr) + (type (unsigned-byte 32) length) + (type (signed-byte 32) flags)) + (syscall ("msync" system-area-pointer size-t int) t addr length flags)) + + +;;;; User and group database structures + +(defstruct user-info + (name "" :type string) + (password "" :type string) + (uid 0 :type unix-uid) + (gid 0 :type unix-gid) + #+solaris (age "" :type string) + #+solaris (comment "" :type string) + #+freebsd (change -1 :type fixnum) + (gecos "" :type string) + (dir "" :type string) + (shell "" :type string)) + +;; see <pwd.h> +#+solaris +(def-alien-type nil + (struct passwd + (pw-name (* char)) ; user's login name + (pw-passwd (* char)) ; no longer used + (pw-uid uid-t) ; user id + (pw-gid gid-t) ; group id + (pw-age (* char)) ; password age (not used) + (pw-comment (* char)) ; not used + (pw-gecos (* char)) ; typically user's full name + (pw-dir (* char)) ; user's home directory + (pw-shell (* char)))) ; user's login shell + +#+bsd +(def-alien-type nil + (struct passwd + (pw-name (* char)) ; user's login name + (pw-passwd (* char)) ; no longer used + (pw-uid uid-t) ; user id + (pw-gid gid-t) ; group id + (pw-change int) ; password change time + (pw-class (* char)) ; user access class + (pw-gecos (* char)) ; typically user's full name + (pw-dir (* char)) ; user's home directory + (pw-shell (* char)) ; user's login shell + (pw-expire int) ; account expiration + #+(or freebsd darwin) + (pw-fields int))) ; internal + +;;;; Other random routines. +(def-alien-routine ("isatty" unix-isatty) boolean + _N"Accepts a Unix file descriptor and returns T if the device + associated with it is a terminal." + (fd int))
-#-unicode -(def-alien-routine ("sendto" unix-sendto) int - (fd int) - (buffer c-string) - (length int) - (flags int) - (sockaddr (* t)) - (len int)) +(def-alien-routine ("ttyname" unix-ttyname) c-string + (fd int))
-(defun unix-sendto (fd buffer length flags sockaddr len) - (alien-funcall (extern-alien "sendto" - (function c-call:int - c-call:int - system-area-pointer - c-call:int - c-call:int - (* t) - c-call:int)) - fd - (system:vector-sap buffer) - length - flags - sockaddr - len)) +(def-alien-routine ("openpty" unix-openpty) int + (amaster int :out) + (aslave int :out) + (name c-string) + (termp (* (struct termios))) + (winp (* (struct winsize))))
-(def-alien-routine ("shutdown" unix-shutdown) int - (socket int) - (level int)) +(def-alien-type nil + (struct itimerval + (it-interval (struct timeval)) ; timer interval + (it-value (struct timeval)))) ; current value
- ;;; ;;; Support for the Interval Timer (experimental) ;;; - - (defconstant ITIMER-REAL 0) (defconstant ITIMER-VIRTUAL 1) (defconstant ITIMER-PROF 2)
-(defun unix-getitimer (which) - _N"Unix-getitimer returns the INTERVAL and VALUE slots of one of - three system timers (:real :virtual or :profile). On success, - unix-getitimer returns 5 values, - T, it-interval-secs, it-interval-usec, it-value-secs, it-value-usec." - (declare (type (member :real :virtual :profile) which) - (values t - #+netbsd (unsigned-byte 63) #-netbsd (unsigned-byte 29) - (mod 1000000) - #+netbsd (unsigned-byte 63) #-netbsd (unsigned-byte 29) - (mod 1000000))) - (let ((which (ecase which - (:real ITIMER-REAL) - (:virtual ITIMER-VIRTUAL) - (:profile ITIMER-PROF)))) - (with-alien ((itv (struct itimerval))) - (syscall* (#-netbsd "getitimer" #+netbsd "__getitimer50" int (* (struct itimerval))) - (values T - (slot (slot itv 'it-interval) 'tv-sec) - (slot (slot itv 'it-interval) 'tv-usec) - (slot (slot itv 'it-value) 'tv-sec) - (slot (slot itv 'it-value) 'tv-usec)) - which (alien-sap (addr itv)))))) - (defun unix-setitimer (which int-secs int-usec val-secs val-usec) _N" Unix-setitimer sets the INTERVAL and VALUE slots of one of three system timers (:real :virtual or :profile). A SIGALRM signal @@ -3182,57 +2386,6 @@ ;;;; User and group database access, POSIX Standard 9.2.2
#+solaris -(defun unix-getpwnam (login) - _N"Return a USER-INFO structure for the user identified by LOGIN, or NIL if not found." - (declare (type simple-string login)) - (with-alien ((buf (array c-call:char 1024)) - (user-info (struct passwd))) - (let ((result - (alien-funcall - (extern-alien "getpwnam_r" - (function (* (struct passwd)) - c-call:c-string - (* (struct passwd)) - (* c-call:char) - c-call:unsigned-int)) - login - (addr user-info) - (cast buf (* c-call:char)) - 1024))) - (when (not (zerop (sap-int (alien-sap result)))) - (make-user-info - :name (string (cast (slot result 'pw-name) c-call:c-string)) - :password (string (cast (slot result 'pw-passwd) c-call:c-string)) - :uid (slot result 'pw-uid) - :gid (slot result 'pw-gid) - :age (string (cast (slot result 'pw-age) c-call:c-string)) - :comment (string (cast (slot result 'pw-comment) c-call:c-string)) - :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) - :dir (string (cast (slot result 'pw-dir) c-call:c-string)) - :shell (string (cast (slot result 'pw-shell) c-call:c-string))))))) - -#+bsd -(defun unix-getpwnam (login) - _N"Return a USER-INFO structure for the user identified by LOGIN, or NIL if not found." - (declare (type simple-string login)) - (let ((result - (alien-funcall - (extern-alien "getpwnam" - (function (* (struct passwd)) - c-call:c-string)) - login))) - (when (not (zerop (sap-int (alien-sap result)))) - (make-user-info - :name (string (cast (slot result 'pw-name) c-call:c-string)) - :password (string (cast (slot result 'pw-passwd) c-call:c-string)) - :uid (slot result 'pw-uid) - :gid (slot result 'pw-gid) - #-darwin :change #-darwin (slot result 'pw-change) - :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) - :dir (string (cast (slot result 'pw-dir) c-call:c-string)) - :shell (string (cast (slot result 'pw-shell) c-call:c-string)))))) - -#+solaris (defun unix-getpwuid (uid) _N"Return a USER-INFO structure for the user identified by UID, or NIL if not found." (declare (type unix-uid uid)) @@ -3282,145 +2435,66 @@ :dir (string (cast (slot result 'pw-dir) c-call:c-string)) :shell (string (cast (slot result 'pw-shell) c-call:c-string))))))
-#+solaris -(eval-when (:compile-toplevel :load-toplevel :execute) - ;; sysconf(_SC_GETGR_R_SIZE_MAX) - (defconstant +sc-getgr-r-size-max+ 7296 - _N"The maximum size of the group entry buffer")) - -#+solaris -(defun unix-getgrnam (name) - _N"Return a GROUP-INFO structure for the group identified by NAME, or NIL if not found." - (declare (type simple-string name)) - (with-alien ((buf (array c-call:char #.+sc-getgr-r-size-max+)) - (group-info (struct group))) - (let ((result - (alien-funcall - (extern-alien "getgrnam_r" - (function (* (struct group)) - c-call:c-string - (* (struct group)) - (* c-call:char) - c-call:unsigned-int)) - name - (addr group-info) - (cast buf (* c-call:char)) - #.+sc-getgr-r-size-max+))) - (unless (zerop (sap-int (alien-sap result))) - (make-group-info - :name (string (cast (slot result 'gr-name) c-call:c-string)) - :password (string (cast (slot result 'gr-passwd) c-call:c-string)) - :gid (slot result 'gr-gid) - :members (loop :with members = (slot result 'gr-mem) - :for i :from 0 - :for member = (deref members i) - :until (zerop (sap-int (alien-sap member))) - :collect (string (cast member c-call:c-string)))))))) - -#+bsd -(defun unix-getgrnam (name) - _N"Return a GROUP-INFO structure for the group identified by NAME, or NIL if not found." - (declare (type simple-string name)) - (let ((result - (alien-funcall - (extern-alien "getgrnam" - (function (* (struct group)) - c-call:c-string)) - name))) - (unless (zerop (sap-int (alien-sap result))) - (make-group-info - :name (string (cast (slot result 'gr-name) c-call:c-string)) - :password (string (cast (slot result 'gr-passwd) c-call:c-string)) - :gid (slot result 'gr-gid) - :members (loop :with members = (slot result 'gr-mem) - :for i :from 0 - :for member = (deref members i) - :until (zerop (sap-int (alien-sap member))) - :collect (string (cast member c-call:c-string))))))) - -#+solaris -(defun unix-getgrgid (gid) - _N"Return a GROUP-INFO structure for the group identified by GID, or NIL if not found." - (declare (type unix-gid gid)) - (with-alien ((buf (array c-call:char #.+sc-getgr-r-size-max+)) - (group-info (struct group))) - (let ((result - (alien-funcall - (extern-alien "getgrgid_r" - (function (* (struct group)) - c-call:unsigned-int - (* (struct group)) - (* c-call:char) - c-call:unsigned-int)) - gid - (addr group-info) - (cast buf (* c-call:char)) - #.+sc-getgr-r-size-max+))) - (unless (zerop (sap-int (alien-sap result))) - (make-group-info - :name (string (cast (slot result 'gr-name) c-call:c-string)) - :password (string (cast (slot result 'gr-passwd) c-call:c-string)) - :gid (slot result 'gr-gid) - :members (loop :with members = (slot result 'gr-mem) - :for i :from 0 - :for member = (deref members i) - :until (zerop (sap-int (alien-sap member))) - :collect (string (cast member c-call:c-string)))))))) - -#+bsd -(defun unix-getgrgid (gid) - _N"Return a GROUP-INFO structure for the group identified by GID, or NIL if not found." - (declare (type unix-gid gid)) - (let ((result - (alien-funcall - (extern-alien "getgrgid" - (function (* (struct group)) - c-call:unsigned-int)) - gid))) - (unless (zerop (sap-int (alien-sap result))) - (make-group-info - :name (string (cast (slot result 'gr-name) c-call:c-string)) - :password (string (cast (slot result 'gr-passwd) c-call:c-string)) - :gid (slot result 'gr-gid) - :members (loop :with members = (slot result 'gr-mem) - :for i :from 0 - :for member = (deref members i) - :until (zerop (sap-int (alien-sap member))) - :collect (string (cast member c-call:c-string))))))) - -#+solaris -(defun unix-setpwent () - (void-syscall ("setpwent"))) +;;; Getrusage is not provided in the C library on Solaris 2.4, and is +;;; rather slow on later versions so the "times" system call is +;;; provided. +#+(and sparc svr4) +(progn +(def-alien-type nil + (struct tms + (tms-utime #-alpha long #+alpha int) ; user time used + (tms-stime #-alpha long #+alpha int) ; system time used. + (tms-cutime #-alpha long #+alpha int) ; user time, children + (tms-cstime #-alpha long #+alpha int))) ; system time, children
-#+solaris -(defun unix-endpwent () - (void-syscall ("endpwent"))) +(declaim (inline unix-times)) +(defun unix-times () + _N"Unix-times returns information about the cpu time usage of the process + and its children." + (with-alien ((usage (struct tms))) + (alien-funcall (extern-alien "times" (function int (* (struct tms)))) + (addr usage)) + (values t + (slot usage 'tms-utime) + (slot usage 'tms-stime) + (slot usage 'tms-cutime) + (slot usage 'tms-cstime)))) +) ; end progn
-#+solaris -(defun unix-getpwent () - (with-alien ((buf (array c-call:char 1024)) - (user-info (struct passwd))) - (let ((result - (alien-funcall - (extern-alien "getpwent_r" - (function (* (struct passwd)) - (* (struct passwd)) - (* c-call:char) - c-call:unsigned-int)) - (addr user-info) - (cast buf (* c-call:char)) - 1024))) - (when (not (zerop (sap-int (alien-sap result)))) - (make-user-info - :name (string (cast (slot result 'pw-name) c-call:c-string)) - :password (string (cast (slot result 'pw-passwd) c-call:c-string)) - :uid (slot result 'pw-uid) - :gid (slot result 'pw-gid) - :age (string (cast (slot result 'pw-age) c-call:c-string)) - :comment (string (cast (slot result 'pw-comment) c-call:c-string)) - :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) - :dir (string (cast (slot result 'pw-dir) c-call:c-string)) - :shell (string (cast (slot result 'pw-shell) c-call:c-string))))))) +;; Requires call to tzset() in main. +;; Don't use this now: we +#+(or linux svr4) +(progn + (def-alien-variable ("daylight" unix-daylight) int) + (def-alien-variable ("timezone" unix-timezone) time-t) + (def-alien-variable ("altzone" unix-altzone) time-t) + #-irix (def-alien-variable ("tzname" unix-tzname) (array c-string 2)) + #+irix (defvar unix-tzname-addr nil) + #+irix (pushnew #'(lambda () (setq unix-tzname-addr nil)) + ext:*after-save-initializations*) + #+irix (declaim (notinline fakeout-compiler)) + #+irix (defun fakeout-compiler (name dst) + (unless unix-tzname-addr + (setf unix-tzname-addr (system:foreign-symbol-address + name + :flavor :data))) + (deref (sap-alien unix-tzname-addr (array c-string 2)) dst)) + (def-alien-routine get-timezone c-call:void + (when c-call:long :in) + (minutes-west c-call:int :out) + (daylight-savings-p alien:boolean :out)) + (defun unix-get-minutes-west (secs) + (multiple-value-bind (ignore minutes dst) (get-timezone secs) + (declare (ignore ignore) (ignore dst)) + (values minutes)) + ) + (defun unix-get-timezone (secs) + (multiple-value-bind (ignore minutes dst) (get-timezone secs) + (declare (ignore ignore) (ignore minutes)) + (values #-irix (deref unix-tzname (if dst 1 0)) + #+irix (fakeout-compiler "tzname" (if dst 1 0))) + ) ) +)
(def-alien-type nil (struct utsname @@ -3443,105 +2517,3 @@ (cast (slot names 'machine) c-string)) #+freebsd 256 (addr names)))) - -#+(and solaris svr4) -(export '(unix-sysinfo - si-sysname si-hostname si-release si-version si-machine - si-architecture si-hw-serial si-hw-provider si-srpc-domain - si-platform si-isalist si-dhcp-cache)) - -#+(and solaris svr4) -(progn -;; From sys/systeminfo.h. We don't list the set values here. -(def-enum + 1 - si-sysname si-hostname si-release si-version si-machine - si-architecture si-hw-serial si-hw-provider si-srpc-domain) - -(def-enum + 513 - si-platform si-isalist si-dhcp-cache) - - -(defun unix-sysinfo (command) - ;; Hope a buffer of length 2048 is long enough. - (with-alien ((buf (array c-call:unsigned-char 2048))) - (let ((result - (alien-funcall - (extern-alien "sysinfo" - (function c-call:int - c-call:int - c-call:c-string - c-call:int)) - command - (cast buf (* c-call:char)) - 2048))) - (when (>= result 0) - (cast buf c-call:c-string))))) -) - -#+solaris -(export '(rlimit_cpu rlimit_fsize rlimit_data rlimit_stack rlimit_core rlimit_nofile - rlimit_vmem rlimit_as)) - -#+solaris -(progn -(defconstant rlimit_cpu 0 - _N"CPU time per process (in milliseconds)") -(defconstant rlimit_fsize 1 - _N"Maximum file size") -(defconstant rlimit_data 2 - _N"Data segment size") -(defconstant rlimit_stack 3 - _N"Stack size") -(defconstant rlimit_core 4 - _N"Core file size") -(defconstant rlimit_nofile 5 - _N"Number of open files") -(defconstant rlimit_vmem 6 - _N"Maximum mapped memory") -(defconstant rlimit_as rlimit_vmem) -) - -#+(and darwin x86) -(export '(rlimit_cpu rlimit_fsize rlimit_data rlimit_stack rlimit_core - rlimit_as rlimit_rss rlimit_memlock rlimit_nproc rlimit_nofile)) - -#+(and darwin x86) -(progn -(defconstant rlimit_cpu 0 - _N"CPU time per process") -(defconstant rlimit_fsize 1 - _N"File size") -(defconstant rlimit_data 2 - _N"Data segment size") -(defconstant rlimit_stack 3 - _N"Stack size") -(defconstant rlimit_core 4 - _N"Core file size") -(defconstant rlimit_as 5 - _N"Addess space (resident set size)") -(defconstant rlimit_rss rlimit_as) -(defconstant rlimit_memlock 6 - _N"Locked-in-memory address space") -(defconstant rlimit_nproc 7 - _N"Number of processes") -(defconstant rlimit_nofile 8 - _N"Number of open files") -) - - -#+(or solaris (and darwin x86)) -(export '(unix-getrlimit)) - -#+(or solaris (and darwin x86)) -(defun unix-getrlimit (resource) - _N"Get the limits on the consumption of system resouce specified by - Resource. If successful, return three values: T, the current (soft) - limit, and the maximum (hard) limit." - - (with-alien ((rlimit (struct rlimit))) - (syscall ("getrlimit" c-call:int (* (struct rlimit))) - (values t - (slot rlimit 'rlim-cur) - (slot rlimit 'rlim-max)) - resource (addr rlimit)))) -;; EOF
===================================== src/contrib/load-unix.lisp ===================================== --- /dev/null +++ b/src/contrib/load-unix.lisp @@ -0,0 +1,7 @@ +;; Load extra functionality in the UNIX package. + +(ext:without-package-locks + (load (compile-file-pathname #-linux "modules:unix/unix" + #+linux "modules:unix/unix-glibc2"))) + +(provide 'unix)
===================================== src/contrib/unix/unix-glibc2.lisp ===================================== --- /dev/null +++ b/src/contrib/unix/unix-glibc2.lisp @@ -0,0 +1,2053 @@ +;;; -*- Package: UNIX -*- +;;; +;;; ********************************************************************** +;;; This code was written as part of the CMU Common Lisp project at +;;; Carnegie Mellon University, and has been placed in the public domain. +;;; +(ext:file-comment + "$Header: src/code/unix-glibc2.lisp $") +;;; +;;; ********************************************************************** +;;; +;;; This file contains the UNIX low-level support for glibc2. Based +;;; on unix.lisp 1.56, converted for glibc2 by Peter Van Eynde (1998). +;;; Alpha support by Julian Dolby, 1999. +;;; +;;; All the functions with #+(or) in front are work in progress, +;;; and mostly don't work. +;;; +;; Todo: #+(or)'ed stuff and ioctl's +;; +;; +;; Large File Support (LFS) added by Pierre Mai and Eric Marsden, Feb +;; 2003. This is necessary to be able to read/write/stat files that +;; are larger than 2GB on a 32-bit system. From a C program, defining +;; a preprocessor macro _LARGEFILE64_SOURCE makes the preproccessor +;; replace a call to open() by open64(), and similarly for stat, +;; fstat, lstat, lseek, readdir and friends. Furthermore, certain data +;; types, that are normally 32 bits wide, are replaced by 64-bit wide +;; equivalents: off_t -> off64_t etc. The libc.so fiddles around with +;; weak symbols to support this mess. +;; +;; From CMUCL, we make FFI calls to the xxx64 functions, and use the +;; 64-bit wide versions of the data structures. The most ugly aspect +;; is that some of the stat functions are not available via dlsym, so +;; we reference them explicitly from linux-stubs.S. Another amusing +;; fact is that on glibc 2.2, stat64() returns a struct stat with a +;; 32-bit ino_t, whereas readdir64() returns a struct dirent that +;; contains a 64-bit ino_t. On glibc 2.1, OTOH, both stat64 and +;; readdir64 use structs with 32-bit ino_t. +;; +;; The current version deals with this by going with the glibc 2.2 +;; definitions, unless the keyword :glibc2.1 also occurs on *features*, +;; in addition to :glibc2, in which case we go with the glibc 2.1 +;; definitions. Note that binaries compiled against glibc 2.1 do in +;; fact work fine on glibc 2.2, because readdir64 is available in both +;; glibc 2.1 and glibc 2.2 versions in glibc 2.2, disambiguated through +;; ELF symbol versioning. We use an entry for readdir64 in linux-stubs.S +;; in order to force usage of the correct version of readdir64 at runtime. +;; +;; So in order to compile for glibc 2.2 and newer, just compile CMUCL +;; on a glibc 2.2 system, and make sure that :glibc2.1 doesn't appear +;; on the *features* list. In order to compile for glibc 2.1 and newer, +;; compile CMUCL on a glibc 2.1 system, and make sure that :glibc2.1 does +;; appear on the *features* list. + +(in-package "UNIX") +(use-package "ALIEN") +(use-package "C-CALL") +(use-package "SYSTEM") +(use-package "EXT") +(intl:textdomain "cmucl-unix-glibc2") + +(export '( + daddr-t caddr-t ino-t swblk-t size-t time-t dev-t off-t uid-t gid-t + blkcnt-t fsblkcnt-t fsfilcnt-t + unix-lockf f_ulock f_lock f_tlock f_test + timeval tv-sec tv-usec timezone tz-minuteswest tz-dsttime + itimerval it-interval it-value tchars t-intrc t-quitc t-startc + t-stopc t-eofc t-brkc ltchars t-suspc t-dsuspc t-rprntc t-flushc + t-werasc t-lnextc sgttyb sg-ispeed sg-ospeed sg-erase sg-kill + sg-flags winsize ws-row ws-col ws-xpixel ws-ypixel + direct d-off d-ino d-reclen d-name + stat st-dev st-mode st-nlink st-uid st-gid st-rdev st-size + st-atime st-mtime st-ctime st-blksize st-blocks + s-ifmt s-ifdir s-ifchr s-ifblk s-ifreg s-iflnk s-ifsock + s-isuid s-isgid s-isvtx s-iread s-iwrite s-iexec + ruseage ru-utime ru-stime ru-maxrss ru-ixrss ru-idrss + ru-isrss ru-minflt ru-majflt ru-nswap ru-inblock ru-oublock + ru-msgsnd ru-msgrcv ru-nsignals ru-nvcsw ru-nivcsw + rlimit rlim-cur rlim-max sc-onstack sc-mask sc-pc + unix-errno get-unix-error-msg + prot_read prot_write prot_exec prot_none + map_shared map_private map_fixed map_anonymous + ms_async ms_sync ms_invalidate + unix-mmap unix-munmap unix-msync unix-mprotect + unix-pathname unix-file-mode unix-fd unix-pid unix-uid unix-gid + unix-setitimer unix-getitimer + unix-access r_ok w_ok x_ok f_ok unix-chdir unix-chmod setuidexec + setgidexec savetext readown writeown execown readgrp writegrp + execgrp readoth writeoth execoth unix-fchmod unix-chown unix-fchown + unix-getdtablesize unix-close unix-creat unix-dup unix-dup2 + unix-fcntl f-dupfd f-getfd f-setfd f-getfl f-setfl f-getown f-setown + fndelay fappend fasync fcreat ftrunc fexcl unix-link unix-lseek + l_set l_incr l_xtnd unix-mkdir unix-open o_rdonly o_wronly o_rdwr + o_ndelay + o_noctty + o_append o_creat o_trunc o_excl unix-pipe unix-read unix-readlink + unix-rename unix-rmdir unix-fast-select fd-setsize fd-set fd-clr + fd-isset fd-zero unix-select unix-sync unix-fsync unix-truncate + unix-ftruncate unix-symlink unix-unlink unix-write unix-ioctl + unix-uname utsname + tcsetpgrp tcgetpgrp tty-process-group + terminal-speeds tty-raw tty-crmod tty-echo tty-lcase + tty-cbreak + termios + c-lflag + c-iflag + c-oflag + tty-icrnl + tty-ocrnl + veof + vintr + vquit + vstart + vstop + vsusp + c-cflag + c-cc + tty-icanon + vmin + vtime + tty-ixon + tcsanow + tcsadrain + tciflush + tcoflush + tcioflush + tcsaflush + unix-tcgetattr + unix-tcsetattr + tty-ignbrk + tty-brkint + tty-ignpar + tty-parmrk + tty-inpck + tty-istrip + tty-inlcr + tty-igncr + tty-iuclc + tty-ixany + tty-ixoff + tty-imaxbel + tty-opost + tty-olcuc + tty-onlcr + tty-onocr + tty-onlret + tty-ofill + tty-ofdel + tty-isig + tty-xcase + tty-echoe + tty-echok + tty-echonl + tty-noflsh + tty-iexten + tty-tostop + tty-echoctl + tty-echoprt + tty-echoke + tty-pendin + tty-cstopb + tty-cread + tty-parenb + tty-parodd + tty-hupcl + tty-clocal + vintr + verase + vkill + veol + veol2 + TIOCGETP TIOCSETP TIOCFLUSH TIOCSETC TIOCGETC TIOCSLTC + TIOCGLTC TIOCNOTTY TIOCSPGRP TIOCGPGRP TIOCGWINSZ TIOCSWINSZ + TIOCSIGSEND + + KBDCGET KBDCSET KBDCRESET KBDCRST KBDCSSTD KBDSGET KBDGCLICK + KBDSCLICK FIONREAD unix-exit unix-stat unix-lstat unix-fstat + unix-getrusage unix-fast-getrusage rusage_self rusage_children + unix-gettimeofday + unix-utimes unix-sched-yield unix-setreuid + unix-setregid + unix-getpid unix-getppid + unix-getgid unix-getegid unix-getpgrp unix-setpgrp unix-getuid + unix-getpagesize unix-gethostname unix-gethostid unix-fork + unix-getenv unix-setenv unix-putenv unix-unsetenv + unix-current-directory unix-isatty unix-ttyname unix-execve + unix-socket unix-connect unix-bind unix-listen unix-accept + unix-recv unix-send unix-getpeername unix-getsockname + unix-getsockopt unix-setsockopt unix-openpty + + unix-recvfrom unix-sendto unix-shutdown + + unix-getpwnam unix-getpwuid unix-getgrnam unix-getgrgid + user-info user-info-name user-info-password user-info-uid + user-info-gid user-info-gecos user-info-dir user-info-shell + group-info group-info-name group-info-gid group-info-members)) + +;;;; Common machine independent structures. + +(defmacro def-enum (inc cur &rest names) + (flet ((defform (name) + (prog1 (when name `(defconstant ,name ,cur)) + (setf cur (funcall inc cur 1))))) + `(progn ,@(mapcar #'defform names)))) + +;;;; User and group database structures: <pwd.h> and <grp.h> + +(defstruct group-info + (name "" :type string) + (password "" :type string) + (gid 0 :type unix-gid) + (members nil :type list)) ; list of logins as strings + +(def-alien-type nil + (struct group + (gr-name (* char)) ; name of the group + (gr-passwd (* char)) ; encrypted group password + (gr-gid gid-t) ; numerical group ID + (gr-mem (* (* char))))) ; vector of pointers to member names + +;;; From stdio.h + +;;; From sys/types.h +;;; and +;;; gnu/types.h + +(defconstant +max-s-long+ 2147483647) + +(def-alien-type quad-t #+alpha long #-alpha (array long 2)) +(def-alien-type qaddr-t (* quad-t)) +(def-alien-type daddr-t int) +(def-alien-type caddr-t (* char)) +(def-alien-type swblk-t long) +(def-alien-type clock-t long) +(def-alien-type uid-t unsigned-int) +(def-alien-type ssize-t #-alpha int #+alpha long) +(def-alien-type key-t int) +(def-alien-type int8-t char) +(def-alien-type u-int8-t unsigned-char) +(def-alien-type int16-t short) +(def-alien-type u-int16-t unsigned-short) +(def-alien-type int32-t int) +(def-alien-type register-t #-alpha int #+alpha long) + +(def-alien-type fsblkcnt-t u-int64-t) +(def-alien-type fsfilcnt-t u-int64-t) +(def-alien-type pid-t int) +;(def-alien-type ssize-t #-alpha int #+alpha long) + +(def-alien-type fsid-t (array int 2)) + +(def-alien-type key-t int) + +(def-alien-type ipc-pid-t unsigned-short) + + +;;; dlfcn.h -> in foreign.lisp + +(defun unix-getdtablesize () + _N"Unix-getdtablesize returns the maximum size of the file descriptor + table. (i.e. the maximum number of descriptors that can exist at + one time.)" + (int-syscall ("getdtablesize"))) + +;;; fcntlbits.h + + + +(defconstant f-dupfd 0 _N"Duplicate a file descriptor") +(defconstant f-getfd 1 _N"Get file desc. flags") +(defconstant f-setfd 2 _N"Set file desc. flags") + +(defconstant F-CLOEXEC 1 _N"for f-getfl and f-setfl") + +#-alpha +(progn + (defconstant F-RDLCK 0 _N"for fcntl and lockf") + (defconstant F-WRLCK 1 _N"for fcntl and lockf") + (defconstant F-UNLCK 2 _N"for fcntl and lockf") + (defconstant F-EXLCK 4 _N"old bsd flock (depricated)") + (defconstant F-SHLCK 8 _N"old bsd flock (depricated)")) +#+alpha +(progn + (defconstant F-RDLCK 1 _N"for fcntl and lockf") + (defconstant F-WRLCK 2 _N"for fcntl and lockf") + (defconstant F-UNLCK 8 _N"for fcntl and lockf") + (defconstant F-EXLCK 16 _N"old bsd flock (depricated)") + (defconstant F-SHLCK 32 _N"old bsd flock (depricated)")) + +(defconstant F-LOCK-SH 1 _N"Shared lock for bsd flock") +(defconstant F-LOCK-EX 2 _N"Exclusive lock for bsd flock") +(defconstant F-LOCK-NB 4 _N"Don't block. Combine with F-LOCK-SH or F-LOCK-EX") +(defconstant F-LOCK-UN 8 _N"Remove lock for bsd flock") + +(def-alien-type nil + (struct flock + (l-type short) + (l-whence short) + (l-start off-t) + (l-len off-t) + (l-pid pid-t))) + +;;; grp.h + +;;; POSIX Standard: 9.2.1 Group Database Access <grp.h> + +#+(or) +(defun unix-setgrend () + _N"Rewind the group-file stream." + (void-syscall ("setgrend"))) + +#+(or) +(defun unix-endgrent () + _N"Close the group-file stream." + (void-syscall ("endgrent"))) + +#+(or) +(defun unix-getgrent () + _N"Read an entry from the group-file stream, opening it if necessary." + + (let ((result (alien-funcall (extern-alien "getgrent" + (function (* (struct group))))))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +;;; ioctl-types.h + +(defconstant +NCC+ 8 + _N"Size of control character vector.") + +(def-alien-type nil + (struct termio + (c-iflag unsigned-int) ; input mode flags + (c-oflag unsigned-int) ; output mode flags + (c-cflag unsigned-int) ; control mode flags + (c-lflag unsigned-int) ; local mode flags + (c-line unsigned-char) ; line discipline + (c-cc (array unsigned-char #.+NCC+)))) ; control characters + +;;; modem lines +(defconstant tiocm-le 1) +(defconstant tiocm-dtr 2) +(defconstant tiocm-rts 4) +(defconstant tiocm-st 8) +(defconstant tiocm-sr #x10) +(defconstant tiocm-cts #x20) +(defconstant tiocm-car #x40) +(defconstant tiocm-rng #x80) +(defconstant tiocm-dsr #x100) +(defconstant tiocm-cd tiocm-car) +(defconstant tiocm-ri #x80) + +;;; ioctl (fd, TIOCSERGETLSR, &result) where result may be as below + +;;; line disciplines +(defconstant N-TTY 0) +(defconstant N-SLIP 1) +(defconstant N-MOUSE 2) +(defconstant N-PPP 3) +(defconstant N-STRIP 4) +(defconstant N-AX25 5) + + +;;; ioctls.h + +;;; Routing table calls. +(defconstant siocaddrt #x890B) ;; add routing table entry +(defconstant siocdelrt #x890C) ;; delete routing table entry +(defconstant siocrtmsg #x890D) ;; call to routing system + +;;; Socket configuration controls. +(defconstant siocgifname #x8910) ;; get iface name +(defconstant siocsiflink #x8911) ;; set iface channel +(defconstant siocgifconf #x8912) ;; get iface list +(defconstant siocgifflags #x8913) ;; get flags +(defconstant siocsifflags #x8914) ;; set flags +(defconstant siocgifaddr #x8915) ;; get PA address +(defconstant siocsifaddr #x8916) ;; set PA address +(defconstant siocgifdstaddr #x8917 ) ;; get remote PA address +(defconstant siocsifdstaddr #x8918 ) ;; set remote PA address +(defconstant siocgifbrdaddr #x8919 ) ;; get broadcast PA address +(defconstant siocsifbrdaddr #x891a ) ;; set broadcast PA address +(defconstant siocgifnetmask #x891b ) ;; get network PA mask +(defconstant siocsifnetmask #x891c ) ;; set network PA mask +(defconstant siocgifmetric #x891d ) ;; get metric +(defconstant siocsifmetric #x891e ) ;; set metric +(defconstant siocgifmem #x891f ) ;; get memory address (BSD) +(defconstant siocsifmem #x8920 ) ;; set memory address (BSD) +(defconstant siocgifmtu #x8921 ) ;; get MTU size +(defconstant siocsifmtu #x8922 ) ;; set MTU size +(defconstant siocsifhwaddr #x8924 ) ;; set hardware address +(defconstant siocgifencap #x8925 ) ;; get/set encapsulations +(defconstant siocsifencap #x8926) +(defconstant siocgifhwaddr #x8927 ) ;; Get hardware address +(defconstant siocgifslave #x8929 ) ;; Driver slaving support +(defconstant siocsifslave #x8930) +(defconstant siocaddmulti #x8931 ) ;; Multicast address lists +(defconstant siocdelmulti #x8932) +(defconstant siocgifindex #x8933 ) ;; name -> if_index mapping +(defconstant siogifindex SIOCGIFINDEX ) ;; misprint compatibility :-) +(defconstant siocsifpflags #x8934 ) ;; set/get extended flags set +(defconstant siocgifpflags #x8935) +(defconstant siocdifaddr #x8936 ) ;; delete PA address +(defconstant siocsifhwbroadcast #x8937 ) ;; set hardware broadcast addr +(defconstant siocgifcount #x8938 ) ;; get number of devices + +(defconstant siocgifbr #x8940 ) ;; Bridging support +(defconstant siocsifbr #x8941 ) ;; Set bridging options + +(defconstant siocgiftxqlen #x8942 ) ;; Get the tx queue length +(defconstant siocsiftxqlen #x8943 ) ;; Set the tx queue length + + +;;; ARP cache control calls. +;; 0x8950 - 0x8952 * obsolete calls, don't re-use +(defconstant siocdarp #x8953 ) ;; delete ARP table entry +(defconstant siocgarp #x8954 ) ;; get ARP table entry +(defconstant siocsarp #x8955 ) ;; set ARP table entry + +;;; RARP cache control calls. +(defconstant siocdrarp #x8960 ) ;; delete RARP table entry +(defconstant siocgrarp #x8961 ) ;; get RARP table entry +(defconstant siocsrarp #x8962 ) ;; set RARP table entry + +;;; Driver configuration calls + +(defconstant siocgifmap #x8970 ) ;; Get device parameters +(defconstant siocsifmap #x8971 ) ;; Set device parameters + +;;; DLCI configuration calls + +(defconstant siocadddlci #x8980 ) ;; Create new DLCI device +(defconstant siocdeldlci #x8981 ) ;; Delete DLCI device + +;;; Device private ioctl calls. + +;; These 16 ioctls are available to devices via the do_ioctl() device +;; vector. Each device should include this file and redefine these +;; names as their own. Because these are device dependent it is a good +;; idea _NOT_ to issue them to random objects and hope. + +(defconstant siocdevprivate #x89F0 ) ;; to 89FF + + +;;; netdb.h + +;; All data returned by the network data base library are supplied in +;; host order and returned in network order (suitable for use in +;; system calls). + +;;; Absolute file name for network data base files. +(defconstant path-hequiv "/etc/hosts.equiv") +(defconstant path-hosts "/etc/hosts") +(defconstant path-networks "/etc/networks") +(defconstant path-nsswitch_conf "/etc/nsswitch.conf") +(defconstant path-protocols "/etc/protocols") +(defconstant path-services "/etc/services") + + +;;; Possible values left in `h_errno'. +(defconstant netdb-internal -1 _N"See errno.") +(defconstant netdb-success 0 _N"No problem.") +(defconstant host-not-found 1 _N"Authoritative Answer Host not found.") +(defconstant try-again 2 _N"Non-Authoritative Host not found,or SERVERFAIL.") +(defconstant no-recovery 3 _N"Non recoverable errors, FORMERR, REFUSED, NOTIMP.") +(defconstant no-data 4 "Valid name, no data record of requested type.") +(defconstant no-address no-data "No address, look for MX record.") + +;;; Description of data base entry for a single host. + +(def-alien-type nil + (struct hostent + (h-name c-string) ; Official name of host. + (h-aliases (* c-string)) ; Alias list. + (h-addrtype int) ; Host address type. + (h_length int) ; Length of address. + (h-addr-list (* c-string)))) ; List of addresses from name server. + +#+(or) +(defun unix-sethostent (stay-open) + _N"Open host data base files and mark them as staying open even after +a later search if STAY_OPEN is non-zero." + (void-syscall ("sethostent" int) stay-open)) + +#+(or) +(defun unix-endhostent () + _N"Close host data base files and clear `stay open' flag." + (void-syscall ("endhostent"))) + +#+(or) +(defun unix-gethostent () + _N"Get next entry from host data base file. Open data base if +necessary." + (let ((result (alien-funcall (extern-alien "gethostent" + (function (* (struct hostent))))))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-gethostbyaddr(addr length type) + _N"Return entry from host data base which address match ADDR with +length LEN and type TYPE." + (let ((result (alien-funcall (extern-alien "gethostbyaddr" + (function (* (struct hostent)) + c-string int int)) + addr len type))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-gethostbyname (name) + _N"Return entry from host data base for host with NAME." + (let ((result (alien-funcall (extern-alien "gethostbyname" + (function (* (struct hostent)) + c-string)) + name))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-gethostbyname2 (name af) + _N"Return entry from host data base for host with NAME. AF must be + set to the address type which as `AF_INET' for IPv4 or `AF_INET6' + for IPv6." + (let ((result (alien-funcall (extern-alien "gethostbyname2" + (function (* (struct hostent)) + c-string int)) + name af))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +;; Description of data base entry for a single network. NOTE: here a +;; poor assumption is made. The network number is expected to fit +;; into an unsigned long int variable. + +(def-alien-type nil + (struct netent + (n-name c-string) ; Official name of network. + (n-aliases (* c-string)) ; Alias list. + (n-addrtype int) ; Net address type. + (n-net unsigned-long))) ; Network number. + +#+(or) +(defun unix-setnetent (stay-open) + _N"Open network data base files and mark them as staying open even + after a later search if STAY_OPEN is non-zero." + (void-syscall ("setnetent" int) stay-open)) + + +#+(or) +(defun unix-endnetent () + _N"Close network data base files and clear `stay open' flag." + (void-syscall ("endnetent"))) + + +#+(or) +(defun unix-getnetent () + _N"Get next entry from network data base file. Open data base if + necessary." + (let ((result (alien-funcall (extern-alien "getnetent" + (function (* (struct netent))))))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + + +#+(or) +(defun unix-getnetbyaddr (net type) + _N"Return entry from network data base which address match NET and + type TYPE." + (let ((result (alien-funcall (extern-alien "getnetbyaddr" + (function (* (struct netent)) + unsigned-long int)) + net type))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-getnetbyname (name) + _N"Return entry from network data base for network with NAME." + (let ((result (alien-funcall (extern-alien "getnetbyname" + (function (* (struct netent)) + c-string)) + name))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +;; Description of data base entry for a single service. +(def-alien-type nil + (struct servent + (s-name c-string) ; Official service name. + (s-aliases (* c-string)) ; Alias list. + (s-port int) ; Port number. + (s-proto c-string))) ; Protocol to use. + +#+(or) +(defun unix-setservent (stay-open) + _N"Open service data base files and mark them as staying open even + after a later search if STAY_OPEN is non-zero." + (void-syscall ("setservent" int) stay-open)) + +#+(or) +(defun unix-endservent (stay-open) + _N"Close service data base files and clear `stay open' flag." + (void-syscall ("endservent"))) + + +#+(or) +(defun unix-getservent () + _N"Get next entry from service data base file. Open data base if + necessary." + (let ((result (alien-funcall (extern-alien "getservent" + (function (* (struct servent))))))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-getservbyname (name proto) + _N"Return entry from network data base for network with NAME and + protocol PROTO." + (let ((result (alien-funcall (extern-alien "getservbyname" + (function (* (struct netent)) + c-string (* char))) + name proto))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-getservbyport (port proto) + _N"Return entry from service data base which matches port PORT and + protocol PROTO." + (let ((result (alien-funcall (extern-alien "getservbyport" + (function (* (struct netent)) + int (* char))) + port proto))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +;; Description of data base entry for a single service. + +(def-alien-type nil + (struct protoent + (p-name c-string) ; Official protocol name. + (p-aliases (* c-string)) ; Alias list. + (p-proto int))) ; Protocol number. + +#+(or) +(defun unix-setprotoent (stay-open) + _N"Open protocol data base files and mark them as staying open even + after a later search if STAY_OPEN is non-zero." + (void-syscall ("setprotoent" int) stay-open)) + +#+(or) +(defun unix-endprotoent () + _N"Close protocol data base files and clear `stay open' flag." + (void-syscall ("endprotoent"))) + +#+(or) +(defun unix-getprotoent () + _N"Get next entry from protocol data base file. Open data base if + necessary." + (let ((result (alien-funcall (extern-alien "getprotoent" + (function (* (struct protoent))))))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-getprotobyname (name) + _N"Return entry from protocol data base for network with NAME." + (let ((result (alien-funcall (extern-alien "getprotobyname" + (function (* (struct protoent)) + c-string)) + name))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-getprotobynumber (proto) + _N"Return entry from protocol data base which number is PROTO." + (let ((result (alien-funcall (extern-alien "getprotobynumber" + (function (* (struct protoent)) + int)) + proto))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-setnetgrent (netgroup) + _N"Establish network group NETGROUP for enumeration." + (int-syscall ("setservent" c-string) netgroup)) + +#+(or) +(defun unix-endnetgrent () + _N"Free all space allocated by previous `setnetgrent' call." + (void-syscall ("endnetgrent"))) + +#+(or) +(defun unix-getnetgrent (hostp userp domainp) + _N"Get next member of netgroup established by last `setnetgrent' call + and return pointers to elements in HOSTP, USERP, and DOMAINP." + (int-syscall ("getnetgrent" (* c-string) (* c-string) (* c-string)) + hostp userp domainp)) + +#+(or) +(defun unix-innetgr (netgroup host user domain) + _N"Test whether NETGROUP contains the triple (HOST,USER,DOMAIN)." + (int-syscall ("innetgr" c-string c-string c-string c-string) + netgroup host user domain)) + +(def-alien-type nil + (struct addrinfo + (ai-flags int) ; Input flags. + (ai-family int) ; Protocol family for socket. + (ai-socktype int) ; Socket type. + (ai-protocol int) ; Protocol for socket. + (ai-addrlen int) ; Length of socket address. + (ai-addr (* (struct sockaddr))) + ; Socket address for socket. + (ai-cononname c-string) + ; Canonical name for service location. + (ai-net (* (struct addrinfo))))) ; Pointer to next in list. + +;; Possible values for `ai_flags' field in `addrinfo' structure. + +(defconstant ai_passive 1 _N"Socket address is intended for `bind'.") +(defconstant ai_canonname 2 _N"Request for canonical name.") + +;; Error values for `getaddrinfo' function. +(defconstant eai_badflags -1 _N"Invalid value for `ai_flags' field.") +(defconstant eai_noname -2 _N"NAME or SERVICE is unknown.") +(defconstant eai_again -3 _N"Temporary failure in name resolution.") +(defconstant eai_fail -4 _N"Non-recoverable failure in name res.") +(defconstant eai_nodata -5 _N"No address associated with NAME.") +(defconstant eai_family -6 _N"ai_family not supported.") +(defconstant eai_socktype -7 _N"ai_socktype not supported.") +(defconstant eai_service -8 _N"SERVICE not supported for ai_socktype.") +(defconstant eai_addrfamily -9 _N"Address family for NAME not supported.") +(defconstant eai_memory -10 _N"Memory allocation failure.") +(defconstant eai_system -11 _N"System error returned in errno.") + + +#+(or) +(defun unix-getaddrinfo (name service req pai) + _N"Translate name of a service location and/or a service name to set of + socket addresses." + (int-syscall ("getaddrinfo" c-string c-string (* (struct addrinfo)) + (* (* struct addrinfo))) + name service req pai)) + + +#+(or) +(defun unix-freeaddrinfo (ai) + _N"Free `addrinfo' structure AI including associated storage." + (void-syscall ("freeaddrinfo" (* struct addrinfo)) + ai)) + + +#+(or) +(defun unix-forkpty (amaster name termp winp) + _N"Create child process and establish the slave pseudo terminal as the + child's controlling terminal." + (int-syscall ("forkpty" (* int) c-string (* (struct termios)) + (* (struct winsize))) + amaster name termp winp)) + + +;; POSIX Standard: 9.2.2 User Database Access <pwd.h> + +#+(or) +(defun unix-setpwent () + _N"Rewind the password-file stream." + (void-syscall ("setpwent"))) + +#+(or) +(defun unix-endpwent () + _N"Close the password-file stream." + (void-syscall ("endpwent"))) + +#+(or) +(defun unix-getpwent () + _N"Read an entry from the password-file stream, opening it if necessary." + (let ((result (alien-funcall (extern-alien "getpwent" + (function (* (struct passwd))))))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +;;; resourcebits.h + +(def-alien-type nil + (struct rlimit + (rlim-cur long) ; current (soft) limit + (rlim-max long))); maximum value for rlim-cur + +;; Priority limits. + +(defconstant prio-min -20 _N"Minimum priority a process can have") +(defconstant prio-max 20 _N"Maximum priority a process can have") + + +;;; The type of the WHICH argument to `getpriority' and `setpriority', +;;; indicating what flavor of entity the WHO argument specifies. + +(defconstant priority-process 0 _N"WHO is a process ID") +(defconstant priority-pgrp 1 _N"WHO is a process group ID") +(defconstant priority-user 2 _N"WHO is a user ID") + +;;; sched.h + +#+(or) +(defun unix-sched_setparam (pid param) + _N"Rewind the password-file stream." + (int-syscall ("sched_setparam" pid-t (struct psched-param)) + pid param)) + +#+(or) +(defun unix-sched_getparam (pid param) + _N"Rewind the password-file stream." + (int-syscall ("sched_getparam" pid-t (struct psched-param)) + pid param)) + + +#+(or) +(defun unix-sched_setscheduler (pid policy param) + _N"Set scheduling algorithm and/or parameters for a process." + (int-syscall ("sched_setscheduler" pid-t int (struct psched-param)) + pid policy param)) + +#+(or) +(defun unix-sched_getscheduler (pid) + _N"Retrieve scheduling algorithm for a particular purpose." + (int-syscall ("sched_getscheduler" pid-t) + pid)) + +(defun unix-sched-yield () + _N"Retrieve scheduling algorithm for a particular purpose." + (int-syscall ("sched_yield"))) + +#+(or) +(defun unix-sched_get_priority_max (algorithm) + _N"Get maximum priority value for a scheduler." + (int-syscall ("sched_get_priority_max" int) + algorithm)) + +#+(or) +(defun unix-sched_get_priority_min (algorithm) + _N"Get minimum priority value for a scheduler." + (int-syscall ("sched_get_priority_min" int) + algorithm)) + + + +#+(or) +(defun unix-sched_rr_get_interval (pid t) + _N"Get the SCHED_RR interval for the named process." + (int-syscall ("sched_rr_get_interval" pid-t (* (struct timespec))) + pid t)) + +;;; schedbits.h + +(defconstant scheduler-other 0) +(defconstant scheduler-fifo 1) +(defconstant scheduler-rr 2) + + +;; Data structure to describe a process' schedulability. + +(def-alien-type nil + (struct sched_param + (sched-priority int))) + +;; Cloning flags. +(defconstant csignal #x000000ff _N"Signal mask to be sent at exit.") +(defconstant clone_vm #x00000100 _N"Set if VM shared between processes.") +(defconstant clone_fs #x00000200 _N"Set if fs info shared between processes") +(defconstant clone_files #x00000400 _N"Set if open files shared between processe") +(defconstant clone_sighand #x00000800 _N"Set if signal handlers shared.") +(defconstant clone_pid #x00001000 _N"Set if pid shared.") + + +;;; shadow.h + +;; Structure of the password file. + +(def-alien-type nil + (struct spwd + (sp-namp c-string) ; Login name. + (sp-pwdp c-string) ; Encrypted password. + (sp-lstchg long) ; Date of last change. + (sp-min long) ; Minimum number of days between changes. + (sp-max long) ; Maximum number of days between changes. + (sp-warn long) ; Number of days to warn user to change the password. + (sp-inact long) ; Number of days the account may be inactive. + (sp-expire long) ; Number of days since 1970-01-01 until account expires. + (sp-flags long))) ; Reserved. + +#+(or) +(defun unix-setspent () + _N"Open database for reading." + (void-syscall ("setspent"))) + +#+(or) +(defun unix-endspent () + _N"Close database." + (void-syscall ("endspent"))) + +#+(or) +(defun unix-getspent () + _N"Get next entry from database, perhaps after opening the file." + (let ((result (alien-funcall (extern-alien "getspent" + (function (* (struct spwd))))))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-getspnam (name) + _N"Get shadow entry matching NAME." + (let ((result (alien-funcall (extern-alien "getspnam" + (function (* (struct spwd)) + c-string)) + name))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +#+(or) +(defun unix-sgetspent (string) + _N"Read shadow entry from STRING." + (let ((result (alien-funcall (extern-alien "sgetspent" + (function (* (struct spwd)) + c-string)) + string))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + +;; + +#+(or) +(defun unix-lckpwdf () + _N"Protect password file against multi writers." + (void-syscall ("lckpwdf"))) + + +#+(or) +(defun unix-ulckpwdf () + _N"Unlock password file." + (void-syscall ("ulckpwdf"))) + +;; Protection bits. + +(defconstant s-isuid #o0004000 _N"Set user ID on execution.") +(defconstant s-isgid #o0002000 _N"Set group ID on execution.") +(defconstant s-isvtx #o0001000 _N"Save swapped text after use (sticky).") +(defconstant s-iread #o0000400 _N"Read by owner") +(defconstant s-iwrite #o0000200 _N"Write by owner.") +(defconstant s-iexec #o0000100 _N"Execute by owner.") + +;;; statfsbuf.h + +(def-alien-type nil + (struct statfs + (f-type int) + (f-bsize int) + (f-blocks fsblkcnt-t) + (f-bfree fsblkcnt-t) + (f-bavail fsblkcnt-t) + (f-files fsfilcnt-t) + (f-ffree fsfilcnt-t) + (f-fsid fsid-t) + (f-namelen int) + (f-spare (array int 6)))) + + +;;; termbits.h + + + +(def-enum + 0 tciflush tcoflush tcioflush) + +(defconstant tty-nl0 0) +(defconstant tty-nl1 #o400) + +(defconstant tty-crdly #o0003000) +(defconstant tty-cr0 #o0000000) +(defconstant tty-cr1 #o0001000) +(defconstant tty-cr2 #o0002000) +(defconstant tty-cr3 #o0003000) +(defconstant tty-tabdly #o0014000) +(defconstant tty-tab0 #o0000000) +(defconstant tty-tab1 #o0004000) +(defconstant tty-tab2 #o0010000) +(defconstant tty-tab3 #o0014000) +(defconstant tty-xtabs #o0014000) +(defconstant tty-bsdly #o0020000) +(defconstant tty-bs0 #o0000000) +(defconstant tty-bs1 #o0020000) +(defconstant tty-vtdly #o0040000) +(defconstant tty-vt0 #o0000000) +(defconstant tty-vt1 #o0040000) +(defconstant tty-ffdly #o0100000) +(defconstant tty-ff0 #o0000000) +(defconstant tty-ff1 #o0100000) + +;; c-cflag bit meaning +(defconstant tty-cbaud #o0010017) +(defconstant tty-b0 #o0000000) ;; hang up +(defconstant tty-b50 #o0000001) +(defconstant tty-b75 #o0000002) +(defconstant tty-b110 #o0000003) +(defconstant tty-b134 #o0000004) +(defconstant tty-b150 #o0000005) +(defconstant tty-b200 #o0000006) +(defconstant tty-b300 #o0000007) +(defconstant tty-b600 #o0000010) +(defconstant tty-b1200 #o0000011) +(defconstant tty-b1800 #o0000012) +(defconstant tty-b2400 #o0000013) +(defconstant tty-b4800 #o0000014) +(defconstant tty-b9600 #o0000015) +(defconstant tty-b19200 #o0000016) +(defconstant tty-b38400 #o0000017) +(defconstant tty-exta tty-b19200) +(defconstant tty-extb tty-b38400) +(defconstant tty-csize #o0000060) +(defconstant tty-cs5 #o0000000) +(defconstant tty-cs6 #o0000020) +(defconstant tty-cs7 #o0000040) +(defconstant tty-cs8 #o0000060) +(defconstant tty-cstopb #o0000100) +(defconstant tty-cread #o0000200) +(defconstant tty-parenb #o0000400) +(defconstant tty-parodd #o0001000) +(defconstant tty-hupcl #o0002000) +(defconstant tty-clocal #o0004000) +(defconstant tty-cbaudex #o0010000) +(defconstant tty-b57600 #o0010001) +(defconstant tty-b115200 #o0010002) +(defconstant tty-b230400 #o0010003) +(defconstant tty-b460800 #o0010004) +(defconstant tty-cibaud #o002003600000) ; input baud rate (not used) +(defconstant tty-crtscts #o020000000000) ;flow control + +;;; tcflow() and TCXONC use these +(def-enum + 0 tty-tcooff tty-tcoon tty-tcioff tty-tcion) + +;; tcflush() and TCFLSH use these */ +(def-enum + 0 tty-tciflush tty-tcoflush tty-tcioflush) + +;; tcsetattr uses these +(def-enum + 0 tty-tcsanow tty-tcsadrain tty-tcsaflush) + +;;; termios.h + +(defun unix-cfsetospeed (termios speed) + _N"Set terminal output speed." + (let ((baud (or (position speed terminal-speeds) + (error _"Bogus baud rate ~S" speed)))) + (void-syscall ("cfsetospeed" (* (struct termios)) int) termios baud))) + +(defun unix-cfgetispeed (termios) + _N"Get terminal input speed." + (multiple-value-bind (speed errno) + (int-syscall ("cfgetispeed" (* (struct termios))) termios) + (if speed + (values (svref terminal-speeds speed) 0) + (values speed errno)))) + +(defun unix-cfsetispeed (termios speed) + _N"Set terminal input speed." + (let ((baud (or (position speed terminal-speeds) + (error _"Bogus baud rate ~S" speed)))) + (void-syscall ("cfsetispeed" (* (struct termios)) int) termios baud))) + +(defun unix-tcsendbreak (fd duration) + _N"Send break" + (declare (type unix-fd fd)) + (void-syscall ("tcsendbreak" int int) fd duration)) + +(defun unix-tcdrain (fd) + _N"Wait for output for finish" + (declare (type unix-fd fd)) + (void-syscall ("tcdrain" int) fd)) + +(defun unix-tcflush (fd selector) + _N"See tcflush(3)" + (declare (type unix-fd fd)) + (void-syscall ("tcflush" int int) fd selector)) + +(defun unix-tcflow (fd action) + _N"Flow control" + (declare (type unix-fd fd)) + (void-syscall ("tcflow" int int) fd action)) + +;;; timebits.h + +;;; unistd.h + +(defun sub-unix-execve (program arg-list env-list) + (let ((argv nil) + (argv-bytes 0) + (envp nil) + (envp-bytes 0) + result error-code) + (unwind-protect + (progn + ;; Blast the stuff into the proper format + (multiple-value-setq + (argv argv-bytes) + (string-list-to-c-strvec arg-list)) + (multiple-value-setq + (envp envp-bytes) + (string-list-to-c-strvec env-list)) + ;; + ;; Now do the system call + (multiple-value-setq + (result error-code) + (int-syscall ("execve" + c-string system-area-pointer system-area-pointer) + program argv envp))) + ;; + ;; Deallocate memory + (when argv + (system:deallocate-system-memory argv argv-bytes)) + (when envp + (system:deallocate-system-memory envp envp-bytes))) + (values result error-code))) + +;;;; UNIX-EXECVE + +(defun unix-execve (program &optional arg-list + (environment *environment-list*)) + _N"Executes the Unix execve system call. If the system call suceeds, lisp + will no longer be running in this process. If the system call fails this + function returns two values: NIL and an error code. Arg-list should be a + list of simple-strings which are passed as arguments to the exec'ed program. + Environment should be an a-list mapping symbols to simple-strings which this + function bashes together to form the environment for the exec'ed program." + (check-type program simple-string) + (let ((env-list (let ((envlist nil)) + (dolist (cons environment) + (push (if (cdr cons) + (concatenate 'simple-string + (string (car cons)) "=" + (cdr cons)) + (car cons)) + envlist)) + envlist))) + (sub-unix-execve (%name->file program) arg-list env-list))) + + +(defmacro round-bytes-to-words (n) + `(logand (the fixnum (+ (the fixnum ,n) 3)) (lognot 3))) + +(defun unix-chown (path uid gid) + _N"Given a file path, an integer user-id, and an integer group-id, + unix-chown changes the owner of the file and the group of the + file to those specified. Either the owner or the group may be + left unchanged by specifying them as -1. Note: Permission will + fail if the caller is not the superuser." + (declare (type unix-pathname path) + (type (or unix-uid (integer -1 -1)) uid) + (type (or unix-gid (integer -1 -1)) gid)) + (void-syscall ("chown" c-string int int) (%name->file path) uid gid)) + +;;; Unix-fchown is exactly the same as unix-chown except that the file +;;; is specified by a file-descriptor ("fd") instead of a pathname. + +(defun unix-fchown (fd uid gid) + _N"Unix-fchown is like unix-chown, except that it accepts an integer + file descriptor instead of a file path name." + (declare (type unix-fd fd) + (type (or unix-uid (integer -1 -1)) uid) + (type (or unix-gid (integer -1 -1)) gid)) + (void-syscall ("fchown" int int int) fd uid gid)) + +#+(or) +(defun unix-pathconf (path name) + _N"Get file-specific configuration information about PATH." + (int-syscall ("pathconf" c-string int) (%name->file path) name)) + +#+(or) +(defun unix-sysconf (name) + _N"Get the value of the system variable NAME." + (int-syscall ("sysconf" int) name)) + +#+(or) +(defun unix-confstr (name) + _N"Get the value of the string-valued system variable NAME." + (with-alien ((buf (array char 1024))) + (values (not (zerop (alien-funcall (extern-alien "confstr" + (function int + c-string + size-t)) + name buf 1024))) + (cast buf c-string)))) + + +(def-alien-routine ("getppid" unix-getppid) int + _N"Unix-getppid returns the process-id of the parent of the current process.") + +;;; Unix-getpgrp returns the group-id associated with the +;;; current process. + +(defun unix-getpgrp () + _N"Unix-getpgrp returns the group-id of the calling process." + (int-syscall ("getpgrp"))) + +;;; Unix-setpgid sets the group-id of the process specified by +;;; "pid" to the value of "pgrp". The process must either have +;;; the same effective user-id or be a super-user process. + +;;; setpgrp(int int)[freebsd] is identical to setpgid and is retained +;;; for backward compatibility. setpgrp(void)[solaris] is being phased +;;; out in favor of setsid(). + +(defun unix-setpgrp (pid pgrp) + _N"Unix-setpgrp sets the process group on the process pid to + pgrp. NIL and an error number are returned upon failure." + (void-syscall ("setpgid" int int) pid pgrp)) + +(defun unix-setpgid (pid pgrp) + _N"Unix-setpgid sets the process group of the process pid to + pgrp. If pgid is equal to pid, the process becomes a process + group leader. NIL and an error number are returned upon failure." + (void-syscall ("setpgid" int int) pid pgrp)) + +#+(or) +(defun unix-setsid () + _N"Create a new session with the calling process as its leader. + The process group IDs of the session and the calling process + are set to the process ID of the calling process, which is returned." + (void-syscall ( "setsid"))) + +#+(or) +(defun unix-getsid () + _N"Return the session ID of the given process." + (int-syscall ( "getsid"))) + +#+(or) +(def-alien-routine ("geteuid" unix-getuid) int + _N"Get the effective user ID of the calling process.") + +(def-alien-routine ("getgid" unix-getgid) int + _N"Unix-getgid returns the real group-id of the current process.") + +(def-alien-routine ("getegid" unix-getegid) int + _N"Unix-getegid returns the effective group-id of the current process.") + +;/* If SIZE is zero, return the number of supplementary groups +; the calling process is in. Otherwise, fill in the group IDs +; of its supplementary groups in LIST and return the number written. */ +;extern int getgroups __P ((int __size, __gid_t __list[])); + +#+(or) +(defun unix-group-member (gid) + _N"Return nonzero iff the calling process is in group GID." + (int-syscall ( "group-member" gid-t) gid)) + + +(defun unix-setuid (uid) + _N"Set the user ID of the calling process to UID. + If the calling process is the super-user, set the real + and effective user IDs, and the saved set-user-ID to UID; + if not, the effective user ID is set to UID." + (int-syscall ("setuid" uid-t) uid)) + +;;; Unix-setreuid sets the real and effective user-id's of the current +;;; process to the arguments "ruid" and "euid", respectively. Usage is +;;; restricted for anyone but the super-user. Setting either "ruid" or +;;; "euid" to -1 makes the system use the current id instead. + +(defun unix-setreuid (ruid euid) + _N"Unix-setreuid sets the real and effective user-id's of the current + process to the specified ones. NIL and an error number is returned + if the call fails." + (void-syscall ("setreuid" int int) ruid euid)) + +(defun unix-setgid (gid) + _N"Set the group ID of the calling process to GID. + If the calling process is the super-user, set the real + and effective group IDs, and the saved set-group-ID to GID; + if not, the effective group ID is set to GID." + (int-syscall ("setgid" gid-t) gid)) + + +;;; Unix-setregid sets the real and effective group-id's of the current +;;; process to the arguments "rgid" and "egid", respectively. Usage is +;;; restricted for anyone but the super-user. Setting either "rgid" or +;;; "egid" to -1 makes the system use the current id instead. + +(defun unix-setregid (rgid egid) + _N"Unix-setregid sets the real and effective group-id's of the current + process process to the specified ones. NIL and an error number is + returned if the call fails." + (void-syscall ("setregid" int int) rgid egid)) + +(defun unix-fork () + _N"Executes the unix fork system call. Returns 0 in the child and the pid + of the child in the parent if it works, or NIL and an error number if it + doesn't work." + (int-syscall ("fork"))) + +;; Environment maninpulation; man getenv(3) +(def-alien-routine ("getenv" unix-getenv) c-call:c-string + (name c-call:c-string) + _N"Get the value of the environment variable named Name. If no such + variable exists, Nil is returned.") + +(def-alien-routine ("setenv" unix-setenv) c-call:int + (name c-call:c-string) + (value c-call:c-string) + (overwrite c-call:int) + _N"Adds the environment variable named Name to the environment with + the given Value if Name does not already exist. If Name does exist, + the value is changed to Value if Overwrite is non-zero. Otherwise, + the value is not changed.") + +(def-alien-routine ("putenv" unix-putenv) c-call:int + (name c-call:c-string) + _N"Adds or changes the environment. Name-value must be a string of + the form "name=value". If the name does not exist, it is added. + If name does exist, the value is updated to the given value.") + +(def-alien-routine ("unsetenv" unix-unsetenv) c-call:int + (name c-call:c-string) + _N"Removes the variable Name from the environment") + +;;; Unix-link creates a hard link from name2 to name1. + +(defun unix-link (name1 name2) + _N"Unix-link creates a hard link from the file with name1 to the + file with name2." + (declare (type unix-pathname name1 name2)) + (void-syscall ("link" c-string c-string) + (%name->file name1) (%name->file name2))) + +(defun tcgetpgrp (fd) + _N"Get the tty-process-group for the unix file-descriptor FD." + (alien:with-alien ((alien-pgrp c-call:int)) + (multiple-value-bind (ok err) + (unix-ioctl fd + tiocgpgrp + (alien:alien-sap (alien:addr alien-pgrp))) + (if ok + (values alien-pgrp nil) + (values nil err))))) + +(defun tty-process-group (&optional fd) + _N"Get the tty-process-group for the unix file-descriptor FD. If not supplied, + FD defaults to /dev/tty." + (if fd + (tcgetpgrp fd) + (multiple-value-bind (tty-fd errno) + (unix-open "/dev/tty" o_rdwr 0) + (cond (tty-fd + (multiple-value-prog1 + (tcgetpgrp tty-fd) + (unix-close tty-fd))) + (t + (values nil errno)))))) + +(defun tcsetpgrp (fd pgrp) + _N"Set the tty-process-group for the unix file-descriptor FD to PGRP." + (alien:with-alien ((alien-pgrp c-call:int pgrp)) + (unix-ioctl fd + tiocspgrp + (alien:alien-sap (alien:addr alien-pgrp))))) + +(defun %set-tty-process-group (pgrp &optional fd) + _N"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not + supplied, FD defaults to /dev/tty." + (let ((old-sigs + (unix-sigblock + (sigmask :sigttou :sigttin :sigtstp :sigchld)))) + (declare (type (unsigned-byte 32) old-sigs)) + (unwind-protect + (if fd + (tcsetpgrp fd pgrp) + (multiple-value-bind (tty-fd errno) + (unix-open "/dev/tty" o_rdwr 0) + (cond (tty-fd + (multiple-value-prog1 + (tcsetpgrp tty-fd pgrp) + (unix-close tty-fd))) + (t + (values nil errno))))) + (unix-sigsetmask old-sigs)))) + +(defsetf tty-process-group (&optional fd) (pgrp) + _N"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not + supplied, FD defaults to /dev/tty." + `(%set-tty-process-group ,pgrp ,fd)) + +#+(or) +(defun unix-getlogin () + _N"Return the login name of the user." + (let ((result (alien-funcall (extern-alien "getlogin" + (function c-string))))) + (declare (type system-area-pointer result)) + (if (zerop (sap-int result)) + nil + result))) + + +#+(or) +(defun unix-sethostname (name len) + (int-syscall ("sethostname" c-string size-t) name len)) + +#+(or) +(defun unix-sethostid (id) + (int-syscall ("sethostid" long) id)) + +#+(or) +(defun unix-getdomainname (name len) + (int-syscall ("getdomainname" c-string size-t) name len)) + +#+(or) +(defun unix-setdomainname (name len) + (int-syscall ("setdomainname" c-string size-t) name len)) + +;;; Unix-fsync writes the core-image of the file described by "fd" to +;;; permanent storage (i.e. disk). + +(defun unix-fsync (fd) + _N"Unix-fsync writes the core image of the file described by + fd to disk." + (declare (type unix-fd fd)) + (void-syscall ("fsync" int) fd)) + + +#+(or) +(defun unix-vhangup () + _N"Revoke access permissions to all processes currently communicating + with the control terminal, and then send a SIGHUP signal to the process + group of the control terminal." + (int-syscall ("vhangup"))) + +#+(or) +(defun unix-revoke (file) + _N"Revoke the access of all descriptors currently open on FILE." + (int-syscall ("revoke" c-string) (%name->file file))) + + +#+(or) +(defun unix-chroot (path) + _N"Make PATH be the root directory (the starting point for absolute paths). + This call is restricted to the super-user." + (int-syscall ("chroot" c-string) (%name->file path))) + +;;; Unix-sync writes all information in core memory which has been modified +;;; to permanent storage (i.e. disk). + +(defun unix-sync () + _N"Unix-sync writes all information in core memory which has been + modified to disk. It returns NIL and an error code if an error + occured." + (void-syscall ("sync"))) + +;;; Unix-truncate accepts a file name and a new length. The file is +;;; truncated to the new length. + +(defun unix-truncate (name length) + _N"Unix-truncate truncates the named file to the length (in + bytes) specified by LENGTH. NIL and an error number is returned + if the call is unsuccessful." + (declare (type unix-pathname name) + (type (unsigned-byte 64) length)) + (void-syscall ("truncate64" c-string off-t) (%name->file name) length)) + +(defun unix-ftruncate (fd length) + _N"Unix-ftruncate is similar to unix-truncate except that the first + argument is a file descriptor rather than a file name." + (declare (type unix-fd fd) + (type (unsigned-byte 64) length)) + (void-syscall ("ftruncate64" int off-t) fd length)) + +#+(or) +(defun unix-getdtablesize () + _N"Return the maximum number of file descriptors + the current process could possibly have." + (int-syscall ("getdtablesize"))) + +(defconstant f_ulock 0 _N"Unlock a locked region") +(defconstant f_lock 1 _N"Lock a region for exclusive use") +(defconstant f_tlock 2 _N"Test and lock a region for exclusive use") +(defconstant f_test 3 _N"Test a region for othwer processes locks") + +(defun unix-lockf (fd cmd length) + _N"Unix-locks can lock, unlock and test files according to the cmd + which can be one of the following: + + f_ulock Unlock a locked region + f_lock Lock a region for exclusive use + f_tlock Test and lock a region for exclusive use + f_test Test a region for othwer processes locks + + The lock is for a region from the current location for a length + of length. + + This is a simpler version of the interface provided by unix-fcntl. + " + (declare (type unix-fd fd) + (type (unsigned-byte 64) length) + (type (integer 0 3) cmd)) + (int-syscall ("lockf64" int int off-t) fd cmd length)) + +;;; utime.h + +;; Structure describing file times. + +(def-alien-type nil + (struct utimbuf + (actime time-t) ; Access time. + (modtime time-t))) ; Modification time. + +;;; waitflags.h + +;; Bits in the third argument to `waitpid'. + +(defconstant waitpid-wnohang 1 _N"Don't block waiting.") +(defconstant waitpid-wuntranced 2 _N"Report status of stopped children.") + +(defconstant waitpid-wclone #x80000000 _N"Wait for cloned process.") + + +;;; sys/fsuid.h + +#+(or) +(defun unix-setfsuid (uid) + _N"Change uid used for file access control to UID, without affecting + other priveledges (such as who can send signals at the process)." + (int-syscall ("setfsuid" uid-t) uid)) + +#+(or) +(defun unix-setfsgid (gid) + _N"Change gid used for file access control to GID, without affecting + other priveledges (such as who can send signals at the process)." + (int-syscall ("setfsgid" gid-t) gid)) + +;;; sys/poll.h + +;; Data structure describing a polling request. + +(def-alien-type nil + (struct pollfd + (fd int) ; File descriptor to poll. + (events short) ; Types of events poller cares about. + (revents short))) ; Types of events that actually occurred. + +;; Event types that can be polled for. These bits may be set in `events' +;; to indicate the interesting event types; they will appear in `revents' +;; to indicate the status of the file descriptor. + +(defconstant POLLIN #o1 _N"There is data to read.") +(defconstant POLLPRI #o2 _N"There is urgent data to read.") +(defconstant POLLOUT #o4 _N"Writing now will not block.") + +;; Event types always implicitly polled for. These bits need not be set in +;;`events', but they will appear in `revents' to indicate the status of +;; the file descriptor. */ + + +(defconstant POLLERR #o10 _N"Error condition.") +(defconstant POLLHUP #o20 _N"Hung up.") +(defconstant POLLNVAL #o40 _N"Invalid polling request.") + + +(defconstant +npollfile+ 30 _N"Canonical number of polling requests to read +in at a time in poll.") + +#+(or) +(defun unix-poll (fds nfds timeout) + _N" Poll the file descriptors described by the NFDS structures starting at + FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for + an event to occur; if TIMEOUT is -1, block until an event occurs. + Returns the number of file descriptors with events, zero if timed out, + or -1 for errors." + (int-syscall ("poll" (* (struct pollfd)) long int) + fds nfds timeout)) + +;;; sys/resource.h + +(defun unix-getrlimit (resource) + _N"Get the soft and hard limits for RESOURCE." + (with-alien ((rlimits (struct rlimit))) + (syscall ("getrlimit" int (* (struct rlimit))) + (values t + (slot rlimits 'rlim-cur) + (slot rlimits 'rlim-max)) + resource (addr rlimits)))) + +(defun unix-setrlimit (resource current maximum) + _N"Set the current soft and hard maximum limits for RESOURCE. + Only the super-user can increase hard limits." + (with-alien ((rlimits (struct rlimit))) + (setf (slot rlimits 'rlim-cur) current) + (setf (slot rlimits 'rlim-max) maximum) + (void-syscall ("setrlimit" int (* (struct rlimit))) + resource (addr rlimits)))) + + +#+(or) +(defun unix-ulimit (cmd newlimit) + _N"Function depends on CMD: + 1 = Return the limit on the size of a file, in units of 512 bytes. + 2 = Set the limit on the size of a file to NEWLIMIT. Only the + super-user can increase the limit. + 3 = Return the maximum possible address of the data segment. + 4 = Return the maximum number of files that the calling process can open. + Returns -1 on errors." + (int-syscall ("ulimit" int long) cmd newlimit)) + +#+(or) +(defun unix-getpriority (which who) + _N"Return the highest priority of any process specified by WHICH and WHO + (see above); if WHO is zero, the current process, process group, or user + (as specified by WHO) is used. A lower priority number means higher + priority. Priorities range from PRIO_MIN to PRIO_MAX (above)." + (int-syscall ("getpriority" int int) + which who)) + +#+(or) +(defun unix-setpriority (which who) + _N"Set the priority of all processes specified by WHICH and WHO (see above) + to PRIO. Returns 0 on success, -1 on errors." + (int-syscall ("setpriority" int int) + which who)) + + +(defun unix-umask (mask) + _N"Set the file creation mask of the current process to MASK, + and return the old creation mask." + (int-syscall ("umask" mode-t) mask)) + +#+(or) +(defun unix-makedev (path mode dev) + _N"Create a device file named PATH, with permission and special bits MODE + and device number DEV (which can be constructed from major and minor + device numbers with the `makedev' macro above)." + (declare (type unix-pathname path) + (type unix-file-mode mode)) + (void-syscall ("makedev" c-string mode-t dev-t) (%name->file name) mode dev)) + + +#+(or) +(defun unix-fifo (name mode) + _N"Create a new FIFO named PATH, with permission bits MODE." + (declare (type unix-pathname name) + (type unix-file-mode mode)) + (void-syscall ("mkfifo" c-string int) (%name->file name) mode)) + +;;; sys/statfs.h + +#+(or) +(defun unix-statfs (file buf) + _N"Return information about the filesystem on which FILE resides." + (int-syscall ("statfs64" c-string (* (struct statfs))) + (%name->file file) buf)) + +;;; sys/swap.h + +#+(or) +(defun unix-swapon (path flags) + _N"Make the block special device PATH available to the system for swapping. + This call is restricted to the super-user." + (int-syscall ("swapon" c-string int) (%name->file path) flags)) + +#+(or) +(defun unix-swapoff (path) + _N"Make the block special device PATH unavailable to the system for swapping. + This call is restricted to the super-user." + (int-syscall ("swapoff" c-string) (%name->file path))) + +;;; sys/sysctl.h + +#+(or) +(defun unix-sysctl (name nlen oldval oldlenp newval newlen) + _N"Read or write system parameters." + (int-syscall ("sysctl" int int (* void) (* void) (* void) size-t) + name nlen oldval oldlenp newval newlen)) + +;;; time.h + +;; POSIX.4 structure for a time value. This is like a `struct timeval' but +;; has nanoseconds instead of microseconds. + +(def-alien-type nil + (struct timespec + (tv-sec long) ;Seconds + (tv-nsec long))) ;Nanoseconds + +;; Used by other time functions. + +(def-alien-type nil + (struct tm + (tm-sec int) ; Seconds. [0-60] (1 leap second) + (tm-min int) ; Minutes. [0-59] + (tm-hour int) ; Hours. [0-23] + (tm-mday int) ; Day. [1-31] + (tm-mon int) ; Month. [0-11] + (tm-year int) ; Year - 1900. + (tm-wday int) ; Day of week. [0-6] + (tm-yday int) ; Days in year.[0-365] + (tm-isdst int) ; DST. [-1/0/1] + (tm-gmtoff long) ; Seconds east of UTC. + (tm-zone c-string))) ; Timezone abbreviation. + +#+(or) +(defun unix-clock () + _N"Time used by the program so far (user time + system time). + The result / CLOCKS_PER_SECOND is program time in seconds." + (int-syscall ("clock"))) + +#+(or) +(defun unix-time (timer) + _N"Return the current time and put it in *TIMER if TIMER is not NULL." + (int-syscall ("time" time-t) timer)) + +;; Requires call to tzset() in main. + +(def-alien-variable ("daylight" unix-daylight) int) +(def-alien-variable ("timezone" unix-timezone) time-t) +;(def-alien-variable ("altzone" unix-altzone) time-t) doesn't exist +(def-alien-variable ("tzname" unix-tzname) (array c-string 2)) + +(def-alien-routine get-timezone c-call:void + (when c-call:long :in) + (minutes-west c-call:int :out) + (daylight-savings-p alien:boolean :out)) + +(defun unix-get-minutes-west (secs) + (multiple-value-bind (ignore minutes dst) (get-timezone secs) + (declare (ignore ignore) (ignore dst)) + (values minutes))) + +(defun unix-get-timezone (secs) + (multiple-value-bind (ignore minutes dst) (get-timezone secs) + (declare (ignore ignore) (ignore minutes)) + (values (deref unix-tzname (if dst 1 0))))) + +;/* Set the current time of day and timezone information. +; This call is restricted to the super-user. */ +;extern int __settimeofday __P ((__const struct timeval *__tv, +; __const struct timezone *__tz)); +;extern int settimeofday __P ((__const struct timeval *__tv, +; __const struct timezone *__tz)); + +;/* Adjust the current time of day by the amount in DELTA. +; If OLDDELTA is not NULL, it is filled in with the amount +; of time adjustment remaining to be done from the last `adjtime' call. +; This call is restricted to the super-user. */ +;extern int __adjtime __P ((__const struct timeval *__delta, +; struct timeval *__olddelta)); +;extern int adjtime __P ((__const struct timeval *__delta, +; struct timeval *__olddelta)); + + +;;; sys/timeb.h + +;; Structure returned by the `ftime' function. + +(def-alien-type nil + (struct timeb + (time time-t) ; Seconds since epoch, as from `time'. + (millitm short) ; Additional milliseconds. + (timezone int) ; Minutes west of GMT. + (dstflag short))) ; Nonzero if Daylight Savings Time used. + +#+(or) +(defun unix-fstime (timebuf) + _N"Fill in TIMEBUF with information about the current time." + (int-syscall ("ftime" (* (struct timeb))) timebuf)) + + +;;; sys/times.h + +;; Structure describing CPU time used by a process and its children. + +(def-alien-type nil + (struct tms + (tms-utime clock-t) ; User CPU time. + (tms-stime clock-t) ; System CPU time. + (tms-cutime clock-t) ; User CPU time of dead children. + (tms-cstime clock-t))) ; System CPU time of dead children. + +#+(or) +(defun unix-times (buffer) + _N"Store the CPU time used by this process and all its + dead children (and their dead children) in BUFFER. + Return the elapsed real time, or (clock_t) -1 for errors. + All times are in CLK_TCKths of a second." + (int-syscall ("times" (* (struct tms))) buffer)) + +;;; sys/wait.h + +#+(or) +(defun unix-wait (status) + _N"Wait for a child to die. When one does, put its status in *STAT_LOC + and return its process ID. For errors, return (pid_t) -1." + (int-syscall ("wait" (* int)) status)) + +#+(or) +(defun unix-waitpid (pid status options) + _N"Wait for a child matching PID to die. + If PID is greater than 0, match any process whose process ID is PID. + If PID is (pid_t) -1, match any process. + If PID is (pid_t) 0, match any process with the + same process group as the current process. + If PID is less than -1, match any process whose + process group is the absolute value of PID. + If the WNOHANG bit is set in OPTIONS, and that child + is not already dead, return (pid_t) 0. If successful, + return PID and store the dead child's status in STAT_LOC. + Return (pid_t) -1 for errors. If the WUNTRACED bit is + set in OPTIONS, return status for stopped children; otherwise don't." + (int-syscall ("waitpit" pid-t (* int) int) + pid status options)) + +;;; the ioctl's. +;;; +;;; I've deleted all the stuff that wasn't in the header files. +;;; This is what survived. + + +;;; asm/sockios.h + +;;; Socket options. + +(define-ioctl-command SIOCSPGRP #x89 #x02) + +(defun siocspgrp (fd pgrp) + _N"Set the socket process-group for the unix file-descriptor FD to PGRP." + (alien:with-alien ((alien-pgrp c-call:int pgrp)) + (unix-ioctl fd + siocspgrp + (alien:alien-sap (alien:addr alien-pgrp))))) + +;;; A few random constants and functions + +(defconstant setuidexec #o4000 _N"Set user ID on execution") +(defconstant setgidexec #o2000 _N"Set group ID on execution") +(defconstant savetext #o1000 _N"Save text image after execution") +(defconstant readown #o400 _N"Read by owner") +(defconstant execown #o100 _N"Execute (search directory) by owner") +(defconstant readgrp #o40 _N"Read by group") +(defconstant writegrp #o20 _N"Write by group") +(defconstant execgrp #o10 _N"Execute (search directory) by group") +(defconstant readoth #o4 _N"Read by others") +(defconstant writeoth #o2 _N"Write by others") +(defconstant execoth #o1 _N"Execute (search directory) by others") + +;;;; Support routines for dealing with unix pathnames. + +(export '(unix-file-kind unix-maybe-prepend-current-directory + unix-resolve-links unix-simplify-pathname)) + +;;; +;;; STRING-LIST-TO-C-STRVEC -- Internal +;;; +;;; STRING-LIST-TO-C-STRVEC is a function which takes a list of +;;; simple-strings and constructs a C-style string vector (strvec) -- +;;; a null-terminated array of pointers to null-terminated strings. +;;; This function returns two values: a sap and a byte count. When the +;;; memory is no longer needed it should be deallocated with +;;; vm_deallocate. +;;; +(defun string-list-to-c-strvec (string-list) + ;; + ;; Make a pass over string-list to calculate the amount of memory + ;; needed to hold the strvec. + (let ((string-bytes 0) + (vec-bytes (* 4 (1+ (length string-list))))) + (declare (fixnum string-bytes vec-bytes)) + (dolist (s string-list) + (check-type s simple-string) + (incf string-bytes (round-bytes-to-words (1+ (length s))))) + ;; + ;; Now allocate the memory and fill it in. + (let* ((total-bytes (+ string-bytes vec-bytes)) + (vec-sap (system:allocate-system-memory total-bytes)) + (string-sap (sap+ vec-sap vec-bytes)) + (i 0)) + (declare (type (and unsigned-byte fixnum) total-bytes i) + (type system:system-area-pointer vec-sap string-sap)) + (dolist (s string-list) + (declare (simple-string s)) + (let ((n (length s))) + ;; + ;; Blast the string into place + #-unicode + (kernel:copy-to-system-area (the simple-string s) + (* vm:vector-data-offset vm:word-bits) + string-sap 0 + (* (1+ n) vm:byte-bits)) + #+unicode + (progn + ;; FIXME: Do we need to apply some kind of transformation + ;; to convert Lisp unicode strings to C strings? Utf-8? + (dotimes (k n) + (setf (sap-ref-8 string-sap k) + (logand #xff (char-code (aref s k))))) + (setf (sap-ref-8 string-sap n) 0)) + ;; + ;; Blast the pointer to the string into place + (setf (sap-ref-sap vec-sap i) string-sap) + (setf string-sap (sap+ string-sap (round-bytes-to-words (1+ n)))) + (incf i 4))) + ;; Blast in last null pointer + (setf (sap-ref-sap vec-sap i) (int-sap 0)) + (values vec-sap total-bytes)))) + +;;; Stuff not yet found in the header files... +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Abandon all hope who enters here... + + +;;;; User and group database access, POSIX Standard 9.2.2 + +(defun unix-getpwnam (login) + _N"Return a USER-INFO structure for the user identified by LOGIN, or NIL if not found." + (declare (type simple-string login)) + (with-alien ((buf (array c-call:char 1024)) + (user-info (struct passwd)) + (result (* (struct passwd)))) + (let ((returned + (alien-funcall + (extern-alien "getpwnam_r" + (function c-call:int + c-call:c-string + (* (struct passwd)) + (* c-call:char) + c-call:unsigned-int + (* (* (struct passwd))))) + login + (addr user-info) + (cast buf (* c-call:char)) + 1024 + (addr result)))) + (when (zerop returned) + (make-user-info + :name (string (cast (slot result 'pw-name) c-call:c-string)) + :password (string (cast (slot result 'pw-passwd) c-call:c-string)) + :uid (slot result 'pw-uid) + :gid (slot result 'pw-gid) + :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) + :dir (string (cast (slot result 'pw-dir) c-call:c-string)) + :shell (string (cast (slot result 'pw-shell) c-call:c-string))))))) + +(defun unix-getgrnam (name) + _N"Return a GROUP-INFO structure for the group identified by NAME, or NIL if not found." + (declare (type simple-string name)) + (with-alien ((buf (array c-call:char 2048)) + (group-info (struct group)) + (result (* (struct group)))) + (let ((returned + (alien-funcall + (extern-alien "getgrnam_r" + (function c-call:int + c-call:c-string + (* (struct group)) + (* c-call:char) + c-call:unsigned-int + (* (* (struct group))))) + name + (addr group-info) + (cast buf (* c-call:char)) + 2048 + (addr result)))) + (when (zerop returned) + (make-group-info + :name (string (cast (slot result 'gr-name) c-call:c-string)) + :password (string (cast (slot result 'gr-passwd) c-call:c-string)) + :gid (slot result 'gr-gid) + :members (loop :with members = (slot result 'gr-mem) + :for i :from 0 + :for member = (deref members i) + :until (zerop (sap-int (alien-sap member))) + :collect (string (cast member c-call:c-string)))))))) + +(defun unix-getgrgid (gid) + _N"Return a GROUP-INFO structure for the group identified by GID, or NIL if not found." + (declare (type unix-gid gid)) + (with-alien ((buf (array c-call:char 2048)) + (group-info (struct group)) + (result (* (struct group)))) + (let ((returned + (alien-funcall + (extern-alien "getgrgid_r" + (function c-call:int + c-call:unsigned-int + (* (struct group)) + (* c-call:char) + c-call:unsigned-int + (* (* (struct group))))) + gid + (addr group-info) + (cast buf (* c-call:char)) + 2048 + (addr result)))) + (when (zerop returned) + (make-group-info + :name (string (cast (slot result 'gr-name) c-call:c-string)) + :password (string (cast (slot result 'gr-passwd) c-call:c-string)) + :gid (slot result 'gr-gid) + :members (loop :with members = (slot result 'gr-mem) + :for i :from 0 + :for member = (deref members i) + :until (zerop (sap-int (alien-sap member))) + :collect (string (cast member c-call:c-string)))))))) + + +;; EOF
===================================== src/contrib/unix/unix.lisp ===================================== --- /dev/null +++ b/src/contrib/unix/unix.lisp @@ -0,0 +1,1116 @@ +;;; -*- Package: UNIX -*- +;;; +;;; ********************************************************************** +;;; This code was written as part of the CMU Common Lisp project at +;;; Carnegie Mellon University, and has been placed in the public domain. +;;; +;;; This contains extra functionality for the UNIX package that is not +;;; needed by CMUCL core. +(ext:file-comment + "$Header: src/contrib/unix/unix.lisp $") +;;; +;;; ********************************************************************** +;;; +;;; This file contains the UNIX low-level support. +;;; +(in-package "UNIX") +(use-package "ALIEN") +(use-package "C-CALL") +(use-package "SYSTEM") +(use-package "EXT") +(intl:textdomain "cmucl-unix") + +(export '(daddr-t caddr-t ino-t swblk-t size-t time-t dev-t off-t uid-t gid-t + timeval tv-sec tv-usec timezone tz-minuteswest tz-dsttime + itimerval it-interval it-value tchars t-intrc t-quitc t-startc + t-stopc t-eofc t-brkc ltchars t-suspc t-dsuspc t-rprntc t-flushc + t-werasc t-lnextc sgttyb sg-ispeed sg-ospeed sg-erase sg-kill + sg-flags winsize ws-row ws-col ws-xpixel ws-ypixel + direct d-off d-ino d-reclen #-(or linux svr4) d-namlen d-name + stat st-dev st-mode st-nlink st-uid st-gid st-rdev st-size + st-atime st-mtime st-ctime st-blksize st-blocks + s-ifmt s-ifdir s-ifchr s-ifblk s-ifreg s-iflnk s-ifsock + s-isuid s-isgid s-isvtx s-iread s-iwrite s-iexec + ruseage ru-utime ru-stime ru-maxrss ru-ixrss ru-idrss + ru-isrss ru-minflt ru-majflt ru-nswap ru-inblock ru-oublock + ru-msgsnd ru-msgrcv ru-nsignals ru-nvcsw ru-nivcsw + rlimit rlim-cur rlim-max sc-onstack sc-mask sc-pc + + unix-errno get-unix-error-msg + + prot_read prot_write prot_exec prot_none + map_shared map_private map_fixed map_anonymous + ms_async ms_sync ms_invalidate + unix-mmap unix-munmap unix-msync + unix-mprotect + + unix-pathname unix-file-mode unix-fd unix-pid unix-uid unix-gid + unix-setitimer unix-getitimer + unix-access r_ok w_ok x_ok f_ok unix-chdir unix-chmod setuidexec + setgidexec savetext readown writeown execown readgrp writegrp + execgrp readoth writeoth execoth unix-fchmod unix-chown unix-fchown + unix-getdtablesize unix-close unix-creat unix-dup unix-dup2 + unix-fcntl f-dupfd f-getfd f-setfd f-getfl f-setfl f-getown f-setown + fndelay fappend fasync fcreat ftrunc fexcl unix-link unix-lseek + l_set l_incr l_xtnd unix-mkdir unix-open o_rdonly o_wronly o_rdwr + #+(or hpux svr4 bsd linux) o_ndelay + #+(or hpux svr4 bsd linux) o_noctty #+(or hpux svr4 bsd) o_nonblock + o_append o_creat o_trunc o_excl unix-pipe unix-read unix-readlink + unix-rename unix-rmdir unix-fast-select fd-setsize fd-set fd-clr + fd-isset fd-zero unix-select unix-sync unix-fsync unix-truncate + unix-ftruncate unix-symlink + #+(and sparc svr4) unix-times + unix-unlink unix-write unix-ioctl + tcsetpgrp tcgetpgrp tty-process-group + terminal-speeds tty-raw tty-crmod tty-echo tty-lcase + #-hpux tty-cbreak #-(or hpux linux) tty-tandem + #+(or hpux svr4 linux bsd) termios + #+(or hpux svr4 linux bsd) c-lflag + #+(or hpux svr4 linux bsd) c-iflag + #+(or hpux svr4 linux bsd) c-oflag + #+(or hpux svr4 linux bsd) tty-icrnl + #+(or hpux svr4 linux) tty-ocrnl + #+(or hpux svr4 bsd) vdsusp #+(or hpux svr4 linux bsd) veof + #+(or hpux svr4 linux bsd) vintr + #+(or hpux svr4 linux bsd) vquit + #+(or hpux svr4 linux bsd) vstart + #+(or hpux svr4 linux bsd) vstop + #+(or hpux svr4 linux bsd) vsusp + #+(or hpux svr4 linux bsd) c-cflag + #+(or hpux svr4 linux bsd) c-cc + #+(or bsd osf1) c-ispeed + #+(or bsd osf1) c-ospeed + #+(or hpux svr4 linux bsd) tty-icanon + #+(or hpux svr4 linux bsd) vmin + #+(or hpux svr4 linux bsd) vtime + #+(or hpux svr4 linux bsd) tty-ixon + #+(or hpux svr4 linux bsd) tcsanow + #+(or hpux svr4 linux bsd) tcsadrain + #+(or hpux svr4 linux bsd) tciflush + #+(or hpux svr4 linux bsd) tcoflush + #+(or hpux svr4 linux bsd) tcioflush + #+(or hpux svr4 linux bsd) tcsaflush + #+(or hpux svr4 linux bsd) unix-tcgetattr + #+(or hpux svr4 linux bsd) unix-tcsetattr + #+(or hpux svr4 bsd) unix-cfgetospeed + #+(or hpux svr4 bsd) unix-cfsetospeed + #+(or hpux svr4 bsd) unix-cfgetispeed + #+(or hpux svr4 bsd) unix-cfsetispeed + #+(or hpux svr4 linux bsd) tty-ignbrk + #+(or hpux svr4 linux bsd) tty-brkint + #+(or hpux svr4 linux bsd) tty-ignpar + #+(or hpux svr4 linux bsd) tty-parmrk + #+(or hpux svr4 linux bsd) tty-inpck + #+(or hpux svr4 linux bsd) tty-istrip + #+(or hpux svr4 linux bsd) tty-inlcr + #+(or hpux svr4 linux bsd) tty-igncr + #+(or hpux svr4 linux) tty-iuclc + #+(or hpux svr4 linux bsd) tty-ixany + #+(or hpux svr4 linux bsd) tty-ixoff + #+hpux tty-ienqak + #+(or hpux irix solaris linux bsd) tty-imaxbel + #+(or hpux svr4 linux bsd) tty-opost + #+(or hpux svr4 linux) tty-olcuc + #+(or hpux svr4 linux bsd) tty-onlcr + #+(or hpux svr4 linux) tty-onocr + #+(or hpux svr4 linux) tty-onlret + #+(or hpux svr4 linux) tty-ofill + #+(or hpux svr4 linux) tty-ofdel + #+(or hpux svr4 linux bsd) tty-isig + #+(or hpux svr4 linux) tty-xcase + #+(or hpux svr4 linux bsd) tty-echoe + #+(or hpux svr4 linux bsd) tty-echok + #+(or hpux svr4 linux bsd) tty-echonl + #+(or hpux svr4 linux bsd) tty-noflsh + #+(or hpux svr4 linux bsd) tty-iexten + #+(or hpux svr4 linux bsd) tty-tostop + #+(or hpux irix solaris linux bsd) tty-echoctl + #+(or hpux irix solaris linux bsd) tty-echoprt + #+(or hpux irix solaris linux bsd) tty-echoke + #+(or hpux irix solaris) tty-defecho + #+(or hpux irix solaris bsd) tty-flusho + #+(or hpux irix solaris linux bsd) tty-pendin + #+(or hpux svr4 linux bsd) tty-cstopb + #+(or hpux svr4 linux bsd) tty-cread + #+(or hpux svr4 linux bsd) tty-parenb + #+(or hpux svr4 linux bsd) tty-parodd + #+(or hpux svr4 linux bsd) tty-hupcl + #+(or hpux svr4 linux bsd) tty-clocal + #+(or irix solaris) rcv1en + #+(or irix solaris) xmt1en + #+(or hpux irix solaris) tty-loblk + #+(or hpux svr4 linux bsd) vintr + #+(or hpux svr4 linux bsd) verase + #+(or hpux svr4 linux bsd) vkill + #+(or hpux svr4 linux bsd) veol + #+(or hpux irix solaris linux bsd) veol2 + #+(or hpux irix solaris) tty-cbaud + #+(or hpux svr4 bsd) tty-csize #+(or hpux svr4 bsd) tty-cs5 + #+(or hpux svr4 bsd) tty-cs6 #+(or hpux svr4 bsd) tty-cs7 + #+(or hpux svr4 bsd) tty-cs8 + #+(or hpux svr4 bsd) unix-tcsendbreak + #+(or hpux svr4 bsd) unix-tcdrain + #+(or hpux svr4 bsd) unix-tcflush + #+(or hpux svr4 bsd) unix-tcflow + + TIOCGETP TIOCSETP TIOCFLUSH TIOCSETC TIOCGETC TIOCSLTC + TIOCGLTC TIOCNOTTY TIOCSPGRP TIOCGPGRP TIOCGWINSZ TIOCSWINSZ + TIOCSIGSEND + + KBDCGET KBDCSET KBDCRESET KBDCRST KBDCSSTD KBDSGET KBDGCLICK + KBDSCLICK FIONREAD #+(or hpux bsd) siocspgrp + unix-exit unix-stat unix-lstat unix-fstat + unix-getrusage unix-fast-getrusage rusage_self rusage_children + unix-gettimeofday + #-hpux unix-utimes #-(or svr4 hpux) unix-setreuid + #-(or svr4 hpux) unix-setregid + unix-getpid unix-getppid + #+(or svr4 bsd)unix-setpgid + unix-getgid unix-getegid unix-getpgrp unix-setpgrp unix-getuid + unix-getpagesize unix-gethostname unix-gethostid unix-fork + unix-getenv unix-setenv unix-putenv unix-unsetenv + unix-current-directory unix-isatty unix-ttyname unix-execve + unix-socket unix-connect unix-bind unix-listen unix-accept + unix-recv unix-send unix-getpeername unix-getsockname + unix-getsockopt unix-setsockopt unix-openpty + + unix-recvfrom unix-sendto unix-shutdown + + unix-getpwnam unix-getpwuid unix-getgrnam unix-getgrgid + user-info user-info-name user-info-password user-info-uid + user-info-gid user-info-gecos user-info-dir user-info-shell + group-info group-info-name group-info-gid group-info-members + + unix-uname)) + + +;;;; Common machine independent structures. + +;;; From sys/types.h + +(def-alien-type u-int64-t (unsigned 64)) + +(def-alien-type daddr-t + #-(or linux alpha) long + #+(or linux alpha) int) + +(def-alien-type caddr-t (* char)) + +(def-alien-type swblk-t long) + + + +;;; Large file support for Solaris. Define some of the 64-bit types +;;; we need. Unlike unix-glibc's large file support, Solaris's +;;; version is a little simpler because all of the 64-bit versions of +;;; the functions actually exist as functions. So instead of calling +;;; the 32-bit versions of the functions, we call the 64-bit versions. +;;; +;;; These functions are: creat64, open64, truncate64, ftruncate64, +;;; stat64, lstat64, fstat64, readdir64. +;;; +;;; There are also some new structures for large file support: +;;; dirent64, stat64. +;;; +;;; FIXME: We should abstract this better, but I (rtoy) don't have any +;;; other system to test this out on, so it's a Solaris hack for now. +#+solaris +(progn + (deftype file-offset64 () '(signed-byte 64)) + (def-alien-type off64-t int64-t) + (def-alien-type ino64-t u-int64-t) + (def-alien-type blkcnt64-t u-int64-t)) + +;;; From sys/time.h + +;;; From ioctl.h + + +;;; From sys/dir.h +;;; + + +;;; From sys/stat.h +;; oh boy, in linux-> 2 stat(s)!! + +#-(or svr4 bsd linux) ; eg hpux and alpha +(def-alien-type nil + (struct stat + (st-dev dev-t) + (st-ino ino-t) + (st-mode mode-t) + (st-nlink nlink-t) + (st-uid uid-t) + (st-gid gid-t) + (st-rdev dev-t) + (st-size off-t) + (st-atime time-t) + (st-spare1 int) + (st-mtime time-t) + (st-spare2 int) + (st-ctime time-t) + (st-spare3 int) + (st-blksize #-alpha long #+alpha unsigned-int) + (st-blocks #-alpha long #+alpha int) + (st-spare4 (array long 2)))) + +#+netbsd +(def-alien-type nil + (struct stat + (st-dev dev-t) + (st-mode mode-t) + (st-ino ino-t) + (st-nlink nlink-t) + (st-uid uid-t) + (st-gid gid-t) + (st-rdev dev-t) + (st-atime (struct timespec-t)) + (st-mtime (struct timespec-t)) + (st-ctime (struct timespec-t)) + (st-birthtime (struct timespec-t)) + (st-size off-t) + (st-blocks off-t) + (st-blksize long) + (st-flags unsigned-long) + (st-gen unsigned-long) + (st-spare (array unsigned-long 2)))) + +;;; From sys/resource.h + +(def-alien-type nil + (struct rlimit + (rlim-cur #-(or linux alpha) int #+linux long #+alpha unsigned-int) ; current (soft) limit + (rlim-max #-(or linux alpha) int #+linux long #+alpha unsigned-int))); maximum value for rlim-cur + + + + +(defun (setf unix-errno) (newvalue) (unix-set-errno newvalue)) + + + +;;;; User and group database structures + + + +(defstruct group-info + (name "" :type string) + (password "" :type string) + (gid 0 :type unix-gid) + (members nil :type list)) ; list of logins as strings + +;; see <grp.h> +(def-alien-type nil + (struct group + (gr-name (* char)) ; name of the group + (gr-passwd (* char)) ; encrypted group password + (gr-gid gid-t) ; numerical group ID + (gr-mem (* (* char))))) ; vector of pointers to member names + + + + +(defun unix-setuid (uid) + _N"Set the user ID of the calling process to UID. + If the calling process is the super-user, set the real + and effective user IDs, and the saved set-user-ID to UID; + if not, the effective user ID is set to UID." + (int-syscall ("setuid" uid-t) uid)) + +(defun unix-setgid (gid) + _N"Set the group ID of the calling process to GID. + If the calling process is the super-user, set the real + and effective group IDs, and the saved set-group-ID to GID; + if not, the effective group ID is set to GID." + (int-syscall ("setgid" gid-t) gid)) + + + +(defun unix-msync (addr length flags) + (declare (type system-area-pointer addr) + (type (unsigned-byte 32) length) + (type (signed-byte 32) flags)) + (syscall ("msync" system-area-pointer size-t int) t addr length flags)) + + + +(defun unix-chown (path uid gid) + _N"Given a file path, an integer user-id, and an integer group-id, + unix-chown changes the owner of the file and the group of the + file to those specified. Either the owner or the group may be + left unchanged by specifying them as -1. Note: Permission will + fail if the caller is not the superuser." + (declare (type unix-pathname path) + (type (or unix-uid (integer -1 -1)) uid) + (type (or unix-gid (integer -1 -1)) gid)) + (void-syscall ("chown" c-string int int) (%name->file path) uid gid)) + +;;; Unix-fchown is exactly the same as unix-chown except that the file +;;; is specified by a file-descriptor ("fd") instead of a pathname. + +(defun unix-fchown (fd uid gid) + _N"Unix-fchown is like unix-chown, except that it accepts an integer + file descriptor instead of a file path name." + (declare (type unix-fd fd) + (type (or unix-uid (integer -1 -1)) uid) + (type (or unix-gid (integer -1 -1)) gid)) + (void-syscall ("fchown" int int int) fd uid gid)) + +;;; Returns the maximum size (i.e. the number of array elements +;;; of the file descriptor table. + +(defun unix-getdtablesize () + _N"Unix-getdtablesize returns the maximum size of the file descriptor + table. (i.e. the maximum number of descriptors that can exist at + one time.)" + (int-syscall ("getdtablesize"))) + +;;; Unix-dup2 makes the second file-descriptor describe the same file +;;; as the first. If the second file-descriptor points to an open +;;; file, it is first closed. In any case, the second should have a +;;; value which is a valid file-descriptor. + +(defun unix-dup2 (fd1 fd2) + _N"Unix-dup2 duplicates an existing file descriptor just as unix-dup + does only the new value of the duplicate descriptor may be requested + through the second argument. If a file already exists with the + requested descriptor number, it will be closed and the number + assigned to the duplicate." + (declare (type unix-fd fd1 fd2)) + (void-syscall ("dup2" int int) fd1 fd2)) + + +;;; Unix-link creates a hard link from name2 to name1. + +(defun unix-link (name1 name2) + _N"Unix-link creates a hard link from the file with name1 to the + file with name2." + (declare (type unix-pathname name1 name2)) + (void-syscall ("link" c-string c-string) + (%name->file name1) (%name->file name2))) + + +;;; Unix-sync writes all information in core memory which has been modified +;;; to permanent storage (i.e. disk). + +(defun unix-sync () + _N"Unix-sync writes all information in core memory which has been + modified to disk. It returns NIL and an error code if an error + occured." + (void-syscall ("sync"))) + +;;; Unix-fsync writes the core-image of the file described by "fd" to +;;; permanent storage (i.e. disk). + +(defun unix-fsync (fd) + _N"Unix-fsync writes the core image of the file described by + fd to disk." + (declare (type unix-fd fd)) + (void-syscall ("fsync" int) fd)) + +;;; Unix-truncate accepts a file name and a new length. The file is +;;; truncated to the new length. + +(defun unix-truncate (name len) + _N"Unix-truncate truncates the named file to the length (in + bytes) specified by len. NIL and an error number is returned + if the call is unsuccessful." + (declare (type unix-pathname name) + (type (unsigned-byte #+solaris 64 #-solaris 32) len)) + #-(and bsd x86) + (void-syscall (#+solaris "truncate64" #-solaris "truncate" c-string int) name len) + #+(and bsd x86) + (void-syscall ("truncate" c-string unsigned-long unsigned-long) name len 0)) + +(defun unix-ftruncate (fd len) + _N"Unix-ftruncate is similar to unix-truncate except that the first + argument is a file descriptor rather than a file name." + (declare (type unix-fd fd) + (type (unsigned-byte #+solaris 64 #-solaris 32) len)) + #-(and bsd x86) + (void-syscall (#+solaris "ftruncate64" #-solaris "ftruncate" int int) fd len) + #+(and bsd x86) + (void-syscall ("ftruncate" int unsigned-long unsigned-long) fd len 0)) + +;;; TTY ioctl commands. + + + +#+(or svr4 hpux bsd linux) +(progn + #+bsd + (defun unix-cfgetospeed (termios) + _N"Get terminal output speed." + (int-syscall ("cfgetospeed" (* (struct termios))) termios)) + + #-bsd + (defun unix-cfsetospeed (termios speed) + _N"Set terminal output speed." + (let ((baud (or (position speed terminal-speeds) + (error _"Bogus baud rate ~S" speed)))) + (void-syscall ("cfsetospeed" (* (struct termios)) int) termios baud))) + + #+bsd + (defun unix-cfsetospeed (termios speed) + _N"Set terminal output speed." + (void-syscall ("cfsetospeed" (* (struct termios)) int) termios speed)) + + #-bsd + (defun unix-cfgetispeed (termios) + _N"Get terminal input speed." + (multiple-value-bind (speed errno) + (int-syscall ("cfgetispeed" (* (struct termios))) termios) + (if speed + (values (svref terminal-speeds speed) 0) + (values speed errno)))) + + #+bsd + (defun unix-cfgetispeed (termios) + _N"Get terminal input speed." + (int-syscall ("cfgetispeed" (* (struct termios))) termios)) + + #-bsd + (defun unix-cfsetispeed (termios speed) + _N"Set terminal input speed." + (let ((baud (or (position speed terminal-speeds) + (error _"Bogus baud rate ~S" speed)))) + (void-syscall ("cfsetispeed" (* (struct termios)) int) termios baud))) + + #+bsd + (defun unix-cfsetispeed (termios speed) + _N"Set terminal input speed." + (void-syscall ("cfsetispeed" (* (struct termios)) int) termios speed)) + + (defun unix-tcsendbreak (fd duration) + _N"Send break" + (declare (type unix-fd fd)) + (void-syscall ("tcsendbreak" int int) fd duration)) + + (defun unix-tcdrain (fd) + _N"Wait for output for finish" + (declare (type unix-fd fd)) + (void-syscall ("tcdrain" int) fd)) + + (defun unix-tcflush (fd selector) + _N"See tcflush(3)" + (declare (type unix-fd fd)) + (void-syscall ("tcflush" int int) fd selector)) + + (defun unix-tcflow (fd action) + _N"Flow control" + (declare (type unix-fd fd)) + (void-syscall ("tcflow" int int) fd action))) + +(defun tcsetpgrp (fd pgrp) + _N"Set the tty-process-group for the unix file-descriptor FD to PGRP." + (alien:with-alien ((alien-pgrp c-call:int pgrp)) + (unix-ioctl fd + tiocspgrp + (alien:alien-sap (alien:addr alien-pgrp))))) + +(defun tcgetpgrp (fd) + _N"Get the tty-process-group for the unix file-descriptor FD." + (alien:with-alien ((alien-pgrp c-call:int)) + (multiple-value-bind (ok err) + (unix-ioctl fd + tiocgpgrp + (alien:alien-sap (alien:addr alien-pgrp))) + (if ok + (values alien-pgrp nil) + (values nil err))))) + +(defun tty-process-group (&optional fd) + _N"Get the tty-process-group for the unix file-descriptor FD. If not supplied, + FD defaults to /dev/tty." + (if fd + (tcgetpgrp fd) + (multiple-value-bind (tty-fd errno) + (unix-open "/dev/tty" o_rdwr 0) + (cond (tty-fd + (multiple-value-prog1 + (tcgetpgrp tty-fd) + (unix-close tty-fd))) + (t + (values nil errno)))))) + +(defun %set-tty-process-group (pgrp &optional fd) + _N"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not + supplied, FD defaults to /dev/tty." + (let ((old-sigs + (unix-sigblock + (sigmask :sigttou :sigttin :sigtstp :sigchld)))) + (declare (type (unsigned-byte 32) old-sigs)) + (unwind-protect + (if fd + (tcsetpgrp fd pgrp) + (multiple-value-bind (tty-fd errno) + (unix-open "/dev/tty" o_rdwr 0) + (cond (tty-fd + (multiple-value-prog1 + (tcsetpgrp tty-fd pgrp) + (unix-close tty-fd))) + (t + (values nil errno))))) + (unix-sigsetmask old-sigs)))) + +(defsetf tty-process-group (&optional fd) (pgrp) + _N"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not + supplied, FD defaults to /dev/tty." + `(%set-tty-process-group ,pgrp ,fd)) + + +;;; Socket options. + +#+(or hpux bsd) +(define-ioctl-command SIOCSPGRP #\s 8 int :in) + +#+linux +(define-ioctl-command SIOCSPGRP #\s #x8904 int :in) + +#+(or hpux bsd linux) +(defun siocspgrp (fd pgrp) + _N"Set the socket process-group for the unix file-descriptor FD to PGRP." + (alien:with-alien ((alien-pgrp c-call:int pgrp)) + (unix-ioctl fd + siocspgrp + (alien:alien-sap (alien:addr alien-pgrp))))) + +;;; Unix-setreuid sets the real and effective user-id's of the current +;;; process to the arguments "ruid" and "euid", respectively. Usage is +;;; restricted for anyone but the super-user. Setting either "ruid" or +;;; "euid" to -1 makes the system use the current id instead. + +#-(or svr4 hpux) +(defun unix-setreuid (ruid euid) + _N"Unix-setreuid sets the real and effective user-id's of the current + process to the specified ones. NIL and an error number is returned + if the call fails." + (void-syscall ("setreuid" int int) ruid euid)) + +;;; Unix-setregid sets the real and effective group-id's of the current +;;; process to the arguments "rgid" and "egid", respectively. Usage is +;;; restricted for anyone but the super-user. Setting either "rgid" or +;;; "egid" to -1 makes the system use the current id instead. + +#-(or svr4 hpux) +(defun unix-setregid (rgid egid) + _N"Unix-setregid sets the real and effective group-id's of the current + process process to the specified ones. NIL and an error number is + returned if the call fails." + (void-syscall ("setregid" int int) rgid egid)) + +(def-alien-routine ("getppid" unix-getppid) int + _N"Unix-getppid returns the process-id of the parent of the current process.") + +(def-alien-routine ("getgid" unix-getgid) int + _N"Unix-getgid returns the real group-id of the current process.") + +(def-alien-routine ("getegid" unix-getegid) int + _N"Unix-getegid returns the effective group-id of the current process.") + +;;; Unix-getpgrp returns the group-id associated with the +;;; current process. + +(defun unix-getpgrp () + _N"Unix-getpgrp returns the group-id of the calling process." + (int-syscall ("getpgrp"))) + +;;; Unix-setpgid sets the group-id of the process specified by +;;; "pid" to the value of "pgrp". The process must either have +;;; the same effective user-id or be a super-user process. + +;;; setpgrp(int int)[freebsd] is identical to setpgid and is retained +;;; for backward compatibility. setpgrp(void)[solaris] is being phased +;;; out in favor of setsid(). + +(defun unix-setpgrp (pid pgrp) + _N"Unix-setpgrp sets the process group on the process pid to + pgrp. NIL and an error number are returned upon failure." + (void-syscall (#-svr4 "setpgrp" #+svr4 "setpgid" int int) pid pgrp)) + +(defun unix-setpgid (pid pgrp) + _N"Unix-setpgid sets the process group of the process pid to + pgrp. If pgid is equal to pid, the process becomes a process + group leader. NIL and an error number are returned upon failure." + (void-syscall ("setpgid" int int) pid pgrp)) + +(defun unix-fork () + _N"Executes the unix fork system call. Returns 0 in the child and the pid + of the child in the parent if it works, or NIL and an error number if it + doesn't work." + (int-syscall ("fork"))) + +;; Environment manipulation; man getenv(3) +(def-alien-routine ("getenv" unix-getenv) c-call:c-string + (name c-call:c-string) + _N"Get the value of the environment variable named Name. If no such + variable exists, Nil is returned.") + +;; This doesn't exist in Solaris 8 but does exist in Solaris 10. +(def-alien-routine ("setenv" unix-setenv) c-call:int + (name c-call:c-string) + (value c-call:c-string) + (overwrite c-call:int) + _N"Adds the environment variable named Name to the environment with + the given Value if Name does not already exist. If Name does exist, + the value is changed to Value if Overwrite is non-zero. Otherwise, + the value is not changed.") + + +(def-alien-routine ("putenv" unix-putenv) c-call:int + (name-value c-call:c-string) + _N"Adds or changes the environment. Name-value must be a string of + the form "name=value". If the name does not exist, it is added. + If name does exist, the value is updated to the given value.") + +;; This doesn't exist in Solaris 8 but does exist in Solaris 10. +(def-alien-routine ("unsetenv" unix-unsetenv) c-call:int + (name c-call:c-string) + _N"Removes the variable Name from the environment") + + +;;;; Support routines for dealing with unix pathnames. + +(export '(unix-file-kind unix-maybe-prepend-current-directory + unix-resolve-links unix-simplify-pathname)) + + +;;;; UNIX-EXECVE + +(defun unix-execve (program &optional arg-list + (environment *environment-list*)) + _N"Executes the Unix execve system call. If the system call suceeds, lisp + will no longer be running in this process. If the system call fails this + function returns two values: NIL and an error code. Arg-list should be a + list of simple-strings which are passed as arguments to the exec'ed program. + Environment should be an a-list mapping symbols to simple-strings which this + function bashes together to form the environment for the exec'ed program." + (check-type program simple-string) + (let ((env-list (let ((envlist nil)) + (dolist (cons environment) + (push (if (cdr cons) + (concatenate 'simple-string + (string (car cons)) "=" + (cdr cons)) + (car cons)) + envlist)) + envlist))) + (sub-unix-execve (%name->file program) arg-list env-list))) + + +(defmacro round-bytes-to-words (n) + `(logand (the fixnum (+ (the fixnum ,n) 3)) (lognot 3))) + +;;; +;;; STRING-LIST-TO-C-STRVEC -- Internal +;;; +;;; STRING-LIST-TO-C-STRVEC is a function which takes a list of +;;; simple-strings and constructs a C-style string vector (strvec) -- +;;; a null-terminated array of pointers to null-terminated strings. +;;; This function returns two values: a sap and a byte count. When the +;;; memory is no longer needed it should be deallocated with +;;; vm_deallocate. +;;; +(defun string-list-to-c-strvec (string-list) + ;; + ;; Make a pass over string-list to calculate the amount of memory + ;; needed to hold the strvec. + (let ((string-bytes 0) + (vec-bytes (* 4 (1+ (length string-list))))) + (declare (fixnum string-bytes vec-bytes)) + (dolist (s string-list) + (check-type s simple-string) + (incf string-bytes (round-bytes-to-words (1+ (length s))))) + ;; + ;; Now allocate the memory and fill it in. + (let* ((total-bytes (+ string-bytes vec-bytes)) + (vec-sap (system:allocate-system-memory total-bytes)) + (string-sap (sap+ vec-sap vec-bytes)) + (i 0)) + (declare (type (and unsigned-byte fixnum) total-bytes i) + (type system:system-area-pointer vec-sap string-sap)) + (dolist (s string-list) + (declare (simple-string s)) + (let ((n (length s))) + ;; + ;; Blast the string into place + #-unicode + (kernel:copy-to-system-area (the simple-string s) + (* vm:vector-data-offset vm:word-bits) + string-sap 0 + (* (1+ n) vm:byte-bits)) + #+unicode + (progn + ;; FIXME: Do we need to apply some kind of transformation + ;; to convert Lisp unicode strings to C strings? Utf-8? + (dotimes (k n) + (setf (sap-ref-8 string-sap k) + (logand #xff (char-code (aref s k))))) + (setf (sap-ref-8 string-sap n) 0)) + + ;; + ;; Blast the pointer to the string into place + (setf (sap-ref-sap vec-sap i) string-sap) + (setf string-sap (sap+ string-sap (round-bytes-to-words (1+ n)))) + (incf i 4))) + ;; Blast in last null pointer + (setf (sap-ref-sap vec-sap i) (int-sap 0)) + (values vec-sap total-bytes)))) + +(defun sub-unix-execve (program arg-list env-list) + (let ((argv nil) + (argv-bytes 0) + (envp nil) + (envp-bytes 0) + result error-code) + (unwind-protect + (progn + ;; Blast the stuff into the proper format + (multiple-value-setq + (argv argv-bytes) + (string-list-to-c-strvec arg-list)) + (multiple-value-setq + (envp envp-bytes) + (string-list-to-c-strvec env-list)) + ;; + ;; Now do the system call + (multiple-value-setq + (result error-code) + (int-syscall ("execve" + c-string system-area-pointer system-area-pointer) + program argv envp))) + ;; + ;; Deallocate memory + (when argv + (system:deallocate-system-memory argv argv-bytes)) + (when envp + (system:deallocate-system-memory envp envp-bytes))) + (values result error-code))) + + + +;;; +;;; Support for the Interval Timer (experimental) +;;; + + +(defun unix-getitimer (which) + _N"Unix-getitimer returns the INTERVAL and VALUE slots of one of + three system timers (:real :virtual or :profile). On success, + unix-getitimer returns 5 values, + T, it-interval-secs, it-interval-usec, it-value-secs, it-value-usec." + (declare (type (member :real :virtual :profile) which) + (values t + #+netbsd (unsigned-byte 63) #-netbsd (unsigned-byte 29) + (mod 1000000) + #+netbsd (unsigned-byte 63) #-netbsd (unsigned-byte 29) + (mod 1000000))) + (let ((which (ecase which + (:real ITIMER-REAL) + (:virtual ITIMER-VIRTUAL) + (:profile ITIMER-PROF)))) + (with-alien ((itv (struct itimerval))) + (syscall* (#-netbsd "getitimer" #+netbsd "__getitimer50" int (* (struct itimerval))) + (values T + (slot (slot itv 'it-interval) 'tv-sec) + (slot (slot itv 'it-interval) 'tv-usec) + (slot (slot itv 'it-value) 'tv-sec) + (slot (slot itv 'it-value) 'tv-usec)) + which (alien-sap (addr itv)))))) + + +;;;; User and group database access, POSIX Standard 9.2.2 + +#+solaris +(defun unix-getpwnam (login) + _N"Return a USER-INFO structure for the user identified by LOGIN, or NIL if not found." + (declare (type simple-string login)) + (with-alien ((buf (array c-call:char 1024)) + (user-info (struct passwd))) + (let ((result + (alien-funcall + (extern-alien "getpwnam_r" + (function (* (struct passwd)) + c-call:c-string + (* (struct passwd)) + (* c-call:char) + c-call:unsigned-int)) + login + (addr user-info) + (cast buf (* c-call:char)) + 1024))) + (when (not (zerop (sap-int (alien-sap result)))) + (make-user-info + :name (string (cast (slot result 'pw-name) c-call:c-string)) + :password (string (cast (slot result 'pw-passwd) c-call:c-string)) + :uid (slot result 'pw-uid) + :gid (slot result 'pw-gid) + :age (string (cast (slot result 'pw-age) c-call:c-string)) + :comment (string (cast (slot result 'pw-comment) c-call:c-string)) + :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) + :dir (string (cast (slot result 'pw-dir) c-call:c-string)) + :shell (string (cast (slot result 'pw-shell) c-call:c-string))))))) + +#+bsd +(defun unix-getpwnam (login) + _N"Return a USER-INFO structure for the user identified by LOGIN, or NIL if not found." + (declare (type simple-string login)) + (let ((result + (alien-funcall + (extern-alien "getpwnam" + (function (* (struct passwd)) + c-call:c-string)) + login))) + (when (not (zerop (sap-int (alien-sap result)))) + (make-user-info + :name (string (cast (slot result 'pw-name) c-call:c-string)) + :password (string (cast (slot result 'pw-passwd) c-call:c-string)) + :uid (slot result 'pw-uid) + :gid (slot result 'pw-gid) + #-darwin :change #-darwin (slot result 'pw-change) + :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) + :dir (string (cast (slot result 'pw-dir) c-call:c-string)) + :shell (string (cast (slot result 'pw-shell) c-call:c-string)))))) + + +#+solaris +(eval-when (:compile-toplevel :load-toplevel :execute) + ;; sysconf(_SC_GETGR_R_SIZE_MAX) + (defconstant +sc-getgr-r-size-max+ 7296 + _N"The maximum size of the group entry buffer")) + +#+solaris +(defun unix-getgrnam (name) + _N"Return a GROUP-INFO structure for the group identified by NAME, or NIL if not found." + (declare (type simple-string name)) + (with-alien ((buf (array c-call:char #.+sc-getgr-r-size-max+)) + (group-info (struct group))) + (let ((result + (alien-funcall + (extern-alien "getgrnam_r" + (function (* (struct group)) + c-call:c-string + (* (struct group)) + (* c-call:char) + c-call:unsigned-int)) + name + (addr group-info) + (cast buf (* c-call:char)) + #.+sc-getgr-r-size-max+))) + (unless (zerop (sap-int (alien-sap result))) + (make-group-info + :name (string (cast (slot result 'gr-name) c-call:c-string)) + :password (string (cast (slot result 'gr-passwd) c-call:c-string)) + :gid (slot result 'gr-gid) + :members (loop :with members = (slot result 'gr-mem) + :for i :from 0 + :for member = (deref members i) + :until (zerop (sap-int (alien-sap member))) + :collect (string (cast member c-call:c-string)))))))) + +#+bsd +(defun unix-getgrnam (name) + _N"Return a GROUP-INFO structure for the group identified by NAME, or NIL if not found." + (declare (type simple-string name)) + (let ((result + (alien-funcall + (extern-alien "getgrnam" + (function (* (struct group)) + c-call:c-string)) + name))) + (unless (zerop (sap-int (alien-sap result))) + (make-group-info + :name (string (cast (slot result 'gr-name) c-call:c-string)) + :password (string (cast (slot result 'gr-passwd) c-call:c-string)) + :gid (slot result 'gr-gid) + :members (loop :with members = (slot result 'gr-mem) + :for i :from 0 + :for member = (deref members i) + :until (zerop (sap-int (alien-sap member))) + :collect (string (cast member c-call:c-string))))))) + +#+solaris +(defun unix-getgrgid (gid) + _N"Return a GROUP-INFO structure for the group identified by GID, or NIL if not found." + (declare (type unix-gid gid)) + (with-alien ((buf (array c-call:char #.+sc-getgr-r-size-max+)) + (group-info (struct group))) + (let ((result + (alien-funcall + (extern-alien "getgrgid_r" + (function (* (struct group)) + c-call:unsigned-int + (* (struct group)) + (* c-call:char) + c-call:unsigned-int)) + gid + (addr group-info) + (cast buf (* c-call:char)) + #.+sc-getgr-r-size-max+))) + (unless (zerop (sap-int (alien-sap result))) + (make-group-info + :name (string (cast (slot result 'gr-name) c-call:c-string)) + :password (string (cast (slot result 'gr-passwd) c-call:c-string)) + :gid (slot result 'gr-gid) + :members (loop :with members = (slot result 'gr-mem) + :for i :from 0 + :for member = (deref members i) + :until (zerop (sap-int (alien-sap member))) + :collect (string (cast member c-call:c-string)))))))) + +#+bsd +(defun unix-getgrgid (gid) + _N"Return a GROUP-INFO structure for the group identified by GID, or NIL if not found." + (declare (type unix-gid gid)) + (let ((result + (alien-funcall + (extern-alien "getgrgid" + (function (* (struct group)) + c-call:unsigned-int)) + gid))) + (unless (zerop (sap-int (alien-sap result))) + (make-group-info + :name (string (cast (slot result 'gr-name) c-call:c-string)) + :password (string (cast (slot result 'gr-passwd) c-call:c-string)) + :gid (slot result 'gr-gid) + :members (loop :with members = (slot result 'gr-mem) + :for i :from 0 + :for member = (deref members i) + :until (zerop (sap-int (alien-sap member))) + :collect (string (cast member c-call:c-string))))))) + +#+solaris +(defun unix-setpwent () + (void-syscall ("setpwent"))) + +#+solaris +(defun unix-endpwent () + (void-syscall ("endpwent"))) + +#+solaris +(defun unix-getpwent () + (with-alien ((buf (array c-call:char 1024)) + (user-info (struct passwd))) + (let ((result + (alien-funcall + (extern-alien "getpwent_r" + (function (* (struct passwd)) + (* (struct passwd)) + (* c-call:char) + c-call:unsigned-int)) + (addr user-info) + (cast buf (* c-call:char)) + 1024))) + (when (not (zerop (sap-int (alien-sap result)))) + (make-user-info + :name (string (cast (slot result 'pw-name) c-call:c-string)) + :password (string (cast (slot result 'pw-passwd) c-call:c-string)) + :uid (slot result 'pw-uid) + :gid (slot result 'pw-gid) + :age (string (cast (slot result 'pw-age) c-call:c-string)) + :comment (string (cast (slot result 'pw-comment) c-call:c-string)) + :gecos (string (cast (slot result 'pw-gecos) c-call:c-string)) + :dir (string (cast (slot result 'pw-dir) c-call:c-string)) + :shell (string (cast (slot result 'pw-shell) c-call:c-string))))))) + +#+(and solaris svr4) +(export '(unix-sysinfo + si-sysname si-hostname si-release si-version si-machine + si-architecture si-hw-serial si-hw-provider si-srpc-domain + si-platform si-isalist si-dhcp-cache)) + +#+(and solaris svr4) +(progn +;; From sys/systeminfo.h. We don't list the set values here. +(def-enum + 1 + si-sysname si-hostname si-release si-version si-machine + si-architecture si-hw-serial si-hw-provider si-srpc-domain) + +(def-enum + 513 + si-platform si-isalist si-dhcp-cache) + + +(defun unix-sysinfo (command) + ;; Hope a buffer of length 2048 is long enough. + (with-alien ((buf (array c-call:unsigned-char 2048))) + (let ((result + (alien-funcall + (extern-alien "sysinfo" + (function c-call:int + c-call:int + c-call:c-string + c-call:int)) + command + (cast buf (* c-call:char)) + 2048))) + (when (>= result 0) + (cast buf c-call:c-string))))) +) + +#+solaris +(export '(rlimit_cpu rlimit_fsize rlimit_data rlimit_stack rlimit_core rlimit_nofile + rlimit_vmem rlimit_as)) + +#+solaris +(progn +(defconstant rlimit_cpu 0 + _N"CPU time per process (in milliseconds)") +(defconstant rlimit_fsize 1 + _N"Maximum file size") +(defconstant rlimit_data 2 + _N"Data segment size") +(defconstant rlimit_stack 3 + _N"Stack size") +(defconstant rlimit_core 4 + _N"Core file size") +(defconstant rlimit_nofile 5 + _N"Number of open files") +(defconstant rlimit_vmem 6 + _N"Maximum mapped memory") +(defconstant rlimit_as rlimit_vmem) +) + +#+(and darwin x86) +(export '(rlimit_cpu rlimit_fsize rlimit_data rlimit_stack rlimit_core + rlimit_as rlimit_rss rlimit_memlock rlimit_nproc rlimit_nofile)) + +#+(and darwin x86) +(progn +(defconstant rlimit_cpu 0 + _N"CPU time per process") +(defconstant rlimit_fsize 1 + _N"File size") +(defconstant rlimit_data 2 + _N"Data segment size") +(defconstant rlimit_stack 3 + _N"Stack size") +(defconstant rlimit_core 4 + _N"Core file size") +(defconstant rlimit_as 5 + _N"Addess space (resident set size)") +(defconstant rlimit_rss rlimit_as) +(defconstant rlimit_memlock 6 + _N"Locked-in-memory address space") +(defconstant rlimit_nproc 7 + _N"Number of processes") +(defconstant rlimit_nofile 8 + _N"Number of open files") +) + + +#+(or solaris (and darwin x86)) +(export '(unix-getrlimit)) + +#+(or solaris (and darwin x86)) +(defun unix-getrlimit (resource) + _N"Get the limits on the consumption of system resouce specified by + Resource. If successful, return three values: T, the current (soft) + limit, and the maximum (hard) limit." + + (with-alien ((rlimit (struct rlimit))) + (syscall ("getrlimit" c-call:int (* (struct rlimit))) + (values t + (slot rlimit 'rlim-cur) + (slot rlimit 'rlim-max)) + resource (addr rlimit)))) +;; EOF
===================================== src/i18n/locale/cmucl-unix-glibc2.pot ===================================== --- a/src/i18n/locale/cmucl-unix-glibc2.pot +++ b/src/i18n/locale/cmucl-unix-glibc2.pot @@ -16,712 +16,701 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n"
#: src/code/unix-glibc2.lisp -msgid "Class not yet defined: ~S" +msgid "" +"Put the absolute pathname of the current working directory in BUF.\n" +" If successful, return BUF. If not, put an error message in\n" +" BUF and return NULL. BUF should be at least PATH_MAX bytes long." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Returns a string describing the error number which was returned by a\n" -" UNIX system call." +msgid "Open for reading" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Unknown error [~d]" +msgid "Open for writing" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-rename renames the file with string name1 to the string\n" -" name2. NIL and an error code is returned if an error occured." +msgid "Read-only flag." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Test for read permission" +msgid "Write-only flag." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Test for write permission" +msgid "Read-write flag." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Test for execute permission" +msgid "Access mode mask." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Test for presence of file" +msgid "Create if nonexistant flag. (not fcntl)" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-fcntl manipulates file descriptors accoridng to the\n" -" argument CMD which can be one of the following:\n" -"\n" -" F-DUPFD Duplicate a file descriptor.\n" -" F-GETFD Get file descriptor flags.\n" -" F-SETFD Set file descriptor flags.\n" -" F-GETFL Get file flags.\n" -" F-SETFL Set file flags.\n" -" F-GETOWN Get owner.\n" -" F-SETOWN Set owner.\n" -"\n" -" The flags that can be specified for F-SETFL are:\n" -"\n" -" FNDELAY Non-blocking reads.\n" -" FAPPEND Append on each write.\n" -" FASYNC Signal pgrp when data ready.\n" -" FCREAT Create if nonexistant.\n" -" FTRUNC Truncate to zero length.\n" -" FEXCL Error if already created.\n" -" " +msgid "Error if already exists. (not fcntl)" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-open opens the file whose pathname is specified by PATH\n" -" for reading and/or writing as specified by the FLAGS argument.\n" -" Returns an integer file descriptor.\n" -" The flags argument can be:\n" -"\n" -" o_rdonly Read-only flag.\n" -" o_wronly Write-only flag.\n" -" o_rdwr Read-and-write flag.\n" -" o_append Append flag.\n" -" o_creat Create-if-nonexistant flag.\n" -" o_trunc Truncate-to-size-0 flag.\n" -" o_excl Error if the file already exists\n" -" o_noctty Don't assign controlling tty\n" -" o_ndelay Non-blocking I/O\n" -" o_sync Synchronous I/O\n" -" o_async Asynchronous I/O\n" -"\n" -" If the o_creat flag is specified, then the file is created with\n" -" a permission of argument MODE if the file doesn't exist." +msgid "Don't assign controlling tty. (not fcntl)" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-getdtablesize returns the maximum size of the file descriptor\n" -" table. (i.e. the maximum number of descriptors that can exist at\n" -" one time.)" +msgid "Truncate flag. (not fcntl)" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-close takes an integer file descriptor as an argument and\n" -" closes the file associated with it. T is returned upon successful\n" -" completion, otherwise NIL and an error number." +msgid "Append flag." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-creat accepts a file name and a mode (same as those for\n" -" unix-chmod) and creates a file by that name with the specified\n" -" permission mode. It returns a file descriptor on success,\n" -" or NIL and an error number otherwise.\n" -"\n" -" This interface is made obsolete by UNIX-OPEN." +msgid "Non-blocking I/O" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Open for reading" +msgid "Synchronous writes (on ext2)" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Open for writing" +msgid "Asynchronous I/O" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Read-only flag." +msgid "Get lock" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Write-only flag." +msgid "Set lock" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Read-write flag." +msgid "Set lock, wait for release" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Access mode mask." +msgid "Set owner (for sockets)" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Create if nonexistant flag. (not fcntl)" +msgid "Get owner (for sockets)" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Error if already exists. (not fcntl)" +msgid "for f-getfl and f-setfl" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Don't assign controlling tty. (not fcntl)" +msgid "" +"Unix-open opens the file whose pathname is specified by PATH\n" +" for reading and/or writing as specified by the FLAGS argument.\n" +" Returns an integer file descriptor.\n" +" The flags argument can be:\n" +"\n" +" o_rdonly Read-only flag.\n" +" o_wronly Write-only flag.\n" +" o_rdwr Read-and-write flag.\n" +" o_append Append flag.\n" +" o_creat Create-if-nonexistant flag.\n" +" o_trunc Truncate-to-size-0 flag.\n" +" o_excl Error if the file already exists\n" +" o_noctty Don't assign controlling tty\n" +" o_ndelay Non-blocking I/O\n" +" o_sync Synchronous I/O\n" +" o_async Asynchronous I/O\n" +"\n" +" If the o_creat flag is specified, then the file is created with\n" +" a permission of argument MODE if the file doesn't exist." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Truncate flag. (not fcntl)" +msgid "Successful" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Append flag." +msgid "Operation not permitted" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Non-blocking I/O" +msgid "No such file or directory" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Synchronous writes (on ext2)" +msgid "No such process" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Asynchronous I/O" +msgid "Interrupted system call" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Duplicate a file descriptor" +msgid "I/O error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get file desc. flags" +msgid "No such device or address" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set file desc. flags" +msgid "Arg list too long" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get file flags" +msgid "Exec format error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set file flags" +msgid "Bad file number" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get lock" +msgid "No children" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set lock" +msgid "Try again" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set lock, wait for release" +msgid "Out of memory" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set owner (for sockets)" +msgid "Permission denied" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get owner (for sockets)" +msgid "Bad address" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "for f-getfl and f-setfl" +msgid "Block device required" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "for fcntl and lockf" +msgid "Device or resource busy" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "old bsd flock (depricated)" +msgid "File exists" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Shared lock for bsd flock" +msgid "Cross-device link" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Exclusive lock for bsd flock" +msgid "No such device" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Don't block. Combine with F-LOCK-SH or F-LOCK-EX" +msgid "Not a director" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Remove lock for bsd flock" +msgid "Is a directory" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "depricated stuff" +msgid "Invalid argument" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Rewind the group-file stream." +msgid "File table overflow" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Close the group-file stream." +msgid "Too many open files" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Read an entry from the group-file stream, opening it if necessary." +msgid "Not a typewriter" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Size of control character vector." +msgid "Text file busy" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "See errno." +msgid "File too large" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "No problem." +msgid "No space left on device" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Authoritative Answer Host not found." +msgid "Illegal seek" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Non-Authoritative Host not found,or SERVERFAIL." +msgid "Read-only file system" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Non recoverable errors, FORMERR, REFUSED, NOTIMP." +msgid "Too many links" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Valid name, no data record of requested type." +msgid "Broken pipe" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "No address, look for MX record." +msgid "Math argument out of domain" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Open host data base files and mark them as staying open even after\n" -"a later search if STAY_OPEN is non-zero." +msgid "Math result not representable" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Close host data base files and clear `stay open' flag." +msgid "Resource deadlock would occur" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get next entry from host data base file. Open data base if\n" -"necessary." +msgid "File name too long" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Return entry from host data base which address match ADDR with\n" -"length LEN and type TYPE." +msgid "No record locks available" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Return entry from host data base for host with NAME." +msgid "Function not implemented" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Return entry from host data base for host with NAME. AF must be\n" -" set to the address type which as `AF_INET' for IPv4 or `AF_INET6'\n" -" for IPv6." +msgid "Directory not empty" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Open network data base files and mark them as staying open even\n" -" after a later search if STAY_OPEN is non-zero." +msgid "Too many symbolic links encountered" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Close network data base files and clear `stay open' flag." +msgid "Operation would block" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Get next entry from network data base file. Open data base if\n" -" necessary." +msgid "No message of desired type" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Return entry from network data base which address match NET and\n" -" type TYPE." +msgid "Identifier removed" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Return entry from network data base for network with NAME." +msgid "Channel number out of range" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Open service data base files and mark them as staying open even\n" -" after a later search if STAY_OPEN is non-zero." +msgid "Level 2 not synchronized" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Close service data base files and clear `stay open' flag." +msgid "Level 3 halted" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Get next entry from service data base file. Open data base if\n" -" necessary." +msgid "Level 3 reset" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Return entry from network data base for network with NAME and\n" -" protocol PROTO." +msgid "Link number out of range" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Return entry from service data base which matches port PORT and\n" -" protocol PROTO." +msgid "Protocol driver not attached" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Open protocol data base files and mark them as staying open even\n" -" after a later search if STAY_OPEN is non-zero." +msgid "No CSI structure available" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Close protocol data base files and clear `stay open' flag." +msgid "Level 2 halted" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Get next entry from protocol data base file. Open data base if\n" -" necessary." +msgid "Invalid exchange" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Return entry from protocol data base for network with NAME." +msgid "Invalid request descriptor" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Return entry from protocol data base which number is PROTO." +msgid "Exchange full" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Establish network group NETGROUP for enumeration." +msgid "No anode" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Free all space allocated by previous `setnetgrent' call." +msgid "Invalid request code" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Get next member of netgroup established by last `setnetgrent' call\n" -" and return pointers to elements in HOSTP, USERP, and DOMAINP." +msgid "Invalid slot" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Test whether NETGROUP contains the triple (HOST,USER,DOMAIN)." +msgid "File locking deadlock error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Socket address is intended for `bind'." +msgid "Bad font file format" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Request for canonical name." +msgid "Device not a stream" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Invalid value for `ai_flags' field." +msgid "No data available" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "NAME or SERVICE is unknown." +msgid "Timer expired" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Temporary failure in name resolution." +msgid "Out of streams resources" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Non-recoverable failure in name res." +msgid "Machine is not on the network" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "No address associated with NAME." +msgid "Package not installed" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "ai_family not supported." +msgid "Object is remote" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "ai_socktype not supported." +msgid "Link has been severed" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "SERVICE not supported for ai_socktype." +msgid "Advertise error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Address family for NAME not supported." +msgid "Srmount error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Memory allocation failure." +msgid "Communication error on send" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "System error returned in errno." +msgid "Protocol error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Translate name of a service location and/or a service name to set of\n" -" socket addresses." +msgid "Multihop attempted" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Free `addrinfo' structure AI including associated storage." +msgid "RFS specific error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Create pseudo tty master slave pair with NAME and set terminal\n" -" attributes according to TERMP and WINP and return handles for both\n" -" ends in AMASTER and ASLAVE." +msgid "Not a data message" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Create child process and establish the slave pseudo terminal as the\n" -" child's controlling terminal." +msgid "Value too large for defined data type" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Rewind the password-file stream." +msgid "Name not unique on network" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Close the password-file stream." +msgid "File descriptor in bad state" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Read an entry from the password-file stream, opening it if necessary." +msgid "Remote address changed" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "The calling process." +msgid "Can not access a needed shared library" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Terminated child processes." +msgid "Accessing a corrupted shared library" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Minimum priority a process can have" +msgid ".lib section in a.out corrupted" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Maximum priority a process can have" +msgid "Attempting to link in too many shared libraries" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "WHO is a process ID" +msgid "Cannot exec a shared library directly" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "WHO is a process group ID" +msgid "Illegal byte sequence" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "WHO is a user ID" +msgid "Interrupted system call should be restarted _N" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set scheduling algorithm and/or parameters for a process." +msgid "Streams pipe error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Retrieve scheduling algorithm for a particular purpose." +msgid "Too many users" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get maximum priority value for a scheduler." +msgid "Socket operation on non-socket" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get minimum priority value for a scheduler." +msgid "Destination address required" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get the SCHED_RR interval for the named process." +msgid "Message too long" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Signal mask to be sent at exit." +msgid "Protocol wrong type for socket" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set if VM shared between processes." +msgid "Protocol not available" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set if fs info shared between processes" +msgid "Protocol not supported" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set if open files shared between processe" +msgid "Socket type not supported" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set if signal handlers shared." +msgid "Operation not supported on transport endpoint" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set if pid shared." +msgid "Protocol family not supported" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Open database for reading." +msgid "Address family not supported by protocol" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Close database." +msgid "Address already in use" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get next entry from database, perhaps after opening the file." +msgid "Cannot assign requested address" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get shadow entry matching NAME." +msgid "Network is down" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Read shadow entry from STRING." +msgid "Network is unreachable" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Protect password file against multi writers." +msgid "Network dropped connection because of reset" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Unlock password file." +msgid "Software caused connection abort" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "These bits determine file type." +msgid "Connection reset by peer" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "FIFO" +msgid "No buffer space available" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Character device" +msgid "Transport endpoint is already connected" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Directory" +msgid "Transport endpoint is not connected" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Block device" +msgid "Cannot send after transport endpoint shutdown" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Regular file" +msgid "Too many references: cannot splice" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Symbolic link." +msgid "Connection timed out" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Socket." +msgid "Connection refused" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set user ID on execution." +msgid "Host is down" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set group ID on execution." +msgid "No route to host" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Save swapped text after use (sticky)." +msgid "Operation already in progress" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Read by owner" +msgid "Operation now in progress" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Write by owner." +msgid "Stale NFS file handle" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Execute by owner." +msgid "Structure needs cleaning" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get terminal output speed." +msgid "Not a XENIX named type file" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set terminal output speed." +msgid "No XENIX semaphores available" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Bogus baud rate ~S" +msgid "Is a named type file" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get terminal input speed." +msgid "Remote I/O error" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set terminal input speed." +msgid "Quota exceeded" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get terminal attributes." +msgid "" +"Returns a string describing the error number which was returned by a\n" +" UNIX system call." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Set terminal attributes." +msgid "Unknown error [~d]" +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "" +"Unix-write attempts to write a character buffer (buf) of length\n" +" len to the file described by the file descriptor fd. NIL and an\n" +" error is returned if the call is unsuccessful." +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "" +"Unix-pipe sets up a unix-piping mechanism consisting of\n" +" an input pipe and an output pipe. Unix-Pipe returns two\n" +" values: if no error occurred the first value is the pipe\n" +" to be read from and the second is can be written to. If\n" +" an error occurred the first value is NIL and the second\n" +" the unix error code." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Send break" +msgid "" +"UNIX-READ attempts to read from the file described by fd into\n" +" the buffer buf until it is full. Len is the length of the buffer.\n" +" The number of bytes actually read is returned or NIL and an error\n" +" number if an error occured." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Wait for output for finish" +msgid "Unix-getpagesize returns the number of bytes in a system page." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "See tcflush(3)" +msgid "" +"UNIX-STAT retrieves information about the specified\n" +" file returning them in the form of multiple values.\n" +" See the UNIX Programmer's Manual for a description\n" +" of the values returned. If the call fails, then NIL\n" +" and an error number is returned instead." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Flow control" +msgid "" +"UNIX-FSTAT is similar to UNIX-STAT except the file is specified\n" +" by the file descriptor FD." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Executes the Unix execve system call. If the system call suceeds, lisp\n" -" will no longer be running in this process. If the system call fails " -"this\n" -" function returns two values: NIL and an error code. Arg-list should be " -"a\n" -" list of simple-strings which are passed as arguments to the exec'ed " -"program.\n" -" Environment should be an a-list mapping symbols to simple-strings which " -"this\n" -" function bashes together to form the environment for the exec'ed " -"program." +"UNIX-LSTAT is similar to UNIX-STAT except the specified\n" +" file must be a symbolic link." +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "These bits determine file type." +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "FIFO" +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "Character device" +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "Directory" +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "Block device" +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "Regular file" +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "Symbolic link." +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "Socket." +msgstr "" + +#: src/code/unix-glibc2.lisp +msgid "Returns either :file, :directory, :link, :special, or NIL." msgstr ""
#: src/code/unix-glibc2.lisp @@ -763,55 +752,35 @@ msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"UNIX-READ attempts to read from the file described by fd into\n" -" the buffer buf until it is full. Len is the length of the buffer.\n" -" The number of bytes actually read is returned or NIL and an error\n" -" number if an error occured." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-write attempts to write a character buffer (buf) of length\n" -" len to the file described by the file descriptor fd. NIL and an\n" -" error is returned if the call is unsuccessful." +"Unix-close takes an integer file descriptor as an argument and\n" +" closes the file associated with it. T is returned upon successful\n" +" completion, otherwise NIL and an error number." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Unix-pipe sets up a unix-piping mechanism consisting of\n" -" an input pipe and an output pipe. Unix-Pipe returns two\n" -" values: if no error occurred the first value is the pipe\n" -" to be read from and the second is can be written to. If\n" -" an error occurred the first value is NIL and the second\n" -" the unix error code." +"Unix-creat accepts a file name and a mode (same as those for\n" +" unix-chmod) and creates a file by that name with the specified\n" +" permission mode. It returns a file descriptor on success,\n" +" or NIL and an error number otherwise.\n" +"\n" +" This interface is made obsolete by UNIX-OPEN." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Given a file path, an integer user-id, and an integer group-id,\n" -" unix-chown changes the owner of the file and the group of the\n" -" file to those specified. Either the owner or the group may be\n" -" left unchanged by specifying them as -1. Note: Permission will\n" -" fail if the caller is not the superuser." +msgid "Returns the pathname with all symbolic links resolved." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-fchown is like unix-chown, except that it accepts an integer\n" -" file descriptor instead of a file path name." +msgid "Error reading link ~S: ~S" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Given a file path string, unix-chdir changes the current working \n" -" directory to the one specified." +msgid "Unix-gethostname returns the name of the host machine as a string." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Put the absolute pathname of the current working directory in BUF.\n" -" If successful, return BUF. If not, put an error message in\n" -" BUF and return NULL. BUF should be at least PATH_MAX bytes long." +msgid "Syscall ~A failed: ~A" msgstr ""
#: src/code/unix-glibc2.lisp @@ -838,200 +807,224 @@ msgid "" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get file-specific configuration information about PATH." +msgid "" +"Unix-getuid returns the real user-id associated with the\n" +" current process." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get the value of the system variable NAME." +msgid "" +"Given a file path string, unix-chdir changes the current working \n" +" directory to the one specified." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get the value of the string-valued system variable NAME." +msgid "" +"Given a file path string and a constant mode, unix-chmod changes the\n" +" permission mode for that file to the one specified. The new mode\n" +" can be created by logically OR'ing the following:\n" +"\n" +" setuidexec Set user ID on execution.\n" +" setgidexec Set group ID on execution.\n" +" savetext Save text image after execution.\n" +" readown Read by owner.\n" +" writeown Write by owner.\n" +" execown Execute (search directory) by owner.\n" +" readgrp Read by group.\n" +" writegrp Write by group.\n" +" execgrp Execute (search directory) by group.\n" +" readoth Read by others.\n" +" writeoth Write by others.\n" +" execoth Execute (search directory) by others.\n" +"\n" +" Thus #o444 and (logior unix:readown unix:readgrp unix:readoth)\n" +" are equivalent for 'mode. The octal-base is familar to Unix users.\n" +" \n" +" It returns T on successfully completion; NIL and an error number\n" +" otherwise." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Unix-getpid returns the process-id of the current process." +msgid "" +"Given an integer file descriptor and a mode (the same as those\n" +" used for unix-chmod), unix-fchmod changes the permission mode\n" +" for that file to the one specified. T is returned if the call\n" +" was successful." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Unix-getppid returns the process-id of the parent of the current process." +"Unix-readlink invokes the readlink system call on the file name\n" +" specified by the simple string path. It returns up to two values:\n" +" the contents of the symbolic link if the call is successful, or\n" +" NIL and the Unix error number." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Unix-getpgrp returns the group-id of the calling process." +msgid "" +"Unix-unlink removes the directory entry for the named file.\n" +" NIL and an error code is returned if the call fails." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-setpgrp sets the process group on the process pid to\n" -" pgrp. NIL and an error number are returned upon failure." +msgid "Test for read permission" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-setpgid sets the process group of the process pid to\n" -" pgrp. If pgid is equal to pid, the process becomes a process\n" -" group leader. NIL and an error number are returned upon failure." +msgid "Test for write permission" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Create a new session with the calling process as its leader.\n" -" The process group IDs of the session and the calling process\n" -" are set to the process ID of the calling process, which is returned." +msgid "Test for execute permission" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Return the session ID of the given process." +msgid "Test for presence of file" msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Unix-getuid returns the real user-id associated with the\n" -" current process." +"Unix-fcntl manipulates file descriptors accoridng to the\n" +" argument CMD which can be one of the following:\n" +"\n" +" F-DUPFD Duplicate a file descriptor.\n" +" F-GETFD Get file descriptor flags.\n" +" F-SETFD Set file descriptor flags.\n" +" F-GETFL Get file flags.\n" +" F-SETFL Set file flags.\n" +" F-GETOWN Get owner.\n" +" F-SETOWN Set owner.\n" +"\n" +" The flags that can be specified for F-SETFL are:\n" +"\n" +" FNDELAY Non-blocking reads.\n" +" FAPPEND Append on each write.\n" +" FASYNC Signal pgrp when data ready.\n" +" FCREAT Create if nonexistant.\n" +" FTRUNC Truncate to zero length.\n" +" FEXCL Error if already created.\n" +" " msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Get the effective user ID of the calling process." +msgid "" +"Unix-rename renames the file with string name1 to the string\n" +" name2. NIL and an error code is returned if an error occured." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Unix-getgid returns the real group-id of the current process." +msgid "" +"Unix-rmdir attempts to remove the directory name. NIL and\n" +" an error number is returned if an error occured." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Unix-getegid returns the effective group-id of the current process." +msgid "" +"Define an ioctl command. If the optional ARG and PARM-TYPE are given\n" +" then ioctl argument size and direction are included as for ioctls defined\n" +" by _IO, _IOR, _IOW, or _IOWR. If DEV is a character then the ioctl type\n" +" is the characters code, else DEV may be an integer giving the type." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Return nonzero iff the calling process is in group GID." +msgid "Get file flags" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Set the user ID of the calling process to UID.\n" -" If the calling process is the super-user, set the real\n" -" and effective user IDs, and the saved set-user-ID to UID;\n" -" if not, the effective user ID is set to UID." +msgid "Set file flags" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-setreuid sets the real and effective user-id's of the current\n" -" process to the specified ones. NIL and an error number is returned\n" -" if the call fails." +msgid "depricated stuff" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Set the group ID of the calling process to GID.\n" -" If the calling process is the super-user, set the real\n" -" and effective group IDs, and the saved set-group-ID to GID;\n" -" if not, the effective group ID is set to GID." +msgid "The calling process." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-setregid sets the real and effective group-id's of the current\n" -" process process to the specified ones. NIL and an error number is\n" -" returned if the call fails." +msgid "Class not yet defined: ~S" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Executes the unix fork system call. Returns 0 in the child and the pid\n" -" of the child in the parent if it works, or NIL and an error number if it\n" -" doesn't work." +msgid "Terminated child processes." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Get the value of the environment variable named Name. If no such\n" -" variable exists, Nil is returned." +"Like call getrusage, but return only the system and user time, and returns\n" +" the seconds and microseconds as separate values." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Adds the environment variable named Name to the environment with\n" -" the given Value if Name does not already exist. If Name does exist,\n" -" the value is changed to Value if Overwrite is non-zero. Otherwise,\n" -" the value is not changed." +"Unix-getrusage returns information about the resource usage\n" +" of the process specified by who. Who can be either the\n" +" current process (rusage_self) or all of the terminated\n" +" child processes (rusage_children). NIL and an error number\n" +" is returned if the call fails." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Adds or changes the environment. Name-value must be a string of\n" -" the form "name=value". If the name does not exist, it is added.\n" -" If name does exist, the value is updated to the given value." +msgid "Perform the UNIX select(2) system call." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Removes the variable Name from the environment" +msgid "" +"Unix-select examines the sets of descriptors passed as arguments\n" +" to see if they are ready for reading and writing. See the UNIX\n" +" Programmers Manual for more information." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Accepts a Unix file descriptor and returns T if the device\n" -" associated with it is a terminal." +"Unix-symlink creates a symbolic link named name2 to the file\n" +" named name1. NIL and an error number is returned if the call\n" +" is unsuccessful." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Unix-link creates a hard link from the file with name1 to the\n" -" file with name2." +"Unix-gethostid returns a 32-bit integer which provides unique\n" +" identification for the host machine." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-symlink creates a symbolic link named name2 to the file\n" -" named name1. NIL and an error number is returned if the call\n" -" is unsuccessful." +msgid "Unix-getpid returns the process-id of the current process." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Unix-readlink invokes the readlink system call on the file name\n" -" specified by the simple string path. It returns up to two values:\n" -" the contents of the symbolic link if the call is successful, or\n" -" NIL and the Unix error number." +"Return a USER-INFO structure for the user identified by UID, or NIL if not " +"found." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Unix-unlink removes the directory entry for the named file.\n" -" NIL and an error code is returned if the call fails." +"If it works, unix-gettimeofday returns 5 values: T, the seconds and\n" +" microseconds of the current time of day, the timezone (in minutes west\n" +" of Greenwich), and a daylight-savings flag. If it doesn't work, it\n" +" returns NIL and the errno." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Unix-rmdir attempts to remove the directory name. NIL and\n" -" an error number is returned if an error occured." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Get the tty-process-group for the unix file-descriptor FD." +"Unix-utimes sets the 'last-accessed' and 'last-updated'\n" +" times on a specified file. NIL and an error number is\n" +" returned if the call is unsuccessful." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Get the tty-process-group for the unix file-descriptor FD. If not supplied," -"\n" -" FD defaults to /dev/tty." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Set the tty-process-group for the unix file-descriptor FD to PGRP." +"Accepts a Unix file descriptor and returns T if the device\n" +" associated with it is a terminal." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not\n" -" supplied, FD defaults to /dev/tty." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Return the login name of the user." +"Create pseudo tty master slave pair with NAME and set terminal\n" +" attributes according to TERMP and WINP and return handles for both\n" +" ends in AMASTER and ASLAVE." msgstr ""
#: src/code/unix-glibc2.lisp @@ -1042,125 +1035,6 @@ msgid "" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "Syscall ~A failed: ~A" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Unix-gethostname returns the name of the host machine as a string." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-fsync writes the core image of the file described by\n" -" fd to disk." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Revoke access permissions to all processes currently communicating\n" -" with the control terminal, and then send a SIGHUP signal to the process\n" -" group of the control terminal." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Revoke the access of all descriptors currently open on FILE." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Make PATH be the root directory (the starting point for absolute paths).\n" -" This call is restricted to the super-user." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-gethostid returns a 32-bit integer which provides unique\n" -" identification for the host machine." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-sync writes all information in core memory which has been\n" -" modified to disk. It returns NIL and an error code if an error\n" -" occured." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Unix-getpagesize returns the number of bytes in a system page." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-truncate truncates the named file to the length (in\n" -" bytes) specified by LENGTH. NIL and an error number is returned\n" -" if the call is unsuccessful." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-ftruncate is similar to unix-truncate except that the first\n" -" argument is a file descriptor rather than a file name." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Return the maximum number of file descriptors\n" -" the current process could possibly have." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Unlock a locked region" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Lock a region for exclusive use" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Test and lock a region for exclusive use" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Test a region for othwer processes locks" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-locks can lock, unlock and test files according to the cmd\n" -" which can be one of the following:\n" -"\n" -" f_ulock Unlock a locked region\n" -" f_lock Lock a region for exclusive use\n" -" f_tlock Test and lock a region for exclusive use\n" -" f_test Test a region for othwer processes locks\n" -"\n" -" The lock is for a region from the current location for a length\n" -" of length.\n" -"\n" -" This is a simpler version of the interface provided by unix-fcntl.\n" -" " -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-utimes sets the 'last-accessed' and 'last-updated'\n" -" times on a specified file. NIL and an error number is\n" -" returned if the call is unsuccessful." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Don't block waiting." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Report status of stopped children." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Wait for cloned process." -msgstr "" - -#: src/code/unix-glibc2.lisp msgid "" "Unix-ioctl performs a variety of operations on open i/o\n" " descriptors. See the UNIX Programmer's Manual for more\n" @@ -1169,867 +1043,48 @@ msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"Change uid used for file access control to UID, without affecting\n" -" other priveledges (such as who can send signals at the process)." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Change gid used for file access control to GID, without affecting\n" -" other priveledges (such as who can send signals at the process)." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "There is data to read." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "There is urgent data to read." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Writing now will not block." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Error condition." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Hung up." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Invalid polling request." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Canonical number of polling requests to read\n" -"in at a time in poll." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -" Poll the file descriptors described by the NFDS structures starting at\n" -" FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for\n" -" an event to occur; if TIMEOUT is -1, block until an event occurs.\n" -" Returns the number of file descriptors with events, zero if timed out,\n" -" or -1 for errors." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Get the soft and hard limits for RESOURCE." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Set the current soft and hard maximum limits for RESOURCE.\n" -" Only the super-user can increase hard limits." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Like call getrusage, but return only the system and user time, and returns\n" -" the seconds and microseconds as separate values." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-getrusage returns information about the resource usage\n" -" of the process specified by who. Who can be either the\n" -" current process (rusage_self) or all of the terminated\n" -" child processes (rusage_children). NIL and an error number\n" -" is returned if the call fails." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Function depends on CMD:\n" -" 1 = Return the limit on the size of a file, in units of 512 bytes.\n" -" 2 = Set the limit on the size of a file to NEWLIMIT. Only the\n" -" super-user can increase the limit.\n" -" 3 = Return the maximum possible address of the data segment.\n" -" 4 = Return the maximum number of files that the calling process can open.\n" -" Returns -1 on errors." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Return the highest priority of any process specified by WHICH and WHO\n" -" (see above); if WHO is zero, the current process, process group, or user\n" -" (as specified by WHO) is used. A lower priority number means higher\n" -" priority. Priorities range from PRIO_MIN to PRIO_MAX (above)." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Set the priority of all processes specified by WHICH and WHO (see above)\n" -" to PRIO. Returns 0 on success, -1 on errors." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Perform the UNIX select(2) system call." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-select examines the sets of descriptors passed as arguments\n" -" to see if they are ready for reading and writing. See the UNIX\n" -" Programmers Manual for more information." +"Unix-mkdir creates a new directory with the specified name and mode.\n" +" (Same as those for unix-chmod.) It returns T upon success, otherwise\n" +" NIL and an error number." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"UNIX-STAT retrieves information about the specified\n" -" file returning them in the form of multiple values.\n" -" See the UNIX Programmer's Manual for a description\n" -" of the values returned. If the call fails, then NIL\n" -" and an error number is returned instead." +"Unix-getitimer returns the INTERVAL and VALUE slots of one of\n" +" three system timers (:real :virtual or :profile). On success,\n" +" unix-getitimer returns 5 values,\n" +" T, it-interval-secs, it-interval-usec, it-value-secs, it-value-usec." msgstr ""
#: src/code/unix-glibc2.lisp msgid "" -"UNIX-FSTAT is similar to UNIX-STAT except the file is specified\n" -" by the file descriptor FD." +" Unix-setitimer sets the INTERVAL and VALUE slots of one of\n" +" three system timers (:real :virtual or :profile). A SIGALRM signal\n" +" will be delivered VALUE <seconds+microseconds> from now. INTERVAL,\n" +" when non-zero, is <seconds+microseconds> to be loaded each time\n" +" the timer expires. Setting INTERVAL and VALUE to zero disables\n" +" the timer. See the Unix man page for more details. On success,\n" +" unix-setitimer returns the old contents of the INTERVAL and VALUE\n" +" slots as in unix-getitimer." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"UNIX-LSTAT is similar to UNIX-STAT except the specified\n" -" file must be a symbolic link." +msgid "Size of control character vector." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Given a file path string and a constant mode, unix-chmod changes the\n" -" permission mode for that file to the one specified. The new mode\n" -" can be created by logically OR'ing the following:\n" -"\n" -" setuidexec Set user ID on execution.\n" -" setgidexec Set group ID on execution.\n" -" savetext Save text image after execution.\n" -" readown Read by owner.\n" -" writeown Write by owner.\n" -" execown Execute (search directory) by owner.\n" -" readgrp Read by group.\n" -" writegrp Write by group.\n" -" execgrp Execute (search directory) by group.\n" -" readoth Read by others.\n" -" writeoth Write by others.\n" -" execoth Execute (search directory) by others.\n" -"\n" -" Thus #o444 and (logior unix:readown unix:readgrp unix:readoth)\n" -" are equivalent for 'mode. The octal-base is familar to Unix users.\n" -" \n" -" It returns T on successfully completion; NIL and an error number\n" -" otherwise." +msgid "Get terminal attributes." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Given an integer file descriptor and a mode (the same as those\n" -" used for unix-chmod), unix-fchmod changes the permission mode\n" -" for that file to the one specified. T is returned if the call\n" -" was successful." +msgid "Set terminal attributes." msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Set the file creation mask of the current process to MASK,\n" -" and return the old creation mask." +msgid "Write by owner" msgstr ""
#: src/code/unix-glibc2.lisp -msgid "" -"Unix-mkdir creates a new directory with the specified name and mode.\n" -" (Same as those for unix-chmod.) It returns T upon success, otherwise\n" -" NIL and an error number." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Create a device file named PATH, with permission and special bits MODE\n" -" and device number DEV (which can be constructed from major and minor\n" -" device numbers with the `makedev' macro above)." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Create a new FIFO named PATH, with permission bits MODE." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Return information about the filesystem on which FILE resides." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Make the block special device PATH available to the system for swapping.\n" -" This call is restricted to the super-user." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Make the block special device PATH unavailable to the system for swapping.\n" -" This call is restricted to the super-user." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Read or write system parameters." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Time used by the program so far (user time + system time).\n" -" The result / CLOCKS_PER_SECOND is program time in seconds." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Return the current time and put it in *TIMER if TIMER is not NULL." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"If it works, unix-gettimeofday returns 5 values: T, the seconds and\n" -" microseconds of the current time of day, the timezone (in minutes west\n" -" of Greenwich), and a daylight-savings flag. If it doesn't work, it\n" -" returns NIL and the errno." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Unix-getitimer returns the INTERVAL and VALUE slots of one of\n" -" three system timers (:real :virtual or :profile). On success,\n" -" unix-getitimer returns 5 values,\n" -" T, it-interval-secs, it-interval-usec, it-value-secs, it-value-usec." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -" Unix-setitimer sets the INTERVAL and VALUE slots of one of\n" -" three system timers (:real :virtual or :profile). A SIGALRM signal\n" -" will be delivered VALUE <seconds+microseconds> from now. INTERVAL,\n" -" when non-zero, is <seconds+microseconds> to be loaded each time\n" -" the timer expires. Setting INTERVAL and VALUE to zero disables\n" -" the timer. See the Unix man page for more details. On success,\n" -" unix-setitimer returns the old contents of the INTERVAL and VALUE\n" -" slots as in unix-getitimer." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Fill in TIMEBUF with information about the current time." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Store the CPU time used by this process and all its\n" -" dead children (and their dead children) in BUFFER.\n" -" Return the elapsed real time, or (clock_t) -1 for errors.\n" -" All times are in CLK_TCKths of a second." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Wait for a child to die. When one does, put its status in *STAT_LOC\n" -" and return its process ID. For errors, return (pid_t) -1." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Wait for a child matching PID to die.\n" -" If PID is greater than 0, match any process whose process ID is PID.\n" -" If PID is (pid_t) -1, match any process.\n" -" If PID is (pid_t) 0, match any process with the\n" -" same process group as the current process.\n" -" If PID is less than -1, match any process whose\n" -" process group is the absolute value of PID.\n" -" If the WNOHANG bit is set in OPTIONS, and that child\n" -" is not already dead, return (pid_t) 0. If successful,\n" -" return PID and store the dead child's status in STAT_LOC.\n" -" Return (pid_t) -1 for errors. If the WUNTRACED bit is\n" -" set in OPTIONS, return status for stopped children; otherwise don't." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Successful" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Operation not permitted" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No such file or directory" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No such process" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Interrupted system call" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "I/O error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No such device or address" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Arg list too long" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Exec format error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Bad file number" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No children" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Try again" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Out of memory" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Permission denied" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Bad address" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Block device required" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Device or resource busy" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "File exists" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Cross-device link" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No such device" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Not a director" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Is a directory" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Invalid argument" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "File table overflow" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Too many open files" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Not a typewriter" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Text file busy" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "File too large" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No space left on device" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Illegal seek" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Read-only file system" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Too many links" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Broken pipe" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Math argument out of domain" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Math result not representable" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Resource deadlock would occur" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "File name too long" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No record locks available" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Function not implemented" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Directory not empty" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Too many symbolic links encountered" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Operation would block" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No message of desired type" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Identifier removed" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Channel number out of range" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Level 2 not synchronized" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Level 3 halted" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Level 3 reset" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Link number out of range" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Protocol driver not attached" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No CSI structure available" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Level 2 halted" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Invalid exchange" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Invalid request descriptor" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Exchange full" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No anode" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Invalid request code" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Invalid slot" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "File locking deadlock error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Bad font file format" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Device not a stream" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No data available" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Timer expired" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Out of streams resources" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Machine is not on the network" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Package not installed" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Object is remote" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Link has been severed" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Advertise error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Srmount error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Communication error on send" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Protocol error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Multihop attempted" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "RFS specific error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Not a data message" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Value too large for defined data type" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Name not unique on network" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "File descriptor in bad state" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Remote address changed" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Can not access a needed shared library" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Accessing a corrupted shared library" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid ".lib section in a.out corrupted" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Attempting to link in too many shared libraries" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Cannot exec a shared library directly" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Illegal byte sequence" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Interrupted system call should be restarted _N" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Streams pipe error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Too many users" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Socket operation on non-socket" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Destination address required" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Message too long" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Protocol wrong type for socket" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Protocol not available" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Protocol not supported" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Socket type not supported" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Operation not supported on transport endpoint" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Protocol family not supported" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Address family not supported by protocol" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Address already in use" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Cannot assign requested address" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Network is down" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Network is unreachable" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Network dropped connection because of reset" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Software caused connection abort" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Connection reset by peer" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No buffer space available" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Transport endpoint is already connected" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Transport endpoint is not connected" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Cannot send after transport endpoint shutdown" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Too many references: cannot splice" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Connection timed out" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Connection refused" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Host is down" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No route to host" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Operation already in progress" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Operation now in progress" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Stale NFS file handle" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Structure needs cleaning" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Not a XENIX named type file" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "No XENIX semaphores available" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Is a named type file" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Remote I/O error" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Quota exceeded" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Define an ioctl command. If the optional ARG and PARM-TYPE are given\n" -" then ioctl argument size and direction are included as for ioctls defined\n" -" by _IO, _IOR, _IOW, or _IOWR. If DEV is a character then the ioctl type\n" -" is the characters code, else DEV may be an integer giving the type." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Set the socket process-group for the unix file-descriptor FD to PGRP." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Set user ID on execution" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Set group ID on execution" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Save text image after execution" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Write by owner" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Execute (search directory) by owner" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Read by group" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Write by group" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Execute (search directory) by group" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Read by others" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Write by others" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Execute (search directory) by others" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Returns either :file, :directory, :link, :special, or NIL." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Returns the pathname with all symbolic links resolved." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "Error reading link ~S: ~S" -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Return a USER-INFO structure for the user identified by LOGIN, or NIL if " -"not found." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Return a USER-INFO structure for the user identified by UID, or NIL if not " -"found." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Return a GROUP-INFO structure for the group identified by NAME, or NIL if " -"not found." -msgstr "" - -#: src/code/unix-glibc2.lisp -msgid "" -"Return a GROUP-INFO structure for the group identified by GID, or NIL if " -"not found." +msgid "Get terminal output speed." msgstr ""
===================================== src/i18n/locale/cmucl-unix.pot ===================================== --- a/src/i18n/locale/cmucl-unix.pot +++ b/src/i18n/locale/cmucl-unix.pot @@ -16,1535 +16,1223 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n"
#: src/code/unix.lisp -msgid "Size of control character vector." -msgstr "" - -#: src/code/unix.lisp -msgid "Successful" -msgstr "" - -#: src/code/unix.lisp -msgid "Operation not permitted" -msgstr "" - -#: src/code/unix.lisp -msgid "No such file or directory" -msgstr "" - -#: src/code/unix.lisp -msgid "No such process" -msgstr "" - -#: src/code/unix.lisp -msgid "Interrupted system call" -msgstr "" - -#: src/code/unix.lisp -msgid "I/O error" -msgstr "" - -#: src/code/unix.lisp -msgid "Device not configured" -msgstr "" - -#: src/code/unix.lisp -msgid "Arg list too long" -msgstr "" - -#: src/code/unix.lisp -msgid "Exec format error" -msgstr "" - -#: src/code/unix.lisp -msgid "Bad file descriptor" -msgstr "" - -#: src/code/unix.lisp -msgid "No child process" -msgstr "" - -#: src/code/unix.lisp -msgid "Resource deadlock avoided" -msgstr "" - -#: src/code/unix.lisp -msgid "No more processes" -msgstr "" - -#: src/code/unix.lisp -msgid "Try again" -msgstr "" - -#: src/code/unix.lisp -msgid "Out of memory" -msgstr "" - -#: src/code/unix.lisp -msgid "Permission denied" -msgstr "" - -#: src/code/unix.lisp -msgid "Bad address" -msgstr "" - -#: src/code/unix.lisp -msgid "Block device required" -msgstr "" - -#: src/code/unix.lisp -msgid "Device or resource busy" -msgstr "" - -#: src/code/unix.lisp -msgid "File exists" -msgstr "" - -#: src/code/unix.lisp -msgid "Cross-device link" -msgstr "" - -#: src/code/unix.lisp -msgid "No such device" -msgstr "" - -#: src/code/unix.lisp -msgid "Not a director" -msgstr "" - -#: src/code/unix.lisp -msgid "Is a directory" -msgstr "" - -#: src/code/unix.lisp -msgid "Invalid argument" -msgstr "" - -#: src/code/unix.lisp -msgid "File table overflow" -msgstr "" - -#: src/code/unix.lisp -msgid "Too many open files" -msgstr "" - -#: src/code/unix.lisp -msgid "Inappropriate ioctl for device" -msgstr "" - -#: src/code/unix.lisp -msgid "Text file busy" -msgstr "" - -#: src/code/unix.lisp -msgid "File too large" -msgstr "" - -#: src/code/unix.lisp -msgid "No space left on device" -msgstr "" - -#: src/code/unix.lisp -msgid "Illegal seek" -msgstr "" - -#: src/code/unix.lisp -msgid "Read-only file system" -msgstr "" - -#: src/code/unix.lisp -msgid "Too many links" -msgstr "" - -#: src/code/unix.lisp -msgid "Broken pipe" -msgstr "" - -#: src/code/unix.lisp -msgid "Numerical argument out of domain" -msgstr "" - -#: src/code/unix.lisp -msgid "Result too large" -msgstr "" - -#: src/code/unix.lisp -msgid "Math result not representable" -msgstr "" - -#: src/code/unix.lisp -msgid "Operation would block" -msgstr "" - -#: src/code/unix.lisp -msgid "Resource temporarily unavailable" -msgstr "" - -#: src/code/unix.lisp -msgid "Operation now in progress" -msgstr "" - -#: src/code/unix.lisp -msgid "Operation already in progress" -msgstr "" - -#: src/code/unix.lisp -msgid "Socket operation on non-socket" -msgstr "" - -#: src/code/unix.lisp -msgid "Destination address required" -msgstr "" - -#: src/code/unix.lisp -msgid "Message too long" -msgstr "" - -#: src/code/unix.lisp -msgid "Protocol wrong type for socket" -msgstr "" - -#: src/code/unix.lisp -msgid "Protocol not available" -msgstr "" - -#: src/code/unix.lisp -msgid "Protocol not supported" -msgstr "" - -#: src/code/unix.lisp -msgid "Socket type not supported" -msgstr "" - -#: src/code/unix.lisp -msgid "Operation not supported on socket" -msgstr "" - -#: src/code/unix.lisp -msgid "Protocol family not supported" -msgstr "" - -#: src/code/unix.lisp -msgid "Address family not supported by protocol family" -msgstr "" - -#: src/code/unix.lisp -msgid "Address already in use" -msgstr "" - -#: src/code/unix.lisp -msgid "Can't assign requested address" -msgstr "" - -#: src/code/unix.lisp -msgid "Network is down" -msgstr "" - -#: src/code/unix.lisp -msgid "Network is unreachable" -msgstr "" - -#: src/code/unix.lisp -msgid "Network dropped connection on reset" +msgid "Syscall ~A failed: ~A" msgstr ""
#: src/code/unix.lisp -msgid "Software caused connection abort" +msgid "Test for read permission" msgstr ""
#: src/code/unix.lisp -msgid "Connection reset by peer" +msgid "Class not yet defined: ~S" msgstr ""
#: src/code/unix.lisp -msgid "No buffer space available" +msgid "Test for write permission" msgstr ""
#: src/code/unix.lisp -msgid "Socket is already connected" +msgid "Test for execute permission" msgstr ""
#: src/code/unix.lisp -msgid "Socket is not connected" +msgid "Test for presence of file" msgstr ""
#: src/code/unix.lisp -msgid "Can't send after socket shutdown" +msgid "" +"Given a file path (a string) and one of four constant modes,\n" +" unix-access returns T if the file is accessible with that\n" +" mode and NIL if not. It also returns an errno value with\n" +" NIL which determines why the file was not accessible.\n" +"\n" +" The access modes are:\n" +" r_ok Read permission.\n" +" w_ok Write permission.\n" +" x_ok Execute permission.\n" +" f_ok Presence of file." msgstr ""
#: src/code/unix.lisp -msgid "Too many references: can't splice" +msgid "" +"Given a file path string, unix-chdir changes the current working \n" +" directory to the one specified." msgstr ""
#: src/code/unix.lisp -msgid "Connection timed out" +msgid "Set user ID on execution" msgstr ""
#: src/code/unix.lisp -msgid "Connection refused" +msgid "Set group ID on execution" msgstr ""
#: src/code/unix.lisp -msgid "Too many levels of symbolic links" +msgid "Save text image after execution" msgstr ""
#: src/code/unix.lisp -msgid "File name too long" +msgid "Read by owner" msgstr ""
#: src/code/unix.lisp -msgid "Host is down" +msgid "Write by owner" msgstr ""
#: src/code/unix.lisp -msgid "No route to host" +msgid "Execute (search directory) by owner" msgstr ""
#: src/code/unix.lisp -msgid "Directory not empty" +msgid "Read by group" msgstr ""
#: src/code/unix.lisp -msgid "Too many processes" +msgid "Write by group" msgstr ""
#: src/code/unix.lisp -msgid "Too many users" +msgid "Execute (search directory) by group" msgstr ""
#: src/code/unix.lisp -msgid "Disc quota exceeded" +msgid "Read by others" msgstr ""
#: src/code/unix.lisp -msgid "namei should continue locally" +msgid "Write by others" msgstr ""
#: src/code/unix.lisp -msgid "namei was handled remotely" +msgid "Execute (search directory) by others" msgstr ""
#: src/code/unix.lisp -msgid "Remote file system error _N" +msgid "" +"Given a file path string and a constant mode, unix-chmod changes the\n" +" permission mode for that file to the one specified. The new mode\n" +" can be created by logically OR'ing the following:\n" +"\n" +" setuidexec Set user ID on execution.\n" +" setgidexec Set group ID on execution.\n" +" savetext Save text image after execution.\n" +" readown Read by owner.\n" +" writeown Write by owner.\n" +" execown Execute (search directory) by owner.\n" +" readgrp Read by group.\n" +" writegrp Write by group.\n" +" execgrp Execute (search directory) by group.\n" +" readoth Read by others.\n" +" writeoth Write by others.\n" +" execoth Execute (search directory) by others.\n" +" \n" +" Thus #o444 and (logior unix:readown unix:readgrp unix:readoth)\n" +" are equivalent for 'mode. The octal-base is familar to Unix users.\n" +"\n" +" It returns T on successfully completion; NIL and an error number\n" +" otherwise." msgstr ""
#: src/code/unix.lisp -msgid "syscall was handled by Vice" +msgid "" +"Given an integer file descriptor and a mode (the same as those\n" +" used for unix-chmod), unix-fchmod changes the permission mode\n" +" for that file to the one specified. T is returned if the call\n" +" was successful." msgstr ""
#: src/code/unix.lisp -msgid "No message of desired type" +msgid "set the file pointer" msgstr ""
#: src/code/unix.lisp -msgid "Identifier removed" +msgid "increment the file pointer" msgstr ""
#: src/code/unix.lisp -msgid "Channel number out of range" +msgid "extend the file size" msgstr ""
#: src/code/unix.lisp -msgid "Level 2 not synchronized" +msgid "" +"Unix-lseek accepts a file descriptor and moves the file pointer ahead\n" +" a certain offset for that file. Whence can be any of the following:\n" +"\n" +" l_set Set the file pointer.\n" +" l_incr Increment the file pointer.\n" +" l_xtnd Extend the file size.\n" +" _N" msgstr ""
#: src/code/unix.lisp -msgid "Level 3 halted" +msgid "" +"Unix-mkdir creates a new directory with the specified name and mode.\n" +" (Same as those for unix-chmod.) It returns T upon success, otherwise\n" +" NIL and an error number." msgstr ""
#: src/code/unix.lisp -msgid "Level 3 reset" +msgid "" +"Unix-unlink removes the directory entry for the named file.\n" +" NIL and an error code is returned if the call fails." msgstr ""
#: src/code/unix.lisp -msgid "Link number out of range" +msgid "Read-only flag." msgstr ""
#: src/code/unix.lisp -msgid "Protocol driver not attached" +msgid "Write-only flag." msgstr ""
#: src/code/unix.lisp -msgid "No CSI structure available" +msgid "Read-write flag." msgstr ""
#: src/code/unix.lisp -msgid "Level 2 halted" +msgid "Non-blocking I/O" msgstr ""
#: src/code/unix.lisp -msgid "Deadlock situation detected/avoided" +msgid "Append flag." msgstr ""
#: src/code/unix.lisp -msgid "No record locks available" +msgid "Create if nonexistant flag." msgstr ""
#: src/code/unix.lisp -msgid "Error 47" +msgid "Truncate flag." msgstr ""
#: src/code/unix.lisp -msgid "Error 48" +msgid "Error if already exists." msgstr ""
#: src/code/unix.lisp -msgid "Bad exchange descriptor" +msgid "Don't assign controlling tty" msgstr ""
#: src/code/unix.lisp -msgid "Bad request descriptor" +msgid "Non-blocking mode" msgstr ""
#: src/code/unix.lisp -msgid "Message tables full" +msgid "Synchronous writes (on ext2)" msgstr ""
#: src/code/unix.lisp -msgid "Anode table overflow" +msgid "" +"Unix-open opens the file whose pathname is specified by path\n" +" for reading and/or writing as specified by the flags argument.\n" +" The flags argument can be:\n" +"\n" +" o_rdonly Read-only flag.\n" +" o_wronly Write-only flag.\n" +" o_rdwr Read-and-write flag.\n" +" o_append Append flag.\n" +" o_creat Create-if-nonexistant flag.\n" +" o_trunc Truncate-to-size-0 flag.\n" +"\n" +" If the o_creat flag is specified, then the file is created with\n" +" a permission of argument mode if the file doesn't exist. An\n" +" integer file descriptor is returned by unix-open." msgstr ""
#: src/code/unix.lisp -msgid "Bad request code" +msgid "" +"Unix-close takes an integer file descriptor as an argument and\n" +" closes the file associated with it. T is returned upon successful\n" +" completion, otherwise NIL and an error number." msgstr ""
#: src/code/unix.lisp -msgid "Invalid slot" +msgid "" +"Unix-creat accepts a file name and a mode (same as those for\n" +" unix-chmod) and creates a file by that name with the specified\n" +" permission mode. It returns a file descriptor on success,\n" +" or NIL and an error number otherwise.\n" +"\n" +" This interface is made obsolete by UNIX-OPEN." msgstr ""
#: src/code/unix.lisp -msgid "File locking deadlock" +msgid "" +"Unix-dup duplicates an existing file descriptor (given as the\n" +" argument) and return it. If FD is not a valid file descriptor, NIL\n" +" and an error number are returned." msgstr ""
#: src/code/unix.lisp -msgid "Bad font file format" +msgid "Duplicate a file descriptor" msgstr ""
#: src/code/unix.lisp -msgid "Not a stream device" +msgid "Get file desc. flags" msgstr ""
#: src/code/unix.lisp -msgid "No data available" +msgid "Set file desc. flags" msgstr ""
#: src/code/unix.lisp -msgid "Timer expired" +msgid "Get file flags" msgstr ""
#: src/code/unix.lisp -msgid "Out of stream resources" +msgid "Set file flags" msgstr ""
#: src/code/unix.lisp -msgid "Machine is not on the network" +msgid "Get owner" msgstr ""
#: src/code/unix.lisp -msgid "Package not installed" +msgid "Get lock" msgstr ""
#: src/code/unix.lisp -msgid "Object is remote" +msgid "Set owner" msgstr ""
#: src/code/unix.lisp -msgid "Link has been severed" +msgid "Set lock" msgstr ""
#: src/code/unix.lisp -msgid "Advertise error" +msgid "Set lock, wait for release" msgstr ""
#: src/code/unix.lisp -msgid "Srmount error" +msgid "Non-blocking reads" msgstr ""
#: src/code/unix.lisp -msgid "Communication error on send" +msgid "Append on each write" msgstr ""
#: src/code/unix.lisp -msgid "Protocol error" +msgid "Signal pgrp when data ready" msgstr ""
#: src/code/unix.lisp -msgid "Multihop attempted" +msgid "Create if nonexistant" msgstr ""
#: src/code/unix.lisp -msgid "Not a data message" +msgid "Truncate to zero length" msgstr ""
#: src/code/unix.lisp -msgid "Value too large for defined data type" +msgid "Error if already created" msgstr ""
#: src/code/unix.lisp -msgid "Name not unique on network" +msgid "" +"Unix-fcntl manipulates file descriptors according to the\n" +" argument CMD which can be one of the following:\n" +"\n" +" F-DUPFD Duplicate a file descriptor.\n" +" F-GETFD Get file descriptor flags.\n" +" F-SETFD Set file descriptor flags.\n" +" F-GETFL Get file flags.\n" +" F-SETFL Set file flags.\n" +" F-GETOWN Get owner.\n" +" F-SETOWN Set owner.\n" +"\n" +" The flags that can be specified for F-SETFL are:\n" +"\n" +" FNDELAY Non-blocking reads.\n" +" FAPPEND Append on each write.\n" +" FASYNC Signal pgrp when data ready.\n" +" FCREAT Create if nonexistant.\n" +" FTRUNC Truncate to zero length.\n" +" FEXCL Error if already created.\n" +" " msgstr ""
#: src/code/unix.lisp -msgid "File descriptor in bad state" +msgid "" +"Unix-pipe sets up a unix-piping mechanism consisting of\n" +" an input pipe and an output pipe. Unix-Pipe returns two\n" +" values: if no error occurred the first value is the pipe\n" +" to be read from and the second is can be written to. If\n" +" an error occurred the first value is NIL and the second\n" +" the unix error code." msgstr ""
#: src/code/unix.lisp -msgid "Remote address changed" +msgid "" +"Unix-read attempts to read from the file described by fd into\n" +" the buffer buf until it is full. Len is the length of the buffer.\n" +" The number of bytes actually read is returned or NIL and an error\n" +" number if an error occured." msgstr ""
#: src/code/unix.lisp -msgid "Can not access a needed shared library" +msgid "" +"Unix-readlink invokes the readlink system call on the file name\n" +" specified by the simple string path. It returns up to two values:\n" +" the contents of the symbolic link if the call is successful, or\n" +" NIL and the Unix error number." msgstr ""
#: src/code/unix.lisp -msgid "Accessing a corrupted shared library" +msgid "" +"Unix-rename renames the file with string name1 to the string\n" +" name2. NIL and an error code is returned if an error occured." msgstr ""
#: src/code/unix.lisp -msgid ".lib section in a.out corrupted" +msgid "" +"Unix-rmdir attempts to remove the directory name. NIL and\n" +" an error number is returned if an error occured." msgstr ""
#: src/code/unix.lisp -msgid "Attempting to link in more shared libraries than system limit" +msgid "" +"Unix-write attempts to write a character buffer (buf) of length\n" +" len to the file described by the file descriptor fd. NIL and an\n" +" error is returned if the call is unsuccessful." msgstr ""
#: src/code/unix.lisp -msgid "Can not exec a shared library directly" +msgid "" +"Unix-ioctl performs a variety of operations on open i/o\n" +" descriptors. See the UNIX Programmer's Manual for more\n" +" information." msgstr ""
#: src/code/unix.lisp -msgid "Error 88" +msgid "Get terminal attributes." msgstr ""
#: src/code/unix.lisp -msgid "Operation not applicable" +msgid "Set terminal attributes." msgstr ""
#: src/code/unix.lisp -msgid "" -"Number of symbolic links encountered during path name traversal exceeds " -"MAXSYMLINKS" +msgid "Get terminal output speed." msgstr ""
#: src/code/unix.lisp -msgid "Error 91" +msgid "" +"Unix-getuid returns the real user-id associated with the\n" +" current process." msgstr ""
#: src/code/unix.lisp -msgid "Error 92" +msgid "Unix-getpagesize returns the number of bytes in a system page." msgstr ""
#: src/code/unix.lisp -msgid "Option not supported by protocol" +msgid "Unix-gethostname returns the name of the host machine as a string." msgstr ""
#: src/code/unix.lisp -msgid "Operation not supported on transport endpoint" +msgid "" +"Unix-gethostid returns a 32-bit integer which provides unique\n" +" identification for the host machine." msgstr ""
#: src/code/unix.lisp -msgid "Cannot assign requested address" +msgid "" +"Unix-exit terminates the current process with an optional\n" +" error code. If successful, the call doesn't return. If\n" +" unsuccessful, the call returns NIL and an error number." msgstr ""
#: src/code/unix.lisp -msgid "Network dropped connection because of reset" +msgid "Size of control character vector." msgstr ""
#: src/code/unix.lisp -msgid "Transport endpoint is already connected" +msgid "" +"Unix-stat retrieves information about the specified\n" +" file returning them in the form of multiple values.\n" +" See the UNIX Programmer's Manual for a description\n" +" of the values returned. If the call fails, then NIL\n" +" and an error number is returned instead." msgstr ""
#: src/code/unix.lisp -msgid "Transport endpoint is not connected" +msgid "" +"Unix-lstat is similar to unix-stat except the specified\n" +" file must be a symbolic link." msgstr ""
#: src/code/unix.lisp -msgid "Cannot send after socket shutdown" +msgid "" +"Unix-fstat is similar to unix-stat except the file is specified\n" +" by the file descriptor fd." msgstr ""
#: src/code/unix.lisp -msgid "Too many references: cannot splice" +msgid "The calling process." msgstr ""
#: src/code/unix.lisp -msgid "Stale NFS file handle" +msgid "Terminated child processes." msgstr ""
#: src/code/unix.lisp -msgid "Resource deadlock would occur" +msgid "" +"Like call getrusage, but return only the system and user time, and returns\n" +" the seconds and microseconds as separate values." msgstr ""
#: src/code/unix.lisp -msgid "Function not implemented" +msgid "" +"Unix-getrusage returns information about the resource usage\n" +" of the process specified by who. Who can be either the\n" +" current process (rusage_self) or all of the terminated\n" +" child processes (rusage_children). NIL and an error number\n" +" is returned if the call fails." msgstr ""
#: src/code/unix.lisp -msgid "Too many symbolic links encountered" +msgid "Returns either :file, :directory, :link, :special, or NIL." msgstr ""
#: src/code/unix.lisp -msgid "Invalid exchange" +msgid "Returns the pathname with all symbolic links resolved." msgstr ""
#: src/code/unix.lisp -msgid "Invalid request descriptor" +msgid "Error reading link ~S: ~S" msgstr ""
#: src/code/unix.lisp -msgid "Exchange full" +msgid "Successful" msgstr ""
#: src/code/unix.lisp -msgid "No anode" +msgid "Operation not permitted" msgstr ""
#: src/code/unix.lisp -msgid "Invalid request code" +msgid "No such file or directory" msgstr ""
#: src/code/unix.lisp -msgid "File locking deadlock error" +msgid "No such process" msgstr ""
#: src/code/unix.lisp -msgid "Device not a stream" +msgid "Interrupted system call" msgstr ""
#: src/code/unix.lisp -msgid "Out of streams resources" +msgid "I/O error" msgstr ""
#: src/code/unix.lisp -msgid "RFS specific error" +msgid "Device not configured" msgstr ""
#: src/code/unix.lisp -msgid "Attempting to link in too many shared libraries" +msgid "Arg list too long" msgstr ""
#: src/code/unix.lisp -msgid "Cannot exec a shared library directly" +msgid "Exec format error" msgstr ""
#: src/code/unix.lisp -msgid "Illegal byte sequence" +msgid "Bad file descriptor" msgstr ""
#: src/code/unix.lisp -msgid "Interrupted system call should be restarted _N" +msgid "No child process" msgstr ""
#: src/code/unix.lisp -msgid "Streams pipe error" +msgid "Resource deadlock avoided" msgstr ""
#: src/code/unix.lisp -msgid "Address family not supported by protocol" +msgid "No more processes" msgstr ""
#: src/code/unix.lisp -msgid "Cannot send after transport endpoint shutdown" +msgid "Try again" msgstr ""
#: src/code/unix.lisp -msgid "Structure needs cleaning" +msgid "Out of memory" msgstr ""
#: src/code/unix.lisp -msgid "Not a XENIX named type file" +msgid "Permission denied" msgstr ""
#: src/code/unix.lisp -msgid "No XENIX semaphores available" +msgid "Bad address" msgstr ""
#: src/code/unix.lisp -msgid "Is a named type file" +msgid "Block device required" msgstr ""
#: src/code/unix.lisp -msgid "Remote I/O error" +msgid "Device or resource busy" msgstr ""
#: src/code/unix.lisp -msgid "Quota exceeded" +msgid "File exists" msgstr ""
#: src/code/unix.lisp -msgid "" -"Returns a string describing the error number which was returned by a\n" -" UNIX system call." +msgid "Cross-device link" msgstr ""
#: src/code/unix.lisp -msgid "Unknown error [~d]" +msgid "No such device" msgstr ""
#: src/code/unix.lisp -msgid "Class not yet defined: ~S" +msgid "Not a director" msgstr ""
#: src/code/unix.lisp -msgid "Syscall ~A failed: ~A" +msgid "Is a directory" msgstr ""
#: src/code/unix.lisp -msgid "" -"Set the user ID of the calling process to UID.\n" -" If the calling process is the super-user, set the real\n" -" and effective user IDs, and the saved set-user-ID to UID;\n" -" if not, the effective user ID is set to UID." +msgid "Invalid argument" msgstr ""
#: src/code/unix.lisp -msgid "" -"Set the group ID of the calling process to GID.\n" -" If the calling process is the super-user, set the real\n" -" and effective group IDs, and the saved set-group-ID to GID;\n" -" if not, the effective group ID is set to GID." +msgid "File table overflow" msgstr ""
#: src/code/unix.lisp -msgid "Test for read permission" +msgid "Too many open files" msgstr ""
#: src/code/unix.lisp -msgid "Test for write permission" +msgid "Inappropriate ioctl for device" msgstr ""
#: src/code/unix.lisp -msgid "Test for execute permission" +msgid "Text file busy" msgstr ""
#: src/code/unix.lisp -msgid "Test for presence of file" +msgid "File too large" msgstr ""
#: src/code/unix.lisp -msgid "" -"Given a file path (a string) and one of four constant modes,\n" -" unix-access returns T if the file is accessible with that\n" -" mode and NIL if not. It also returns an errno value with\n" -" NIL which determines why the file was not accessible.\n" -"\n" -" The access modes are:\n" -" r_ok Read permission.\n" -" w_ok Write permission.\n" -" x_ok Execute permission.\n" -" f_ok Presence of file." +msgid "No space left on device" msgstr ""
#: src/code/unix.lisp -msgid "" -"Given a file path string, unix-chdir changes the current working \n" -" directory to the one specified." +msgid "Illegal seek" msgstr ""
#: src/code/unix.lisp -msgid "Set user ID on execution" +msgid "Read-only file system" msgstr ""
#: src/code/unix.lisp -msgid "Set group ID on execution" +msgid "Too many links" msgstr ""
#: src/code/unix.lisp -msgid "Save text image after execution" +msgid "Broken pipe" msgstr ""
#: src/code/unix.lisp -msgid "Read by owner" +msgid "Numerical argument out of domain" msgstr ""
#: src/code/unix.lisp -msgid "Write by owner" +msgid "Result too large" msgstr ""
#: src/code/unix.lisp -msgid "Execute (search directory) by owner" +msgid "Math result not representable" msgstr ""
#: src/code/unix.lisp -msgid "Read by group" +msgid "Operation would block" msgstr ""
#: src/code/unix.lisp -msgid "Write by group" +msgid "Resource temporarily unavailable" msgstr ""
#: src/code/unix.lisp -msgid "Execute (search directory) by group" +msgid "Operation now in progress" msgstr ""
#: src/code/unix.lisp -msgid "Read by others" +msgid "Operation already in progress" msgstr ""
#: src/code/unix.lisp -msgid "Write by others" +msgid "Socket operation on non-socket" msgstr ""
#: src/code/unix.lisp -msgid "Execute (search directory) by others" +msgid "Destination address required" msgstr ""
#: src/code/unix.lisp -msgid "" -"Given a file path string and a constant mode, unix-chmod changes the\n" -" permission mode for that file to the one specified. The new mode\n" -" can be created by logically OR'ing the following:\n" -"\n" -" setuidexec Set user ID on execution.\n" -" setgidexec Set group ID on execution.\n" -" savetext Save text image after execution.\n" -" readown Read by owner.\n" -" writeown Write by owner.\n" -" execown Execute (search directory) by owner.\n" -" readgrp Read by group.\n" -" writegrp Write by group.\n" -" execgrp Execute (search directory) by group.\n" -" readoth Read by others.\n" -" writeoth Write by others.\n" -" execoth Execute (search directory) by others.\n" -" \n" -" Thus #o444 and (logior unix:readown unix:readgrp unix:readoth)\n" -" are equivalent for 'mode. The octal-base is familar to Unix users.\n" -"\n" -" It returns T on successfully completion; NIL and an error number\n" -" otherwise." +msgid "Message too long" msgstr ""
#: src/code/unix.lisp -msgid "" -"Given an integer file descriptor and a mode (the same as those\n" -" used for unix-chmod), unix-fchmod changes the permission mode\n" -" for that file to the one specified. T is returned if the call\n" -" was successful." +msgid "Protocol wrong type for socket" msgstr ""
#: src/code/unix.lisp -msgid "" -"Given a file path, an integer user-id, and an integer group-id,\n" -" unix-chown changes the owner of the file and the group of the\n" -" file to those specified. Either the owner or the group may be\n" -" left unchanged by specifying them as -1. Note: Permission will\n" -" fail if the caller is not the superuser." +msgid "Protocol not available" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-fchown is like unix-chown, except that it accepts an integer\n" -" file descriptor instead of a file path name." +msgid "Protocol not supported" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-getdtablesize returns the maximum size of the file descriptor\n" -" table. (i.e. the maximum number of descriptors that can exist at\n" -" one time.)" +msgid "Socket type not supported" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-close takes an integer file descriptor as an argument and\n" -" closes the file associated with it. T is returned upon successful\n" -" completion, otherwise NIL and an error number." +msgid "Operation not supported on socket" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-creat accepts a file name and a mode (same as those for\n" -" unix-chmod) and creates a file by that name with the specified\n" -" permission mode. It returns a file descriptor on success,\n" -" or NIL and an error number otherwise.\n" -"\n" -" This interface is made obsolete by UNIX-OPEN." +msgid "Protocol family not supported" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-dup duplicates an existing file descriptor (given as the\n" -" argument) and return it. If FD is not a valid file descriptor, NIL\n" -" and an error number are returned." +msgid "Address family not supported by protocol family" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-dup2 duplicates an existing file descriptor just as unix-dup\n" -" does only the new value of the duplicate descriptor may be requested\n" -" through the second argument. If a file already exists with the\n" -" requested descriptor number, it will be closed and the number\n" -" assigned to the duplicate." +msgid "Address already in use" msgstr ""
#: src/code/unix.lisp -msgid "Duplicate a file descriptor" +msgid "Can't assign requested address" msgstr ""
#: src/code/unix.lisp -msgid "Get file desc. flags" +msgid "Network is down" msgstr ""
#: src/code/unix.lisp -msgid "Set file desc. flags" +msgid "Network is unreachable" msgstr ""
#: src/code/unix.lisp -msgid "Get file flags" +msgid "Network dropped connection on reset" msgstr ""
#: src/code/unix.lisp -msgid "Set file flags" +msgid "Software caused connection abort" msgstr ""
#: src/code/unix.lisp -msgid "Get owner" +msgid "Connection reset by peer" msgstr ""
#: src/code/unix.lisp -msgid "Get lock" +msgid "No buffer space available" msgstr ""
#: src/code/unix.lisp -msgid "Set owner" +msgid "Socket is already connected" msgstr ""
#: src/code/unix.lisp -msgid "Set lock" +msgid "Socket is not connected" msgstr ""
#: src/code/unix.lisp -msgid "Set lock, wait for release" +msgid "Can't send after socket shutdown" msgstr ""
#: src/code/unix.lisp -msgid "Non-blocking reads" +msgid "Too many references: can't splice" msgstr ""
#: src/code/unix.lisp -msgid "Append on each write" +msgid "Connection timed out" msgstr ""
#: src/code/unix.lisp -msgid "Signal pgrp when data ready" +msgid "Connection refused" msgstr ""
#: src/code/unix.lisp -msgid "Create if nonexistant" +msgid "Too many levels of symbolic links" msgstr ""
#: src/code/unix.lisp -msgid "Truncate to zero length" +msgid "File name too long" msgstr ""
#: src/code/unix.lisp -msgid "Error if already created" +msgid "Host is down" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-fcntl manipulates file descriptors according to the\n" -" argument CMD which can be one of the following:\n" -"\n" -" F-DUPFD Duplicate a file descriptor.\n" -" F-GETFD Get file descriptor flags.\n" -" F-SETFD Set file descriptor flags.\n" -" F-GETFL Get file flags.\n" -" F-SETFL Set file flags.\n" -" F-GETOWN Get owner.\n" -" F-SETOWN Set owner.\n" -"\n" -" The flags that can be specified for F-SETFL are:\n" -"\n" -" FNDELAY Non-blocking reads.\n" -" FAPPEND Append on each write.\n" -" FASYNC Signal pgrp when data ready.\n" -" FCREAT Create if nonexistant.\n" -" FTRUNC Truncate to zero length.\n" -" FEXCL Error if already created.\n" -" " +msgid "No route to host" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-link creates a hard link from the file with name1 to the\n" -" file with name2." +msgid "Directory not empty" msgstr ""
#: src/code/unix.lisp -msgid "set the file pointer" +msgid "Too many processes" msgstr ""
#: src/code/unix.lisp -msgid "increment the file pointer" +msgid "Too many users" msgstr ""
#: src/code/unix.lisp -msgid "extend the file size" +msgid "Disc quota exceeded" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-lseek accepts a file descriptor and moves the file pointer ahead\n" -" a certain offset for that file. Whence can be any of the following:\n" -"\n" -" l_set Set the file pointer.\n" -" l_incr Increment the file pointer.\n" -" l_xtnd Extend the file size.\n" -" _N" +msgid "namei should continue locally" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-mkdir creates a new directory with the specified name and mode.\n" -" (Same as those for unix-chmod.) It returns T upon success, otherwise\n" -" NIL and an error number." +msgid "namei was handled remotely" msgstr ""
#: src/code/unix.lisp -msgid "Read-only flag." +msgid "Remote file system error _N" msgstr ""
#: src/code/unix.lisp -msgid "Write-only flag." +msgid "syscall was handled by Vice" msgstr ""
#: src/code/unix.lisp -msgid "Read-write flag." +msgid "No message of desired type" msgstr ""
#: src/code/unix.lisp -msgid "Non-blocking I/O" +msgid "Identifier removed" msgstr ""
#: src/code/unix.lisp -msgid "Append flag." +msgid "Channel number out of range" msgstr ""
#: src/code/unix.lisp -msgid "Create if nonexistant flag." +msgid "Level 2 not synchronized" msgstr ""
#: src/code/unix.lisp -msgid "Truncate flag." +msgid "Level 3 halted" msgstr ""
#: src/code/unix.lisp -msgid "Error if already exists." +msgid "Level 3 reset" msgstr ""
#: src/code/unix.lisp -msgid "Don't assign controlling tty" +msgid "Link number out of range" msgstr ""
#: src/code/unix.lisp -msgid "Non-blocking mode" +msgid "Protocol driver not attached" msgstr ""
#: src/code/unix.lisp -msgid "Synchronous writes (on ext2)" +msgid "No CSI structure available" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-open opens the file whose pathname is specified by path\n" -" for reading and/or writing as specified by the flags argument.\n" -" The flags argument can be:\n" -"\n" -" o_rdonly Read-only flag.\n" -" o_wronly Write-only flag.\n" -" o_rdwr Read-and-write flag.\n" -" o_append Append flag.\n" -" o_creat Create-if-nonexistant flag.\n" -" o_trunc Truncate-to-size-0 flag.\n" -"\n" -" If the o_creat flag is specified, then the file is created with\n" -" a permission of argument mode if the file doesn't exist. An\n" -" integer file descriptor is returned by unix-open." +msgid "Level 2 halted" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-pipe sets up a unix-piping mechanism consisting of\n" -" an input pipe and an output pipe. Unix-Pipe returns two\n" -" values: if no error occurred the first value is the pipe\n" -" to be read from and the second is can be written to. If\n" -" an error occurred the first value is NIL and the second\n" -" the unix error code." +msgid "Deadlock situation detected/avoided" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-read attempts to read from the file described by fd into\n" -" the buffer buf until it is full. Len is the length of the buffer.\n" -" The number of bytes actually read is returned or NIL and an error\n" -" number if an error occured." +msgid "No record locks available" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-readlink invokes the readlink system call on the file name\n" -" specified by the simple string path. It returns up to two values:\n" -" the contents of the symbolic link if the call is successful, or\n" -" NIL and the Unix error number." +msgid "Error 47" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-rename renames the file with string name1 to the string\n" -" name2. NIL and an error code is returned if an error occured." +msgid "Error 48" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-rmdir attempts to remove the directory name. NIL and\n" -" an error number is returned if an error occured." +msgid "Bad exchange descriptor" msgstr ""
#: src/code/unix.lisp -msgid "" -"Perform the UNIX select(2) system call.\n" -" (declare (type (integer 0 #.FD-SETSIZE) num-descriptors)\n" -" (type (or (alien (* (struct fd-set))) null)\n" -" read-fds write-fds exception-fds)\n" -" (type (or null (unsigned-byte 31)) timeout-secs)\n" -" (type (unsigned-byte 31) timeout-usecs)\n" -" (optimize (speed 3) (safety 0) (inhibit-warnings 3)))" +msgid "Bad request descriptor" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-select examines the sets of descriptors passed as arguments\n" -" to see if they are ready for reading and writing. See the UNIX\n" -" Programmers Manual for more information." +msgid "Message tables full" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-sync writes all information in core memory which has been\n" -" modified to disk. It returns NIL and an error code if an error\n" -" occured." +msgid "Anode table overflow" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-fsync writes the core image of the file described by\n" -" fd to disk." +msgid "Bad request code" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-truncate truncates the named file to the length (in\n" -" bytes) specified by len. NIL and an error number is returned\n" -" if the call is unsuccessful." +msgid "Invalid slot" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-ftruncate is similar to unix-truncate except that the first\n" -" argument is a file descriptor rather than a file name." +msgid "File locking deadlock" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-symlink creates a symbolic link named name2 to the file\n" -" named name1. NIL and an error number is returned if the call\n" -" is unsuccessful." +msgid "Bad font file format" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-unlink removes the directory entry for the named file.\n" -" NIL and an error code is returned if the call fails." +msgid "Not a stream device" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-write attempts to write a character buffer (buf) of length\n" -" len to the file described by the file descriptor fd. NIL and an\n" -" error is returned if the call is unsuccessful." +msgid "No data available" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-ioctl performs a variety of operations on open i/o\n" -" descriptors. See the UNIX Programmer's Manual for more\n" -" information." +msgid "Timer expired" msgstr ""
#: src/code/unix.lisp -msgid "Get terminal attributes." +msgid "Out of stream resources" msgstr ""
#: src/code/unix.lisp -msgid "Set terminal attributes." +msgid "Machine is not on the network" msgstr ""
#: src/code/unix.lisp -msgid "Get terminal output speed." +msgid "Package not installed" msgstr ""
#: src/code/unix.lisp -msgid "Set terminal output speed." +msgid "Object is remote" msgstr ""
#: src/code/unix.lisp -msgid "Bogus baud rate ~S" +msgid "Link has been severed" msgstr ""
#: src/code/unix.lisp -msgid "Get terminal input speed." +msgid "Advertise error" msgstr ""
#: src/code/unix.lisp -msgid "Set terminal input speed." +msgid "Srmount error" msgstr ""
#: src/code/unix.lisp -msgid "Send break" +msgid "Communication error on send" msgstr ""
#: src/code/unix.lisp -msgid "Wait for output for finish" +msgid "Protocol error" msgstr ""
#: src/code/unix.lisp -msgid "See tcflush(3)" +msgid "Multihop attempted" msgstr ""
#: src/code/unix.lisp -msgid "Flow control" +msgid "Not a data message" msgstr ""
#: src/code/unix.lisp -msgid "Set the tty-process-group for the unix file-descriptor FD to PGRP." +msgid "Value too large for defined data type" msgstr ""
#: src/code/unix.lisp -msgid "Get the tty-process-group for the unix file-descriptor FD." +msgid "Name not unique on network" msgstr ""
#: src/code/unix.lisp -msgid "" -"Get the tty-process-group for the unix file-descriptor FD. If not supplied," -"\n" -" FD defaults to /dev/tty." +msgid "File descriptor in bad state" msgstr ""
#: src/code/unix.lisp -msgid "" -"Set the tty-process-group for the unix file-descriptor FD to PGRP. If not\n" -" supplied, FD defaults to /dev/tty." +msgid "Remote address changed" msgstr ""
#: src/code/unix.lisp -msgid "Set the socket process-group for the unix file-descriptor FD to PGRP." +msgid "Can not access a needed shared library" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-exit terminates the current process with an optional\n" -" error code. If successful, the call doesn't return. If\n" -" unsuccessful, the call returns NIL and an error number." +msgid "Accessing a corrupted shared library" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-stat retrieves information about the specified\n" -" file returning them in the form of multiple values.\n" -" See the UNIX Programmer's Manual for a description\n" -" of the values returned. If the call fails, then NIL\n" -" and an error number is returned instead." +msgid ".lib section in a.out corrupted" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-lstat is similar to unix-stat except the specified\n" -" file must be a symbolic link." +msgid "Attempting to link in more shared libraries than system limit" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-fstat is similar to unix-stat except the file is specified\n" -" by the file descriptor fd." +msgid "Can not exec a shared library directly" msgstr ""
#: src/code/unix.lisp -msgid "The calling process." +msgid "Error 88" msgstr ""
#: src/code/unix.lisp -msgid "Terminated child processes." +msgid "Operation not applicable" msgstr ""
#: src/code/unix.lisp msgid "" -"Like call getrusage, but return only the system and user time, and returns\n" -" the seconds and microseconds as separate values." +"Number of symbolic links encountered during path name traversal exceeds " +"MAXSYMLINKS" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-getrusage returns information about the resource usage\n" -" of the process specified by who. Who can be either the\n" -" current process (rusage_self) or all of the terminated\n" -" child processes (rusage_children). NIL and an error number\n" -" is returned if the call fails." +msgid "Error 91" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-times returns information about the cpu time usage of the process\n" -" and its children." +msgid "Error 92" msgstr ""
#: src/code/unix.lisp -msgid "" -"If it works, unix-gettimeofday returns 5 values: T, the seconds and\n" -" microseconds of the current time of day, the timezone (in minutes west\n" -" of Greenwich), and a daylight-savings flag. If it doesn't work, it\n" -" returns NIL and the errno." +msgid "Option not supported by protocol" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-utimes sets the 'last-accessed' and 'last-updated'\n" -" times on a specified file. NIL and an error number is\n" -" returned if the call is unsuccessful." +msgid "Operation not supported on transport endpoint" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-setreuid sets the real and effective user-id's of the current\n" -" process to the specified ones. NIL and an error number is returned\n" -" if the call fails." +msgid "Cannot assign requested address" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-setregid sets the real and effective group-id's of the current\n" -" process process to the specified ones. NIL and an error number is\n" -" returned if the call fails." +msgid "Network dropped connection because of reset" msgstr ""
#: src/code/unix.lisp -msgid "Unix-getpid returns the process-id of the current process." +msgid "Transport endpoint is already connected" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-getppid returns the process-id of the parent of the current process." +msgid "Transport endpoint is not connected" msgstr ""
#: src/code/unix.lisp -msgid "Unix-getgid returns the real group-id of the current process." +msgid "Cannot send after socket shutdown" msgstr ""
#: src/code/unix.lisp -msgid "Unix-getegid returns the effective group-id of the current process." +msgid "Too many references: cannot splice" msgstr ""
#: src/code/unix.lisp -msgid "Unix-getpgrp returns the group-id of the calling process." +msgid "Stale NFS file handle" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-setpgrp sets the process group on the process pid to\n" -" pgrp. NIL and an error number are returned upon failure." +msgid "Resource deadlock would occur" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-setpgid sets the process group of the process pid to\n" -" pgrp. If pgid is equal to pid, the process becomes a process\n" -" group leader. NIL and an error number are returned upon failure." +msgid "Function not implemented" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-getuid returns the real user-id associated with the\n" -" current process." +msgid "Too many symbolic links encountered" msgstr ""
#: src/code/unix.lisp -msgid "Unix-getpagesize returns the number of bytes in a system page." +msgid "Invalid exchange" msgstr ""
#: src/code/unix.lisp -msgid "Unix-gethostname returns the name of the host machine as a string." +msgid "Invalid request descriptor" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-gethostid returns a 32-bit integer which provides unique\n" -" identification for the host machine." +msgid "Exchange full" msgstr ""
#: src/code/unix.lisp -msgid "" -"Executes the unix fork system call. Returns 0 in the child and the pid\n" -" of the child in the parent if it works, or NIL and an error number if it\n" -" doesn't work." +msgid "No anode" msgstr ""
#: src/code/unix.lisp -msgid "" -"Get the value of the environment variable named Name. If no such\n" -" variable exists, Nil is returned." +msgid "Invalid request code" msgstr ""
#: src/code/unix.lisp -msgid "" -"Adds the environment variable named Name to the environment with\n" -" the given Value if Name does not already exist. If Name does exist,\n" -" the value is changed to Value if Overwrite is non-zero. Otherwise,\n" -" the value is not changed." +msgid "File locking deadlock error" msgstr ""
#: src/code/unix.lisp -msgid "" -"Adds or changes the environment. Name-value must be a string of\n" -" the form "name=value". If the name does not exist, it is added.\n" -" If name does exist, the value is updated to the given value." +msgid "Device not a stream" msgstr ""
#: src/code/unix.lisp -msgid "Removes the variable Name from the environment" +msgid "Out of streams resources" msgstr ""
#: src/code/unix.lisp -msgid "Returns either :file, :directory, :link, :special, or NIL." +msgid "RFS specific error" msgstr ""
#: src/code/unix.lisp -msgid "Returns the pathname with all symbolic links resolved." +msgid "Attempting to link in too many shared libraries" msgstr ""
#: src/code/unix.lisp -msgid "Error reading link ~S: ~S" +msgid "Cannot exec a shared library directly" msgstr ""
#: src/code/unix.lisp -msgid "" -"Accepts a Unix file descriptor and returns T if the device\n" -" associated with it is a terminal." +msgid "Illegal byte sequence" msgstr ""
#: src/code/unix.lisp -msgid "" -"Executes the Unix execve system call. If the system call suceeds, lisp\n" -" will no longer be running in this process. If the system call fails " -"this\n" -" function returns two values: NIL and an error code. Arg-list should be " -"a\n" -" list of simple-strings which are passed as arguments to the exec'ed " -"program.\n" -" Environment should be an a-list mapping symbols to simple-strings which " -"this\n" -" function bashes together to form the environment for the exec'ed " -"program." +msgid "Interrupted system call should be restarted _N" msgstr ""
#: src/code/unix.lisp -msgid "" -"Unix-getitimer returns the INTERVAL and VALUE slots of one of\n" -" three system timers (:real :virtual or :profile). On success,\n" -" unix-getitimer returns 5 values,\n" -" T, it-interval-secs, it-interval-usec, it-value-secs, it-value-usec." +msgid "Streams pipe error" msgstr ""
#: src/code/unix.lisp -msgid "" -" Unix-setitimer sets the INTERVAL and VALUE slots of one of\n" -" three system timers (:real :virtual or :profile). A SIGALRM signal\n" -" will be delivered VALUE <seconds+microseconds> from now. INTERVAL,\n" -" when non-zero, is <seconds+microseconds> to be loaded each time\n" -" the timer expires. Setting INTERVAL and VALUE to zero disables\n" -" the timer. See the Unix man page for more details. On success,\n" -" unix-setitimer returns the old contents of the INTERVAL and VALUE\n" -" slots as in unix-getitimer." +msgid "Address family not supported by protocol" msgstr ""
#: src/code/unix.lisp -msgid "" -"Return a USER-INFO structure for the user identified by LOGIN, or NIL if " -"not found." +msgid "Cannot send after transport endpoint shutdown" msgstr ""
#: src/code/unix.lisp -msgid "" -"Return a USER-INFO structure for the user identified by UID, or NIL if not " -"found." +msgid "Structure needs cleaning" +msgstr "" + +#: src/code/unix.lisp +msgid "Not a XENIX named type file" msgstr ""
#: src/code/unix.lisp -msgid "The maximum size of the group entry buffer" +msgid "No XENIX semaphores available" msgstr ""
#: src/code/unix.lisp -msgid "" -"Return a GROUP-INFO structure for the group identified by NAME, or NIL if " -"not found." +msgid "Is a named type file" msgstr ""
#: src/code/unix.lisp -msgid "" -"Return a GROUP-INFO structure for the group identified by GID, or NIL if " -"not found." +msgid "Remote I/O error" msgstr ""
#: src/code/unix.lisp -msgid "CPU time per process (in milliseconds)" +msgid "Quota exceeded" msgstr ""
#: src/code/unix.lisp -msgid "Maximum file size" +msgid "" +"Returns a string describing the error number which was returned by a\n" +" UNIX system call." msgstr ""
#: src/code/unix.lisp -msgid "Data segment size" +msgid "Unknown error [~d]" msgstr ""
#: src/code/unix.lisp -msgid "Stack size" +msgid "" +"Perform the UNIX select(2) system call.\n" +" (declare (type (integer 0 #.FD-SETSIZE) num-descriptors)\n" +" (type (or (alien (* (struct fd-set))) null)\n" +" read-fds write-fds exception-fds)\n" +" (type (or null (unsigned-byte 31)) timeout-secs)\n" +" (type (unsigned-byte 31) timeout-usecs)\n" +" (optimize (speed 3) (safety 0) (inhibit-warnings 3)))" msgstr ""
#: src/code/unix.lisp -msgid "Core file size" +msgid "" +"Unix-select examines the sets of descriptors passed as arguments\n" +" to see if they are ready for reading and writing. See the UNIX\n" +" Programmers Manual for more information." msgstr ""
#: src/code/unix.lisp -msgid "Number of open files" +msgid "" +"Unix-symlink creates a symbolic link named name2 to the file\n" +" named name1. NIL and an error number is returned if the call\n" +" is unsuccessful." msgstr ""
#: src/code/unix.lisp -msgid "Maximum mapped memory" +msgid "" +"If it works, unix-gettimeofday returns 5 values: T, the seconds and\n" +" microseconds of the current time of day, the timezone (in minutes west\n" +" of Greenwich), and a daylight-savings flag. If it doesn't work, it\n" +" returns NIL and the errno." msgstr ""
#: src/code/unix.lisp -msgid "CPU time per process" +msgid "" +"Unix-utimes sets the 'last-accessed' and 'last-updated'\n" +" times on a specified file. NIL and an error number is\n" +" returned if the call is unsuccessful." msgstr ""
#: src/code/unix.lisp -msgid "File size" +msgid "Unix-getpid returns the process-id of the current process." msgstr ""
#: src/code/unix.lisp -msgid "Addess space (resident set size)" +msgid "" +"Accepts a Unix file descriptor and returns T if the device\n" +" associated with it is a terminal." msgstr ""
#: src/code/unix.lisp -msgid "Locked-in-memory address space" +msgid "" +" Unix-setitimer sets the INTERVAL and VALUE slots of one of\n" +" three system timers (:real :virtual or :profile). A SIGALRM signal\n" +" will be delivered VALUE <seconds+microseconds> from now. INTERVAL,\n" +" when non-zero, is <seconds+microseconds> to be loaded each time\n" +" the timer expires. Setting INTERVAL and VALUE to zero disables\n" +" the timer. See the Unix man page for more details. On success,\n" +" unix-setitimer returns the old contents of the INTERVAL and VALUE\n" +" slots as in unix-getitimer." msgstr ""
#: src/code/unix.lisp -msgid "Number of processes" +msgid "" +"Return a USER-INFO structure for the user identified by UID, or NIL if not " +"found." msgstr ""
#: src/code/unix.lisp msgid "" -"Get the limits on the consumption of system resouce specified by\n" -" Resource. If successful, return three values: T, the current (soft)\n" -" limit, and the maximum (hard) limit." +"Unix-times returns information about the cpu time usage of the process\n" +" and its children." msgstr ""
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/compare/ea775196480fd9f029c2a701f...