errno.scm 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Mike Sperber, Will Noble, William Vining
  3. ; Error codes
  4. (import-dynamic-externals "=scheme48external/posix")
  5. (define-record-type unnamed-errno :unnamed-errno
  6. (make-unnamed-errno resume-value os-number)
  7. unnamed-errno?
  8. (resume-value unnamed-errno-resume-value)
  9. (os-number unnamed-errno-os-number))
  10. (define-record-discloser :unnamed-errno
  11. (lambda (u-s)
  12. (list 'errno (unnamed-errno-os-number u-s))))
  13. ; These are not meaningful after a dump (because the value may not have the
  14. ; same meaning on the OS on which we are resumed).
  15. (define-record-resumer :unnamed-errno #f)
  16. (define *unnamed-errnos* #f)
  17. (define-finite-type errno :named-errno ()
  18. named-errno?
  19. named-errnos
  20. named-errno-name
  21. named-errno-index
  22. (os-number named-errno-os-number set-named-errno-os-number!)
  23. ( ; POSIX
  24. (toobig) ; [E2BIG] Argument list too long.
  25. (acces) ; Permission denied.
  26. (addrinuse) ; Address in use.
  27. (addrnotavail) ; Address not available.
  28. (afnosupport) ; Address family not supported.
  29. (again) ; Resource unavailable, try again (may be the same value as [EWOULDBLOCK]).
  30. (already) ; Connection already in progress.
  31. (badf) ; Bad file descriptor.
  32. (badmsg) ; Bad message.
  33. (busy) ; Device or resource busy.
  34. (canceled) ; Operation canceled.
  35. (child) ; No child processes.
  36. (connaborted) ; Connection aborted.
  37. (connrefused) ; Connection refused.
  38. (connreset) ; Connection reset.
  39. (deadlk) ; Resource deadlock would occur.
  40. (destaddrreq) ; Destination address required.
  41. (dom) ; Mathematics argument out of domain of function.
  42. (dquot) ; Reserved.
  43. (exist) ; File exists.
  44. (fault) ; Bad address.
  45. (fbig) ; File too large.
  46. (hostunreach) ; Host is unreachable.
  47. (idrm) ; Identifier removed.
  48. (ilseq) ; Illegal byte sequence.
  49. (inprogress) ; Operation in progress.
  50. (intr) ; Interrupted function.
  51. (inval) ; Invalid argument.
  52. (io) ; I/O error.
  53. (isconn) ; Socket is connected.
  54. (isdir) ; Is a directory.
  55. (loop) ; Too many levels of symbolic links.
  56. (mfile) ; Too many open files.
  57. (mlink) ; Too many links.
  58. (msgsize) ; Message too large.
  59. (multihop) ; Reserved.
  60. (nametoolong) ; Filename too long.
  61. (netdown) ; Network is down.
  62. (netreset) ; Connection aborted by network.
  63. (netunreach) ; Network unreachable.
  64. (nfile) ; Too many files open in system.
  65. (nobufs) ; No buffer space available.
  66. (nodata) ; [XSR] No message is available on the STREAM head read queue.
  67. (nodev) ; No such device.
  68. (noent) ; No such file or directory.
  69. (noexec) ; Executable file format error.
  70. (nolck) ; No locks available.
  71. (nolink) ; Reserved.
  72. (nomem) ; Not enough space.
  73. (nomsg) ; No message of the desired type.
  74. (noprotoopt) ; Protocol not available.
  75. (nospc) ; No space left on device.
  76. (nosr) ; [XSR] No STREAM resources.
  77. (nostr) ; [XSR] Not a STREAM.
  78. (nosys) ; Function not supported.
  79. (notconn) ; The socket is not connected.
  80. (notdir) ; Not a directory.
  81. (notempty) ; Directory not empty.
  82. (notsock) ; Not a socket.
  83. (notsup) ; Not supported.
  84. (notty) ; Inappropriate I/O control operation.
  85. (nxio) ; No such device or address.
  86. (opnotsupp) ; Operation not supported on socket.
  87. (overflow) ; Value too large to be stored in data type.
  88. (perm) ; Operation not permitted.
  89. (pipe) ; Broken pipe.
  90. (proto) ; Protocol error.
  91. (protonosupport) ; Protocol not supported.
  92. (prototype) ; Protocol wrong type for socket.
  93. (range) ; Result too large.
  94. (rofs) ; Read-only file system.
  95. (spipe) ; Invalid seek.
  96. (srch) ; No such process.
  97. (stale) ; Reserved.
  98. (time) ; [XSR] Stream ioctl() timeout.
  99. (timedout) ; Connection timed out.
  100. (txtbsy) ; Text file busy.
  101. (wouldblock) ; Operation would block (may be the same value as [EAGAIN]).
  102. (xdev) ; Cross-device link.
  103. ))
  104. (define-record-discloser :named-errno
  105. (lambda (n-s)
  106. (list 'errno (named-errno-name n-s))))
  107. ; Find the errno called `name'.
  108. (define (name->errno name)
  109. (if (not (symbol? name))
  110. (assertion-violation 'name->errno "argument not a symbol" name)
  111. (let loop ((i 0))
  112. (cond ((= i (vector-length named-errnos))
  113. #f)
  114. ((eq? name
  115. (named-errno-name
  116. (vector-ref named-errnos i)))
  117. (vector-ref named-errnos i))
  118. (else
  119. (loop (+ i 1)))))))
  120. (define (get-unnamed-errno num)
  121. (call-with-current-continuation
  122. (lambda (return)
  123. (walk-population
  124. (lambda (e)
  125. (if (= num (unnamed-errno-os-number e)) (return e)))
  126. *unnamed-errnos*)
  127. (let ((e (make-unnamed-errno 'nonportable-signal num)))
  128. (add-to-population! e *unnamed-errnos*)
  129. e))))
  130. (define (integer->errno num)
  131. (let loop ((i 0))
  132. (if (= i (vector-length named-errnos))
  133. (get-unnamed-errno num)
  134. (let* ((e (vector-ref named-errnos i))
  135. (errno-number (named-errno-os-number e)))
  136. (if (and errno-number (= num errno-number))
  137. e
  138. (loop (+ i 1)))))))
  139. ; Write the contents of the C array mapping canonical error numbers
  140. ; to os error numbers.
  141. (define (write-c-errno-include-file filename)
  142. (call-with-output-file filename
  143. (lambda (out)
  144. (do ((i 0 (+ i 1)))
  145. ((= i (vector-length named-errnos)))
  146. (let* ((name (named-errno-name
  147. (vector-ref named-errnos i)))
  148. (posix-name (if (eq? name 'toobig)
  149. "2BIG"
  150. (symbol->string name))))
  151. (display (string-append
  152. "#ifdef E" (string-upcase posix-name) newline-string
  153. " E" (string-upcase posix-name) "," newline-string
  154. "#else" newline-string
  155. " -1," newline-string
  156. "#endif" newline-string)
  157. out))))))
  158. (define newline-string (list->string '(#\newline)))
  159. ;----------------
  160. ; Dispatching on the two kinds of errnos.
  161. (define (errno? x)
  162. (or (named-errno? x)
  163. (unnamed-errno? x)))
  164. (define (errno-name x)
  165. (cond ((named-errno? x)
  166. (named-errno-name x))
  167. ((unnamed-errno? x)
  168. #f)
  169. (else
  170. (assertion-violation 'errno-name "argument not a errno" x))))
  171. (define (errno-os-number x)
  172. (cond ((named-errno? x)
  173. (named-errno-os-number x))
  174. ((unnamed-errno? x)
  175. (unnamed-errno-os-number x))
  176. (else
  177. (assertion-violation 'errno-os-number "argument not a errno" x))))
  178. ; Two errnos are the same if they are exactly the same or if they are
  179. ; both named errnos and have the same (non-#F) os number.
  180. (define (errno=? s1 s2)
  181. (or (eq? s1 s2)
  182. (and (named-errno? s1)
  183. (named-errno? s2)
  184. (named-errno-os-number s1)
  185. (eq? (named-errno-os-number s1)
  186. (named-errno-os-number s2)))))
  187. ;----------------
  188. ; What we contribute to and receive from the C layer.
  189. (define-exported-binding "posix-errnos-vector" named-errnos)
  190. (import-lambda-definition-2 initialize-named-errnos ()
  191. "posix_initialize_named_errnos")
  192. ;----------------
  193. ; A vector mapping os-errno numbers to errnos and add to it any errnos
  194. ; that have existing errno queues.
  195. (define os-errno-map (make-session-data-slot! #f))
  196. ; Initializing the above vector.
  197. (define (initialize-errnos)
  198. (set! *unnamed-errnos* (make-population))
  199. (let ((ints (set-enabled-interrupts! no-interrupts)))
  200. (initialize-named-errnos)
  201. (let* ((named (vector->list named-errnos))
  202. (size (+ 1 (apply max
  203. (map (lambda (errno)
  204. (or (errno-os-number errno)
  205. -1))
  206. named))))
  207. (mapper (make-vector size '())))
  208. (for-each (lambda (errno)
  209. (cond
  210. ((errno-os-number errno)
  211. => (lambda (number)
  212. (let ((old (vector-ref mapper number)))
  213. (vector-set! mapper number (cons errno old)))))))
  214. named)
  215. (session-data-set! os-errno-map mapper)
  216. (set-enabled-interrupts! ints))))
  217. ;----------------
  218. ; Initialize errnos now ...
  219. (initialize-errnos)
  220. ; ... and on later startups.
  221. (define-reinitializer errno-reinitializer initialize-errnos)