天天看点

读书笔记 -《Advanced Programming in the UNIX Env》- (1)

1. Standards

The proliferation of different versions of Unix during the 1980s has been tempered by the various international standards that were started during the late 1980s. These include the ANSI standard for the C programming language, the IEEE POSIX family (still being developed), and the X/Open portability guide.

Please refer to http://en.wikipedia.org/wiki/ANSI_C

Please refer to http://en.wikipedia.org/wiki/POSIX

Please refer to http://en.wikipedia.org/wiki/X/Open

2. Architecture of the UNIX operating system

Kernal ------>> System Call(POSIX API) ------>> Shell         ------>> Application

                                                                       ------>> Libraray Routines    ------>> Application

                                                                       ------>> Application    

For more vavid diagram, please see the p_w_upload #1.

3. Standard Input, Standard Output, and Standard Error

Header: unistd.h

Constants: STDIN_FILENO, STDOUT_FILENO and STDERR_FILENO

Functions:  open, read, write, lseek, and close

Header: stdio.h

Constants: stdin, stdout, stderr, EOF

Functions: printf, getc and putc

4. fork and execlp

We call fork to create a new process, which is a copy of the caller. We say that the caller is the parent and that the newly created process is the child. Then fork returns the non-negative process ID of the new child process to the parent, and returns 0 to the child. Because fork creates a new process, we say that it is called onceby the parentbut returns twicein the parent and in the child.

In the child, we call execlp to execute the command that was read from the standard input. This replaces the child process with the new program file. The combination of a fork, followed by an exec, is what some operating systems call spawning a new process. In the UNIX System, the two parts are separated into individual functions. We'll have a lot more to say about these functions in Chapter 8.

Because the child calls execlp to execute the new program file, the parent wants to wait for the child to terminate. This is done by calling waitpid, specifying which process we want to wait for: the pid argument, which is the process ID of the child. The waitpid function also returns the termination status of the childthe status variablebut in this simple program, we don't do anything with this value. We could examine it to determine exactly how the child terminated.

C代码

#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) {  /*Fork starts a new process, the new process is a copy of the current process. Then fork returns the non-negative process ID of the new child process to the parent, and returns 0 to the child.*/  

            err_sys("fork error");   

        } else if (pid == 0) {      /* child */ /*The child process gets the pid == 0, so goes here.*/  

            execlp(buf, buf, (char *)0);   

            err_ret("couldn't execute: %s", buf); /*If execlp runs successfully, it exit the process. If not, it goes here.*/  

            exit(127);   

        }   

        /* parent */ /*The parent process gets the pid > 0, so goes here.*/  

        if ((pid = waitpid(pid, &status, 0)) < 0)   

            err_sys("waitpid error");   

        printf("%% ");   

    }   

    exit(0);   

}   

5. Error processing function

char *strerror(int errnum);

This function maps errnum, which is typically the errno value, into an error message string and returns a pointer to the string.

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.

int main(int argc, char *argv[])   

    fprintf(stderr, "EACCES: %s\n", strerror(EACCES));   

    errno = ENOENT;   

    perror(argv[0]);   

}  

6. How to process signal?

    int signal(SIGINT, sig_int)

    SIGINT: Interupt Signal by Ctrl + C/Delete.

    void sig_int(int signo)

    sig_int is a function to receive the signal.

7. Time

The clock time, sometimes called wall clock time, is the amount of time the process takes to run, and its value depends on the number of other processes being run on the system.

The user CPU time is the CPU time attributed to user instructions.

The system CPU time is the CPU time attributed to the kernel when it executes on behalf of the process.

8. The relation between System Calls and Library Functions.

For more vavid diagram, please see the p_w_upload #2.