Newer
Older
;;; -*- 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: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/code/unix.lisp,v 1.39 1994/11/06 18:00:36 ram Exp $")
;;;
;;; **********************************************************************
;;;
;;; This file contains the UNIX low-level support.
;;;
(in-package "UNIX")
(use-package "ALIEN")
(use-package "C-CALL")
(use-package "SYSTEM")
(use-package "EXT")
(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 #-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
unix-errno get-unix-error-msg
unix-pathname unix-file-mode unix-fd unix-pid unix-uid unix-gid
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_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
tcsetpgrp tcgetpgrp tty-process-group
terminal-speeds tty-raw tty-crmod tty-echo tty-lcase
#-(or hpux svr4) tty-cbreak #-(or hpux svr4) tty-tandem
#+(or hpux svr4) termios #+(or hpux svr4) c-lflag
#+(or hpux svr4) c-iflag #+(or hpux svr4) c-oflag
#+(or hpux svr4) tty-icrnl #+(or hpux svr4) tty-ocrnl
#+(or hpux svr4) vdsusp #+(or hpux svr4) veof
#+(or hpux svr4) vintr #+(or hpux svr4) vquit #+(or hpux svr4) vstart
#+(or hpux svr4) vstop #+(or hpux svr4) vsusp
#+(or hpux svr4) c-cflag
#+(or hpux svr4) c-cc #+(or hpux svr4) tty-icanon
#+(or hpux svr4) vmin #+(or hpux svr4) vtime
#+(or hpux svr4) tty-ixon
#+(or hpux svr4) tcsaflush #+(or hpux svr4)
unix-tcgetattr #+(or hpux svr4) unix-tcsetattr
TIOCGETP TIOCSETP TIOCFLUSH TIOCSETC TIOCGETC TIOCSLTC
TIOCGLTC TIOCNOTTY TIOCSPGRP TIOCGPGRP TIOCGWINSZ TIOCSWINSZ
KBDCGET KBDCSET KBDCRESET KBDCRST KBDCSSTD KBDSGET KBDGCLICK
KBDSCLICK FIONREAD #+hpux 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
unix-getgid unix-getegid unix-getpgrp unix-setpgrp unix-getuid
unix-getpagesize unix-gethostname unix-gethostid unix-fork
unix-current-directory unix-isatty unix-ttyname unix-execve
unix-socket unix-connect unix-bind unix-listen unix-accept
unix-recv unix-send))
(pushnew :unix *features*)
;;;; Common machine independent structures.
;;; From sys/types.h
(def-alien-type ino-t #-alpha unsigned-long #+alpha unsigned-int)
(def-alien-type size-t #-alpha long #+alpha unsigned-long)
(def-alien-type time-t #-alpha unsigned-long #+alpha unsigned-int)
(def-alien-type dev-t #-(or alpha svr4) short #+alpha int #+svr4 unsigned-long)
(def-alien-type off-t #-alpha long #+alpha unsigned-long)
(def-alien-type uid-t #-(or alpha svr4) unsigned-short #+alpha unsigned-int
#+svr4 long)
(def-alien-type gid-t #-(or alpha svr4) unsigned-short #+alpha unsigned-int
#+svr4 long)
(def-alien-type mode-t #-(or alpha svr4) unsigned-short
(def-alien-type nlink-t #-svr4 unsigned-short #+svr4 unsigned-long)
(defconstant FD-SETSIZE #-(or hpux alpha) 256 #+hpux 2048 #+alpha 4096)
(fds-bits (array #-alpha unsigned-long #+alpha int #.(/ fd-setsize 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))))))
(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))))))))
(defmacro fd-isset (offset fd-set)
(let ((word (gensym))
(bit (gensym)))
`(multiple-value-bind (,word ,bit) (floor ,offset 32)
(logbitp ,bit (deref (slot ,fd-set 'fds-bits) ,word)))))
(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))))
;;; From sys/time.h
(def-alien-type nil
(struct timeval
(tv-sec time-t) ; seconds
(tv-usec time-t))) ; and microseconds
(def-alien-type nil
(struct timezone
(tz-minuteswest int) ; minutes west of Greenwich
(tz-dsttime ; type of dst correction
(enum nil :none :usa :aust :wet :met :eet :can))))
(def-alien-type nil
(struct itimerval
(it-interval (struct timeval)) ; timer interval
(it-value (struct timeval)))) ; current value
#+svr4
; High-res time. Actually posix definition under svr4 name.
(def-alien-type nil
(struct timestruc-t
(tv-sec time-t)
(tv-nsec long)))
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
;;; From ioctl.h
(def-alien-type nil
(struct tchars
(t-intrc char) ; interrupt
(t-quitc char) ; quit
(t-startc char) ; start output
(t-stopc char) ; stop output
(t-eofc char) ; end-of-file
(t-brkc char))) ; input delimiter (like nl)
(def-alien-type nil
(struct ltchars
(t-suspc char) ; stop process signal
(t-dsuspc char) ; delayed stop process signal
(t-rprntc char) ; reprint line
(t-flushc char) ; flush output (toggles)
(t-werasc char) ; word erase
(t-lnextc char))) ; literal next character
(def-alien-type nil
(struct sgttyb
(sg-ispeed char) ; input speed.
(sg-ospeed char) ; output speed
(sg-erase char) ; erase character
(sg-kill char) ; kill character
(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
(def-alien-type nil
(struct termios
(c-iflag unsigned-int)
(c-oflag unsigned-int)
(c-cflag unsigned-int)
(c-lflag unsigned-int)
(c-cc (array unsigned-char #+hpux 16 #+solaris 19 #+irix 23))))
;;; From sys/dir.h
(def-alien-type nil
(struct direct
#+(and sunos (not svr4)) (d-off long) ; offset of next disk directory entry
#-svr4
(d-namlen unsigned-short) ; length of string in d-name
(d-name (array char 256)))) ; name must be no longer than this
;;; From sys/stat.h
(def-alien-type nil
(struct stat
(st-dev dev-t)
(st-ino ino-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)
(def-alien-type nil
(struct stat
(st-dev dev-t)
(st-pad1 (array long 3))
(st-ino ino-t)
(st-mode unsigned-long)
(st-nlink short)
(st-uid uid-t)
(st-gid gid-t)
(st-rdev dev-t)
(st-pad2 (array long 2))
(st-size off-t)
(st-pad3 long)
(st-atime (struct timestruc-t))
(st-mtime (struct timestruc-t))
(st-ctime (struct timestruc-t))
(st-blksize long)
(st-blocks long)
(st-fstype (array char 16))
(st-pad4 (array long 8))))
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
(defconstant s-ifmt #o0170000)
(defconstant s-ifdir #o0040000)
(defconstant s-ifchr #o0020000)
(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)
;;; 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 "
(def-alien-type nil
(struct rlimit
(rlim-cur #-alpha int #+alpha unsigned-int) ; current (soft) limit
(rlim-max #-alpha int #+alpha unsigned-int))); maximum value for rlim-cur
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
;;;; 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)
(proclaim '(simple-vector *unix-errors*)))))
) ;eval-when
;;;
;;; From <errno.h>
;;;
(def-unix-error ESUCCESS 0 "Successful")
(def-unix-error EPERM 1 "Not owner")
(def-unix-error ENOENT 2 "No such file or directory")
(def-unix-error ESRCH 3 "No such process")
(def-unix-error EINTR 4 "Interrupted system call")
(def-unix-error EIO 5 "I/O error")
(def-unix-error ENXIO 6 "No such device or address")
(def-unix-error E2BIG 7 "Arg list too long")
(def-unix-error ENOEXEC 8 "Exec format error")
(def-unix-error EBADF 9 "Bad file number")
(def-unix-error ECHILD 10 "No children")
(def-unix-error EAGAIN 11 "No more processes")
(def-unix-error ENOMEM 12 "Not enough core")
(def-unix-error EACCES 13 "Permission denied")
(def-unix-error EFAULT 14 "Bad address")
(def-unix-error ENOTBLK 15 "Block device required")
(def-unix-error EBUSY 16 "Mount device busy")
(def-unix-error EEXIST 17 "File exists")
(def-unix-error EXDEV 18 "Cross-device link")
(def-unix-error ENODEV 19 "No such device")
(def-unix-error ENOTDIR 20 "Not a director")
(def-unix-error EISDIR 21 "Is a directory")
(def-unix-error EINVAL 22 "Invalid argument")
(def-unix-error ENFILE 23 "File table overflow")
(def-unix-error EMFILE 24 "Too many open files")
(def-unix-error ENOTTY 25 "Not a typewriter")
(def-unix-error ETXTBSY 26 "Text file busy")
(def-unix-error EFBIG 27 "File too large")
(def-unix-error ENOSPC 28 "No space left on device")
(def-unix-error ESPIPE 29 "Illegal seek")
(def-unix-error EROFS 30 "Read-only file system")
(def-unix-error EMLINK 31 "Too many links")
(def-unix-error EPIPE 32 "Broken pipe")
;;;
;;; Math
(def-unix-error EDOM 33 "Argument too large")
(def-unix-error ERANGE 34 "Result too large")
;;;
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
;;; non-blocking and interrupt i/o
(def-unix-error EWOULDBLOCK 35 "Operation would block")
(def-unix-error EDEADLK 35 "Operation would block") ; Ditto
(def-unix-error EINPROGRESS 36 "Operation now in progress")
(def-unix-error EALREADY 37 "Operation already in progress")
;;;
;;; ipc/network software
(def-unix-error ENOTSOCK 38 "Socket operation on non-socket")
(def-unix-error EDESTADDRREQ 39 "Destination address required")
(def-unix-error EMSGSIZE 40 "Message too long")
(def-unix-error EPROTOTYPE 41 "Protocol wrong type for socket")
(def-unix-error ENOPROTOOPT 42 "Protocol not available")
(def-unix-error EPROTONOSUPPORT 43 "Protocol not supported")
(def-unix-error ESOCKTNOSUPPORT 44 "Socket type not supported")
(def-unix-error EOPNOTSUPP 45 "Operation not supported on socket")
(def-unix-error EPFNOSUPPORT 46 "Protocol family not supported")
(def-unix-error EAFNOSUPPORT 47 "Address family not supported by protocol family")
(def-unix-error EADDRINUSE 48 "Address already in use")
(def-unix-error EADDRNOTAVAIL 49 "Can't assign requested address")
;;;
;;; operational errors
(def-unix-error ENETDOWN 50 "Network is down")
(def-unix-error ENETUNREACH 51 "Network is unreachable")
(def-unix-error ENETRESET 52 "Network dropped connection on reset")
(def-unix-error ECONNABORTED 53 "Software caused connection abort")
(def-unix-error ECONNRESET 54 "Connection reset by peer")
(def-unix-error ENOBUFS 55 "No buffer space available")
(def-unix-error EISCONN 56 "Socket is already connected")
(def-unix-error ENOTCONN 57 "Socket is not connected")
(def-unix-error ESHUTDOWN 58 "Can't send after socket shutdown")
(def-unix-error ETOOMANYREFS 59 "Too many references: can't splice")
(def-unix-error ETIMEDOUT 60 "Connection timed out")
(def-unix-error ECONNREFUSED 61 "Connection refused")
;;;
(def-unix-error ELOOP 62 "Too many levels of symbolic links")
(def-unix-error ENAMETOOLONG 63 "File name too long")
;;;
(def-unix-error EHOSTDOWN 64 "Host is down")
(def-unix-error EHOSTUNREACH 65 "No route to host")
(def-unix-error ENOTEMPTY 66 "Directory not empty")
;;;
;;; quotas & resource
(def-unix-error EPROCLIM 67 "Too many processes")
(def-unix-error EUSERS 68 "Too many users")
(def-unix-error EDQUOT 69 "Disc quota exceeded")
;;;
;;; CMU RFS
(def-unix-error ELOCAL 126 "namei should continue locally")
(def-unix-error EREMOTE 127 "namei was handled remotely")
;;;
;;; VICE
(def-unix-error EVICEERR 70 "Remote file system error ")
(def-unix-error EVICEOP 71 "syscall was handled by Vice")
;;;
;;; Mach Emulation
(def-unix-error ERESTART 72 "Mach Emulation Error (?)")
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
)
#+svr4
(progn
(def-unix-error ENOMSG 35 "No message of desired type")
(def-unix-error EIDRM 36 "Identifier removed")
(def-unix-error ECHRNG 37 "Channel number out of range")
(def-unix-error EL2NSYNC 38 "Level 2 not synchronized")
(def-unix-error EL3HLT 39 "Level 3 halted")
(def-unix-error EL3RST 40 "Level 3 reset")
(def-unix-error ELNRNG 41 "Link number out of range")
(def-unix-error EUNATCH 42 "Protocol driver not attached")
(def-unix-error ENOCSI 43 "No CSI structure available")
(def-unix-error EL2HLT 44 "Level 2 halted")
(def-unix-error EDEADLK 45 "Deadlock situation detected/avoided")
(def-unix-error ENOLCK 46 "No record locks available")
(def-unix-error ECANCELED 47 "Error 47")
(def-unix-error ENOTSUP 48 "Error 48")
(def-unix-error EBADE 50 "Bad exchange descriptor")
(def-unix-error EBADR 51 "Bad request descriptor")
(def-unix-error EXFULL 52 "Message tables full")
(def-unix-error ENOANO 53 "Anode table overflow")
(def-unix-error EBADRQC 54 "Bad request code")
(def-unix-error EBADSLT 55 "Invalid slot")
(def-unix-error EDEADLOCK 56 "File locking deadlock")
(def-unix-error EBFONT 57 "Bad font file format")
(def-unix-error ENOSTR 60 "Not a stream device")
(def-unix-error ENODATA 61 "No data available")
(def-unix-error ETIME 62 "Timer expired")
(def-unix-error ENOSR 63 "Out of stream resources")
(def-unix-error ENONET 64 "Machine is not on the network")
(def-unix-error ENOPKG 65 "Package not installed")
(def-unix-error EREMOTE 66 "Object is remote")
(def-unix-error ENOLINK 67 "Link has been severed")
(def-unix-error EADV 68 "Advertise error")
(def-unix-error ESRMNT 69 "Srmount error")
(def-unix-error ECOMM 70 "Communication error on send")
(def-unix-error EPROTO 71 "Protocol error")
(def-unix-error EMULTIHOP 74 "Multihop attempted")
(def-unix-error EBADMSG 77 "Not a data message")
(def-unix-error ENAMETOOLONG 78 "File name too long")
(def-unix-error EOVERFLOW 79 "Value too large for defined data type")
(def-unix-error ENOTUNIQ 80 "Name not unique on network")
(def-unix-error EBADFD 81 "File descriptor in bad state")
(def-unix-error EREMCHG 82 "Remote address changed")
(def-unix-error ELIBACC 83 "Can not access a needed shared library")
(def-unix-error ELIBBAD 84 "Accessing a corrupted shared library")
(def-unix-error ELIBSCN 85 ".lib section in a.out corrupted")
(def-unix-error ELIBMAX 86 "Attempting to link in more shared libraries than system limit")
(def-unix-error ELIBEXEC 87 "Can not exec a shared library directly")
(def-unix-error EILSEQ 88 "Error 88")
(def-unix-error ENOSYS 89 "Operation not applicable")
(def-unix-error ELOOP 90 "Number of symbolic links encountered during path name traversal exceeds MAXSYMLINKS")
(def-unix-error ERESTART 91 "Error 91")
(def-unix-error ESTRPIPE 92 "Error 92")
(def-unix-error ENOTEMPTY 93 "Directory not empty")
(def-unix-error EUSERS 94 "Too many users")
(def-unix-error ENOTSOCK 95 "Socket operation on non-socket")
(def-unix-error EDESTADDRREQ 96 "Destination address required")
(def-unix-error EMSGSIZE 97 "Message too long")
(def-unix-error EPROTOTYPE 98 "Protocol wrong type for socket")
(def-unix-error ENOPROTOOPT 99 "Option not supported by protocol")
(def-unix-error EPROTONOSUPPORT 120 "Protocol not supported")
(def-unix-error ESOCKTNOSUPPORT 121 "Socket type not supported")
(def-unix-error EOPNOTSUPP 122 "Operation not supported on transport endpoint")
(def-unix-error EPFNOSUPPORT 123 "Protocol family not supported")
(def-unix-error EAFNOSUPPORT 124 "Address family not supported by protocol family")
(def-unix-error EADDRINUSE 125 "Address already in use")
(def-unix-error EADDRNOTAVAIL 126 "Cannot assign requested address")
(def-unix-error ENETDOWN 127 "Network is down")
(def-unix-error ENETUNREACH 128 "Network is unreachable")
(def-unix-error ENETRESET 129 "Network dropped connection because of reset")
(def-unix-error ECONNABORTED 130 "Software caused connection abort")
(def-unix-error ECONNRESET 131 "Connection reset by peer")
(def-unix-error ENOBUFS 132 "No buffer space available")
(def-unix-error EISCONN 133 "Transport endpoint is already connected")
(def-unix-error ENOTCONN 134 "Transport endpoint is not connected")
(def-unix-error ESHUTDOWN 143 "Cannot send after socket shutdown")
(def-unix-error ETOOMANYREFS 144 "Too many references: cannot splice")
(def-unix-error ETIMEDOUT 145 "Connection timed out")
(def-unix-error ECONNREFUSED 146 "Connection refused")
(def-unix-error EHOSTDOWN 147 "Host is down")
(def-unix-error EHOSTUNREACH 148 "No route to host")
(def-unix-error EWOULDBLOCK 11 "Resource temporarily unavailable")
(def-unix-error EALREADY 149 "Operation already in progress")
(def-unix-error EINPROGRESS 150 "Operation now in progress")
(def-unix-error ESTALE 151 "Stale NFS file handle")
)
;;;
;;; And now for something completely different ...
(emit-unix-errors)
(def-alien-variable ("errno" unix-errno) int)
;;; GET-UNIX-ERROR-MSG -- public.
;;;
(defun get-unix-error-msg (&optional (error-number unix-errno))
"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.
(deftype unix-pathname () 'simple-string)
(deftype unix-fd () `(integer 0 ,most-positive-fixnum))
#+mach
(progn
(deftype unix-file-mode () '(unsigned-byte 16))
(deftype unix-pid () '(unsigned-byte 16))
(deftype unix-uid () '(unsigned-byte 16))
(deftype unix-gid () '(unsigned-byte 16)))
#-mach
(progn
(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)))
(defmacro syscall ((name &rest arg-types) success-form &rest args)
`(let ((result (alien-funcall (extern-alien ,name (function int ,@arg-types))
,@args)))
(if (minusp result)
(values nil unix-errno)
,success-form)))
;;; 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 (minusp result)
(error "Syscall ~A failed: ~A" ,name (get-unix-error-msg))
,success-form)))
Loading
Loading full blame...