4.1 用 stat 函数替换图 4-3 程序中的 lstat函数,如若命令行残数之一是符号链接,会发生什么变化?

stat不支持链接,如果有参数是链接符号,会显示链接后的文件属性。

4.2 如果文件模式创建屏蔽字 777 (八进制),结果会怎样?用shell的umask命令验证该结果

pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ vim ex4-.c
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ gcc ex4-.c
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ ./a.out
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ ls
-.c -.c -.c -.c -.c a.out ex4-2_bar ex4-2_foo myfile times
-.c -.c -.c -.c -.c changemod ex4-.c foo tags
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ ls -la ex4-2_bar ex4-2_foo
---------- pi pi Dec : ex4-2_bar
-rw-rw-rw- pi pi Dec : ex4-2_foo

会把所有的位都屏蔽掉

4.3 关闭一个你所拥有文件的用户读权限,将导致拒绝你访问自己的文件,对此进行验证。

pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ chmod u-rw ex4-2_foo
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ cat ex4-2_foo
cat: ex4-2_foo: Permission denied

4.4 创建文件foo和bar后,运行图4-9的程序,讲发生什么情况?

pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ ./a.out
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ ls -l foo bar
-rw------- pi pi Dec : bar
-rw-rw-rw- pi pi Dec : foo
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ chmod a-r foo bar
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ ls -l foo bar
--w------- pi pi Dec : bar
--w--w--w- pi pi Dec : foo
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ ./a.out
pi@raspberrypi:~/chen_DIR/APUE/chapter_4 $ ls -l foo bar
--w------- pi pi Dec : bar
--w--w--w- pi pi Dec : foo

文件的权限没有变,但是文件内容什么的修改时间都被改了。

4.5 4.12节中讲到一个普通文件的大小可以为0,同时我们又知道st_size字段是为目录或符号链接定义的,那么目录和符号链接的长度是否可以为0?

目录的长度从来不会是0,因为它总是包含 . 和 .. 两项。符号链接的长度指其路径名包含的字符数,由于路径名中至少有一个字符,所以长度也不为0。

4.6 编写一个类似cp(1)的程序,他复制包含空洞的文件,但不将字节0写到输出文件中去。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h> #define BUF_SIZE 4096 int main(int argc, char *argv[])
{
char *filePathFrom;
char *filePathTo;
int fdFrom, fdTo;
int have_holes, byte_count, res, current_position;
char buff[BUF_SIZE];
struct stat st; if(argc != || !argv[] || !argv[])
{
fprintf(stderr, "Usage: %s <source file path> <target file path>\n",
argv[]);
exit();
}
filePathFrom = argv[];
filePathTo = argv[];
if((fdFrom = open(filePathFrom, O_RDWR)) < )
{
fprintf(stderr, "open path from error");
exit();
} if(fstat(fdFrom, &st) != )
fprintf(stderr, "stat error");
else {
if(S_ISREG(st.st_mode) && st.st_size > * st.st_blocks) {
have_holes = ;
printf("%s is a sparse-block file!\n", filePathFrom);
} else {
have_holes = ;
printf("%s is not a sparse-block file!\n", filePathFrom);
}
} if((fdTo = open(filePathTo, O_RDWR|O_APPEND|O_CREAT|O_TRUNC, )) < )
{
fprintf(stderr, "open path to error");
exit();
} memset(buff, '\0', BUF_SIZE);
if((res = read(fdFrom, buff, BUF_SIZE)) < )
{
fprintf(stderr, "fdFrom read error");
exit();
}
if(have_holes)
{
byte_count = ;
for(current_position = ;current_position < res; current_position++)
{
if(buff[current_position] != )
{
buff[byte_count] = buff[current_position];
byte_count++;
}
}
} else
byte_count = res; if((res = write(fdTo, buff, byte_count)) < )
{
fprintf(stderr, "fdTo write error");
exit();
} close(fdFrom);
close(fdTo);
}

4.7 在4.12节ls命令的输出中,core和core.copy的访问权限不同,如果创建两个文件时umask没有变,说明为什么会发生这种差别。

当创建新的core文件时,内核对其访问权限有一个默认设置,在本例中是rw-r--r--。这一默认值可能会也可能不会被umask的值修改。shell对创建的重定向的新文件也有一个默认的访问权限,本例中为rw-rw-rw-,这个值总是被当前的umask修改,在本例中umask为02.

4.8 在运行图4-16的程序时,使用了df(1)命令来检查空闲的磁盘空间。为什么不使用du(1)命令?

不能使用du的原因是它需要文件名,如

du tempfile或目录名,如

du .

只有当unlink函数返回时才释放tempfile的目录项,du .命令没有计算仍然被tempfile占用空间。本例中只能使用df命令查看文件系统中实际可用的空闲空间。

4.9 图4-20中显示unlink函数会修改文件状态更改时间,这是怎样发生的?

如果被删除的链接不是该文件的最后一个链接,则不会删除该文件。此时,文件的状态更改时间被更新。但是,如果被删除的链接是最后一个链接,则该文件将物理删除。这时再去更新文件的状态更改时间就没有意义,因为包含文件所有信息的i借点将会随着文件的删除而被释放。

4.10 4.22节中,系统对可打开文件数的限制对myftw函数会产生什么影响?

用opendir打开一个目录后,递归调用函数dopath。假设opendir使用一个文件描述符,并且只有在处理完目录后才调用closedir释放描述符,这就意味着每次降一级就要使用另外一个描述符。所以进程可以打开的最大描述符就限制了我们可以遍历的文件系统数的深度。single Unix sepcification的XSI扩展中说明的ftw允许调用者指定使用的描述符,这隐含着可以关闭描述符并且重用它们。

4.11 在4.22节中的myftw从不改变其目录,对这种处理方法进行改动;每次遇到一个目录就调用chdir,这样每次调用lstat时就可以使用文件名而非路径名,处理完所有的目录项后执行chdir("..")。比较这种版本的程序和书中程序的运行时间。

#include "apue.h"
#include <dirent.h>
#include <limits.h>
#include "../chapter_2/2-16.c" /* function type that is called for each filename */
typedef int Myfunc(const char *, const struct stat *, int); static Myfunc myfunc;
static int myftw(char *, Myfunc *);
static int dopath(Myfunc *);
static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot; int main(int argc, char *argv[])
{
int ret;
if(argc != )
err_quit("usage: ftw <starting-pathname>");
ret = myftw(argv[], myfunc); /* does it all */
ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
if(ntot == )
ntot = ;
printf("regular files = %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot);
printf("directories = %7ld, %5.2f %%\n", ndir, ndir*100.0/ntot);
printf("block special = %7ld, %5.2f %%\n", nblk, nblk*100.0/ntot);
printf("char special = %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot);
printf("FIFOs = %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot);
printf("symbolic links = %7ld, %5.2f %%\n", nslink, nslink*100.0/ntot);
printf("sockets = %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot);
exit(ret);
} #define FTW_F 1
#define FTW_D 2
#define FTW_DNR 3
#define FTW_NS 4 static char *fullpath;
static char *filename;
static size_t pathlen; static int myftw(char *pathname, Myfunc *func)
{
filename = path_alloc(&pathlen); if(pathlen <= strlen(pathname)) {
pathlen = strlen(pathname) * ;
if((filename = realloc(filename, pathlen)) == NULL)
err_sys("realloc failed.");
}
strcpy(filename, pathname);
return (dopath(func));
} static int dopath(Myfunc *func)
{
struct stat statbuf;
struct dirent *dirp;
DIR *dp;
int ret, n; if(lstat(filename, &statbuf) < )
return(func(filename, &statbuf, FTW_NS));
if(S_ISDIR(statbuf.st_mode) == )
return(func(filename, &statbuf, FTW_F)); if((ret = func(filename, &statbuf, FTW_D)) != )
return(ret);
n = strlen(filename);
if(n + NAME_MAX + > pathlen) {
pathlen *= ;
if((filename = realloc(filename, pathlen)) == NULL)
err_sys("realloc failed");
}
//filename[n++] = '/';
//filename[n] = 0;
if((dp = opendir(filename)) == NULL)
return(func(filename, &statbuf, FTW_DNR));
if(chdir(filename) < )
err_sys("chdir %s error", filename);
while((dirp = readdir(dp)) != NULL) {
if(strcmp(dirp->d_name, ".") == ||
strcmp(dirp->d_name, "..") == )
continue;
filename = dirp->d_name;
if((ret = dopath(func)) != )
break;
}
if(chdir("..") < )
err_sys("chdir .. error");
if(closedir(dp) < )
err_ret("can't close directory %s", filename);
return(ret);
} static int myfunc(const char *pathname, const struct stat *statptr, int type)
{
switch(type) {
case FTW_F:
switch(statptr->st_mode & S_IFMT) {
case S_IFREG: nreg++; break;
case S_IFBLK: nblk++; break;
case S_IFCHR: nchr++; break;
case S_IFIFO: nfifo++; break;
case S_IFLNK: nslink++; break;
case S_IFSOCK: nsock++; break;
case S_IFDIR: err_dump("for S_IFDIR for %s", pathname);
}
break;
case FTW_D:
ndir++;
break;
case FTW_DNR:
err_ret("can't read directory %s", pathname);
break;
case FTW_NS:
err_ret("stat error for %s", pathname);
break;
default:
err_dump("unknown type %d for pathname %s", type, pathname);
}
return();
}

4.12 每个进程都有一个根目录用于解析绝对路径名,可以通过chroot函数改变根目录。在手册中查询次函数。说明这个函数什么时候有用

chroot函数被因特网文件传输协议(Internet File Transfer Protocal,FTP)程序用于辅助安全性。系统中没有账户的用户(也称为匿名FTP)放在一个单独的目录下,利用chroot将此目录当作新的根目录,就可以阻止用户方位此目录以外的文件。

chroot也用于在另一台机器上构造一个文件系统层次结构的副本,然后修改此副本,不会更改原来的文件系统。这可用于测试新软件包的安装。

chroot只能由超级用户执行,一旦更改了一个进程的根,该进程及其后代进程就再也不能回复至原先的根。

apue第4章习题的更多相关文章

  1. apue第七章学习总结

    apue第七章学习总结 1.main函数 程序是如何执行有关的c程序的? C程序总是从main函数开始执行.main函数的原型是 int main(int argc,char *argv[]); 其中 ...

  2. apue第六章学习总结

    apue第六章学习总结 1.关于阴影文件与口令 在口令文件当中,常见的字段有(以root为例): root(用户名):x(加密口令):0(uid):0(gid):root(注释字段):/root(用户 ...

  3. apue第四章学习总结

    apue第四章学习总结 4.1.若以stat函数去替换lstat函数,会发生: 原来的目录路径: $:~/workspace/apue2/include$ ls -l apue.h abc lrwxr ...

  4. [物理学与PDEs]第1章习题参考解答

    [物理学与PDEs]第1章习题1 无限长直线的电场强度与电势 [物理学与PDEs]第1章习题2 均匀带电球面的电场强度与电势 [物理学与PDEs]第1章习题3 常场强下电势的定解问题 [物理学与PDE ...

  5. [物理学与PDEs]第2章习题参考解答

    [物理学与PDEs]第2章习题1 无旋时的 Euler 方程 [物理学与PDEs]第2章习题2 质量力有势时的能量方程 [物理学与PDEs]第2章习题3 Laplace 方程的 Neumann 问题 ...

  6. [物理学与PDEs]第3章习题参考解答

    [物理学与PDEs]第3章习题1 只有一个非零分量的磁场 [物理学与PDEs]第3章习题2 仅受重力作用的定常不可压流理想流体沿沿流线的一个守恒量 [物理学与PDEs]第3章习题3电磁场的矢势在 Lo ...

  7. [物理学与PDEs]第4章习题参考解答

    [物理学与PDEs]第4章习题1 反应力学方程组形式的化约 - 动量方程与未燃流体质量平衡方程 [物理学与PDEs]第4章习题2 反应力学方程组形式的化约 - 能量守恒方程 [物理学与PDEs]第4章 ...

  8. [物理学与PDEs]第5章习题参考解答

    [物理学与PDEs]第5章习题1 矩阵的极分解 [物理学与PDEs]第5章习题2 Jacobian 的物质导数 [物理学与PDEs]第5章习题3 第二 Piola 应力张量的对称性 [物理学与PDEs ...

  9. 统计学习导论:基于R应用——第三章习题

    第三章习题 部分证明题未给出答案 1. 表3.4中,零假设是指三种形式的广告对TV的销量没什么影响.而电视广告和收音机广告的P值小说明,原假设是错的,也就是电视广告和收音机广告均对TV的销量有影响:报 ...

随机推荐

  1. yii2 后台前后台 前后台登陆、退出问题

    问题描述:我使用前后台分离 配置如下: 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => ...

  2. mybatis plus generator工具集成(一)

    参数配置文档 配置分两步 1.添加依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId> ...

  3. TextView详解

    android:autoLink设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web /email/phone/map/all)android: ...

  4. Vue.config.optionMergeStrategies 用法分析

    举个例子,假设有个对象,他叫objA, 技能是说hello,他喜欢的女生叫小花,但是他是一个花心的人! objA = { name: 'objA ', sayHello_ () { console.l ...

  5. (转)Spring Boot干货系列:(四)开发Web应用之Thymeleaf篇

    转:http://tengj.top/2017/03/13/springboot4/ 前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boot对Web开发的支持. 正文 Sp ...

  6. 深入理解dijkstra+堆优化

    深入理解dijkstra+堆优化 其实就这几种代码几种结构,记住了完全就可以举一反三,所以多记多练多优化多思考. Dijkstra   对于一个有向图或无向图,所有边权为正(边用邻接矩阵的形式给出), ...

  7. 一.jenkins安装(windows环境)

    前提:jdk等已安装 jenkins下载地址:https://jenkins.io/download/ 以我目前的知识记录两种启动方式: 1.直接下载war包 通过   java -jar jenki ...

  8. 使用LoadRunner监控Apache

    前提本文使用的是lampp环境下自带的Apache服务 一.查看文件 查看文件确保目录中有Apache,我在这里使用的是用xampp自带apache [root@besttest ~]# ll 二.配 ...

  9. Android组件内核之Service内核原理(三)

    阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680本篇文章将先从以下三个内容来介绍Service内核原理: [startSe ...

  10. SpringBoot传递单一参数时@RequestParam和@RequestBody的区

    用SpringBoot框架做项目时,经常需要前端给后端传递参数,如果需要多条参数,通常的做法是把这些参数封装为一个对象来传递,前端用POST方式调用.但有时会遇到后端只需要一条参数(比如一个Strin ...