mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-26 06:22:33 -08:00
file.d: introduce :nonblock and :close-on-exec options for open
Maps directly to flags for open syscall. Ignored on Windows. We now let the user decide whether to open fifos in nonblocking mode or not. Manual has been extended to document the new extensions and slightly rearranged to put the important information first.
This commit is contained in:
parent
3827daf4d9
commit
da26facffa
6 changed files with 92 additions and 57 deletions
14
src/c/file.d
14
src/c/file.d
|
|
@ -5299,6 +5299,12 @@ ecl_open_stream(cl_object fn, enum ecl_smmode smm, cl_object if_exists,
|
|||
if_exists != @':overwrite') {
|
||||
FEinvalid_option(@':if-exists', if_exists);
|
||||
}
|
||||
if (flags & ECL_STREAM_CLOSE_ON_EXEC) {
|
||||
open_flags |= O_CLOEXEC;
|
||||
}
|
||||
if (flags & ECL_STREAM_NONBLOCK) {
|
||||
open_flags |= O_NONBLOCK;
|
||||
}
|
||||
|
||||
fd = safe_open(fname, open_flags, mode);
|
||||
if (fd < 0) {
|
||||
|
|
@ -5367,6 +5373,8 @@ ecl_open_stream(cl_object fn, enum ecl_smmode smm, cl_object if_exists,
|
|||
(if_does_not_exist ECL_NIL idnesp)
|
||||
(external_format @':default')
|
||||
(cstream ECL_T)
|
||||
(close_on_exec ECL_T)
|
||||
(nonblock ECL_NIL)
|
||||
&aux strm)
|
||||
enum ecl_smmode smm;
|
||||
int flags = 0;
|
||||
|
|
@ -5414,6 +5422,12 @@ ecl_open_stream(cl_object fn, enum ecl_smmode smm, cl_object if_exists,
|
|||
if (!Null(cstream)) {
|
||||
flags |= ECL_STREAM_C_STREAM;
|
||||
}
|
||||
if (!Null(close_on_exec)) {
|
||||
flags |= ECL_STREAM_CLOSE_ON_EXEC;
|
||||
}
|
||||
if (!Null(nonblock)) {
|
||||
flags |= ECL_STREAM_NONBLOCK;
|
||||
}
|
||||
strm = ecl_open_stream(filename, smm, if_exists, if_does_not_exist,
|
||||
byte_size, flags, external_format);
|
||||
@(return strm);
|
||||
|
|
|
|||
|
|
@ -1359,6 +1359,7 @@ cl_symbols[] = {
|
|||
{KEY_ "CATCH" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "CASE" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "CIRCLE" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "CLOSE-ON-EXEC" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "COMPILE-TOPLEVEL" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "COMMON" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "CONC-NAME" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
|
|
@ -1435,6 +1436,7 @@ cl_symbols[] = {
|
|||
{KEY_ "NEW-VERSION" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "NEWEST" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "NICKNAMES" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "NONBLOCK" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "OBJECT" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "OFFSET" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
{KEY_ "OPERATION" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)},
|
||||
|
|
|
|||
|
|
@ -293,11 +293,11 @@ Controls escaping of the arguments passed to @code{CreateProcess}.
|
|||
@subsection FIFO files (named pipes)
|
||||
|
||||
Named pipe (known as fifo) may be created on UNIX with a shell command
|
||||
mkfifo. ECL opens such files in non-blocking
|
||||
mode. @coderef{ext:file-kind} will return for such file
|
||||
@code{:fifo}. Since it is impossible to guess how many characters are
|
||||
available in this special file @code{file-length} function will return
|
||||
NIL.
|
||||
mkfifo. They can be opened in non-blocking mode by using @code{:nonblock
|
||||
t} option for @coderef{open}. @coderef{ext:file-kind} will return for
|
||||
such file @code{:fifo}. Since it is impossible to guess how many
|
||||
characters are available in this special file @code{file-length}
|
||||
function will return @code{nil}.
|
||||
|
||||
@node Operating System Interface Reference
|
||||
@subsection Operating System Interface Reference
|
||||
|
|
|
|||
|
|
@ -108,59 +108,23 @@ and the table of known symbols is shown below. Note how some symbols (@code{:cr}
|
|||
@node Streams - Dictionary
|
||||
@subsection Dictionary
|
||||
|
||||
@subsubsection Sequence Streams
|
||||
|
||||
@lspdef ext:sequence-stream
|
||||
@deftp {System Class} ext:sequence-stream
|
||||
|
||||
@paragraph Class Precedence List
|
||||
@coderef{ext:sequence-stream}, @code{stream}, @code{t}
|
||||
|
||||
@paragraph Description
|
||||
Sequence streams work similar to string streams for vectors. The
|
||||
supplied vectors that the streams read from or write to must have a
|
||||
byte sized element type, i.e. @code{(signed-byte 8)},
|
||||
@code{(unsigned-byte 8)} or @code{base-char}.
|
||||
|
||||
The semantics depend on the vector element type and the external
|
||||
format of the stream. If no external format is supplied and the
|
||||
element type is an integer type, the stream is a binary stream and
|
||||
accepts only integers of the same type as the element type of the
|
||||
vector. Otherwise, the stream accepts both characters and integers and
|
||||
converts them using the given external format. If the element type is
|
||||
@code{base-char}, the elements of the vectors are treated as bytes.
|
||||
This means that writing a character may use multiple elements of the
|
||||
vector, whose @code{char-code}s will be equal to the values of the
|
||||
bytes comprising the character in the given external format.
|
||||
@end deftp
|
||||
|
||||
@lspdef ext:make-sequence-input-stream
|
||||
@defun ext:make-sequence-input-stream vector &key (start 0) (end nil) (external-format nil)
|
||||
Create a sequence input stream with the subsequence bounded by
|
||||
@var{start} and @var{end} of the given vector.
|
||||
@end defun
|
||||
@lspdef ext:make-sequence-output-stream
|
||||
@defun ext:make-sequence-output-stream vector &key (external-format nil)
|
||||
Create a sequence output stream.
|
||||
@end defun
|
||||
|
||||
@exindex Using sequence streams
|
||||
Example:
|
||||
|
||||
Using sequence streams to convert to a UTF8 encoded base string
|
||||
@lisp
|
||||
CL-USER> (defvar *output* (make-array 20 :element-type 'base-char :adjustable t :fill-pointer 0))
|
||||
*OUTPUT*
|
||||
CL-USER> (defvar *stream* (ext:make-sequence-output-stream *output* :external-format :utf-8))
|
||||
*STREAM*
|
||||
CL-USER> (write-string "Spätzle mit Soß'" *stream*)
|
||||
"Spätzle mit Soß'"
|
||||
CL-USER> *output*
|
||||
"Spätzle mit SoÃ\237'"
|
||||
@end lisp
|
||||
|
||||
@subsubsection File Stream Extensions
|
||||
|
||||
@lspdef open
|
||||
@defun open filespec &key direction element-type if-exists if-does-not-exist external-format close-on-exec nonblock
|
||||
Additional options for @clhs{f_open.htm,open} include:
|
||||
@table @code
|
||||
@item :close-on-exec
|
||||
Child processes don't inherit a copy of this stream: new processes
|
||||
created by @code{fork} and @code{exec} (for example by calling
|
||||
@coderef{ext:run-program}) close the stream after calling @code{exec}.
|
||||
Defaults to @code{t}.
|
||||
@item :nonblock
|
||||
Open fifos or device files in nonblocking mode. Defaults to @code{nil}.
|
||||
@end table
|
||||
These options are ignored on operating systems which do not support them.
|
||||
@end defun
|
||||
|
||||
@lspdef ext:set-buffering-mode
|
||||
@defun ext:set-buffering-mode stream mode
|
||||
Control the buffering mode of a stream
|
||||
|
|
@ -303,6 +267,56 @@ that the error can be ignored or the octets can be replaced with a
|
|||
character.
|
||||
@end defun
|
||||
|
||||
@subsubsection Sequence Streams
|
||||
|
||||
@lspdef ext:sequence-stream
|
||||
@deftp {System Class} ext:sequence-stream
|
||||
|
||||
@paragraph Class Precedence List
|
||||
@coderef{ext:sequence-stream}, @code{stream}, @code{t}
|
||||
|
||||
@paragraph Description
|
||||
Sequence streams work similar to string streams for vectors. The
|
||||
supplied vectors that the streams read from or write to must have a
|
||||
byte sized element type, i.e. @code{(signed-byte 8)},
|
||||
@code{(unsigned-byte 8)} or @code{base-char}.
|
||||
|
||||
The semantics depend on the vector element type and the external
|
||||
format of the stream. If no external format is supplied and the
|
||||
element type is an integer type, the stream is a binary stream and
|
||||
accepts only integers of the same type as the element type of the
|
||||
vector. Otherwise, the stream accepts both characters and integers and
|
||||
converts them using the given external format. If the element type is
|
||||
@code{base-char}, the elements of the vectors are treated as bytes.
|
||||
This means that writing a character may use multiple elements of the
|
||||
vector, whose @code{char-code}s will be equal to the values of the
|
||||
bytes comprising the character in the given external format.
|
||||
@end deftp
|
||||
|
||||
@lspdef ext:make-sequence-input-stream
|
||||
@defun ext:make-sequence-input-stream vector &key (start 0) (end nil) (external-format nil)
|
||||
Create a sequence input stream with the subsequence bounded by
|
||||
@var{start} and @var{end} of the given vector.
|
||||
@end defun
|
||||
@lspdef ext:make-sequence-output-stream
|
||||
@defun ext:make-sequence-output-stream vector &key (external-format nil)
|
||||
Create a sequence output stream.
|
||||
@end defun
|
||||
|
||||
@exindex Using sequence streams
|
||||
Example:
|
||||
|
||||
Using sequence streams to convert to a UTF8 encoded base string
|
||||
@lisp
|
||||
CL-USER> (defvar *output* (make-array 20 :element-type 'base-char :adjustable t :fill-pointer 0))
|
||||
*OUTPUT*
|
||||
CL-USER> (defvar *stream* (ext:make-sequence-output-stream *output* :external-format :utf-8))
|
||||
*STREAM*
|
||||
CL-USER> (write-string "Spätzle mit Soß'" *stream*)
|
||||
"Spätzle mit Soß'"
|
||||
CL-USER> *output*
|
||||
"Spätzle mit SoÃ\237'"
|
||||
@end lisp
|
||||
|
||||
@node Streams - C Reference
|
||||
@subsection C Reference
|
||||
|
|
|
|||
|
|
@ -234,6 +234,9 @@ extern enum ecl_ffi_tag ecl_foreign_type_code(cl_object type);
|
|||
#define OPEN_RA "a+b"
|
||||
|
||||
/* Windows does not have this flag (POSIX thing) */
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
#ifndef O_NONBLOCK
|
||||
#define O_NONBLOCK 0
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -634,7 +634,9 @@ enum {
|
|||
ECL_STREAM_LITTLE_ENDIAN = 128,
|
||||
ECL_STREAM_C_STREAM = 256,
|
||||
ECL_STREAM_MIGHT_SEEK = 512,
|
||||
ECL_STREAM_CLOSE_COMPONENTS = 1024
|
||||
ECL_STREAM_CLOSE_COMPONENTS = 1024,
|
||||
ECL_STREAM_CLOSE_ON_EXEC = 2048,
|
||||
ECL_STREAM_NONBLOCK = 4096
|
||||
};
|
||||
|
||||
/* buffer points to an array of bytes ending at buffer_end. Decode one
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue