5 The scope of this interface is "operating system calls on a typical
6 Unixlike platform". This is section 2 of the Unix manual, plus
7 section 3 calls that are (a) typically found in libc, but (b) not part
8 of the C standard. For example, we intend to provide support for
9 opendir() and readdir(), but not for printf(). Note that we do not
10 assert or imply any claim of conformance with the official standards
11 issued by POSIX groups or SVID or anyone else: we're simply using
12 "POSIX" in a generic sense to refer to Unix and Unix-like systems.
14 Some facilities are omitted where they offer absolutely no additional
15 use over some portable function, or would be actively dangerous to the
16 consistency of Lisp. Not all functions are available on all
17 platforms. [TBD: unavailable functions should (a) not exist, or (b)
18 exist but signal some kind of "not available on this platform" error]
20 The general intent is for a low-level interface. There are three
21 reasons for this: it's easier to write a high-level interface given a
22 low-level one than vice versa, there are fewer philosophical
23 disagreements about what it should look like, and the work of
24 implementing it is easily parallelisable - and in fact, can be
25 attempted on an as-needed basis by the various people who want it.
29 In SBCL this interface is in the SB-POSIX package. This package
30 contains a Lisp function for each supported Unix function, and a
31 variable or constant for each supported unix constant. A symbol name
32 is derived from the C binding's name, by (a) uppercasing, then (b)
33 removing leading underscores (#\_) then replacing remaining underscore
34 characters with the hyphen (#\-). The requirement to uppercase is so
35 that in a standard upcasing reader the user may write posix:creat
36 instead of posix:|creat| as would otherise be required - some
37 extra-standard implementations may have alternative means to achieve
40 No other changes to "Lispify" symbol names are made, so creat()
41 becomes CREAT, not CREATE
43 The user is encouraged not to (USE-PACKAGE :SB-POSIX) but instead to
44 use the SB-POSIX: prefix on all references, as some of our symbols
45 have the same name as CL symbols (OPEN, CLOSE, SIGNAL etc).
47 [ Rationale: We use similar names to the C bindings so that unix
48 manual pages can be used for documentation. To avoid name clashes
49 with CL or other functions, the approaches considered were (a) prefix
50 the names of clashing symbols with "POSIX-" or similar, (b) prefix
51 _all_ symbols with "POSIX-", (c) use the packaging system to resolve
52 ambiguities. (a) was rejected as the set of symbols we may
53 potentially clash with is not fixed (for example, if new symbols are
54 added to SB-EXT) so symbols might have to be renamed over the lifetime
55 of SB-POSIX, which is not good. The choice between (b) and (c) was
56 made on the grounds that POSIX-OPEN is about as much typing as
57 SB-POSIX:OPEN anyway, and symbol munging is, the author feels,
58 slightly tacky, when there's a package system available to do it more
64 Some functions accept objects such as filenames or file
65 descriptors. In the C binding to POSIX these are represented as
66 strings and small integers respectively. For the Lisp programmer's
67 convenience we introduce designators such that CL pathnames or open
68 streams can be passed to these functions.
72 A file-descriptor is a non-negative small integer.
74 A file-stream is a designator for a file-descriptor: the streams file
75 descriptor is extracted. Note that mixing io operations on a stream
76 with operations directly on its descriptor may produce unexpected
77 results if the stream is buffered.
81 A filename is a string.
83 A pathname is a designator for a file-descriptor: the filename is
84 computed as if by NAMESTRING
88 A buffer is an opaque object with accessors BUFFER-START and
89 BUFFER-LENGTH, which represents an area of memory that system calls
90 may access. A buffer can be created using ALLOCATE-BUFFER or GET-BUFFER.
92 [ TODO: GET-BUFFER is a silly name. Come up with a better one ]
94 The object NIL is a designator for a buffer, meaning a NULL pointer.
96 A vector of (UNSIGNED-BYTE 8) is a designator for a buffer: it is
97 converted to a buffer of appropriate start and length using an
98 identity mapping. This may or may not involve creating a copy of the
101 A vector of CHARACTER is a designator for a buffer: it is converted to
102 a buffer of appropriate start and length using an implementation-
103 defined transformation that obviously depends on the implementation's
104 representation of characters. This may or may not involve creating a
107 Implementations may optionally extend these designators to include
108 other types - for example, types that already exist in the
109 implementation's FFI.
111 ** Structures, unions
113 C structures and unions are opaque to Lisp and may be implemented
114 using any appropriate method. Structure names are chosen according to
115 the general rules for symbols.
117 Accessors must be provided for each documented field in the
118 structure. These are named structure-name-field-name where the two
119 components are chosen according to the general rules, with the
120 exception that in cases where all fields in a given structure have a
121 common prefix, that prefix is omitted. For example, stat.st_dev in C
122 becomes STAT-DEV in Lisp.
124 For any structure that the user may need to allocate himself, there
125 must also be a MAKE-structure-name function. This takes keyword
126 arguments with names deriving from each documented field name
127 according to the general rules for symbols.
129 [ TDB: GC issues for buffers/structures/unions: probably a
130 WITHOUT-MOVING macro or similar that will stop them from being moved
131 or collected during its extent ]
134 ** Type conversion functions
136 For each of these types there is a function of the same name that
137 converts any valid designator for the type into an object of said type.
139 This example is merely an example: actual output will vary between
140 systems, implementations and environments
142 (with-open-file (o "/tmp/foo" :direction :output)
143 (sb-posix:file-descriptor o))
146 [ TBD: some memorable and nicely uniform protocol for transforming
147 objects of these new types into instances of the Lisp-friendly types
148 that may designate them: e.g how to get a stream from a fd ]
151 * Function parameters
153 The calling convention is modelled after that of CMUCL's UNIX package:
154 in particular, it's like the C interface except that
156 a) length arguments are omitted or optional where the sensible value
157 is obvious. For example,
159 (read fd buffer &optional (length (length buffer))) => bytes-read
161 b) where C simulates "out" parameters using pointers (for instance, in
162 pipe() or socketpair()) we may use multiple return values instead.
163 This doesn't apply to data transfer functions that fill buffers.
165 c) some functions accept objects such as filenames or file
166 descriptors. Wherver these are specified as such in the C bindings,
167 the Lisp interface accepts designators for them as specified in the
168 'Types' section above
170 [ Rationale: Keeping exact 1:1 correspondence with C conventions is
171 less important here, as the function argument list can easily be
172 accessed to find out exactly what the arguments are. Designators
173 are primarily a convenience feature ]
175 * Function return values
177 The return value is usually the same as for the C binding, except in
178 error cases: where the C function is defined as returning some
179 sentinel value and setting "errno" on error, we instead signal an
180 error of type SYSCALL-ERROR. The actual error value ("errno") is
181 stored in this condition and can be accessed with SYSCALL-ERRNO.
182 [TBA: some interface to strerror, to get the user-readable translation
185 We do not automatically translate the returned value into "Lispy"
186 objects - for example, SB-POSIX:OPEN returns a small integer, not a
189 [ Rationale: This is an interface to POSIX, not a high-level interface
190 that uses POSIX, and many people using it will actually want to mess
191 with the file descriptors directly. People needing Lispy interfaces
192 can implement them atop this - or indeed, use the existing COMMON-LISP
193 package, which already has many high-level constructs built on top of
194 the operating system ;-) ]
199 The initial implementation is in contrib/sb-posix, and being filled
200 out on an as-needed basis. Contributions following these style rules
201 are welcome from anyone who writes them, provided the author is happy
202 to release the code as Public Domain or MIT-style licence.
204 See/update the TODO list for current status
208 See designator.lisp, add a define-designator form
212 The use of DEFINE-CALL macro in interface.lisp should be obvious from
213 the existing examples, if less so from the macroexpansion
221 buffers that refer to C stuff are probably not movable by GC anyway
223 a buffer that refers to a Lisp object may have trouble if the Lisp