RIO包是CSAPP中一个基于read和write函数实现的能够处理终端并提供了带缓冲区读取的IO包。代码很简单,但很巧妙。

缩减了原程序的初始化等函数之后,主要有以下四个对外函数:

1.ssize_t readn(int fd,void *usrbuf,size_t n);

fd为通过open得到的文件描述符,通常为一个小整数。该函数从指定文件读取n个byte到usrbuf中。如果成功执行,返回传输的字节数,如果读到EOF,返回0,如果出错,返回-1。

2.ssize_t writen(int fd,void *usrbuf,size_t n);

该函数将usebuf中最多n个字节写到文件中。如果成功,返回写入的字节数,如果出错返回-1.

3.ssize_t readlineb(rio_t rp,voidusrbuf,size_t maxlen);

rio_t是一个定义乐缓冲区的结构体,具体实现见下面代码。该函数一次从缓冲区/文件读取一行数据(最长不超过maxlen)

4.ssize_t readnb(rio_t rp,voidusrbuf,size_t n);

该函数是带有缓冲区版本的read,类似于readn。

myrio.h

#pragma once

#include

#include

#include

#include

#include

#include

//a buffer named rio_t

#define RIO_BUFSIZE 8192

typedef struct rio_t{

int rio_fd;

int rio_cnt; //unread bytes in rio_buf

char *rio_bufptr; //next unread byte in rio_buf

char rio_buf[RIO_BUFSIZE]; //internal buffer

rio_t(int fd)

:rio_fd(fd),rio_cnt(0),rio_bufptr(rio_buf){ }

} rio_t;

class Rio{

public:

//io function without internal buffer

//Succeed: return the number of byte; EOF: return 0; Fail: return -1

ssize_t readn(int fd,void *usrbuf,size_t n);

ssize_t writen(int fd,void *usrbuf,size_t n);

//io function with internal buffer

//Succeed: return the number of byte; EOF: return 0; Fail: return -1

ssize_t readlineb(rio_t *rp,void *usrbuf,size_t maxlen);

ssize_t readnb(rio_t *rp,void *usrbuf,size_t n);

private:

//read with buffer

ssize_t rio_read(rio_t *rp,char *usrbuf,size_t n);

};

myrio.cpp

#include "myrio.h"

//the difference between these function and system's is that:

//this function can deal with the interrupt.

ssize_t Rio::readn(int fd,void *usrbuf,size_t n){

size_t nleft = n;

ssize_t nread;

char *buf = static_cast(usrbuf);

while(nleft > 0){

if((nread = read(fd,buf,nleft))<0){

if(errno ==EINTR) nread = 0;

else return -1;

}else if(nleft == 0){

break;

}else{

nleft -= nread;

buf += nread;

}

}

return (n - nleft);

}

ssize_t Rio::writen(int fd,void *usrbuf,size_t n){

size_t nleft = n;

ssize_t nwriten;

char *buf = static_cast(usrbuf);

while(nleft > 0){

if((nwriten = write(fd,buf,nleft)) <= 0){

if(errno == EINTR) nwriten = 0;

else return -1;

}else{

nleft -= nwriten;

buf += nwriten;

}

return n;

}

}

ssize_t Rio::rio_read(rio_t *rp,char *usrbuf,size_t n){

int cnt;

while(rp->rio_cnt <= 0){ //refill rio_buf if buf is empty

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 < 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){

char c;

char *buf = static_cast(usrbuf);

int n,rc;

for(n=1;n

if((rc = rio_read(rp,&c,1)) == 1){

*buf = c;

buf++;

if(c == '\n')

break;

}else if(rc == 0){

if(n == 1) return 0;

else break;

}else{

return -1;

}

}

*buf = '\0';

return n;

}

ssize_t Rio::readnb(rio_t *rp,void *usrbuf,size_t n){

size_t nleft = n;

ssize_t nread;

char *buf = static_cast(usrbuf);

while(nleft > 0){

if((nread = rio_read(rp,buf,nleft)) < 0){

if(errno == EINTR) nread = 0;

else return -1;

}else if(nread == 0){

break;

}else{

nleft -= nread;

buf += nread;

}

}

return (n-nleft);

}

linux的rio包在哪个头文件,[Linux] RIO C++封装相关推荐

  1. linux内核态延时函数及头文件,Linux内核延时函数

    linux内核提供3个函数分别进行纳秒,微妙和毫秒延时(使用时包要含头文件): void ndelay(unsigned long nsecs); void udelay(unsigned long ...

  2. linux下的socket在哪个头文件,linux下socket编程常用头文件

    sys/types.h:数据类型定义 sys/socket.h:提供socket函数及数据结构 netinet/in.h:定义数据结构sockaddr_in arpa/inet.h:提供IP地址转换函 ...

  3. linux的头文件下载,Linux内核头文件(linux headers)

    更新 Linux 内核头文件(linux headers) 三 8th, 2013 2,474 views | 发表评论 | Trackback 一般来说,如果不是自己编译 kernel,那么更新头文 ...

  4. Linux C try 头文件,linux c 头文件

    //1.Linux中一些头文件的作用: #include //ANSI C.提供断言,assert(表达式) #include //GCC.GTK,GNOME的基础库,提供很多有用的函数,如有数据结构 ...

  5. 在linux下vcd光盘提取,linux下抓取Vcd的视频文件[Linux安全]

    赞助商链接 本文"linux下抓取Vcd的视频文件[Linux安全]"是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判 ...

  6. linux 内核头文件 linux kernel header

    1.内核头文件的发展历史         在 Linux 2.2/2.4 的纯真年代,内核头文件一直保持着 Unix 世界的"KISS"传统,只需将内核源码树中的头文件直接复制到 ...

  7. linux默认头文件,Linux安装合适内核头文件的方法

    摘要 腾兴网为您分享:Linux安装合适内核头文件的方法,桌面时钟,中建在线,圆通金刚,西餐菜谱等软件知识,以及万象,我不信表情包,兔子洞,服你网,电商直播app,网络工具箱,ffu文件,电脑功率计算 ...

  8. linux+C环境下动态管理头文件和库文件

    本文共分三个部分:首先给出了一个简单的Makefile的例子,然后分别详细阐述了头文件和库文件的相关知识 1.一个Makefile的例: -L是指定链接时搜索路径,比如-L./等: -l是指定具体的库 ...

  9. Linux下gcc编译中关于头文件与库文件搜索路径相关问题

    如何指定GCC的默认头文件路径 网上偶搜得之,以之为宝:) 原地址:http://blog.chinaunix.net/u/28781/showart.php?id=401631 ========== ...

最新文章

  1. android manifest 分辨率,android程序界面自动适应屏幕分辨率例子
  2. is_valid校验机制
  3. ostream作为函数返回值_GO语言基础函数
  4. WWW 2021有哪些值得读的图机器学习相关论文?
  5. 安卓ps2模拟器_安卓PSP模拟器评测:合金装备 和平步行者
  6. 【机器学习实践】Jupyter Notebook安装 侧边导航栏功能 操作及其他常用扩展功能介绍...
  7. java 类加载器_Java 类加载器
  8. Python 之 函数基础
  9. 大数据量下求均值的方法
  10. perl 5.10.0安装包下载
  11. k8s系列03-kubeadm部署calico网络的k8s集群
  12. opencv-contrib sfm扩展模块下载安装
  13. OC load 和 initialize 方法
  14. USB接口,MicroUSB接口
  15. Linux查看内存信息(型号、大小、速率等)
  16. 我对价值投资的思考(二)
  17. Cesium 实现粒子效果贴地(伪)
  18. ORC科普3-创业小王子Turboden
  19. 计算机主机电源故障分析检测维修,电源故障:台式机电脑电源故障检修
  20. Web安全——文件包含漏洞

热门文章

  1. 【简历制作合集】面试时到底是用彩打简历还是黑白简历更出彩呢?|智测优聘出品
  2. python数据分析项目实战—————链家北京租房数据统计分析
  3. 030 | 广西趣海有限责任公司创业计划书 | 大学生创新训练项目申请书 | 极致技术工厂
  4. win10-weblogic12.1.1.0新建域
  5. 英语八年级上册计算机的事实,人教版英语|八年级上册各单元必考知识点汇总,收藏!...
  6. 计算机数字表示方法有哪些,补码(计算机中数字的表示方式)
  7. linux程序注释生成器,Doxygen—程序文档生成工具
  8. 187. 重复的DNA序列
  9. 球形罩铆接机械臂设计(lunwen+开题报告+指导记录+设计图纸+PLC控制程序)
  10. 详细讲解:RocketMQ的限时订单实战与RocketMQ的源码分析!