Open wittyResry opened 8 years ago
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(char *filename, int flags, mode_t mode);
//O_RDONLY:只读;O_WRONLY:只写;O_RDWR:可读写。
fd = open("foo.txt", O_RDONLY, 0);
//O_CREAT:文件不存在,创建一个空文件;O_TRUNC:文件存在,则截断它;O_APPEND:在每次写之前,设置文件位置到文件的末尾处。
fd = open("foo.txt", O_WRONLY|O_APPEND, 0);
打开文件的mode表示新文件的访问位权限,采用S_IRUSR,S_IWUSR,S_IXUSR 使用者的读、写、执行;S_IRGRP,S_IWGRP,S_IXGRP分组拥有者的读写执行;S_IROTH,S_IWOTH,S_IXOTH其他(任何人)能够读、写、执行。
umask(DEF_UMASK);
fd = open("foo.txt", O_CREAT|O_TRUNC|O_WRONLY, DEF_MODE);
#include <unistd.h>
int close(int fd);
#include <unistd.h>
//若成功则返回为读的字节数,若EOF则为0,若出错为-1。
ssize_t read(int fd, void *buf, size_t n);
//若成功则返回为写的字节数,否则出错返回-1。
ssize_t write(int fd, const void *buf, size_t n);
#include <csapp.h>
//从fd的当前文件位置最多传n个字节到存储器位置usrbuf
ssize_t rio_readn(int fd, void *usrbuf, size_t n);
//从usrbuf传送n个字节到描述符fd。
ssize_t rio_writen(int fd, void *usrbuf, size_t n);
//读一个文本行,并且拷贝到存储器位置usrbuf
void rio_readinitb(rio_t *rp, int fd);
//最多读maxlen
ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen);
//从文件rp读n个字节到存储器位置usrbuf
ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n);
ssize_t rio_readn(int fd, void *usrbuf, size_t n) {
size_t nleft = n;
ssize_t nread;
char *bufp = usrbuf;
while (nleft > 0) {
if ((nread = read(fd, bufp, nleft)) < 0) {
if (errno == EINTR) {
nread = 0; /* and call read() again*/
} else {
reutrn -1; /* errno set by read()*/
}
} else if (nread == 0) {
break;
}
nleft -= nread;
bufp += nread;
}
return (n - nleft);
}
ssize_t rio_writen(int fd, void *usrbuf, size_t n) {
size_t nleft = n;
ssize_t nwritten;
char *bufp = usrbuf;
while (nleft > 0) {
if ((nwritten = write(fd, bufp, nleft)) < 0) {
if (errno == EINTR) {
nwritten = 0; /* and call read() again*/
} else {
reutrn -1; /* errno set by read()*/
}
}
nleft -= nwritten;
bufp += nwritten;
}
return n;
}
#define RIO_BUFSIZE 8192
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 */
} riot;
static ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n) {
int cnt;
while (rp -> rio_cnt <= 0) {
rp -> rio_cnt = read(rp -> rio_fd, rp -> rio_buf, sizeof(rp -> rio_buf));
if (rp -> rio_cnt < 0) {
if (errno != EINTR) {
return -1;
}
} else if (rp -> rio_cnt == 0) {
return 0;
} else {
rp -> rio_bufptr = rp -> rio_buf;
}
}
cnt = n;
if (rp -> rio_cnt < 0) {
cnt = rp -> rio_cnt;
}
memcpy (usrbuf, rp -> rio_bufptr, cnt);
rp -> rio_bufptr += cnt;
rp -> rio_cnt -= cnt;
return cnt;
}
ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n) {
size_t nleft = n;
ssize_t nread;
char *bufp = usrbuf;
while (nleft > 0) {
if ((nread = rio_read(rp, bufp, nleft)) < 0) {
if (errno == EINTR) {
return 0; /*Call read() again*/
} else {
return -1; /* errno set by read() */
}
} else if (nread == 0) {
break; /* EOF */
}
nleft -= nread;
bufp += nread;
}
return (n - nleft);
}
ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen) {
int n, rc;
char c, *bufp = usrbuf;
for (n = 1; n < maxlen; ++n) {
if ((rc = rio_read(rp, &c, 1)) == 1) {
*bufp++ = c;
if (c == '\n')
break;
} else if (rc == 0) {
if (n == 1) {
return 0; /* EOF, no data read */
} else {
break; /* EOF, some data read */
}
} else {
return -1;
}
}
*bufp = 0; /*设置行结尾ASCII = '\0'*/
return n;
}
第九章 虚拟存储器
动态存储器分配
显式分配器的设计和实现
malloc和free函数
不要使用:
最好使用下面的方式:
碎片
隐式空闲链表
分配器的搜索方式
显式空闲链表
分离空闲链表
垃圾收集
基础知识
Mark&Sweep垃圾收集器
由标记和清除两个阶段组成
C程序中常见的与存储有关的错误
未初始化的存储器
栈缓冲区溢出
默认假设指针和它们指向的对象相同大小
造成错位
引用指针,而不是它所指向的对象。
误解指针运算
引用不存在的变量
引用堆块中的数据
引起存储器泄露