1. Scatter/Gather I/O(vectored I/O)
#include <sys/uio.h>
ssize_t readv (int fd,
const struct iovec *iov,
int count);
ssize_t writev (int fd,
const struct iovec *iov,
int count);
struct iovec {
void *iov_base;
size_t iov_len;
};
example:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/uio.h>
int main()
{
struct iovec iov[3];
ssize_t nr;
int fd, i;
char *buf[] = {
"The term buccaneer comes from the world boucan.\n",
"A boucan is a wooden frame used for cooking meat.\n",
"Buccaneer is the West Indies name for a pirate.\n"
};
fd = open("buccaner.txt", O_WRONLY | O_CREAT | O_TRUNC);
if (fd == -1){
perror("open");
return 1;
}
for (i = 0; i < 3; i++){
iov[i].iov_base = buf[i];
iov[i].iov_len = strlen(buf[i]) + 1;
}
nr = writev(fd, iov, 3);
if (nr == -1){
perror("writev");
return 1;
}
printf("wrote %d bytes\n", nr);
if (close(fd)){
perror("close");
return 1;
}
return 0;
}
2. Creating a New Epoll Instance
#include <sys/epoll.h>
int epoll_create1(int flags);
// Only EPOLL_CLOEXEC is a valid flag.
errno:
EINVAL: Invalid flags parameter
EMFILE: The user has reached limit on the total number of open files.
ENFILE: The system has reached its limit on the total number of open files.
ENOMEM: Insufficient memory was available to complete the operation.
3. Controlling Epoll
#include <sys/epoll.h>
int epoll_ctl(int epfd,
int op,
int fd,
struct epoll_event *event);
op: EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD
struct epoll_event{
_u32 events;
union {
void *ptr;
int fd;
__u32 u32;
__u64 u64;
} data;
};
events:
EPOLLERR, EPOLLET, EPOLLHUP, EPOLLIN, EPOLLONESHOT, EPOLLOUT, EPOLLPRI
4. Waiting for Events with Epoll
#include <sys/epoll.h>
int epoll_wait(int epfd,
struct epoll_event *events,
int maxevents,
int timeout);
5. mmap()
#include <sys/mman.h>
void *mmap (void *addr,
size_t len,
int prot,
int flags,
int fd,
off_t offset);
prot: PROT_READ, PROT_WRITE, PROT_EXEC
flags:MAP_FIXED, MAP_PRIVATE, MAP_SHARED
6. The page size
#include <unistd.h>
long sysconf(int name); // best bet for portability and future compatility
long page_size = sysconf(_SC_PAGESIZE);
#include <unistd.h>
int getpagesize(void); // was dropped from the 1003.1-2001 revision of the POSIX standard.
#include <sys/usr.h>
int page_size = PAGE_SIZE;
SIGBUS
This signal is generated when a process attempts to access a region of a mapping that is no longer valid--for example, because the file was truncated after it was mmaped.
SIGSEGV
This signal is generated when a process attempts to write to a region that is mapped read-only.
7. munmap()
#include <sys/mman.h>
int munmap (void *addr, size_t len);
Example: (of map)
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int main(int argc, char *argv[])
{
struct stat sb;
off_t len;
char *p;
int fd;
if (argc < 2) {
fprintf(stderr, "usage: %s <file>\n", argv[0]);
return 1;
}
fd = open(argv[1], O_RDONLY);
if (fd == -1){
perror("open");
return 1;
}
if (fstat(fd, &sb) == -1){
perror("fstat");
return 1;
}
if (!S_ISREG (sb.st_mode)){
fprintf(stderr, "%s is not a file\n", argv[1]);
return 1;
}
p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (p == MAP_FAILED){
perror ("mmap");
return 1;
}
if (close(fd) == -1){
perror("close");
return 1;
}
for (len = 0; len < sb.st_size; len++){
putchar (p[len]);
}
if (munmap (p, sb.st_size) == -1){
perror("munmap");
return 1;
}
return 0;
}
8. Resizing a Mapping
#define _GNU_SOURCE
#include <sys/mman.h>
void * mremap(void *addr, size_t old_size, size_t new_size, unsigned long flags);
flags: 0 or MREMAP_MAYMOVE
9. Changing the protection of a Mapping
#include <sys/mman.h>
int mprotect (const void *addr, size_t len, int prot);
10. Synchronizing File with a Mapping
#include <sys/mman.h>
int msync (void *addr, size_t len, int flags);
flags:
MS_SYNC:
The sync() call will not return until all pages are written back to disk.
MS_ASYNC:
The sync() call returns immediately without waiting for the writes to take place.
MS_INVALIDATE:
Specifies that all other cached copies of the mapping be invalidated.
11. Giving Advice on a Mapping
#include <sys/mman.h>
int madvise (void *addr, size_t len, int advice);
advice:
MADV_NORMAL
MADV_RANDOM
MADV_SEQENTIAL
MADV_WILLNEED
MADV_DONTNEED
MADV_DONTFORK
MADV_DOFORK+
12. The posix_fadvise() System Call
#include <fcntl.h>
int posix_fadvise(int fd,
off_t offset,
off_t len,
int advice);
advice:
POSIX_FADV_NORMAL
POSIX_FADV_RANDOM
POSIX_FADV_SEQUENTIAL
POSIX_FADV_WILLNEED
POSIX_FADV_NOREUSE
POSIX_FADV_DONTNEED
13. The readhead() System Call
#define _GNU_SOURCE
#include <fcntl.h>
ssize_t readhead(int fd,
off64_t offset,
size_t count);
14. Asynchronous I/O
#include <aio.h>
/* asynchronous I/O control block */
struct aiocb {
int aio_fildes;
int aio_lio_opcode;
int aio_reqprio;
volatile void *aio_buf;
size_t aio_nbytes;
struct sigevent aio_sigevent;
/* internal, private members follow... */
};
int aio_read(struct aiocb *aiocbp);
int aio_write(struct aiocb *aiocbp);
int aio_error(const struct aiocbp *aiocbp);
int aio_return(struct aiocb *aiocbp);
int aio_cancel(int fd, struct aiocb *aiocbp);
int aio_fsync(int op, struct aiocb *aiocbp);
int aio_suspend(const struct aiocb * const cblist[],
int n,
const struct timespec *timeout);