UNIX环境高级编程1-5从标准输入读命令并执行

从标准输入读命令并执行 
隐藏行号 复制代码
  1. // program 1-5 proc/shell1.c
    
  2.   // proc/shell1.c
  3. #include "apue.h"
    
  4. #include <sys/wait.h>
    
  5. int main(void)
    
  6. {
    
  7.     char buf[MAXLINE]; /* from apue.h */
    
  8.     pid_t pid;
    
  9.     int status;
    
  10.     printf("%% "); /* print prompt (printf requires %% to print %) */
    
  11.     // We use the standard I/O function fgets to read one line at a time from the
    
  12.     // standard input. When we type the end-of-file character (which is often
    
  13.     // Control-D) as the first character of a line, fgets returns a null pointer, the loop
    
  14.     // stops, and the process terminates. In Chapter 18, we describe all the special
    
  15.     // terminal characters--end of file, backspace one character, erase entire line, and
    
  16.     // so on -- and how to change them.
    
  17.     // Because each line returned by fgets is terminated with a newline character,
    
  18.     // followed by a null byte, we use the standard C function strlen to calculate the
    
  19.     // length of the string, and then replace the newline with a null byte. We do this
    
  20.     // because the execlp function wants a null-terminated argument, not a
    
  21.     // newline-terminated argument.
    
  22.     // We call fork to create a new process, which is a copy of the caller. We say that
    
  23.     // the caller is the parent and that the newly created process is the child. Then
    
  24.     // fork returns the non-negative process ID of the new child process to the parent,
    
  25.     // and returns 0 to the child. Because fork creates a new process, we say that it is
    
  26.     // called once--by the parent--but returns twice--in the parent and in the child.
    
  27.     // In the child, we call execlp to execute the command that was read from the
    
  28.     // standard input. This replaces the child process with the new program file. The
    
  29.     // combination of fork followed by exec is called spawning a new process on
    
  30.     // some operating systems. In the UNIX System, the two parts are separated into
    
  31.     // individual functions. We'll say a lot more about these functions in Chapter 8.
    
  32.     // Because the child calls execlp to execute the new program file, the parent
    
  33.     // wants to wait for the child to terminate. This is done by calling waitpid,
    
  34.     // specifying which process to wait for: the pid argument, which is the process ID
    
  35.     // of the child. The waitpid function also returns the termination status of the
    
  36.     // child--the status variable--but in this simple program, we don't do anything
    
  37.     // with this value. We could examine it to determine how the child terminated
    
  38.     // The most fundamental limitation of this program is that we can't pass
    
  39.     // arguments to the command we execute. We can't, for example, specify the name
    
  40.     // of a directory to list. We can execute ls only on the working directory. To allow
    
  41.     // arguments would require that we parse the input line, separating the arguments
    
  42.     // by some convention, probably spaces or tabs, and then pass each argument as a
    
  43.     // separate parameter to the execlp function. Nevertheless, this program is still a
    
  44.     // useful demonstration of the UNIX System's process control functions.
    
  45. while (fgets(buf, MAXLINE, stdin) != NULL)
    
  46.     {
    
  47.         if (buf[strlen(buf) - 1] == '\n')
    
  48.         {
    
  49.             buf[strlen(buf) - 1] = 0; /* replace newline with null */
    
  50. }
    
  51.         if ((pid = fork()) < 0)
    
  52.         {
    
  53.             err_sys("fork error");
    
  54.         }
    
  55.         else if (pid == 0)
    
  56.         {   /* child */
    
  57.             // if the execlp execute successfully, execlp will not return
    
  58.             // if it execute failed, return -1, and the error number store in errno variable
    
  59. execlp(buf, buf, (char *)0);
    
  60.             err_ret("couldn't execute: %s", buf);
    
  61.             exit(127);
    
  62.         }
    
  63.         /* parent */
    
  64. if ((pid = waitpid(pid, &status, 0)) < 0)
    
  65.         {
    
  66.             err_sys("waitpid error");
    
  67.         }
    
  68.         printf("%% ");
    
  69.     }
    
  70.     return 0;
    
  71. }
    
  72. 
    

 

 
all: shell1
shell1: shell1.c
	g++ -g -Wall shell1.c ../lib/libapue.a -I ../include -o shell1
clean:
	rm shell1

 

QWM$`)$CNEP[OIR0_IOESBI

{I6RCN309JQ({W24NC2DJ}D

418a519ed94d98c0e33a56dd65a02c8a

posted @ 2015-01-29 16:39  孙永杰  阅读(203)  评论(0)    收藏  举报