unix环境高级编程学习笔记(一)

图1-3 ls命令简单实现

#include "apue.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);
        exit(0);

}

在这里插入图片描述
C语言opendir()函数:打开目录函数
C语言readdir()函数:读取目录函数

图1-4 从标准输入读,并向标准输出写

#include "apue.h"

#define BUFFSIZE 4096

int main(void)
{
        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");

        exit(0);

}

在这里插入图片描述
如果愿意从标准输入读,并向标准输出写,则图1.4的程序可用于复制任一UNIX普通文件

把输出的东西放到data文件里
在这里插入图片描述
在这里插入图片描述

图1.5 跟图1.4功能差不多一样

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

在这里插入图片描述
图1.5的程序也能复制任一UNIX普通文件
STDIN_FILENO的作用及与stdin 的区别

int ferror(FILE * stream);

The function ferror() tests the error indicator for the stream pointed to by stream, returning nonzero if it is set. The error indicator can be reset only by the clearerr() function.

函数ferror()用于测试所指向的流的错误指示器,如果设置了,则返回非零。误差指示器可以只能由clearerr()函数重置。

图1.6 打印进程ID

#include "apue.h"

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

在这里插入图片描述
调用了函数getpid得到进程id,getpid返回一个pid_t数据类型。我不知道它的大小,只知道标准会保证它能保存在一个long中。所以需要强制转换,虽然PID可以用int表示,但用long可以提高移植性。

图1.7 UNIX系统的进程控制功能简单的程序说明

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

int main(void)
{
        char  buf[MAXLINE];
        pid_t pid;
        int   status;

        printf("%% ");
        while (fgets(buf, MAXLINE, stdin) != NULL)
        {
        		//因为execlp函数要求的参数是以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);
}

在这里插入图片描述
输入文件结束符(Ctrl + D)结束
EOF = -1
MAXLINE = 4096

从标准输入中读取一行数据到缓冲区buf中
原型 char * fgets(char * s, int n,FILE *stream);
参数:
s: 字符型指针,指向存储读入数据的缓冲区的地址。
n: 从流中读入n-1个字符
stream : 指向读取的流。

返回值:

  1. 当n<=0 时返回NULL,即空指针。
  2. 当n=1 时,返回空串"".
  3. 如果读入成功,则返回缓冲区的地址。
  4. 如果读入错误或遇到文件结尾(EOF),则返回NULL.

代码逻辑:
这是我理解的,有啥不对的指正一下,循环判断是否有输入,有输入放到buf里面,没输入就会一直等待不会进到循环里,第一个if是因为execlp函数要求的参数是以null结束而不是以换行符结束。第二个if是创建一个一个子进程,然后父进程等待子进程结束,子进程通过execlp 从PATH 环境变量中查找文件并执行,找到直接退出没有返回,没找到就err_ret打印,然后子进程退出,父进程继续等待输入。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小阿大:)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值