UNIX环境高级编程-第三章习题
1,当读写磁盘文件时,read,write等函数确实是不带缓冲机制的吗?请说明原因。
答:所有磁盘I/O都要经过内核的块缓存区(即内核的缓冲区高速缓存)。唯一例外的是对原始磁盘设备的I/O,但是我们不考虑这种情况。既然read或write的数据都要被内核缓冲,那么术语“不带缓冲的I/O”指的是在用户的进程中对这两个函数不会自动缓冲,每次read或write就要进行一次系统调用。
2,编写一个与dup2功能相同的函数,要求不调用fcntl函数,并且要有正确的出错处理。
答:
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h> #define OPEN_MAX_GUESS 256 long
open_max(void) //这里是第二章的习题代码
{
long openmax;
struct rlimit rl; if ((openmax = sysconf(_SC_OPEN_MAX)) < || openmax == LONG_MAX)
{
if (getrlimit(RLIMIT_NOFILE, &rl) < )
perror("can't get file limit");
if (rl.rlim_max == RLIM_INFINITY)
openmax = OPEN_MAX_GUESS;
else
openmax = rl.rlim_max;
}
return(openmax);
} int my_dup2(int oldfd, int newfd)
{
int fd;
int begin_fd;
long t_openmax;
int i;
t_openmax = open_max();
printf("open_max is %ld\n", t_openmax);
if(oldfd < || newfd < || oldfd > (t_openmax - ) || newfd > (t_openmax - )) //以当前系统最大打开文件数量为限
{
perror("fd error");
return -;
} if(oldfd == newfd)
{
return newfd;
}
close(newfd);
fd = dup(oldfd);
begin_fd = fd;
while(fd < (t_openmax - )) //循环对比当前复制的文件描述符是否符号要求
{
if(fd == newfd)
{
printf("get newfd\n");
break;
}
fd = dup(oldfd);
if(fd == -)
{
perror("dup error");
return -;
} }
for(i = begin_fd;i < fd; i++)
{
close(i);
}
return fd;
} int main(int argc, char *argv[])
{
int oldfd;
int newfd; char *buf="This is my_dup2 test\n"; if((oldfd = open("my_dup2_text.txt",O_RDWR|O_CREAT,)) == -)
{
perror("my_dup2_text open error");
exit(-);
}
newfd = my_dup2(oldfd, );
if(newfd == -)
{
perror("my_dup2 error");
exit(-);
}
printf("newfd is %d\n", newfd);
if(write(newfd, buf, strlen(buf)) != strlen(buf))
{
perror("write error");
exit(-);
} close(newfd);
exit();
}
3,假设一个进程执行下面3个函数调用:
fd1 = open(path, oflags);
fd2 = dup(fd1);
fd3 = open(path, oflags);
指出三个文件描述符的文件表关系。对fcntl作用于fd1来说,F_SETFD命令会影响哪一个文件描述符?F_SETEL呢?
答:fd1、fd2指向同一个文件表,fd3有新的文件表,但是v节点表与fd1、fd2一样。F_SETFD只影响fd1,因为这个标志位的作用是设置文件描述符。F_SETEL影响fd1和fd2,因为它设置的是文件的状态。

4,许多程序中都包含下面一段代码:
dup2(fd, );
dup2(fd, );
dup2(fd, );
if (fd > )
close(fd);
为了说明if语句的必要性,假设fd是1,画出每次调用dup2时3个描述符及相应的文件表项的变化情况。然后再画出fd为3的情况。
答:fd为1的情况:fd标志为0、2、1都指向同样的文件表。
fd为3的情况:fd标志为0、1、2、4都指向同样的文件表。
因为 0、1、2分别对应stdin, stdout, stderr,是不应该关闭的,这段程序的目的是把stdin, stdout, stderr这三个标准fd重定向到同一个文件描述符里,当fd大于2时,因为目的已经达成,大于2的fd已经不需要了,为了避免造成浪费,所以关闭它。
5,在bourne shell、Bourne-again shell和Korn shell中,digit1>&digit2表示要将描述符digit1重定向至描述符digit2的同一文件。请说明下面两条命令的区别。
./a.out > outfile >&
./a.out >& > outfile
答:第一条是把标准错误和标准输出都重定向到outfile,指向同一文件表项;
第二条是标准错误重定向到标准输出,然后标准输出又重定向到outfile,所以标准输出指向outfile的文件表项,标准错误指向终端的文件表项,所有标准错误都会打印到终端。
6,如果使用追加标志打开一个文件以便读、写,能否仍用lseek在任一位置开始读?能否用lseek更新文件中任一部分的数据?请编写一段程序验证。
答:能在任一位置开始读,但不能更新任一部分的数据,只能追加,程序如下:
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
{
int fd;
char buf_read[10];
char *buf="This is lseek test\n";
if((fd = open("lseek.txt",O_RDWR|O_CREAT|O_APPEND,0644)) == -1)
{
perror("fd open error");
exit(-1);
}
if(write(fd, buf, strlen(buf)) != strlen(buf))
{
perror("write error");
exit(-1);
}
lseek(fd, 2, SEEK_SET);
read(fd, buf_read, 10);
lseek(fd, 2, SEEK_SET);
printf("lseek read is: %s\n", buf_read);
if(write(fd, buf, strlen(buf)) != strlen(buf))
{
perror("write error");
exit(-1);
}
close(fd);
exit(0);
}
运行结果如下:
dog@dog:~/test$ ./a.out
lseek read is: is is lsee
dog@dog:~/test$ cat lseek.txt
This is lseek test
This is lseek test
UNIX环境高级编程-第三章习题的更多相关文章
- unix环境高级编程第三章笔记
文件描述符 1.文件描述符的概念 对于内核而言,所有打开的文件都会用一个文件描述符来引用,打开或和创建一个新文件的时候,内核会给进程返回一个文件描述符,而当使用read write时,可以使用这个文件 ...
- 【转】apue《UNIX环境高级编程第三版》第一章答案详解
原文网址:http://blog.csdn.net/hubbybob1/article/details/40859835 大家好,从这周开始学习apue<UNIX环境高级编程第三版>,在此 ...
- Linux - Unix环境高级编程(第三版) 代码编译
Unix环境高级编程(第三版) 代码编译 本文地址:http://blog.csdn.net/caroline_wendy 时间:2014.10.2 1. 下载代码:http://www.apuebo ...
- Unix环境高级编程第三版中实例代码如何在自己的linux上运行的问题
学习Linux已经有2个月了,最近被期末考试把进度耽误了,前几天把Unix环境高级编程看了两章,感觉对Linux的整体有了一些思路,今天尝试着对第一章涉及到的一个简单的交互式shell编译运行一下,结 ...
- UNIX环境高级编程 第8章 进程控制
本章是UNIX系统中进程控制原语,包括进程创建.执行新程序.进程终止,另外还会对进程的属性加以说明,包括进程ID.实际/有效用户ID. 进程标识 每个进程某一时刻在系统中都是独一无二的,它们之间是用一 ...
- UNIX环境高级编程 第7章 进程环境
本章涉及C/C++程序中main函数是如何被调用的.命令行参数如何传递给main函数.程序的内存空间布局.程序如何使用环境变量.程序如何终止退出. main函数 C程序或C++程序总是从main函数开 ...
- UNIX环境高级编程 第4章 文件和目录
第三章说明了关于文件I/O的基本函数,主要是针对普通regular类型文件.本章描述文件的属性,除了regular文件还有其他类型的文件. 函数stat.fstat.fstatat和lstat sta ...
- unix环境高级编程-读书笔记与习题解答-第一篇
从这周开始逐渐的进入学习状态,每天晚上都会坚持写c程序,并且伴随对这本书的深入,希望能写出更高质量的读书笔记和程序. 本书的第一章,介绍了一些关于unix的基础知识,在这里我不想去讨论linux到底是 ...
- UNIX环境高级编程 第6章 系统数据文件和信息
UNIX系统的正常运作需要用到大量与系统有关的数据文件,例如系统用户账号.用户密码.用户组等文件.出于历史原因,这些数据文件都是ASCII文本文件,并且使用标准I/O库函数来读取. 口令文件 /etc ...
随机推荐
- php--->底层的运行机制与数据结构原理
PHP 底层的运行机制与数据结构原理 1. PHP的设计理念及特点 多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,当然,随着时代发展,PHP也早 ...
- learn more ,study less(一):整体性学习策略
作者:scott young 一.整体性学习策略 整体性学习是一种学习理论.它更精确.全面地描述了我们大脑是如何工作的.各位, 你的大脑并非简单如计算机的文档储存,计算机文档的本质是一系列 0 和 1 ...
- JVM性能优化系列-(3) 虚拟机执行子系统
3. 虚拟机执行子系统 3.1 Java跨平台的基础 Java刚诞生的宣传口号:一次编写,到处运行(Write Once, Run Anywhere),其中字节码是构成平台无关的基石,也是语言无关性的 ...
- js的三种输出语句,以及html的运行循序
js最常见的三种输出语句 1.console.log()这个语句是在浏览器控制台输出的.进入网页点击f12可查看 2.alert()弹出一个对话框, 3.document.write这个语句是在页面输 ...
- ROS和Gazebo进行机器人仿真(二)
一.在Gazebo中使用ROS控制器 在本节中,我们将讨论如何在Gazebo中让机器人的每个关节运动. 为了让关节动起来,我们需要分配一个ROS控制器,尤其是,我们需要为每个关节连上一个与transm ...
- nginx适用哪些场景
1.静态资源服务 通过本地文件系统提供服务 2.反向代理服务 ningx的强大性能 缓存 负载均衡 3.API服务 openresty
- Java并发读书笔记:线程安全与互斥同步
目录 导致线程不安全的原因 什么是线程安全 不可变 绝对线程安全 相对线程安全 线程兼容 线程对立 互斥同步实现线程安全 synchronized内置锁 锁即对象 是否要释放锁 实现原理 啥是重进入? ...
- 大牛给的ACM进阶建议
转:https://blog.csdn.net/mmy1996/article/details/56011084 来自知乎 在他后面的回答中发现 不用IDE ,修炼内功挺好的,不过他和我的以前的那种 ...
- 脚本、脚本语言、shell脚本
脚本是批处理文件的延伸,是一种纯文本保存的程序,一般来说的计算机脚本程序是确定的一系列控制计算机进行运算操作动作的组合,在其中可以实现一定的逻辑分支等.脚本程序相对一般程序开发来说比较接近自然语言,可 ...
- Andriod you must restart adb and eclipse
今天看着视频 学习着 andriod ,启动 的时候 竟然报错 我试了N种google来的方法,都失效,现在把我的解决方法告诉大家,希望能帮到大家. 首先,我先罗列下我搜到的方法,大家也可以尝试. 1 ...