#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);
}
编译生成ls1文件,运行:
# ./ls1 .. // 列出上一级目录中的所有文件
The opendir function returns a pointer to a DIR structure, and we pass this pointer to the readdir function. We don't care what's in the DIR structure. We then call readdir in a loop, to read each directory entry. The readdir function returns a pointer to a dirent structure or, when it's finished with the directory, a null pointer. All we examine in the dirent structure is the name of each directory entry (d_name). Using this name, we could then call the stat function (Section 4.2) to determine all the attributes of the file.
程序清单1-2:将标准输入复制到标准输出
#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);
}
The constants STDIN_FILENO and STDOUT_FILENO are defined in <unistd.h> and specify the file descriptors for standard input and standard output. These values are typically 0 and 1, respectively, but we'll use the new names for portability.
程序清单1-3:用标准I/O将标准输入复制到标准输出
#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);
}
The function getc reads one character at a time, and this character is written by putc. After the last byte of input has been read, getc returns the constant EOF (defined in <stdio.h>). The standard I/O constants stdin and stdout are also defined in the <stdio.h> header and refer to the standard input and standard output.
程序清单1-4:打印进程ID
#include "apue.h"
int
main(void)
{
printf("hello world from process ID %d\n", getpid());
exit(0);
}
程序清单1-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);
}
If we run this program, we get the following results. Note that our program has a different promptthe percent signto distinguish it from the shell's prompt.
$ ./a.out
% date
Sun Aug 1 03:04:47 EDT 2004 programmers work late
% who
sar :0 Jul 26 22:54
sar pts/0 Jul 26 22:54 (:0)
sar pts/1 Jul 26 22:54 (:0)
sar pts/2 Jul 26 22:54 (:0)
% pwd
/home/sar/bk/apue/2e
% ls
Makefile
a.out
shell1.c
% ^D type the end-of-file character
$ the regular shell prompt
The most fundamental limitation of this program is that we can't pass arguments to the command that we execute.
If this program is compiled into the file a.out, we have
$ ./a.out
EACCES: Permission denied
./a.out: No such file or directory
There are two rules to be aware of with respect to errno. First, its value is never cleared by a routine if an error does not occur. Therefore, we should examine its value only when the return value from a function indicates that an error occurred. Second, the value of errno is never set to 0 by any of the functions, and none of the constants defined in <errno.h> has a value of 0.
Two functions are defined by the C standard to help with printing error messages.
#include <string.h>
char *strerror(int errnum);
Returns: pointer to message string
This function maps errnum, which is typically the errno value, into an error message string and returns a pointer to the string.
The perror function produces an error message on the standard error, based on the current value of errno, and returns.
#include <stdio.h>
void perror(const char *msg);
It outputs the string pointed to by msg, followed by a colon and a space, followed by the error message corresponding to the value of errno, followed by a newline.
To catch this signal, the program needs to call the signal function, specifying the name of the function to call when the SIGINT signal is generated. The function is named sig_int; when it's called, it just prints a message and a new prompt.