《UNIX环境高级编程》第三版例程学习笔记及问题汇总


本文记录unix环境高级编程书里的例程问题,学习编程,最佳的捷径就是运行一遍程序,这个胜于十遍的低效阅读。

1. 资源下载

官方源码:
http://www.apuebook.com/code3e.html

2. fatal error:

apue.h

示例一是myls.c

root@ubuntu:/# cc myls.c
myls.c:1:18: fatal error: apue.h: No such file or directory

提示这个错误说明没有找到apue.h这个文件,此时找到从第一步下载的源码,解压,然后把include下的apute.h拷贝到/usr/include 目录下

cp ./apue.3e/include/apue.h /usr/include/

再次执行 gcc myls.c 提示如下错误:

myls.c:(.text+0x22): undefined reference to `err_quit'
myls.c:(.text+0x55): undefined reference to `err_sys'

这个是因为err_quit跟err_sys是作者自己定义的错误处理函数,做下面两步操作。

cp ./apue.3e/lib/error.c /usr/include/
然后
vim apue.h
在endif前添加 #include "error.c"

在这里插入图片描述

3. 第三章

hole.c

该例程演示了lseek函数会影响文件当前位置指针的值。

#include "apue.h"
#include <fcntl.h>

char    buf1[] = "abcdefghij";
char    buf2[] = "ABCDEFGHIJ";

int
main(void)
{
    
    
        int             fd;

        if ((fd = creat("file.hole", FILE_MODE)) < 0)
                err_sys("creat error");

        if (write(fd, buf1, 10) != 10)
                err_sys("buf1 write error");
        /* offset now = 10 */

        if (lseek(fd, 1024, SEEK_SET) == -1)
                err_sys("lseek error");
        /* offset now = 16384 */

        if (write(fd, buf2, 10) != 10)
                err_sys("buf2 write error");
        /* offset now = 16394 */

        exit(0);
}

argc[], arcv[]

argc 是 argument count的缩写,表示传入main函数的参数个数;
argv 是 argument vector的缩写,表示传入main函数的参数序列或指针,并且第一个参数argv[0]一定是程序的名称,并且包含了程序所在的完整路径,所以确切的说需要我们输入的main函数的参数个数应该是argc-1个;

下列示例为filetype.c
函数从shell命令行去读参数,每一个空格认为是一个参数,参数的个数赋值给argc,每个参数的首地址赋值给argv。

扫描二维码关注公众号,回复: 12046636 查看本文章
#include "apue.h"

int
main(int argc, char *argv[])
{
    
    
	int			i;
	struct stat	buf;
	char		*ptr;

	for (i = 1; i < argc; i++) {
    
    
		printf("%s: ", argv[i]);
		if (lstat(argv[i], &buf) < 0) {
    
    
			err_ret("lstat error");
			continue;
		}
		if (S_ISREG(buf.st_mode))
			ptr = "regular";
		else if (S_ISDIR(buf.st_mode))
			ptr = "directory";
		else if (S_ISCHR(buf.st_mode))
			ptr = "character special";
		else if (S_ISBLK(buf.st_mode))
			ptr = "block special";
		else if (S_ISFIFO(buf.st_mode))
			ptr = "fifo";
		else if (S_ISLNK(buf.st_mode))
			ptr = "symbolic link";
		else if (S_ISSOCK(buf.st_mode))
			ptr = "socket";
		else
			ptr = "** unknown mode **";
		printf("%s\n", ptr);
	}
	exit(0);
}

运行结果
在这里插入图片描述

4. 第四章

umask.c

路径 apue.3e/filedir

设置文件权限,函数中定义了一个宏变量,引用相应的变量代表关闭该功能。
S_IRUSR: 用户读权限
S_IWUSR: 用户写权限
S_IRGRP: Group读
S_IWGRP: Group写
S_IROTH: 其它用户读
S_IWOTH: 其它用户写
相应的宏定义在这stat结构体里,文件权限对应的 st_mode变量,这个变量也是结构体类型。
在这里插入图片描述
st_mode有如下几个取值

在这里插入图片描述
我们知道,在chmod这个命令下,输入数字即可改变文件权限,对应的数字值如下:

在这里插入图片描述

ebook附带的umask.c:

#include "apue.h"
#include <fcntl.h>

#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

int
main(void)
{
    
    
        umask(0);
        if (creat("foo", RWRWRW) < 0)
                err_sys("creat error for foo");
        umask(S_IRGRP|S_IWGRP | S_IROTH | S_IWOTH);
        if (creat("bar", RWRWRW) < 0)
                err_sys("creat error for bar");
        exit(0);
}

mgm@ubuntu:~/usr/apue.3e/filedir$ gcc umask.c -o umask
mgm@ubuntu:~/usr/apue.3e/filedir$ umask //这里的umask是系统函数
0002
mgm@ubuntu:~/usr/apue.3e/filedir$ ./umask
mgm@ubuntu:~/usr/apue.3e/filedir$ ls -l foo bar
-rw------- 1 mgm mgm 0 Sep 18 02:24 bar
-rw-rw-rw- 1 mgm mgm 0 Sep 18 02:24 foo

假如我们把程序里的umask值修改一下,

#include "apue.h"
#include <fcntl.h>

#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

int
main(void)
{
    
    
        umask(0);
        if (creat("foo", RWRWRW) < 0)
                err_sys("creat error for foo");
        umask(S_IWGRP | S_IROTH | S_IWOTH);
        if (creat("bar", RWRWRW) < 0)
                err_sys("creat error for bar");
        exit(0);
}

编译前记得把上次编译好的foo和bar函数删除。
再次执行可以看到变化。group权限多了一个读。
mgm@ubuntu:~/usr/apue.3e/filedir$ rm bar
mgm@ubuntu:~/usr/apue.3e/filedir$ rm foo
mgm@ubuntu:~/usr/apue.3e/filedir$ ./umask2
mgm@ubuntu:~/usr/apue.3e/filedir$ ls -l foo bar
-rw-r----- 1 mgm mgm 0 Sep 18 02:26 bar
-rw-rw-rw- 1 mgm mgm 0 Sep 18 02:26 foo

changemod.c

首先调用stat函数,获取结构体里的值,保存在statbuf里面。
然后用chmod函数修改st_mode的值。

#include "apue.h"

int
main(void)
{
    
    
        struct stat             statbuf;

        /* turn on set-group-ID and turn off group-execute */

        if (stat("foo", &statbuf) < 0)
                err_sys("stat error for foo");
        if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)
                err_sys("chmod error for foo");

        /* set absolute mode to "rw-r--r--" */

        if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
                err_sys("chmod error for bar");

        exit(0);
}

猜你喜欢

转载自blog.csdn.net/malcolm_110/article/details/108297338