ssize_t read(int fd, void buf, size_t n);
ssize_t write(int fd, const void buf, size_t n);
void rio_readinitb(rio_t rp, int fd);//将描述符fd和地址rp处的一个类型为rio_t的读缓存区联系起来。
ssize_t rio_readlineb(rio_t rp,void usrbuf, size_t maxlen);//从文件rp中读出一个文本行,包括换行符,拷贝到存储器位置usrbuf,并用空字符结束这个文本行。最多赌到maxlen-1个字节,最后一个给结尾的空字符。
ssize_t rio_readnb(rio_t rp, void *usrbuf, size_t n);//从文件rp中读取最多n个字符到存储器位置usrbuf中
int main(int argc, char **argv)
{
int n;
rio_t rio;
char buf[MAXLINE];
Rio_readinitb(&rio, STDIN_FILENO);//连接标准输入和rio地址
while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) //当成功返回时,将rio中的内容拷贝到存储器位置buf中,最多读maxline-1
Rio_writen(STDOUT_FILENO, buf, n);//把存储器位置中的数据拷贝到标注输出中。
exit(0);
}
static ssize_t rio_read(rio_t rp, char usrbuf, size_t n)
{
int cnt;
while (rp->rio_cnt <= 0) { /* 如果缓存区为空,调用read填满它 */
rp->rio_cnt = read(rp->rio_fd, rp->rio_buf,
sizeof(rp->rio_buf));
if (rp->rio_cnt < 0) {
if (errno != EINTR) /* 出错返回-1*/
return -1;
}
else if (rp->rio_cnt == 0) /* EOF返回0 */
return 0;
else
rp->rio_bufptr = rp->rio_buf; /* reset buffer ptr */
}
/* 一旦缓存区非空,就从读缓存区拷贝n和rp->rio_cnt中较小值个字节到用户缓存区,并且返回拷贝的字节数 */
cnt = n;
if (rp->rio_cnt < n)
cnt = rp->rio_cnt;
memcpy(usrbuf, rp->rio_bufptr, cnt);
rp->rio_bufptr += cnt;
rp->rio_cnt -= cnt;
return cnt;
}
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++) { //最多是maxlen-1个
if ((rc = rio_read(rp, &c, 1)) == 1) {
*bufp++ = c;
if (c == '\n')//找到换行符,就退出
break;
} else if (rc == 0) {
if (n == 1)
return 0; /* EOF,并且没有读到数据 */
else
break; /* EOF,有数据,出现不足值 */
} else
return -1; /* 错误,返回-1 */
}
*bufp = 0;
return n;//返回成功传送的字节数
}
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)
nread = 0; /* 调用read填充 */
else
return -1; /* 错误,返回-1 */
}
else if (nread == 0)
break; /* EOF */
nleft -= nread;
bufp += nread;
}
return (n - nleft); /* 返回成功传送的字节数*/
}
int main (int argc, char **argv)
{
struct stat stat;
char type, readok;
Stat(argv[1], &stat);//文件选择argv[1],写入一个stat数据结构
if (S_ISREG(stat.st_mode)) /* 如果是一个文本文件 */
type = "regular";
else if (S_ISDIR(stat.st_mode))//如果是一个目录文件
type = "directory";
else
type = "other";
if ((stat.st_mode & S_IRUSR)) /* 检查阅读权限 */
readok = "yes";
else
readok = "no";
printf("type: %s, read: %s\n", type, readok);
exit(0);
}
void unix_error(char msg) / unix-style error /
{
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(0);
}
/ $end unixerror */
void posix_error(int code, char msg) / posix-style error */
{
fprintf(stderr, "%s: %s\n", msg, strerror(code));
exit(0);
}
void dns_error(char msg) / dns-style error */
{
fprintf(stderr, "%s: DNS error %d\n", msg, h_errno);
exit(0);
}
void app_error(char msg) / application error */
{
fprintf(stderr, "%s\n", msg);
exit(0);
}
成功时返回void,返回错误时包装函数打印一条信息,然后退出
void Kill(pid_t pid, int signum)
{
int rc;
if ((rc = kill(pid, signum)) < 0)
unix_error("Kill error");
}
Posix风格
---------
成功时返回void,错误返回码中不会包含有用的结果
void Pthread_detach(pthread_t tid) {
int rc;
if ((rc = pthread_detach(tid)) != 0)
posix_error(rc, "Pthread_detach error");
}
struct hostent Gethostbyname(const char name)
{
struct hostent *p;
if ((p = gethostbyname(name)) == NULL)
dns_error("Gethostbyname error");
return p;
}
if ((pid = wait(NULL)) < 0){
fprintf(stderr, "wait error: %s\n",strerror(errno));//strerror函数返回某个errno值的文本描述
exit(0);
}
if((retcode = pthread_create(&tid, NULL, thread, NULL) != 0) {
fprintf(stderr,"pthread_create error:%s\n",
strerror(retcode));
exit(0);
}
if((p = gethostbyname(name)) == NULL) {
fprintf(stderr,"gethostbyname error:%s\n",
hstrerror(retcode));
exit(0);
}
资料参考来自:《深入理解计算机系统》
资料参考来自:20135202博客http://www.cnblogs.com/20135202yjx/p/4947272.html