11.2 Redirection

Team-FLY

POSIX handles I/O in a device-independent way through file descriptors. After obtaining an open file descriptor through a call such as open or pipe , the program can execute read or write , using the handle returned from the call. Redirection allows a program to reassign a handle that has been opened for one file to designate another file. (See Section 4.7 for a review of redirection.)

Most shells allow redirection of standard input, standard output and possibly standard error from the command line. Filters are programs that read from standard input and write to standard output. Redirection on the command line allows filters to operate on other files without recompilation.

Example 11.9

The following cat command redirects its standard input to my.input and its standard output to my.output .

 cat < my.input > my.output 

Recall that open file descriptors are inherited on exec calls (unless specifically prevented). For shells this means that the child must redirect its I/O before calling execvp . (After the execvp , the process no longer has access to the variables holding the destination descriptors.)

Program 11.4 shows a version of executecmd that redirects standard input and standard output as designated by the input command line incmd . It calls parseandredirectin and parseandredirectout , which are shown in Program 11.5.

Program 11.4 executecmdredirect.c

A version of executecmd that handles redirection .

 #include <errno.h> #include <stdio.h> #include <unistd.h> int makeargv(const char *s, const char *delimiters, char ***argvp); int parseandredirectin(char *s); int parseandredirectout(char *s); void executecmd(char *incmd) {     char **chargv;     if (parseandredirectout(incmd) == -1)         perror("Failed to redirect output");     else if (parseandredirectin(incmd) == -1)         perror("Failed to redirect input");     else if (makeargv(incmd, " \t", &chargv) <= 0)         fprintf(stderr, "Failed to parse command line\n");     else {         execvp(chargv[0], chargv);         perror("Failed to execute command");     }     exit(1); } 

The parseandredirectin function looks for the standard input redirection symbol < . If the symbol is found, the program replaces it with a string terminator. This removes it from the command. The program then uses strtok to remove leading and trailing blanks and tabs. What is left is the name of the file to use for redirection. The parseandredirectout function works similarly.

Since the version of executecmd in Program 11.4 calls parseandredirectout before parseandredirectin , it assumes that the output redirection appears on the command line after the input redirection.

Exercise 11.10

How does Program 11.2 handle the following command? How would you fix it?

 sort > t.2 < t.1 

Answer:

After the call to parseandredirectout , the > is replaced by a string terminator so the command is just sort . The redirection of standard input is ignored. One way to fix this problem is to use strchr to find the positions of both redirection symbols before handling redirection. If both symbols are present, the redirection corresponding to the one that appears last should be done first.

Link ush2 with executecmdredirect and parseandredirect to obtain a shell that handles simple redirection.

Exercise 11.11

How would ush2 handle redirection from an invalid file?

Answer:

If parseandredirectin or parseandredirectout fails to open the file, the function returns “1 and executecmdredirect does not attempt to execute the command.

Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net