libslack(fio) - fifo and file control module and some I/O
#include <slack/fio.h>
char *fgetline(char *line, size_t size, FILE *stream); char *fgetline_unlocked(char *line, size_t size, FILE *stream); int read_timeout(int fd, long sec, long usec); int write_timeout(int fd, long sec, long usec); int rw_timeout(int fd, long sec, long usec); int nap(long sec, long usec); int fcntl_set_flag(int fd, int flag); int fcntl_clear_flag(int fd, int flag); int fcntl_lock(int fd, int cmd, int type, int whence, int start, int len); int nonblock_set(int fd, int arg); int nonblock_on(int fd); int nonblock_off(int fd); int fifo_exists(const char *path, int prepare); int fifo_has_reader(const char *path, int prepare); int fifo_open(const char *path, mode_t mode, int lock, int *writefd);
This module provides various I/O related functions: reading a line of text no matter what line endings are used; timeouts for read/write operations without signals; exclusively opening a fifo for reading; and some random shorthand functions for manipulating file flags and locks.
char *fgetline(char *line, size_t size, FILE *stream)
Similar to fgets(3) except that it recognises UNIX (``\n''), DOS (``\r\n'') and Macintosh
(``\r'') line endings (even different line ending in the same file). Reads
in at most size - 1
characters from stream
and stores them into the buffer pointed to by line
. Reading stops after an EOF
or the end of the line. If the end of the line was read, a newline is
stored into the buffer. A null
is stored after the last character in the buffer. On success, returns line
. On error, or when the end of file occurs while no characters have been
read, returns null
. Calls to this function can be mixed with calls to other input functions
from the stdio library for the same input stream.
char *fgetline_unlocked(char *line, size_t size, FILE *stream)
Equivalent to fgetline() except that stream
is not locked.
int read_timeout(int fd, long sec, long usec)
Performs a select(2) on a single file descriptor, fd
, for reading and exceptions (i.e. arrival of urgent data), that times out
after sec
seconds and usec
microseconds. This is just a shorthand function to provide a simple timed read(2) (or readv(2) or accept(2) or
recv(2) or recvfrom(2) or recvmsg(2) without resorting to
alarm(3) and SIGALRM
signals (best avoided). On success, returns 0
. On error, returns -1
with errno
set appropriately (ETIMEDOUT
if it timed out, otherwise set by select(2)). Usage:
if (read_timeout(fd, 5, 0) == -1 || (bytes = read(fd, buf, count)) == -1) return -1;
int write_timeout(int fd, long sec, long usec)
Performs a select(2) on a single file descriptor, fd
, for writing, that times out after sec
seconds and usec
microseconds. This is just a shorthand function to provide a simple timed write(2) (or writev(2) or
send(2) or sendto(2) or sendmsg(2)) without resorting to
alarm(3) and SIGALRM
signals (best avoided). On success, returns 0
. On error, returns -1
with errno
set appropriately (ETIMEDOUT
if it timed out, otherwise set by select(2)). Usage:
if (write_timeout(fd, 5, 0) == -1 || (bytes = write(fd, buf, count)) == -1) return -1;
int rw_timeout(int fd, long sec, long usec)
Performs a select(2) on a single file descriptor, fd
, for reading, writing and exceptions (i.e. arrival of urgent data), that
times out after
sec
seconds and usec
microseconds. This is just a shorthand function to provide a simple timed read(2) or write(2) without resorting to
alarm(3) and SIGALRM
signals (best avoided). On success, returns a bit mask indicating whether fd
is readable (R_OK
), writable (W_OK
) and/or has urgent data available (X_OK
). On error, returns -1
with
errno
set appropriately (ETIMEDOUT
if it timed out, otherwise set by
select(2)).
int nap(long sec, long usec)
Puts the process to sleep for sec
seconds and usec
microseconds. Note, however, that many systems' timers only have 10ms
resolution. On success, returns 0
. On error, returns -1
with errno
set appropriately.
int fcntl_set_flag(int fd, int flag)
Shorthand for setting the file flag, flag
, on the file descriptor, fd
, using fcntl(2). All other flags are unaffected. On success, returns 0
. On error, returns -1
with errno
set by fcntl(2) with F_GETFL
or
F_SETFL
as the command.
int fcntl_clear_flag(int fd, int flag)
Shorthand for clearing the file flag, flag
, from the file descriptor,
fd
, using fcntl(2). All other flags are unaffected. On success, returns 0
. On error, returns -1
with errno
set by fcntl(2) with
F_GETFL
or F_SETFL
as the command.
int fcntl_lock(int fd, int cmd, int type, int whence, int start, int len)
Shorthand for performing discretionary file locking operations on the file
descriptor, fd
. cmd
is the locking command and is passed to
fcntl(2). type
, whence
, start
and len
are used to fill a
flock structure which is passed to fcntl(2). Returns the same as
fcntl(2) with cmd
as the command.
int nonblock_set(int fd, int arg)
Sets non-blocking mode for the file descriptor, fd
, if arg
is non-zero. Sets blocking mode if arg
is zero. On success, returns 0
. On error, returns -1
with errno
set by fcntl(2) with F_GETFL
or
F_SETFL
as the command.
int nonblock_on(int fd)
Sets non-blocking mode for the file descriptor, fd
. On success, returns
0
. On error, returns -1
with errno
set by fcntl(2) with
F_GETFL
or F_SETFL
as the command.
int nonblock_off(int fd)
Sets blocking mode for the file descriptor, fd
. On success, returns 0
. On error, returns -1
with errno
set by fcntl(2) with F_GETFL
or
F_SETFL
as the command.
int fifo_exists(const char *path, int prepare)
Determines whether or not path
refers to a fifo. Returns 0
if path
doesn't exist or doesn't refer to a fifo. If path
refers to a fifo, returns 1. If prepare
is non-zero, and path
refers to a non-fifo, it will be unlinked. On error, returns -1
with errno
set by stat(2).
int fifo_has_reader(const char *path, int prepare)
Determines whether or not path
refers to a fifo that is being read by another process. If path
does not exist or does not refer to a fifo or if the fifo can't be opened
for non-blocking write(2), returns 0
. If
prepare
is non-zero, and path refers to a non-fifo, it will be unlinked. On error,
returns -1
with errno
set by stat(2) or open(2).
int fifo_open(const char *path, mode_t mode, int lock, int *writefd)
Creates a fifo named path
with creation mode mode
for reading. If
path
already exists, is a fifo and has a reader process, returns -1
with errno
set to EADDRINUSE
. If the fifo is created (or an existing one can be reused), two file
descriptors are opened to the fifo. A read descriptor and a write
descriptor. On success, returns the read descriptor. The write descriptor
only exists to ensure that there is always at least one writer process for
the fifo. This allows a read(2) on the read descriptor to block until another process writes to the fifo
rather than returning an
EOF
condition. This is done in a POSIX compliant way. If lock
is non-zero, the fifo is exclusively locked. If writefd
is not null
, the write descriptor is stored there. On error, returns -1
with errno
set by stat(2), open(2), mkfifo(2), fstat(2) or fcntl(2).
These functions set errno
to the following values. errno
may also be set by the underlying system calls. See their manpages for
details.
ETIMEDOUT
The read_timeout(), write_timeout() and rw_timeout() functions set this when a timeout occurs.
EADDRINUSE
fifo_open() sets this when the path refers to a fifo that already has another process reading from it.
MT-Safe
Mac OS X doesn't have flockfile(3), funlockfile(3) or getc_unlocked(3) so freadline() is not MT-Safe on such platforms. You must guard all stdio calls in multi threaded programs with explicit synchronisation variables.
Some systems, such as Mac OS X, can't lock fifos. On these systems, fifo_open() ignores the locking failure and returns successfully. This means that there is no guarantee of a unique reader process on these systems. You will need to lock an ordinary file yourself to provide this guarantee.
libslack(3), fcntl(2), stat(2), fstat(2), open(2), write(2), read(2), mkfifo(2)
20011109 raf <raf@raf.org>