@ -0,0 +1,28 @@ | |||
.TH io_canread 3 | |||
.SH NAME | |||
io_canread \- return a file descriptor that can be read from | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int64 \fBio_canread\fP(); | |||
.SH DESCRIPTION | |||
io_canread returns the next file descriptor that can be read from. | |||
You have to have used io_wantread() on the file descriptor earlier, and | |||
you have to have called io_wait() or io_waituntil(). | |||
These functions then keep an internal data structure on which | |||
descriptors were reported readable by the operating system. | |||
Please note that there is no guarantee that there still is data that can | |||
be read from the descriptor, just that there was data when io_wait() or | |||
io_waituntil() were called. Another process could have read the data | |||
before you. Look at the result from io_tryread(). | |||
If there are no more descriptors that you can write to without blocking, | |||
io_canwrite will return -1. In this case you should call io_wait() or | |||
io_waituntil() again. | |||
You should use io_tryread(3) to read from the descriptor, not plain | |||
read(2). If you use read(2) and you get EAGAIN, call io_eagain(3). | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canwrite(3), io_eagain(3) |
@ -0,0 +1,29 @@ | |||
.TH io_canwrite 3 | |||
.SH NAME | |||
io_canwrite \- return a file descriptor that can be written to | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int64 \fBio_canwrite\fP(); | |||
.SH DESCRIPTION | |||
io_canwrite returns the next file descriptor that can be written to. | |||
You have to have used io_wantwrite() on the file descriptor earlier, and | |||
you have to have called io_wait() or io_waituntil(). | |||
These functions then keep an internal data structure on which | |||
descriptors were reported writable by the operating system. | |||
Please note that there is no guarantee that you can still write data | |||
without blocking to that descriptor, just that you could when io_wait() | |||
or io_waituntil() were called. Another process could have written | |||
something before you. Look at the result from io_trywrite(). | |||
If there are no more descriptors that you can write to without blocking, | |||
io_canwrite will return -1. In this case you should call io_wait() or | |||
io_waituntil() again. | |||
You should only use io_trywrite(3), io_sendfile(3) or iob_send(3) to | |||
write to the file, not plain write(2). If you use write(2) and get | |||
EAGAIN, call io_eagain(3). | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canwrite(3) |
@ -0,0 +1,11 @@ | |||
.TH io_check 3 | |||
.SH NAME | |||
io_check \- check for new readable or writable descriptors | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int64 \fBio_check\fP(); | |||
.SH DESCRIPTION | |||
io_check is like io_waituntil() with a deadline of now. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_waituntil(3) |
@ -0,0 +1,24 @@ | |||
.TH io_close 3 | |||
.SH NAME | |||
io_close \- close a file descriptor | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_close\fP(int64 fd); | |||
.SH DESCRIPTION | |||
io_close eliminates the descriptor numbered \fIfd\fR. This usually does not | |||
mean eliminating the object that the descriptor is talking to. | |||
(For example, if a descriptor writes to a named disk file, closing the | |||
descriptor will not remove the file; it simply removes one way of | |||
writing to the file. On the other hand, a pipe disappears as soon as no | |||
descriptors refer to it.) | |||
io_close has no return value; it always succeeds in deallocating the | |||
memory used for the descriptor. If \fIfd\fR is not the number of a | |||
descriptor, io_close has no effect. | |||
io_close() is like close(), but it also removes the descriptor from the | |||
internal io_wait() data structures. If you called io_fd on a | |||
descriptor, you need to use io_close to close it, not just close(). | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canwrite(3) |
@ -0,0 +1,14 @@ | |||
.TH io_closeonexec 3 | |||
.SH NAME | |||
io_closeonexec \- mark a file descriptor non-inheritable | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_closeonexec\fP(int64 fd); | |||
.SH DESCRIPTION | |||
io_closeonexec marks a file descriptor non-inheritable. It will be | |||
automatically closed if the process executes a different one. The | |||
descriptor will not be automatically closed when you fork() a new child | |||
process, though. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canwrite(3) |
@ -0,0 +1,17 @@ | |||
.TH io_createfile 3 | |||
.SH NAME | |||
io_createfile \- create a file | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_createfile\fP(int64* d,const char* s); | |||
.SH DESCRIPTION | |||
io_createfile sets d to the number of a new descriptor writing to the disk file | |||
named \fIs\fR, and returns 1. If \fIs\fR already existed, it is truncated to length 0; | |||
otherwise, it is created, with mode 0600. | |||
If something goes wrong, io_createfile sets \fIerrno\fR to indicate the error, and | |||
returns 0; it does not create a new descriptor, and it does not touch d. | |||
(However, it may have truncated or created the file.) | |||
.SH "SEE ALSO" | |||
io_readfile(3) |
@ -0,0 +1,18 @@ | |||
.TH io_dontwantread 3 | |||
.SH NAME | |||
io_dontwantread \- signal that you do not want to read from a descriptor | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_dontwantread\fP(int64 fd); | |||
.SH DESCRIPTION | |||
io_dontwantread tells the next io_wait() that you don't want to read | |||
from this descriptor for now. Call io_wantread() again if you change | |||
your mind. | |||
You have to have called io_fd on the descriptor first (io_pipe and | |||
io_socketpair do this for you). Waiting on descriptors only works for | |||
sockets, fifos and pipes. It may also work on devices and TTYs, but | |||
that is platform dependent -- you should not rely on that. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canread(3), io_wantread(3), io_fd(3) |
@ -0,0 +1,18 @@ | |||
.TH io_dontwantwrite 3 | |||
.SH NAME | |||
io_dontwantwrite \- signal that you do not want to write to a descriptor | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_dontwantwrite\fP(int64 fd); | |||
.SH DESCRIPTION | |||
io_dontwantwrite tells the next io_wait() that you don't want to write | |||
to this descriptor for now. Call io_wantwrite() again if you change | |||
your mind. | |||
You have to have called io_fd on the descriptor first (io_pipe and | |||
io_socketpair do this for you). Waiting on descriptors only works for | |||
sockets, fifos and pipes. It may also work on devices and TTYs, but | |||
that is platform dependent -- you should not rely on that. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canwrite(3), io_wantwrite(3), io_fd(3) |
@ -0,0 +1,20 @@ | |||
.TH io_eagain 3 | |||
.SH NAME | |||
io_eagain \- tell io_wait that you got an EAGAIN | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_eagain\fP(int64 fd); | |||
.SH DESCRIPTION | |||
If io_wait() said that you can read from a descriptor, you try to read | |||
from it, and you get EAGAIN, you need to tell io_wait(). This is | |||
important for edge triggered event notification schemes like Linux 2.4's | |||
SIGIO, or you will lose events. | |||
io_tryread(), io_trywrite() and io_sendfile() and iob_send() already | |||
take care of this for you. | |||
This function is only of interest if you integrate io_wait() with legacy | |||
code that uses read/write directly. | |||
.SH "SEE ALSO" | |||
io_wait(3) |
@ -0,0 +1,19 @@ | |||
.TH io_fd 3 | |||
.SH NAME | |||
io_fd \- prepare descriptor for io_wait | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_fd\fP(int64 fd); | |||
.SH DESCRIPTION | |||
If you want to use io_canread() and io_canwrite() on a descriptor, you | |||
have to use io_wait() on it first, and io_wait() has to know which | |||
descriptors you are interested in. Use io_fd() for this. | |||
io_pipe and io_socketpair already call io_fd for you. | |||
Waiting on descriptors only works for sockets, fifos and pipes. It may | |||
also work on devices and TTYs, but that is platform dependent -- you | |||
should not rely on that. It does not work on files. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_wantread(3), io_canread(3), io_eagain(3), io_nonblock(3) |
@ -0,0 +1,14 @@ | |||
.TH io_finishandshutdown 3 | |||
.SH NAME | |||
io_finishandshutdown \- deallocate internal data structures | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_finishandshutdown\fP(); | |||
.SH DESCRIPTION | |||
io_finishandshutdown deallocates the internal data structures of | |||
io_wait(). This only makes sense if you run your program in a malloc | |||
checker and want to eliminate the false alarms. Your OS will free data | |||
structures automatically on process termination. | |||
.SH "SEE ALSO" | |||
io_wait(3) |
@ -0,0 +1,23 @@ | |||
.TH io_getcookie 3 | |||
.SH NAME | |||
io_getcookie \- retrieve cookie | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void* \fBio_getcookie\fP(int64 fd); | |||
.SH DESCRIPTION | |||
io_getcookie retrieves a cookie (pointer to some anonymous data | |||
structure you associated with this descriptor). | |||
Use io_setcookie(3) to associate a cookie with a descriptor. | |||
If you did not associate a cookie with this descriptor, io_getcookie | |||
returns NULL. | |||
The idea is that you put the state associated with a TCP connection you | |||
serve in a common struct. Then you do not need to have your own data | |||
structure to retrieve the state for a connection, you can just use the | |||
data structure io_wait already maintains. The lookup works in constant | |||
time and should not cause any cache misses. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_setcookie(3) |
@ -0,0 +1,43 @@ | |||
.TH io_nonblock 3 | |||
.SH NAME | |||
io_nonblock \- switch to non-blocking I/O | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_nonblock\fP(int64 fd); | |||
.SH DESCRIPTION | |||
io_nonblock puts UNIX descriptor fd into ``non-blocking mode.'' Calling | |||
io_nonblock(\fIfd\fR) before io_fd(\fIfd\fR) makes io_tryread and | |||
io_trywrite faster and more efficient. | |||
Actually, current UNIX kernels do not support non-blocking descriptors; they | |||
support non-blocking open files. Furthermore, many programs will break if they | |||
encounter non-blocking mode. This means that you must not use io_nonblock for a | |||
descriptor inherited from another program. | |||
io_nonblock has no return value; it always succeeds. If d is not the number of | |||
a UNIX descriptor, io_nonblock has no effect. | |||
If io_fd is given a descriptor in blocking mode, io_tryread and io_trywrite go | |||
through the following contortions to avoid blocking: | |||
.RS 0 | |||
.nr step 1 1 | |||
.IP \n[step] 3 | |||
Stop if poll says that the descriptor is not ready. Otherwise there's a good | |||
chance, but not a guarantee: even if poll says the descriptor is ready, the | |||
descriptor might not be ready a moment later. (Furthermore, poll can fail on | |||
some systems.) | |||
.IP \n+[step] | |||
Catch SIGALRM. SIGALRM must not be blocked, and must not be used elsewhere in | |||
the program. | |||
.IP \n+[step] | |||
Set an interval timer so that any blocking call will be interrupted by SIGALRM | |||
within 10 milliseconds. (Current UNIX kernels do not allow any shorter | |||
interval.) Of course, this may still mean a 10-millisecond delay. | |||
.RE | |||
If io_fd is given a descriptor in non-blocking mode (or a descriptor for a | |||
regular disk file), io_tryread and io_trywrite avoid these contortions. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canwrite(3) |
@ -0,0 +1,19 @@ | |||
.TH io_passfd 3 | |||
.SH NAME | |||
io_passfd \- pass a file descriptor over a Unix Domain socket | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_passfd\fP(int64 sock,int64 fd); | |||
.SH DESCRIPTION | |||
io_passfd transfers the file descriptor \fIfd\fR over the Unix Domain | |||
socket \fIsock\fR. This works much like dup(2), only that the copy of | |||
the descriptor appears not in this process but at the other end of the | |||
Unix Domain socket (which therefore must be a process on the same | |||
system). | |||
The peer can then use io_receivefd(3) to receive the file descriptor. | |||
Note that the passed descriptor stays open in the sending process. | |||
.SH "SEE ALSO" | |||
io_receivefd(3) |
@ -0,0 +1,28 @@ | |||
.TH io_pipe 3 | |||
.SH NAME | |||
io_pipe \- create a Unix pipe | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_pipe\fP(int64 pfd[2]); | |||
.SH DESCRIPTION | |||
io_pipe creates a new UNIX ``pipe.'' The pipe can receive data and provide | |||
data; any bytes written to the pipe can then be read from the pipe in the same | |||
order. | |||
A pipe is typically stored in an 8192-byte memory buffer; the exact number | |||
depends on the UNIX kernel. Bytes are written to the end of the buffer and read | |||
from the beginning of the buffer. Once a byte has been read, it is eliminated | |||
from the buffer, making space for another byte to be written; readers cannot | |||
``rewind'' a pipe to read old data. Once 8192 bytes have been written to the | |||
buffer, the pipe will not be ready for further writing until some of the bytes | |||
have been read. Once all the bytes written have been read, the pipe will not be | |||
ready for further reading until more bytes are written. | |||
io_pipe sets \fId\fR[0] to the number of a new descriptor reading from the pipe, and | |||
sets \fId\fR[1] to the number of a new descriptor writing to the pipe. It then | |||
returns 1 to indicate success. If something goes wrong, io_pipe returns 0, | |||
setting errno to indicate the error; in this case it frees any memory that it | |||
allocated for the new pipe, and it leaves \fId\fR alone. | |||
.SH "SEE ALSO" | |||
io_readfile(3), io_createfile(3), io_socketpair(3) |
@ -0,0 +1,15 @@ | |||
.TH io_readfile 3 | |||
.SH NAME | |||
io_readfile \- open a file for reading | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_readfile\fP(int64* d,const char* s); | |||
.SH DESCRIPTION | |||
io_readfile sets d to the number of a new descriptor reading from the | |||
disk file named \fIs\fR, and returns 1. | |||
If something goes wrong, io_readfile sets \fIerrno\fR to indicate the error, and | |||
returns 0; it does not create a new descriptor, and it does not touch d. | |||
.SH "SEE ALSO" | |||
io_readfile(3) |
@ -0,0 +1,18 @@ | |||
.TH io_receivefd 3 | |||
.SH NAME | |||
io_receivefd \- receive a file descriptor over a Unix Domain socket | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int64 \fBio_receivefd\fP(int64 sock); | |||
.SH DESCRIPTION | |||
io_receivefd receives a file descriptor from the Unix Domain socket | |||
\fIsock\fR. You can send a descriptor using io_passfd(3). | |||
io_receivefd returns -1 on error or the file descriptor. | |||
The underlying Unix API can send more than one descriptor at the time. | |||
This function expects only one descriptor and will return the first | |||
one if more than one were sent. | |||
.SH "SEE ALSO" | |||
io_passfd(3) |
@ -0,0 +1,20 @@ | |||
.TH io_sendfile 3 | |||
.SH NAME | |||
io_sendfile \- send data from a file to a socket | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int64 \fBio_sendfile\fP(int64 sock,int64 fd,uint64 off,uint64 n); | |||
.SH DESCRIPTION | |||
io_sendfile sends data from a file to a socket. This function tries to | |||
do this in a way that allows high quality operating systems to do | |||
zero-copy TCP (serving the data without copying the file contents to | |||
user space or inside kernel space). This function will use special | |||
operating system "sendfile" primitives where available and use memory | |||
mapped I/O otherwise. It should always be faster than using read() and | |||
write() to copy the data yourself. | |||
io_sendfile will return the number of bytes sent. If an error occurred, | |||
it will return -1 for EAGAIN, or -3 otherwise. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_waituntil(3) |
@ -0,0 +1,25 @@ | |||
.TH io_setcookie 3 | |||
.SH NAME | |||
io_setcookie \- associate cookie with descriptor | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_setcookie\fP(int64 fd,void* cookie); | |||
.SH DESCRIPTION | |||
io_setcookie associates a cookie (pointer to some anonymous data | |||
structure) with this descriptor. Only one cookie can be associated with | |||
a descriptor. | |||
Use io_getcookie(3) to retrieve the cookie for a descriptor (usually | |||
after io_canread or io_canwrite brought it to your attention). | |||
Please note that io_close does not deallocate your cookie. You need to | |||
do that yourself. | |||
The idea is that you put the state associated with a TCP connection you | |||
serve in a common struct. Then you do not need to have your own data | |||
structure to retrieve the state for a connection, you can just use the | |||
data structure io_wait already maintains. The lookup works in constant | |||
time and should not cause any cache misses. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_getcookie(3) |
@ -0,0 +1,18 @@ | |||
.TH io_socketpair 3 | |||
.SH NAME | |||
io_socketpair \- create a pair of sockets | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_socketpair\fP(int64 pfd[2]); | |||
.SH DESCRIPTION | |||
io_socketpair creates a new UNIX socket pair and writes both descriptors | |||
to \fId\fR. The socket pair works much like a pipe, but it is | |||
bidirectional (i.e. both descriptors are for reading and writing). | |||
io_socketpair returns 1 to indicate success. If something goes wrong, | |||
io_socketpair returns 0, setting errno to indicate the error; in this | |||
case it frees any memory that it allocated for the new socketpair, and | |||
it leaves \fId\fR alone. | |||
.SH "SEE ALSO" | |||
io_readfile(3), io_createfile(3), io_pipe(3) |
@ -0,0 +1,18 @@ | |||
.TH io_timeout 3 | |||
.SH NAME | |||
io_timeout \- set time limit on descriptor | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_timeout\fP(int64 fd,tai6464 deadline); | |||
.SH DESCRIPTION | |||
The io library keeps track of an optional ``timeout'' for each descriptor. The | |||
timeout is a specific moment in time, stored in a tai6464 variable. | |||
io_timeout(\fId\fR,\fIt\fR) sets the timeout for descriptor \fId\fR to \fIt\fR. | |||
io_timeout has no return value; it always succeeds. (Space to store the timeout | |||
was already allocated as part of the descriptor.) It has no effect if \fId\fR is not | |||
the number of a descriptor. | |||
.SH "SEE ALSO" | |||
io_waituntil(3), io_timeouted(3) |
@ -0,0 +1,17 @@ | |||
.TH io_timeouted 3 | |||
.SH NAME | |||
io_timeouted \- return a file descriptor over deadline | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int64 \fBio_timeouted\fP(); | |||
.SH DESCRIPTION | |||
io_timeouted returns the next file descriptor that is past it's deadline. | |||
If no descriptors are past their deadlines, it returns -1. | |||
After io_timeouted() returned -1, you should wait a second before | |||
calling it again. Checking for connections past their deadline involves | |||
walking through the whole data structure, which may thrash the CPU | |||
cache needlessly. Treat it as an expensive operation. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_timeout(3) |
@ -0,0 +1,42 @@ | |||
.TH io_tryread 3 | |||
.SH NAME | |||
io_tryread \- read from a descriptor without blocking | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_tryread\fP(int64 fd,char* buf,int64 len); | |||
.SH DESCRIPTION | |||
io_tryread tries to read \fIlen\fR bytes of data from descriptor | |||
\fIfd\fR into buf[0], buf[1], ..., buf[len-1]. (The effects are | |||
undefined if \fIlen\fR is 0 or smaller.) There are several possible | |||
results: | |||
.RS 0 | |||
.IP \[bu] 3 | |||
o_tryread returns an integer between 1 and \fIlen\fR: This number of bytes was | |||
available for immediate reading; the bytes were read into the beginning | |||
of \fIbuf\fR. Note that this number can be, and often is, smaller than \fIlen\fR; | |||
you must not assume that io_tryread always succeeds in reading exactly | |||
\fIlen\fR bytes. | |||
.IP \[bu] | |||
io_tryread returns 0: No bytes were read, because the descriptor is at | |||
end of file. For example, this descriptor has reached the end of a disk | |||
file, or is reading an empty pipe that has been closed by all writers. | |||
.IP \[bu] | |||
io_tryread returns -1, setting \fIerrno\fR to EAGAIN: No bytes were read, | |||
because the descriptor is not ready. For example, the descriptor is | |||
reading an empty pipe that could still be written to. | |||
.IP \[bu] | |||
io_tryread returns -3, setting \fIerrno\fR to something other than | |||
EAGAIN: No bytes were read, because the read attempt encountered a | |||
persistent error, such as a serious disk failure (EIO), an unreachable | |||
network (ENETUNREACH), or an invalid descriptor number (EBADF). | |||
.RE | |||
io_tryread does not pause waiting for a descriptor that is not ready. | |||
If you want to pause, use io_waitread or io_wait. | |||
You can make io_tryread faster and more efficient by making | |||
the socket non-blocking with io_nonblock(). | |||
.SH "SEE ALSO" | |||
io_nonblock(3), io_waitread(3), io_tryreadtimeout(3) |
@ -0,0 +1,23 @@ | |||
.TH io_tryreadtimeout 3 | |||
.SH NAME | |||
io_tryreadtimeout \- read from a descriptor without blocking | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_tryreadtimeout\fP(int64 fd,char* buf,int64 len); | |||
.SH DESCRIPTION | |||
io_tryreadtimeout is identical to io_tryread, with the following | |||
exception: if | |||
.RS 0 | |||
.IP \[bu] 3 | |||
io_tryread returns -1 (the descriptor is not ready for reading), and | |||
.IP \[bu] | |||
the descriptor has a timeout, and | |||
.IP \[bu] | |||
the read attempt was after the descriptor's timeout, | |||
.RE | |||
then io_tryreadtimeout instead returns -2, with errno set to ETIMEDOUT. | |||
.SH "SEE ALSO" | |||
io_nonblock(3), io_waitread(3), io_tryread(3) |
@ -0,0 +1,51 @@ | |||
.TH io_trywrite 3 | |||
.SH NAME | |||
io_trywrite \- write to a descriptor without blocking | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_trywrite\fP(int64 fd,const char* buf,int64 len); | |||
.SH DESCRIPTION | |||
io_trywrite tries to write \fIlen\fR bytes of data from | |||
buf[0], buf[1], ..., buf[len-1] to descriptor \fIfd\fR. (The effects are | |||
undefined if \fIlen\fR is 0 or smaller.) There are several possible | |||
results: | |||
.RS 0 | |||
.IP \[bu] 3 | |||
o_trywrite returns an integer between 1 and \fIlen\fR: This number of bytes was | |||
immediately written from the beginning of \fIbuf\fR. | |||
Note that this number can be, and often is, smaller than \fIlen\fR; | |||
you must not assume that io_trywrite always succeeds in writing exactly | |||
\fIlen\fR bytes. | |||
.IP \[bu] | |||
io_trywrite returns -1, setting \fIerrno\fR to EAGAIN: No bytes were | |||
written, because the descriptor is not ready. For example, the | |||
descriptor is writing to a full pipe that could still be read. | |||
.IP \[bu] | |||
io_trywrite returns -3, setting \fIerrno\fR to something other than | |||
EAGAIN: No bytes were written, because the write attempt encountered a | |||
persistent error, such as a serious disk failure (EIO), an unreachable | |||
network (ENETUNREACH), or an invalid descriptor number (EBADF). | |||
.RE | |||
io_trywrite does not pause waiting for a descriptor that is not ready. | |||
If you want to pause, use io_waitread or io_wait. | |||
You can make io_trywrite faster and more efficient by making | |||
the socket non-blocking with io_nonblock(). | |||
Once upon a time, many UNIX programs neglected to check the success of | |||
their writes. They would often encounter EPIPE, and would blithely | |||
continue writing, rather than exiting with an appropriate exit code. The | |||
UNIX kernel developers decided to send a SIGPIPE signal, which | |||
terminates the process by default, along with returning EPIPE. This | |||
papers over the problem without fixing it: the same programs ignore | |||
other errors such as EIO. One hopes that the programs have been fixed by | |||
now; kernels nevertheless continue to generate the SIGPIPE signal. The | |||
first time io_trywrite or io_waitwrite is called, it arranges for | |||
SIGPIPE to be ignored. (Technically, for SIGPIPE to be caught by an | |||
empty signal handler, so this doesn't affect child processes.) Do not | |||
use SIGPIPE elsewhere in the program. | |||
.SH "SEE ALSO" | |||
io_nonblock(3), io_waitread(3), io_trywritetimeout(3) |
@ -0,0 +1,23 @@ | |||
.TH io_trywritetimeout 3 | |||
.SH NAME | |||
io_trywritetimeout \- write to a descriptor without blocking | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
int \fBio_trywritetimeout\fP(int64 fd,const char* buf,int64 len); | |||
.SH DESCRIPTION | |||
io_trywritetimeout is identical to io_trywrite, with the following | |||
exception: if | |||
.RS 0 | |||
.IP \[bu] 3 | |||
io_trywrite returns -1 (the descriptor is not ready for writing), and | |||
.IP \[bu] | |||
the descriptor has a timeout, and | |||
.IP \[bu] | |||
the write attempt was after the descriptor's timeout, | |||
.RE | |||
then io_trywritetimeout instead returns -2, with errno set to ETIMEDOUT. | |||
.SH "SEE ALSO" | |||
io_nonblock(3), io_waitwrite(3), io_trywrite(3) |
@ -0,0 +1,21 @@ | |||
.TH io_wantread 3 | |||
.SH NAME | |||
io_wantread \- signal that you want to read from a descriptor | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_wantread\fP(int64 fd); | |||
.SH DESCRIPTION | |||
io_wantread tells the next io_wait() that you want to read from this | |||
descriptor. Call io_dontwantread() again if you change your mind. | |||
The next time you call io_wait(), it will look whether this descriptor | |||
becomes readable, too. You can then use io_canread() to check whether | |||
the descriptor has become readable. | |||
You have to have called io_fd on the descriptor first (io_pipe and | |||
io_socketpair do this for you). Waiting on descriptors only works for | |||
sockets, fifos and pipes. It may also work on devices and TTYs, but | |||
that is platform dependent -- you should not rely on that. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canread(3), io_wantread(3), io_fd(3) |
@ -0,0 +1,21 @@ | |||
.TH io_wantwrite 3 | |||
.SH NAME | |||
io_wantwrite \- signal that you want to write to a descriptor | |||
.SH SYNTAX | |||
.B #include <io.h> | |||
void \fBio_wantwrite\fP(int64 fd); | |||
.SH DESCRIPTION | |||
io_wantwrite tells the next io_wait() that you want to write to this | |||
descriptor. Call io_dontwantwrite() again if you change your mind. | |||
The next time you call io_wait(), it will look whether this descriptor | |||
becomes writeable, too. You can then use io_canwrite() to check whether | |||
the descriptor has become writable. | |||
You have to have called io_fd on the descriptor first (io_pipe and | |||
io_socketpair do this for you). Waiting on descriptors only works for | |||
sockets, fifos and pipes. It may also work on devices and TTYs, but | |||
that is platform dependent -- you should not rely on that. | |||
.SH "SEE ALSO" | |||
io_wait(3), io_canwrite(3), io_wantwrite(3), io_fd(3) |