《unix环境高级编程》-- Unix基础知识

列出一个目录中的所有文件

ls1.c

#include "apue.h"
#include <stdio.h>
#include <dirent.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);
    return 0;
}

这里写图片描述

将标准输入复制到标准输出
shell1.c

#include "apue.h"

#define BUFFSIZE 4096

int main(void)
{
    int n;
    char buf[BUFFSIZE];

    /*
       <unistd.h> 包含了STDIN_FILENO和STDOUT_FILENO
       分别为标准输入、标准输出文件描述符
       read 返回读得的字节数
       wirte 返回写得的字节数
    */
    while((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
        if(write(STDOUT_FILENO, buf, n) != n)
            err_sys("write error");
    if(n < 0)
        err_sys("read error");

    exit(0);
}

停止输入时为Ctr+D

这里写图片描述
这里写图片描述

用标准I/O将标准输入复制到标准输出
shell2.c
不用选取缓冲区大小

#include "apue.h"

int main(void)
{
    int c;
    while((c = getc(stdin)) != EOF)
        if(putc(c, stdout) == EOF)
            err_sys("output error");

    if(ferror(stdin))
        err_sys("input error");

    exit(0);
}

这里写图片描述

打印进程ID
hello.c

#include "apue.h"

int main(void)
{
    printf("hello world from process ID %d\n", getpid());
    exit(0);
}

这里写图片描述

从标准输入读入命令并执行
shell3.c
不能向命令传递参数

#include "apue.h"
#include <sys/wait.h>

int main(void)
{
    char buf[MAXLINE];  /* from apue.h */
    pid_t  pid;
    int status;

    printf("%% "); /* 提示符,以区别于shell的提示符 */
    while(fgets(buf, MAXLINE, stdin) != NULL)
    {
        if(buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = 0; /* execlp要求参数以null结束  */

        if((pid = fork()) < 0)
            err_sys("fork, error");
        else if(pid == 0)  /* child */
        {
            /*
            execlp执行从标准输入读入的命令。用新的程序替换了子进程原先执行的程序。
            */
            execlp(buf, buf, (char *)0); 
            err_ret("couldn't execute: %s", buf);
            exit(127);
        }

        /* parent */
        if((pid == waitpid(pid, &status, 0)) < 0)
            err_sys("waitpid error");
        printf("%% ");
    }
    exit(0);
}

这里写图片描述

打印用户ID和组ID
uidgid.c

#include "apue.h"

int main(void)
{
    /*
       root: 用户ID为0
           组ID:同组成员之间可共享资源
    */
    printf("uid = %d, gid = %d\n", getuid(), getgid());
    exit(0);
}

这里写图片描述

从标准输入读入命令并执行
shell4.c

信号是通知进程发生某种情况的一种技术

终端键盘上两种产生信号的方式:
中断键:Ctrl + C
退出键: Ctrl + \

捕捉中断键信号,只是打印一条消息

#include "apue.h"
#include <sys/wait.h>

static void sig_int(int);  /* out signal-catching function */

int main(void)
{
    char buf[MAXLINE]; /* from apue.h */
    pid_t pid;  
    int status;

    if(signal(SIGINT, sig_int) == SIG_ERR)
        err_sys("signal error");

    printf("%% ");
    while(fgets(buf, MAXLINE, stdin) != NULL)
    {
        if(buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = 0;

        if((pid = fork()) < 0)
        {
            err_sys("fork error");
        }
        else if(pid == 0)
        {
            execlp(buf, buf, (char *)0);
            err_ret("couldn't execute: %s", buf);
            exit(127);
        }

        /* parent */
        if((pid = waitpid(pid, &status, 0)) < 0)
            err_sys("waitpid error");
        printf("%% ");
    }
    exit(0);
}

void sig_int(int signo)
{
    printf("interruput\n%%");
}

这里写图片描述

系统调用和库函数
库函数可替换,系统调用不可替换
内核中的系统调用sbrk分配另外一块空格给进程,而库函数malloc则在用户层次管理这一空间
系统调用通常提供一种最小接口,而库函数通常提供较为复杂的功能

Makefile

ROOT = ..

# 执行apue.3e/systype.sh
PLATFORM = $(shell $(ROOT)/systype.sh)

# 引入基本量
include $(ROOT)/Make.defines.$(PLATFORM)

PROGS = ls1 shell1 shell2 hello shell3 testerror uidgid shell4

# 目标all, 即运行make后所要达到的最终结果
all: $(PROGS)

# 执行gcc命令,相应的量的值在Make.defines.xxx文件中,@表示依赖文件
# CC:C编译器。默认是cc
# CFLAGS:C编译器选项。make会将这个选项作为参数,在将.c文件变成.o的阶段传给编译器
# LDFLAGS:类似CFLAGS,不过它是在将.o变成可执行程序的阶段传给连接器。
# LDLIBS:如果你用了LDFLAGS,但不想库名选项与查找路径混在一起,可以将库名选项写在这里。
%: %.c $(LIBAPUE)
   $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) $(LDLIBS)

clean:
    rm -f $(PROGS) $(TEMPFILES) *.O

# 引入apue.3e/Make.libapue.inc文件
include $(ROOT)/Make.libapue.inc
本书全面介绍了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、付费专栏及课程。

余额充值