APUE学习(一)基础知识

本文通过多个C语言代码示例展示了UNIX环境下文件操作、进程控制及信号处理等核心功能,包括模拟ls命令、读写标准输入输出、获取进程ID、执行外部命令、处理信号中断等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


代码段一:

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

make后在../lib生成libapue.a,然后

gcc ls1.c    -L ../lib -lapue -I ../include/
连接库和头文件,可以模拟ls命令,
man 1 ls //查看命令都是man 1

exit()通常用0表示正常终止

代码段二:

#include "apue.h"

#define BUFFSIZE 4096

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

gcc iotest.c -L ../lib -lapue -I ../include/

输入什么就得到什么输出

stdin,stdout,stderr是行缓冲的,回车刷新,可以使用>或>>重定向到文件

系统io是不带缓冲的,例如read,write,lseek,open,close

标准io是带缓冲的,例如fprint,fread,fwrite

代码段三:

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

效果同上

代码段4

#include "apue.h"

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

运行

sun@sun-PC:~/Downloads/linux/UNIX环境高级编程.tar/apue.3e/intro$ gcc hello.c -L ../lib/ -lapue -I ../include/
sun@sun-PC:~/Downloads/linux/UNIX环境高级编程.tar/apue.3e/intro$ ./a.out
hello world from process ID 13135,parent process ID 22719
sun@sun-PC:~/Downloads/linux/UNIX环境高级编程.tar/apue.3e/intro$ ps -aux |grep 22719
sun      13151  0.0  0.0  14540  1044 pts/0    S+   19:14   0:00 grep 22719
sun      22719  0.0  0.0  22940  4760 pts/0    Ss   16:47   0:00 /bin/bash

代码段5

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

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

    printf("%% ");  /* print prompt (printf requires %% to print %) */
    while (fgets(buf, MAXLINE, stdin) != NULL) {
        if (buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = 0; /* replace newline with null */

        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)
            err_sys("waitpid error");
        printf("%% ");
    }
    exit(0);
}

运行:

sun@sun-PC:~/Downloads/linux/UNIX环境高级编程.tar/apue.3e/intro$ ./a.out
% date
Tue May  1 19:46:56 CST 2018
% pwd
/home/sun/Downloads/linux/UNIX环境高级编程.tar/apue.3e/intro
% abcde
couldn't execute: abcde: No such file or directory
% sun@sun-PC:~/Downloads/linux/UNIX环境高级编程.tar/apue.3e/intro$

extern int execlp (const char *__file, const char *__arg, ...)

execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名, 找到后便执行该文件, 然后将第二个以后的参数当做该文件的argv[0]、argv[1]……, 最后一个参数必须用空指针(NULL)作结束,例如

execlp("ls","ls","-al","/zhmc",(char *)0);

waitpid(pid_t pid,int* status,int option);阻塞等待进程号为pid的子线程结束,并回收进程号等资源

代码段6

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

int
main(int argc, char *argv[])
{
    fprintf(stderr, "EACCES: %s\n", strerror(EACCES));
    errno = ENOENT;
    perror(argv[0]);
    exit(0);
}

运行

sun@sun-PC:~/Downloads/linux/UNIX环境高级编程.tar/apue.3e/intro$ gcc testerror.c -L ../lib/ -lapue -I ../include/
sun@sun-PC:~/Downloads/linux/UNIX环境高级编程.tar/apue.3e/intro$ ./a.out
EACCES: Permission denied
./a.out: No such file or directory

int fprintf (FILE* stream, const char*format, [argument])

char*  strerror(int erorno);

void perror(char*);

代码段7

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
        uid_t uid=getuid();
        gid_t gid=getgid();
        printf("uid:%d,gid:%d\n",(int)uid,(int)gid);
        return 0;
}

运行:

[root@localhost apue]# ./a.out
uid:0,gid:0
[root@localhost apue]# su sun
[sun@localhost apue]$ ./a.out
uid:500,gid:500
代码段8
#include "apue.h"
#include <sys/wait.h>

static void sig_int(int);       /* our 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("%% ");  /* print prompt (printf requires %% to print %) */
    while (fgets(buf, MAXLINE, stdin) != NULL) {
        if (buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = 0; /* replace newline with null */

        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)
            err_sys("waitpid error");
        printf("%% ");
    }
    exit(0);
}

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

其中signal()如下

#include "apue.h"

/* Reliable version of signal(), using POSIX sigaction(). */
Sigfunc *
signal(int signo, Sigfunc *func)
{
    struct sigaction    act, oact;

    act.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if (signo == SIGALRM) {
#ifdef  SA_INTERRUPT
        act.sa_flags |= SA_INTERRUPT;
#endif
    } else {
        act.sa_flags |= SA_RESTART;
    }
    if (sigaction(signo, &act, &oact) < 0)
        return(SIG_ERR);
    return(oact.sa_handler);
}

信号详说






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值