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. 【leetcode】654. Maximum Binary Tree

    题目如下: Given an integer array with no duplicates. A maximum tree building on this array is defined as ...

  2. cocos2D-X 显示中文

    { 将所在的cpp文件改为utf-8 无签名格式再编译 //但,治标不治本 }

  3. boost smart pointer

    1. boost::scoped_ptr is a smart pointer that is the sole owner of a dynamically allocated object and ...

  4. PHP chgrp() 函数

    定义和用法 chgrp() 函数改变指定文件的用户组. 如果成功则返回 TRUE,如果失败则返回 FALSE. 语法 chgrp(file,group) 参数 描述 file 必需.规定要检查的文件. ...

  5. <自动化测试>之<使用unittest Python测试框架进行参数化测试>

    最近在看视频时,虫师简单提到了简化自动化测试脚本用例中的代码量,而python中本身的参数化方法用来测试很糟糕,他在实际操作中使用了parameterized参数化... 有兴趣就查了下使用的方法,来 ...

  6. 自己总结的CSS3中transform变换、transition过渡、animation动画的基本用法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  7. 《ArcGIS Runtime SDK for .NET开发笔记》 --Hello Word

    这里我们将创建第一个用于显示地图的APP. 1.新建一个WPF程序 首先我们打开Visual Studio,选择新建项目. 选择已安装——模板——Windows桌面——WPF应用程序  2.添加Run ...

  8. python 操作数据库的常用SQL命令

    这俩天在学习PYTHON操作数据库的知识.其实基本SQL命令是与以前学习的MYSQL命令一致,只是增加了一些PYTHON语句. 1,安装pymysql,并导入. import pymysql 2,因为 ...

  9. HDU1251-统计难题-map+输入

    Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input输入数据的第一部分 ...

  10. upc组队赛3 T-net【贪心】

    T-net 题目描述 T-net which is a new telecommunications company, plans to install its base stations in th ...