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. double中首字母大写与小写的区别

    Double 是类 double是基础数据类型.Double类型是double的包装类.Double 和double之间的相互转化称为自动拆箱和自动装箱.如果从对象角度理解,那么Double就是对象, ...

  2. 深入理解java虚拟机:笔记

    1.运行时数据区域 1.程序计数器 当前线程执行字节码的行号指示器,字节码解释器工作通过改变这个计数器的值来选取下一条需要执行的字节码指令,每一个线程拥有独立的程序计数器,线程私有的内存 2.虚拟机栈 ...

  3. HDU-4609(FFT/NTT)

    HDU-4609(FFT/NTT) 题意: 给出n个木棒,现从中不重复地选出3根来,求能拼出三角形的概率. 计算合法概率容易出现重复,所以建议计算不合法方案数 枚举选出的最大边是哪条,然后考虑剩下两条 ...

  4. c# 定义operator运算符

    public void TestFunc() { Complex complex1 = new Complex(); Complex complex2 = new Complex(); var s = ...

  5. Andrdoid中对应用程序的行为拦截实现方式之----从Java层进行拦截

    致谢: 感谢 简行之旅的这篇blog:http://blog.csdn.net/l173864930/article/details/38455951,这篇文章是参考这篇blog的进行一步一步操作的, ...

  6. AcWing 243. 一个简单的整数问题2 (树状数组)打卡

    题目:https://www.acwing.com/problem/content/244/ 题意:区间加,区间查询 思路:我们把原先那个差分数组分解一下 ∑i=1x∑j=1ib[j]=∑i=1x(x ...

  7. 存储-docker存储(12)

    storage driver 和 data volume 是容器存放数据的两种方式 storage driver方式 docker info | grep "Storage Driver&q ...

  8. [CSP-S模拟测试]:简单的玄学(数学)

    题目描述 有$m$个在$[0,2^n)$内均匀随机取值的整型变量,球至少有两个变量取值相同的概率.为了避免精度误差,假设你的答案可以表示成$\frac{a}{b}$的形式,(其中$(a,b)=1$), ...

  9. visual studio code -- python

    录: 前提: 已安装python 在vsc中安装pthon模块 快速入门 打开控制台(ctrl+shift+P):Python: Select Interpreter,选择python解释器 或者在软 ...

  10. 框架-.NET:.NET Core

    ylbtech-框架-.NET:.NET Core .NET Core是适用于 windows.linux 和 macos 操作系统的免费.开源托管的计算机软件框架,是微软开发的第一个官方版本,具有跨 ...