strace
: print system call
/dev/
: device
/dev/tty2
: terminal
/boot/
: kernel
/proc/
: kernel data structure
Unix File:
sequence of bytes
has [current file position], indicate offset in file to read and write (lseek()
to move such pointer)
types of file
file ending: \n
(LF) in unix, \r\n
(CR+LF) in windows and http
.
to itself
..
to parent
...
invalid because there is no link named ...
in directory
../..
to parent of parent
pwd
path, tree
see directory as tree
file descriptor:
STDIN
: 0
STDOUT
: 1
STDERR
: 2
open()
: return lowest numbered file descriptor not currently open
close()
:
closing already closed file in multi-threaded program is dangerous (always check return value)
closing stdin/stdout/stderr
cannot be re-opened again (maybe unless you save it somewhere)
read(fd, buf, sizeof(buf))
:
read from current file position, and update file position
return number of bytes read
short counts: read less than requested (not error)
error EINTR
when interrupted by other signal, in this case, typically retry
write(fd, buf, sizeof(buf))
:
write up to size of buffer
short counts: write less than requested (not error)
error EINTR
when interrupted by other signal, in this case, typically retry
Short count:
Encountering (end-of-file) EOF on reads
Reading text lines from a terminal
Reading and writing network sockets
No short count:
Reading from disk files (except for reading EOF at the end of file)
Writing to disk files
Buffer:
syscall
is expensiveFile Metadata: maintained by kernel
Accessed by users with the stat
and fstat
functions
File Sharing
Open File Multiple Time:
Forking Process:
dup2()
:
printf()
: using stream buffer, flush on \n
by default
fflush(stddout)
: flush
ssize_t rio_readn(int fd, void *usrbuf, size_t n)
Same as read
but short count only at EOF
only use when know how many bytes to read
rio_writen
write
but never returns short countCalls to rio_readn
and rio_writen
can be interleaved arbitrarily on the same descriptor
Thread-safe, typically no short count, can be interleaved on the same descriptor with all buffered version.
typedef struct {
int rio_fd; /* descriptor for this internal buf */
int rio_cnt; /* unread bytes in internal buf */
char *rio_bufptr; /* next unread byte in internal buf */
char rio_buf[RIO_BUFSIZE]; /* internal buffer */
} rio_t;
void rio_readinitb(rio_t *rp, int fd)
rp
for specific fd
ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen)
read up to maxlen
into usrbuf
use when reading network sockets
stop when reach maxlen
, EOF
, or \n
ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n)
maxlen
, or EOF
mmap()
is good for copy file to memory, copy files
System I/O Good:
most general, lowest overhead
provide functions for accessing file metadata
async-signal-safe, can be used in signal handlers
System I/O Bad:
short counts is error prone
need buffering if want to read efficiently
Buffered I/O Good:
increase efficiency by decreasing number of syscall
handled short counts
Buffered I/O Bad:
no interface for accessing metadata
Standard I/O are not async-signal-safe
Standard I/O not good for network sockets
Standard I/O: disk, terminal Unix I/O: signal handlers, highest performance RIO: network sockets
Binary:
don't use fgets
, scanf
, rio_readlineb
since they interpret EOL
don't use strlen
, strcpy
, strcat
use rio_readn
or rio_readnb
instead
Table of Content