diff --git a/CHANGES b/CHANGES index c62a185..8a8d30e 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,7 @@ add io_socketpair add io_passfd and io_receivefd (and test/fdpassing.c) io_trywrite and io_waitwrite not ignore SIGPIPE + add man pages for libio 0.18: make libowfat compile on BSD again (sorry, and thanks to everyone who diff --git a/io/io_sigpipe.c b/io/io_sigpipe.c index 379dacc..e92c876 100644 --- a/io/io_sigpipe.c +++ b/io/io_sigpipe.c @@ -2,6 +2,8 @@ #include #include +/* this is an internal function, called by io_trywrite and io_waitwrite */ + void io_sigpipe(void) { static int isitdone; if (!isitdone) { diff --git a/io/io_wait.3 b/io/io_wait.3 new file mode 100644 index 0000000..615fa17 --- /dev/null +++ b/io/io_wait.3 @@ -0,0 +1,27 @@ +.TH io_wait 3 +.SH NAME +io_wait \- wait for events +.SH SYNTAX +.B #include + +void \fBio_wait\fP(); +.SH DESCRIPTION +io_wait() checks the descriptors that the program is interested in to +see whether any of them are ready. If none of them are ready, io_wait() +tries to pause until one of them is ready, so that it does not take time +away from other programs running on the same computer. + +io_wait pays attention to timeouts: if a descriptor reaches its timeout, +and the program is interested in reading or writing that descriptor, +io_wait will return promptly. + +Under some circumstances, io_wait will return even though no interesting +descriptors are ready. Do not assume that a descriptor is ready merely +because io_wait has returned. + +io_wait is not interrupted by the delivery of a signal. Programs that +expect interruption are unreliable: they will block if the same signal +is delivered a moment before io_wait. The correct way to handle signals +is with the self-pipe trick. +.SH "SEE ALSO" +io_waituntil(3), io_check(3), io_wantread(3), io_wantwrite(3), io_fd(3) diff --git a/io/io_waitread.3 b/io/io_waitread.3 new file mode 100644 index 0000000..0768d0d --- /dev/null +++ b/io/io_waitread.3 @@ -0,0 +1,33 @@ +.TH io_waitread 3 +.SH NAME +io_waitread \- read from a descriptor +.SH SYNTAX +.B #include + +int \fBio_waitread\fP(int64 fd,char* buf,int64 len); +.SH DESCRIPTION +io_waitread 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_waitread 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_waitread always succeeds in reading exactly +\fIlen\fR bytes. +.IP \[bu] +io_waitread 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_waitread 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 + +.SH "SEE ALSO" +io_nonblock(3), io_waitread(3), io_waitreadtimeout(3) diff --git a/io/io_waituntil.3 b/io/io_waituntil.3 new file mode 100644 index 0000000..19e9884 --- /dev/null +++ b/io/io_waituntil.3 @@ -0,0 +1,11 @@ +.TH io_waituntil 3 +.SH NAME +io_waituntil \- wait for events +.SH SYNTAX +.B #include + +void \fBio_wait\fP(tai6464 t); +.SH DESCRIPTION +io_waituntil(t) is like io_wait() but does not wait (noticeably) past time \fIt\fR. +.SH "SEE ALSO" +io_wait(3), io_check(3), io_wantread(3), io_wantwrite(3), io_fd(3) diff --git a/io/iob_addbuf.3 b/io/iob_addbuf.3 new file mode 100644 index 0000000..f3f2e85 --- /dev/null +++ b/io/iob_addbuf.3 @@ -0,0 +1,15 @@ +.TH iob_addbuf 3 +.SH NAME +iob_addbuf \- add buffer to I/O batch +.SH SYNTAX +.B #include + +void \fBiob_addbuf\fP(io_batch* b,const void* buf,uint64 n); +.SH DESCRIPTION +iob_addbuf schedules \fIn\fR bytes starting at \fIbuf\fR to be written +with the I/O batch \fIb\fR. + +Use \fBiob_addbuf_free\fR if you want the buffer to be deallocated +automatically by \fBiob_reset\fR. +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf_free(3), iob_adds(3), iob_addfile(3) diff --git a/io/iob_addbuf_free.3 b/io/iob_addbuf_free.3 new file mode 100644 index 0000000..4227db4 --- /dev/null +++ b/io/iob_addbuf_free.3 @@ -0,0 +1,14 @@ +.TH iob_addbuf_free 3 +.SH NAME +iob_addbuf_free \- add buffer to I/O batch, with deallocation +.SH SYNTAX +.B #include + +void \fBiob_addbuf_free\fP(io_batch* b,const void* buf,uint64 n); +.SH DESCRIPTION +iob_addbuf_free schedules \fIn\fR bytes starting at \fIbuf\fR to be +written with the I/O batch \fIb\fR. + +The buffer will automatically be deallocated by \fBiob_reset\fR. +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf(3), iob_adds(3), iob_addfile(3) diff --git a/io/iob_addfile.3 b/io/iob_addfile.3 new file mode 100644 index 0000000..4803f10 --- /dev/null +++ b/io/iob_addfile.3 @@ -0,0 +1,17 @@ +.TH iob_addfile 3 +.SH NAME +iob_addfile \- add file region to I/O batch +.SH SYNTAX +.B #include + +void \fBiob_addfile\fP(io_batch* b,int64 fd,uint64 off,uint64 n); +.SH DESCRIPTION +iob_addfile schedules \fIn\fR bytes from the file descriptor \fIfd\fR +starting at offset \fIoff\fR to be written with the I/O batch \fIb\fR. + +You may not close \fIfd\fR before iob_send indicates it is done. + +Use \fBiob_addfile_close\fR if you want the file descriptor to be closed +automatically by \fBiob_reset\fR. +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf(3), iob_addfile_close(3) diff --git a/io/iob_addfile_close.3 b/io/iob_addfile_close.3 new file mode 100644 index 0000000..ac38a9e --- /dev/null +++ b/io/iob_addfile_close.3 @@ -0,0 +1,16 @@ +.TH iob_addfile_close 3 +.SH NAME +iob_addfile_close \- add file region to I/O batch +.SH SYNTAX +.B #include + +void \fBiob_addfile_close\fP(io_batch* b,int64 fd,uint64 off,uint64 n); +.SH DESCRIPTION +iob_addfile_close schedules \fIn\fR bytes from the file descriptor \fIfd\fR +starting at offset \fIoff\fR to be written with the I/O batch \fIb\fR. + +You may not close \fIfd\fR before iob_send indicates it is done. + +\fBiob_reset\fR will call io_close(fd). +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf(3), iob_addfile(3) diff --git a/io/iob_adds.3 b/io/iob_adds.3 new file mode 100644 index 0000000..7b3d162 --- /dev/null +++ b/io/iob_adds.3 @@ -0,0 +1,15 @@ +.TH iob_adds 3 +.SH NAME +iob_adds \- add buffer to I/O batch +.SH SYNTAX +.B #include + +void \fBiob_adds\fP(io_batch* b,const char* s); +.SH DESCRIPTION +iob_adds schedules the ASCIIZ C string \fIs\fR to be written +with the I/O batch \fIb\fR. + +Use \fBiob_adds\fR if you want the string to be deallocated +automatically by \fBiob_reset\fR. +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf(3), iob_adds_free(3), iob_addfile(3) diff --git a/io/iob_adds_free.3 b/io/iob_adds_free.3 new file mode 100644 index 0000000..6410b28 --- /dev/null +++ b/io/iob_adds_free.3 @@ -0,0 +1,14 @@ +.TH iob_adds_free 3 +.SH NAME +iob_adds_free \- add buffer to I/O batch +.SH SYNTAX +.B #include + +void \fBiob_adds_free\fP(io_batch* b,const char* s); +.SH DESCRIPTION +iob_adds_free schedules the ASCIIZ C string \fIs\fR to be written +with the I/O batch \fIb\fR. + +\fBiob_reset\fR will deallocate the string automatically. +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf(3), iob_adds(3), iob_addfile(3) diff --git a/io/iob_new.3 b/io/iob_new.3 new file mode 100644 index 0000000..7b41414 --- /dev/null +++ b/io/iob_new.3 @@ -0,0 +1,22 @@ +.TH iob_new 3 +.SH NAME +iob_new \- create new I/O batch +.SH SYNTAX +.B #include + +io_batch* \fBiob_new\fP(int hint_entries); +.SH DESCRIPTION +iob_new creates a new I/O batch with enough space allocated for +\fIhint_entries\fR entries (buffers or files). This is purely a +performance hint, if you are unsure just pass 1. + +You can add buffers, strings and files to an I/O batch and then send it +all at once using iob_send. + +The benefit of the I/O batch API is that it exploits platform specific +APIs like FreeBSD's sendfile. The file contents will always be sent in +a way that allows the operating systems to perform zero copy TCP, and +the buffers will always be sent using as few syscalls as possible and +avoiding unnecessary copying (using writev). +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf(3), iob_adds_free(3), iob_addfile(3) diff --git a/io/iob_prefetch.3 b/io/iob_prefetch.3 new file mode 100644 index 0000000..a0bb10c --- /dev/null +++ b/io/iob_prefetch.3 @@ -0,0 +1,15 @@ +.TH iob_prefetch 3 +.SH NAME +iob_prefetch \- prefetch data for I/O batch +.SH SYNTAX +.B #include + +void \fBiob_prefetch\fP(io_batch* b,uint64 n); +.SH DESCRIPTION +iob_prefetch makes sure the next \fIn\fR bytes are in memory. + +This is useful when serving large files over the network concurrently. +Prefetching the data can then reduce hard disk head movement and enhance +throughput. +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf(3), iob_adds_free(3), iob_addfile(3) diff --git a/io/iob_send.3 b/io/iob_send.3 new file mode 100644 index 0000000..3fb13c0 --- /dev/null +++ b/io/iob_send.3 @@ -0,0 +1,29 @@ +.TH iob_send 3 +.SH NAME +iob_send \- send I/O batch +.SH SYNTAX +.B #include + +int64 \fBiob_send\fP(int64 s,io_batch* b); +.SH DESCRIPTION +iob_send sends the (rest of) \fIb\fR over the socket \fIs\fR. + +iob_send returns the number of bytes written, 0 if there were no more +bytes to be written in the batch, -1 for EAGAIN, or -3 for a permanent +error (for example "connection reset by peer"). + +The normal usage pattern is using io_wait to know when a descriptor is +writable, and then calling iob_send until it returns 0, -1 or -3. + +If it returns 0, terminate the loop (everything was written OK). If it +returns -1, call io_wait again. If it returned -3, signal an error and +close the socket. + +The benefit of the I/O batch API is that it exploits platform specific +APIs like FreeBSD's sendfile. The file contents will always be sent in +a way that allows the operating systems to perform zero copy TCP, and +the buffers will always be sent using as few syscalls as possible and +avoiding unnecessary copying (using writev). +.SH "SEE ALSO" +iob_reset(3), iob_send(3), iob_addbuf(3), iob_adds_free(3), iob_addfile(3), +iob_prefetch(3)