unix高级环境编程 例子 代码实现练习 第一章:unix基础知识

缘由

花了接近一周的时间死劲的读新买了的:unix高级环境编程
所以,没有写博客,现在差不多大概读完了,但是没有敲代码,没有查看练习题,只是对这本书有一个粗浅的认识。
现在的计划是:

  1. 敲完书中所有的例子代码
  2. 然后解决练习题

注意:主要是写代码,不会重复书中的话。当然真的有价值的总结还是会进行的,原来犯的错误就是老是总结书中的观点、重复书中的话,非常耽误时间。

  • 今天是unix的基础知识,所以还看不出这些代码的价值,越到后面就越能看出书中代码的宝贵

配置头文件

书中大量使用apue.h和打印错误的error.c,首先要把就两个头文件加入编写的代码里面。

需要的代码可以从这里下载:源代码

搭配的问题可参考:看unix高级编程时遇到apue.h找不到的问题


程序清单1-1:列出一个目录中的所有文件

#include "apue.h"
#include <dirent.h>
#include "error.c" 	/*不是.h*/
/**
 * 程序清单1-1:列出一个目录中的所有文件(P4)
 * 
 * zy:
 * 现实了简单的ls的功能,请添加头文件
 * 第五页对此有详细的解释,由于非常简单,就不多解释了
 */
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);
}


程序清单1-2:将标准输入复制到标准输出

/**
 * 程序清单1-2:将标准输入复制到标准输出(P6)
 *
 * zy:
 * 对标准输入和标准输出有加深认识.
 * 试用了P7所说的几种方法
 * 改变标准输入和标准输出。
 */
#include "apue.h"
#include "error.c" 	/*不是.h*/
#define BUFFSIZE 4096
int main(){
	int n;
	char buf[BUFFSIZE];

	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");
}

 程序清单1-3:用标准I/O将标准输入复制到标准输出

/**
 * 程序清单1-3:用标准I/O将标准输入复制到标准输出
 *
 * zy:
 * 和上一个程序的区别主要在于使用了getc,而不是read
 * 使用了putc,而不是write.
 * 从P7的描述来看,read和write应该是系统调用,需要我们自己关心缓冲区问题
 * I/O标准库的函数为我们提供了一系列的函数,让我们不用担心缓冲区的问题,
 * 比如fgets读一行,getc和putc是一个字节
 *
 * */
#include "apue.h"
#include "error.c"     /*不是.h*/
int main()
{
    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);
}

程序清单1-4:打印进程ID


/**
 * 程序清单1-4:打印进程ID
 *
 * zy:
 * 本来很简单的问题,但是请记住,
 * 这个getpid()的来自库文件:unistd.h
 * */
#include "apue.h"
#include "error.c"     /*不是.h*/
int main()
{
    printf("the pid:%d\n",getpid());
}

程序清单1-5:从标准输入读命令并且执行

/**
 * 程序清单1-5:从标准输入读命令并且执行
 *
 * zy:
 * 相当于完成了一个小shell
 * 因为子进程执行了execlp
 * */
#include "apue.h"
#include "sys/wait.h"     /*不是.h*/
#include "error.c"
int main()
{
    char buf[MAXLINE];
    pid_t pid;
    int status;

    printf("%% ");//打印一个提示符
    while(fgets(buf,MAXLINE,stdin)!=NULL){
        if(buf[strlen(buf)-1]=='\n')
            buf[strlen(buf)-1]=0;//用null代替换行符(我居然写成了‘0’),这是下面那个execlp的要求
        if((pid=fork())<0){
            err_sys("fork error");
        }else if(pid==0){//child
            execlp(buf,buf,(char *)0);
            err_ret("couldn't execute :%s ",buf);
            exit(127);
        }
        //parent
        if((pid=waitpid(pid,&status,0))<0)//P179对此函数有着更多的说明
            err_sys("waitpid error");
        printf("%% ");
    }
}

程序清单1-6:例示strerror和perror

/**
 * 程序清单1-6:例示strerror和perror
 *
 * zy:
 * strerror只是产生一个字符串,然后我们还要手动将其打印出来,
 * 而perror要方便多了,对errno赋值之后,我们可以直接调用perror
 * */
#include "apue.h"
#include "error.c"
int main(int argc,char *argv[])
{
    fprintf(stderr,"EACCES:%s\n",strerror(EACCES));
    errno=ENOENT;//这个errno是c标准里面定义好的东西
    perror(argv[0]);
}


结果:
zy@zy:~/Documents/eclipseWorkSpace/test/src$ ./a.out  
EACCES:Permission denied
./a.out: No such file or directory
zy@zy:~/Documents/eclipseWorkSpace/test/src$ 

程序清单1-7:打印用户ID和组ID

/**
 * 程序清单1-7:打印用户ID和组ID
 *
 * */
#include "apue.h"
#include "error.c"     /*不是.h*/
int main()
{
    printf("the uid:%d,gid=%d\n",getuid(),getgid());
    exit(0);
}


程序清单1-8:从标准输入读命令并执行,涉及信号

/**
 * 程序清单1-8:从标准输入读命令并执行,涉及信号
 *
 * zy:
 * 主要是简单的认识一下信号,这里的SIGINT信号没有采用默认的方法,而是被截断了执行sig_int的方法
 * */
#include "apue.h"
#include "sys/wait.h"     /*不是.h*/
#include "error.c"

void sig_int(int signo){
    printf("interrupt\%%");
}
int main()
{
    char buf[MAXLINE];
    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;//用null代替换行符(我居然写成了‘0’),这是下面那个execlp的要求
        if((pid=fork())<0){
            err_sys("fork error");
        }else if(pid==0){//child
            execlp(buf,buf,(char *)0);
            err_ret("couldn't execute :%s ",buf);
            exit(127);
        }
        //parent
        if((pid=waitpid(pid,&status,0))<0)//P179对此函数有着更多的说明
            err_sys("waitpid error");
        printf("%% ");
    }
}



其它问题总结

eclipse下C/C++自动补全

关键就是如下图中的那个Content Assist:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值