3 Note: this file's description of a POSIX binding for Common Lisp does
4 not necessarily describe the state of the sb-posix module. If you're
5 looking for a description sb-posix, look at sb-posix.texinfo in this
10 The scope of this interface is "operating system calls on a typical
11 Unixlike platform". This is section 2 of the Unix manual, plus
12 section 3 calls that are (a) typically found in libc, but (b) not part
13 of the C standard. For example, we intend to provide support for
14 opendir() and readdir(), but not for printf(). Note that we do not
15 assert or imply any claim of conformance with the official standards
16 issued by POSIX groups or SVID or anyone else: we're simply using
17 "POSIX" in a generic sense to refer to Unix and Unix-like systems.
19 Some facilities are omitted where they offer absolutely no additional
20 use over some portable function, or would be actively dangerous to the
21 consistency of Lisp. Not all functions are available on all
22 platforms. [TBD: unavailable functions should (a) not exist, or (b)
23 exist but signal some kind of "not available on this platform" error]
25 The general intent is for a low-level interface. There are three
26 reasons for this: it's easier to write a high-level interface given a
27 low-level one than vice versa, there are fewer philosophical
28 disagreements about what it should look like, and the work of
29 implementing it is easily parallelisable - and in fact, can be
30 attempted on an as-needed basis by the various people who want it.
34 In SBCL this interface is in the SB-POSIX package. This package
35 contains a Lisp function for each supported Unix function, and a
36 variable or constant for each supported unix constant. A symbol name
37 is derived from the C binding's name, by (a) uppercasing, then (b)
38 removing leading underscores (#\_) then replacing remaining underscore
39 characters with the hyphen (#\-). The requirement to uppercase is so
40 that in a standard upcasing reader the user may write posix:creat
41 instead of posix:|creat| as would otherise be required - some
42 extra-standard implementations may have alternative means to achieve
45 No other changes to "Lispify" symbol names are made, so creat()
46 becomes CREAT, not CREATE
48 The user is encouraged not to (USE-PACKAGE :SB-POSIX) but instead to
49 use the SB-POSIX: prefix on all references, as some of our symbols
50 have the same name as CL symbols (OPEN, CLOSE, SIGNAL etc).
52 [ Rationale: We use similar names to the C bindings so that unix
53 manual pages can be used for documentation. To avoid name clashes
54 with CL or other functions, the approaches considered were (a) prefix
55 the names of clashing symbols with "POSIX-" or similar, (b) prefix
56 _all_ symbols with "POSIX-", (c) use the packaging system to resolve
57 ambiguities. (a) was rejected as the set of symbols we may
58 potentially clash with is not fixed (for example, if new symbols are
59 added to SB-EXT) so symbols might have to be renamed over the lifetime
60 of SB-POSIX, which is not good. The choice between (b) and (c) was
61 made on the grounds that POSIX-OPEN is about as much typing as
62 SB-POSIX:OPEN anyway, and symbol munging is, the author feels,
63 slightly tacky, when there's a package system available to do it more
69 Some functions accept objects such as filenames or file
70 descriptors. In the C binding to POSIX these are represented as
71 strings and small integers respectively. For the Lisp programmer's
72 convenience we introduce designators such that CL pathnames or open
73 streams can be passed to these functions.
77 A file-descriptor is a non-negative small integer.
79 A file-stream is a designator for a file-descriptor: the streams file
80 descriptor is extracted. Note that mixing io operations on a stream
81 with operations directly on its descriptor may produce unexpected
82 results if the stream is buffered.
86 A filename is a string.
88 A pathname is a designator for a filename: the filename is computed
89 using the same mechanism as the implementation would use to map
90 pathnames to OS filenames internally.
92 In an implementation that supports pathnames to files on other hosts,
93 using mechanisms not available to the underlying OS (for example,
94 using an FTP or HTTP client in the Lisp implementation), the effect
95 of supplying this interface with a pathname to such a file is undefined.
100 A buffer is an opaque object which represents an area of memory that
101 system calls may access. It has accessors BUFFER-START and
102 BUFFER-LENGTH, and can be created using ALLOCATE-BUFFER or GET-BUFFER.
104 [ TODO: GET-BUFFER is a silly name. Come up with a better one ]
106 The object NIL is a designator for a buffer, meaning a NULL pointer.
108 A vector of (UNSIGNED-BYTE 8) is a designator for a buffer: it is
109 converted to a buffer of appropriate start and length using an
110 identity mapping. This may or may not involve creating a copy of the
113 A vector of CHARACTER is a designator for a buffer: it is converted to
114 a buffer of appropriate start and length using an implementation-
115 defined transformation that obviously depends on the implementation's
116 representation of characters. This may or may not involve creating a
119 Implementations may optionally extend these designators to include
120 other types - for example, types that already exist in the
121 implementation's FFI.
123 ** Structures, unions
125 C structures and unions are opaque to Lisp and may be implemented
126 using any appropriate method. Structure names are chosen according to
127 the general rules for symbols.
129 Accessors must be provided for each documented field in the
130 structure. These are named structure-name-field-name where the two
131 components are chosen according to the general rules, with the
132 exception that in cases where all fields in a given structure have a
133 common prefix, that prefix is omitted. For example, stat.st_dev in C
134 becomes STAT-DEV in Lisp.
136 For any structure that the user may need to allocate himself, there
137 must also be a MAKE-structure-name function. This takes keyword
138 arguments with names deriving from each documented field name
139 according to the general rules for symbols.
141 [ TDB: GC issues for buffers/structures/unions: probably a
142 WITHOUT-MOVING macro or similar that will stop them from being moved
143 or collected during its extent ]
146 ** Type conversion functions
148 For each of these types there is a function of the same name that
149 converts any valid designator for the type into an object of said type.
151 This example is merely an example: actual output will vary between
152 systems, implementations and environments
154 (with-open-file (o "/tmp/foo" :direction :output)
155 (sb-posix:file-descriptor o))
158 [ TBD: some memorable and nicely uniform protocol for transforming
159 objects of these new types into instances of the Lisp-friendly types
160 that may designate them: e.g how to get a stream from a fd ]
163 * Function parameters
165 The calling convention is modelled after that of CMUCL's UNIX package:
166 in particular, it's like the C interface except that
168 a) length arguments are omitted or optional where the sensible value
169 is obvious. For example,
171 (read fd buffer &optional (length (length buffer))) => bytes-read
173 b) where C simulates "out" parameters using pointers (for instance, in
174 pipe() or socketpair()) these may be optional or omitted in the Lisp
175 interface: if not provided, appropriate objects will be allocated and
176 returned (using multiple return values if necessary).
178 c) some functions accept objects such as filenames or file
179 descriptors. Wherever these are specified as such in the C bindings,
180 the Lisp interface accepts designators for them as specified in the
181 'Types' section above
183 [ Rationale: Keeping exact 1:1 correspondence with C conventions is
184 less important here, as the function argument list can easily be
185 accessed to find out exactly what the arguments are. Designators
186 are primarily a convenience feature ]
188 * Function return values
190 The return value is usually the same as for the C binding, except in
191 error cases: where the C function is defined as returning some
192 sentinel value and setting "errno" on error, we instead signal an
193 error of type SYSCALL-ERROR. The actual error value ("errno") is
194 stored in this condition and can be accessed with SYSCALL-ERRNO.
195 [TBA: some interface to strerror, to get the user-readable translation
198 We do not automatically translate the returned value into "Lispy"
199 objects - for example, SB-POSIX:OPEN returns a small integer, not a
200 stream. Exception: boolean-returning functions (or, more commonly,
201 macros) do not return a C integer, but instead a lisp boolean [ or
202 maybe "true"/"false" in CLtS parlance ]; the rationale behind this
203 exception is that there is nothing that can be meaningfully done with
204 the boolean except test for truth or falsity -- it cannot be passed
205 meaningfully to other POSIX functions.
207 [ Rationale: This is an interface to POSIX, not a high-level interface
208 that uses POSIX, and many people using it will actually want to mess
209 with the file descriptors directly. People needing Lispy interfaces
210 can implement them atop this - or indeed, use the existing COMMON-LISP
211 package, which already has many high-level constructs built on top of
212 the operating system ;-) ]
217 The initial implementation is in contrib/sb-posix, and being filled
218 out on an as-needed basis. Contributions following these style rules
219 are welcome from anyone who writes them, provided the author is happy
220 to release the code as Public Domain or MIT-style licence.
222 See/update the TODO list for current status
226 See designator.lisp, add a define-designator form
230 The use of DEFINE-CALL macro in interface.lisp should be obvious from
231 the existing examples, if less so from the macroexpansion
239 buffers that refer to C stuff are probably not movable by GC anyway
241 a buffer that refers to a Lisp object may have trouble if the Lisp