libslack(fio) - fifo and file control module and some I/O
#include <slack/std.h>
#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)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)stream is not locked.
int read_timeout(int fd, long sec, long usec)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)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)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)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)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)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)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)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)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)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)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)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)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.
ETIMEDOUTEADDRINUSE
MT-Safe
Mac OS X doesn't have flockfile(3), funlockfile(3) or getc_unlocked(3) so fgetline(3) 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(3) 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)
20020916 raf <raf@raf.org>