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.
ANSI C
Please refer to http://en.wikipedia.org/wiki/ANSI_C
IEEE POSIX
Please refer to http://en.wikipedia.org/wiki/POSIX
X/Open Portability Guide
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
Unbuffered I/O
Header: unistd.h
Constants: STDIN_FILENO, STDOUT_FILENO and STDERR_FILENO
Functions: open, read, write, lseek, and close
Standard I/O
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.
- #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) {
- 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);
- }
-
- if ((pid = waitpid(pid, &status, 0)) < 0)
- err_sys("waitpid error");
- printf("%% ");
- }
- exit(0);
- }
#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.
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.
- int main(int argc, char *argv[])
- {
- fprintf(stderr, "EACCES: %s\n", strerror(EACCES));
- errno = ENOENT;
- perror(argv[0]);
- exit(0);
- }
int main(int argc, char *argv[])
{
fprintf(stderr, "EACCES: %s\n", strerror(EACCES));
errno = ENOENT;
perror(argv[0]);
exit(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
Clock 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.
User CPU time
The user CPU time is the CPU time attributed to user instructions.
System CPU time
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.