#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); }
终端执行
./fig1.3.out ./
可以打印出当前目录下的文件/目录
其中argc表示运行时指定的参数的个数,argv数组保存参数的内容,如果没有参数,argv[0]为执行文件的文件名,argc=1。
我们先不关心DIR以及dirent结构的具体内容,仅观察其中的函数调用
opendir函数以一个目录名为参数,返回一个DIR类型的指针。
readdir函数以一个DIR类型的指针为参数,返回一个dirent类型的指针
dirp->d_name返回目录项的名字
整个函数模拟了ls命令
Unbuffered I/O函数通常有:
open, read, write, lseek, 和close
#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); }
终端执行:
./fig1.4.out < infile > outfile
#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); }
getc函数一次从标准输入读1个字符,putc函数将字符c输出至标准输出。
进程:
getpid()函数返回当前进程的进程id
三个主要的进程操作函数分别是:fork,exec,waitpid。相关的使用方法如下:
#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); }
fgets函数从标准输入读取一行。
注意要将换行符改变成字符串终结符'\0'
int execlp(const char * file,const char * arg,...,(char *)0);
execlp函数会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果用常数0来表示一个空指针。
fork()函数产生一个当前进程的复制进程作为子进程
返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
pid_t waitpid(pid_t pid,int * status,int options);
waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程
结束。如果在调用 waitpid()时子进程已经结束,则 waitpid()会立即
返回子进程结束状态值。
参数pid为等待的子进程id,status接受子进程结束的状态值,返回值为子进程id