Note: This page gather some remarks made by people on news:comp.lang.lisp
We're not merging Common-Lisp and POSIX!
We want to have access to POSIX primitives from Common-Lisp applications as easily as from a C application. The POSIX API being the Operating System Interface for the applications.
In particular, we won't convert between PATHNAMES and strings containing unix paths, and we won't convert between unix file descriptors and Common-Lisp streams. (There may already exist such a conversion function in the Common-Lisp implementation extension packages).
This API is defined by the Single UNIX Specification version 3.
It is recommended that the various implementations reside in packages named like:
COM.INFORMATIMAGO.COMMON-LISP.SUSV3 NET.SOURCEFORGE.CLISP.SUSV3 COM.SMART-LISP-CORP.SUSV3
The user can then choose one implementation or the other, and
re-nickname it to the reserved package name SUSV3
.
Note: The package name POSIX
is already taken in various
implementations. Moreover, it's not descriptive enough.
Alternative:
SUS3
.
SUSv3 defines various optional or extension API. (See codes).
These extensions will be defined in additional packages nicknamed:
Nickname: Example of package name: ------------- ------------------------------- SUSV3-ADV COM.INFORMATIMAGO.COMMON-LISP.SUSV3.ADV SUSV3-AIO COM.INFORMATIMAGO.COMMON-LISP.SUSV3.AIO SUSV3-BAR COM.INFORMATIMAGO.COMMON-LISP.SUSV3.BAR SUSV3-CPT etc... SUSV3-CS SUSV3-FSC SUSV3-IP6 SUSV3-MC1 (See: abreviation of a combination of options) SUSV3-MC2 (See: abreviation of a combination of options) SUSV3-MC3 (See: abreviation of a combination of options) SUSV3-MF SUSV3-MF-SHM (A combination) SUSV3-ML SUSV3-MR SUSV3-MON SUSV3-MPR SUSV3-MSG SUSV3-MX SUSV3-PIO SUSV3-PS SUSV3-RS SUSV3-RTS SUSV3-REM SUSV3-SHM SUSV3-SIO SUSV3-SPI SUSV3-SPN SUSV3-SS SUSV3-TCT SUSV3-TEF SUSV3-THR SUSV3-TMO SUSV3-TMR SUSV3-TPI SUSV3-TPP SUSV3-TPS SUSV3-TRC SUSV3-TRI SUSV3-TRL SUSV3-TSA SUSV3-TSF SUSV3-TSH SUSV3-TSP SUSV3-TSS SUSV3-TYM SUSV3-XSI SUSV3-XSR
Some code may not be relevant to a Common-Lisp API.
Alternatives:
I don't like this option, leading to the use of #+ and #-.
Note: When defining lisp structures, we put all the fields, even the optional ones that will be used only when the optional feature is available.
[***SEE***: We need a mean to determine if a given extension is available.
Should each package export an AVAILABLE-P predicate? ]
A symbol name is derived from the C binding's name, by:
No other changes to "Lispify" symbol names are made, so creat()
becomes CREAT
, not CREATE
.
Lisp constants, types, and structures are defined corresponding to the constants, types and structures in the C API.
The API is defined in terms of Common-Lisp.
(read fd buffer &optional (length (length buffer))) => bytes-read
[***SEE***: This doesn't apply to data transfer functions that fill buffers.]
Note: We won't allow passing pathnames as unix path string parameters. Common-Lisp pathnames are messy, no two implementation can agree on their exact semantic, so it would defeat portability.
The return value is usually the same as for the C binding, except in error cases: where the C function is defined as returning some sentinel value and setting "errno" on error, we instead signal a condition of type SYSCALL-ERROR. The actual error value ("errno") is stored in this condition and can be accessed with SYSCALL-ERRNO. [***SEE***: some interface to strerror, to get the user-readable translation of the error number]
We do not automatically translate the returned value into "Lispy" objects - for example, POSIX:OPEN returns a small integer, not a stream.
Rationale: This is an interface to POSIX, not a high-level interface that uses POSIX, and many people using it will actually want to mess with the file descriptors directly. People needing Lispy interfaces can implement them atop this - or indeed, use the existing COMMON-LISP package, which already has many high-level constructs built on top of the operating system.
Similarly, interfacing to [f]printf() is superfluous. vfprintf() is mandatory when coming from a foreign language. Which is *not* to say that there should be no POSIX:PRINTF. I'm all in favour of it! But it is more likely to expand to a call to vprintf(), especially in some implementations which create calls at run-time, instead of generating compile-time native-code.
(defun posix:fprintf (fp format &rest args) (posix:vfprintf fp format (coerce args 'vector)))
A compiler-macro optimization might handle the case when posix:printf is called literally, i.e. with a known number of arguments, on those systems which generate native-code.
I have yet to see non-wrapper FFI definitions for variable-arg functions.
Which leads to another question: how to deal with [vsnf]printf and its sisters' arguments which are all polymorphic??
(typecase ((unsigned-int 32) ... (signed-int 32) ... single-float ... string ... (array fixnum) (array ... ... FFI-pointer
sigaction() is more like [newact] [oldact] whereas &optional always implies [newact [oldact]], i.e. you cannot leave out the first. The performance penalty of choosing to always create and return a sigact structure vs. the C programmer's freedom to choose is debatable.
Note: SUSv3 has provision of locales and multibytes characters!