《UNIX环境高级编程》APUE源码使用方法

 

 
 

一、《UNIX环境高级编程》第一版源码编译

Installation Guide of Example Source Code
1. Download SourceCode.zip 2. Type command: unzip SourceCode.zip
3. Type command: cd SourceCode
4. Type command: cp -f Make.def.rhlin Make.defines
5. Type command: cd lib.rhlin
6. Modify Makefile, delete the target strerror.o, replace the leading spaces with a TAB character at
line 58
7. Type command: make redhat60linux
8. Modify the path information in Make.defines at line 11 and line 19
9. Done

10.示例代码位置见Sourcefiles文件

1.1          file/ls1.c
1.2          mycat/mycat.c
1.3          mycat/getcputc.c

二、《UNIX环境高级编程》第二版源码编译

1.在http://www.apuebook.com下载(我是在学校网下)

2.解压缩,并认真阅读REAME并设置目录.

To build the source, edit the Make.defines.* file for your system and set

WKDIR to the pathname of the tree containing the source code.         Then just

run "make"

不幸我Make时有两个错误出现,但没关系,能在lib文件夹里生成一个库文本libapue.a即可

3. 把C源码中的#include "apue.h"改成#include "../include/apue.h或合适的路径。

4. gcc sourcefile.c ../lib/libapue.a
5. 应该有更好方法,但这个方法可以成功。这么麻烦可能是因我Make时有两个错误出现吧:(

修正说明(现在成功了^_^):

1.在http://www.apuebook.com下载(我是在学校网下)

2.解压缩,并认真阅读REAME并设置目录.
To build the source, edit the Make.defines.* file for your system and set
WKDIR to the pathname of the tree containing the source code.         Then just
run "make"


3.我的系统是RedHat 修改Source\Make.define.linux 文件如下
WKDIR=/home/thx/apue.2e
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS)
LDDIR=-L../lib
LDLIBS=../lib/libapue.a $(EXTRALIBS)
CFLAGS=-DLINUX -ansi -I$(WKDIR)/include -Wall -D_GNU_SOURCE $(EXTRA)
###taohx modify 2008-6-18
CPPFLAGS=-I/home/thx/apue.2e/include/

# Our library that almost every program needs.
LIB=../libapue.a

# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out typescript*


4.运行make. 因为我加了CPPFLAGS语句,指出了apue.h文件的位置。现在该正确了^_^


5.若不想重新全部编译,只编译某目录下的源文件.(以source\file目录为例)
#cd file
#cp linux.mk Makefile
#make


6.现在不用再把C源码中的#include "apue.h"改成#include "../include/apue.h ^_^

                                   

《UNIX环境高级编程》源码编译方法  
            来源:http://www.cublog.cn/u/33048/showart_256254.html

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  最近在学习《UNIX环境高级编程》(Advanced Programming in the UNIX Environment, 简称APUE,以下使用简称)。该书的作者是W.Richard.Stevens,国际知名的UNIX和网络专家。我看的是该书的第一版,尤晋元翻译的。网上有的评论该书翻译的比较差劲,有的说还行。我个人觉得,这本书的翻译还可以。并且,如果本身就有一定的UNIX/Linux基础的话,读起来应该不是很吃力。同时我也下了该书的第二版(英文版),有什么看不懂的地方,再对照英文版看一下,辅助理解。
                                                            这里要谈到的一个问题就是该书中的源代码编译的问题。此书中差不多每个历程中,都会有这样一行源码:
                                                #include "ourhdr.h"
                                                   
                                                在第二版中改为:
                                                #include "apue.h"
                                               
                                                             这个头文件是作者把把每个例程中常用的标准头文件,一些常用的出错处理函数(err_**()之类的函数)和一些常用的宏定义给整理在一个头文件中。这个可以省去在每个例程中录入较多的重复代码,这样可以减少每个例程的长度。但是,这样就给读者带来了不少麻烦。因为我们还要去搞明白如和把这个头文件编译,然后做成库文件,添加到我们的系统中。特别读于初学者,本来满怀信心的,结果在编译第一个程序的时候就出现了问题。我也没有搞明白如何把 "ourhdr.h"静态的编译到系统中。
                                               
                                                             不过,不明白如何使用"ourhdr.h"这个头文件,并不会影响我们学习APUE,也不会影响我们编译和运行每一个例程。其实,简单的想一下,如果一个 C程序要能顺利的编译和运行,除了我们要语法正确等方面外,最根本的是要保证我们程序中所调用的函数以及宏等等都要有完整的来源,也就是必须包含所有调用函数和宏所在的头文件。对于一个具体的源程序,如果我们正确的包含了头文件,那么剩下的就是程序本生语法方面应该注意的事项。
                                               
                                                             如何确定系统调用函数包含在那个头文件中呢?这在Unix/Linux系统下并非一件难事。Unix/Linux下命令man可以帮助我们找到。man命令不仅可以帮助我们查找一般命令的用法,同时提供不同层次的帮助诸如系统调用或者管理员级别的命令等等(譬如FreeBSD6.1中,man 1是用户专用手册,man 2是系统调用,man 3是库函数查询等等)。
                                               
                                                             下面我们就以APUE书中程序1-1 (实现ls命令部分功能)为例,来说明如何将书中的程序改编成全部使用标准头文件的程序。其中,操作系统用的是FreeBSD6.1,经过相应的修改可以在书中所说的几个Unix系统及Linux系统中运行,我也曾在Debian Linux下成功编译和运行该程序。书中1-1.c的原始代码如下:
                                               
                                                #include <sys/types.h>
                                                #include <dirent.h>
                                                #include "ourhdr.h"
                                               
                                                int
                                                main(int argc, char *argv[])
                                                {
                                                             DIR                         *dp;
                                                             struct dirent             *dirp;
                                               
                                                             if (argc != 2)
                                                                 err_quit("usage: ls directory_name");
                                               
                                                             if ((dp = opendir(argv[1])) == NULL)
                                                                 err_sys("can't open %s", argv[1]);
                                                             while ((dirp = readdir(dp)) != NULL)
                                                                 printf("%s\n", dirp->d_name);
                                               
                                                             closedir(dp);
                                                             exit(0);
                                                }
                                               
                                                    从书后面的附录中可以看到"ourhdr.h"的内容比较多,包含了比较多的常用头文件,一些宏定义和一些常用函数和出错函数的定义。其实,对于每一个具体的程序,我们只需要找到该程序中用到的头文件即可。
                                               
                                                             该1-1.c中所用到的系统函数调用有:opnedir(),readdir(),printf(),closedir()和exit()。
                                                其中,对于常用的函数prinft()和exit(),它们所在的头文件一般都知道,分别是<stdio.h>和<stdlib.h>。而对于opnedir (),readdir()和closedir(),我们可以通过man opendir,man readdir,man closedir得到这三个关于目录操作的函数所在的头文件都是:<sys/types.h>和<dirent.h>。这两个头文件在源程序中也已经列出。
                                               
                                                             其次,1-1.c中还用到了作者自定义的两个函数:err_quit()和err_sys()。这两个函数主要使用来进行出错处理的。当然,使用这两个函数对错误信息的处理是比较完善的。但是,作为我们学习来讲,了解程序的核心功能是首要的,我们可以将出错处理简化一点,即当遇到错误的时候,我们只简单的使用printf()函数来提示一下有错误发生。当然,用printf()来进行出错处理并不是一种很合理的方法,而且往往我们看不到更关键的错误信息,但对于我们仅仅作为学习来用还是可以接受的。毕竟我们要理解的核心部分是程序的功能实现,出错处理在于其次。
                                               
                                                            通过以上的说明,我们可以将1-1.c修改为如下内容:
                                               
                                                #include <sys/types.h>
                                                #include <dirent.h>
                                                #include <stdio.h>
                                                #include <stdlib.h>
                                                int main(int argc, char* argv[])
                                                {
                                                             DIR *dp;
                                                             struct dirent *dirp;
                                                    
                                                             if(argc != 2)
                                                             {
                                                                 printf("You need input the directory name.\n");
                                                                 exit(1);   //该行代码不要也可  
                                                             }
                                                    
                                                             if((dp = opendir(argv[1])) == NULL)
                                                             {
                                                                 printf("cannot open %s\n", argv[1]);
                                                                 exit(1);    //该行代码不要也可
                                                             }
                                               
                                                             while ((dirp = readdir(dp)) != NULL)
                                                                 printf("%s\n", dirp->d_name);
                                               
                                               
                                                             closedir(dp);
                                               
                                                             exit(0);
                                                }
                                               
                                                    这样修改后的程序已经与作者的头文件"ourhdr.h"没有关系,可以单独的进行编译。我使用的是root用户,执行命令:
                                               
                                                # gcc 1-1.c           //生成目标文件a.out
                                                或者
                                                # gcc -o 1-1 1-1.c           //生成目标文件1-1
                                               
                                                             没有任何错误和警告,说明编译成功。这时我们执行生成的目标文件:
                                               
                                                # ./a.out /home
                                                或者
                                                # ./1-1 /home
                                               
                                                             则会列出/home路径下的所有文件,包括目录(.)和(..)。
                                               
                                                             通过这样的方法,基本上我们可以将该书中所有的例程修改成不包含"ourhdr.h"的程序。这样,我们就可以单独的编译每一个例程,而不用顾及作者所给的杂凑的头文件。同时这种比较笨的方法,反而有利于帮助我们了解不同系统调用所对应的头文件,对于学习来说,这应该是一件好事。
                                               
                                                             现在,我也才学到APUE的第四章了。前四章的程序,我都是采用这种方法进行编译和运行。如果也有在学习APUE的朋友,我们可以一起交流。                                                                                                                                                                                                                                                                                                                                                                                               
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书全面介绍了UNIX系统的程序设计界面—系统调用界面和标准C库提供的许多函数。 本书的前15章着重于理论知识的阐述,主要内容包括UNIX文件和目录、进程环境、进程控制、 进程间通信以及各种I/O。在此基础上,分别按章介绍了多个应用实例,包括如何创建数据库函数库, PostScript 打印机驱动程序,调制解调器拨号器及在伪终端上运行其他程序的程序等。 本书内容丰富权威, 概念清晰精辟,一直以来被誉为UNIX编程的“圣经”,对于所有UNIX程序员—无论是初学者还是专家级人士 —都是一本无价的参考书籍。 目 录 译者序 译者简介 前言 第1章 UNIX基础知识 1 1.1 引言 1 1.2 登录 1 1.2.1 登录名 1 1.2.2 shell 1 1.3 文件和目录 2 1.3.1 文件系统 2 1.3.2 文件名 2 1.3.3 路径名 2 1.3.4 工作目录 4 1.3.5 起始目录 4 1.4 输入和输出 5 1.4.1 文件描述符 5 1.4.2 标准输入、标准输出和标准 出错 5 1.4.3 不用缓存的I/O 5 1.4.4 标准I/O 6 1.5 程序和进程 7 1.5.1 程序 7 1.5.2 进程和进程ID 7 1.5.3 进程控制 7 1.6 ANSI C 9 1.6.1 函数原型 9 1.6.2 类属指针 9 1.6.3 原始系统数据类型 10 1.7 出错处理 10 1.8 用户标识 11 1.8.1 用户ID 11 1.8.2 组ID 12 1.8.3 添加组ID 12 1.9 信号 12 1.10 UNIX时间值 14 1.11 系统调用和库函数 14 1.12 小结 16 习题 16 第2章 UNIX标准化及实现 17 2.1 引言 17 2.2 UNIX标准化 17 2.2.1 ANSI C 17 2.2.2 IEEE POSIX 18 2.2.3 X/Open XPG3 19 2.2.4 FIPS 19 2.3 UNIX实现 19 2.3.1 SVR4 20 2.3.2 4.3+BSD 20 2.4 标准和实现的关系 21 2.5 限制 21 2.5.1 ANSI C限制 22 2.5.2 POSIX限制 22 2.5.3 XPG3限制 24 2.5.4 sysconf、pathconf 和fpathconf 函数 24 2.5.5 FIPS 151-1要求 28 2.5.6 限制总结 28 2.5.7 未确定的运行时间限制 29 2.6 功能测试宏 32 2.7 基本系统数据类型 32 2.8 标准之间的冲突 33 2.9 小结 34 习题 34 第3章 文件I/O 35 3.1 引言 35 3.2 文件描述符 35 3.3 open函数 35 3.4 creat函数 37 3.5 close函数 37 3.6 lseek函数 38 3.7 read函数 40 3.8 write函数 41 3.9 I/O的效率 41 3.10 文件共享 42 3.11 原子操作 45 3.11.1 添加至一个文件 45 3.11.2 创建一个文件 45 3.12 dup和dup2函数 46 3.13 fcntl函数 47 3.14 ioctl函数 50 3.15 /dev/fd 51 3.16 小结 52 习题 52 第4章 文件和目录 54 4.1 引言 54 4.2 stat, fstat和lstat函数 54 4.3 文件类型 55 4.4 设置-用户-ID和设置-组-ID 57 4.5 文件存取许可权 58 4.6 新文件和目录的所有权 60 4.7 access函数 60 4.8 umask函数 62 4.9 chmod和fchmod函数 63 4.10 粘住位 65 4.11 chown, fchown和 lchown函数 66 4.12 文件长度 67 4.13 文件截短 68 4.14 文件系统 69 4.15 link, unlink, remove和rename 函数 71 4.16 符号连接 73 4.17 symlink 和readlink函数 76 4.18 文件的时间 76 4.19 utime函数 78 4.20 mkdir和rmdir函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值