Annotation of 43BSDReno/share/doc/ps2/03.uprog/p5, revision 1.1.1.1

1.1       root        1: .\"    @(#)p5  6.3 (Berkeley) 5/10/86
                      2: .\"
                      3: .NH
                      4: PROCESSES
                      5: .PP
                      6: It is often easier to use a program written
                      7: by someone else than to invent one's own.
                      8: This section describes how to
                      9: execute a program from within another.
                     10: .NH 2
                     11: The ``System'' Function
                     12: .PP
                     13: The easiest way to execute a program from another
                     14: is to use
                     15: the standard library routine
                     16: .UL system .
                     17: .UL system
                     18: takes one argument, a command string exactly as typed
                     19: at the terminal
                     20: (except for the newline at the end)
                     21: and executes it.
                     22: For instance, to time-stamp the output of a program,
                     23: .P1
                     24: main()
                     25: {
                     26:        system("date");
                     27:        /* rest of processing */
                     28: }
                     29: .P2
                     30: If the command string has to be built from pieces,
                     31: the in-memory formatting capabilities of
                     32: .UL sprintf
                     33: may be useful.
                     34: .PP
                     35: Remember than
                     36: .UL getc
                     37: and
                     38: .UL putc
                     39: normally buffer their input;
                     40: terminal I/O will not be properly synchronized unless
                     41: this buffering is defeated.
                     42: For output, use 
                     43: .UL fflush ;
                     44: for input, see
                     45: .UL setbuf 
                     46: in the appendix.
                     47: .NH 2
                     48: Low-Level Process Creation \(em Execl and Execv
                     49: .PP
                     50: If you're not using the standard library,
                     51: or if you need finer control over what
                     52: happens,
                     53: you will have to construct calls to other programs
                     54: using the more primitive routines that the standard
                     55: library's
                     56: .UL system
                     57: routine is based on.
                     58: .PP
                     59: The most basic operation is to execute another program
                     60: .ul
                     61: without
                     62: .IT returning ,
                     63: by using the routine
                     64: .UL execl  .
                     65: To print the date as the last action of a running program,
                     66: use
                     67: .P1
                     68: execl("/bin/date", "date", NULL);
                     69: .P2
                     70: The first argument to
                     71: .UL execl
                     72: is the
                     73: .ul
                     74: file name
                     75: of the command; you have to know where it is found
                     76: in the file system.
                     77: The second argument is conventionally
                     78: the program name
                     79: (that is, the last component of the file name),
                     80: but this is seldom used except as a place-holder.
                     81: If the command takes arguments, they are strung out after
                     82: this;
                     83: the end of the list is marked by a 
                     84: .UL NULL
                     85: argument.
                     86: .PP
                     87: The
                     88: .UL execl
                     89: call
                     90: overlays the existing program with
                     91: the new one,
                     92: runs that, then exits.
                     93: There is
                     94: .ul
                     95: no
                     96: return to the original program.
                     97: .PP
                     98: More realistically,
                     99: a program might fall into two or more phases
                    100: that communicate only through temporary files.
                    101: Here it is natural to make the second pass
                    102: simply an
                    103: .UL execl
                    104: call from the first.
                    105: .PP
                    106: The one exception to the rule that the original program never gets control
                    107: back occurs when there is an error, for example if the file can't be found
                    108: or is not executable.
                    109: If you don't know where
                    110: .UL date
                    111: is located, say
                    112: .P1
                    113: execl("/bin/date", "date", NULL);
                    114: execl("/usr/bin/date", "date", NULL);
                    115: fprintf(stderr, "Someone stole 'date'\en");
                    116: .P2
                    117: .PP
                    118: A variant of
                    119: .UL execl
                    120: called
                    121: .UL execv
                    122: is useful when you don't know in advance how many arguments there are going to be.
                    123: The call is
                    124: .P1
                    125: execv(filename, argp);
                    126: .P2
                    127: where
                    128: .UL argp
                    129: is an array of pointers to the arguments;
                    130: the last pointer in the array must be 
                    131: .UL NULL
                    132: so
                    133: .UL execv
                    134: can tell where the list ends.
                    135: As with
                    136: .UL execl ,
                    137: .UL filename
                    138: is the file in which the program is found, and
                    139: .UL argp[0]
                    140: is the name of the program.
                    141: (This arrangement is identical to the
                    142: .UL argv
                    143: array for program arguments.)
                    144: .PP
                    145: Neither of these routines provides the niceties of normal command execution.
                    146: There is no automatic search of multiple directories \(em
                    147: you have to know precisely where the command is located.
                    148: Nor do you get the expansion of metacharacters like
                    149: .UL < ,
                    150: .UL > ,
                    151: .UL * ,
                    152: .UL ? ,
                    153: and
                    154: .UL []
                    155: in the argument list.
                    156: If you want these, use
                    157: .UL execl
                    158: to invoke the shell
                    159: .UL sh ,
                    160: which then does all the work.
                    161: Construct a string
                    162: .UL commandline
                    163: that contains the complete command as it would have been typed
                    164: at the terminal, then say
                    165: .P1
                    166: execl("/bin/sh", "sh", "-c", commandline, NULL);
                    167: .P2
                    168: The shell is assumed to be at a fixed place,
                    169: .UL /bin/sh .
                    170: Its argument
                    171: .UL -c
                    172: says to treat the next argument
                    173: as a whole command line, so it does just what you want.
                    174: The only problem is in constructing the right information
                    175: in
                    176: .UL commandline .
                    177: .NH 2
                    178: Control of Processes \(em Fork and Wait
                    179: .PP
                    180: So far what we've talked about isn't really all that useful by itself.
                    181: Now we will show how to regain control after running
                    182: a program with
                    183: .UL execl
                    184: or
                    185: .UL execv .
                    186: Since these routines simply overlay the new program on the old one,
                    187: to save the old one requires that it first be split into
                    188: two copies;
                    189: one of these can be overlaid, while the other waits for the new,
                    190: overlaying program to finish.
                    191: The splitting is done by a routine called
                    192: .UL fork :
                    193: .P1
                    194: proc_id = fork();
                    195: .P2
                    196: splits the program into two copies, both of which continue to run.
                    197: The only difference between the two is the value of
                    198: .UL proc_id ,
                    199: the ``process id.''
                    200: In one of these processes (the ``child''),
                    201: .UL proc_id
                    202: is zero.
                    203: In the other
                    204: (the ``parent''),
                    205: .UL proc_id
                    206: is non-zero; it is the process number of the child.
                    207: Thus the basic way to call, and return from,
                    208: another program is
                    209: .P1
                    210: if (fork() == 0)
                    211:        execl("/bin/sh", "sh", "-c", cmd, NULL);        /* in child */
                    212: .P2
                    213: And in fact, except for handling errors, this is sufficient.
                    214: The
                    215: .UL fork
                    216: makes two copies of the program.
                    217: In the child, the value returned by
                    218: .UL fork
                    219: is zero, so it calls
                    220: .UL execl
                    221: which does the
                    222: .UL command
                    223: and then dies.
                    224: In the parent,
                    225: .UL fork
                    226: returns non-zero
                    227: so it skips the
                    228: .UL execl.
                    229: (If there is any error,
                    230: .UL fork
                    231: returns
                    232: .UL -1 ).
                    233: .PP
                    234: More often, the parent wants to wait for the child to terminate
                    235: before continuing itself.
                    236: This can be done with
                    237: the function
                    238: .UL wait :
                    239: .P1
                    240: int status;
                    241: 
                    242: if (fork() == 0)
                    243:        execl(...);
                    244: wait(&status);
                    245: .P2
                    246: This still doesn't handle any abnormal conditions, such as a failure
                    247: of the
                    248: .UL execl
                    249: or
                    250: .UL fork ,
                    251: or the possibility that there might be more than one child running simultaneously.
                    252: (The
                    253: .UL wait
                    254: returns the
                    255: process id
                    256: of the terminated child, if you want to check it against the value
                    257: returned by
                    258: .UL fork .)
                    259: Finally, this fragment doesn't deal with any
                    260: funny behavior on the part of the child
                    261: (which is reported in
                    262: .UL status ).
                    263: Still, these three lines
                    264: are the heart of the standard library's
                    265: .UL system
                    266: routine,
                    267: which we'll show in a moment.
                    268: .PP
                    269: The
                    270: .UL  status 
                    271: returned by
                    272: .UL wait
                    273: encodes in its low-order eight bits
                    274: the system's idea of the child's termination status;
                    275: it is 0 for normal termination and non-zero to indicate
                    276: various kinds of problems.
                    277: The next higher eight bits are taken from the argument
                    278: of the call to
                    279: .UL exit
                    280: which caused a normal termination of the child process.
                    281: It is good coding practice
                    282: for all programs to return meaningful
                    283: status.
                    284: .PP
                    285: When a program is called by the shell,
                    286: the three file descriptors
                    287: 0, 1, and 2 are set up pointing at the right files,
                    288: and all other possible file descriptors
                    289: are available for use.
                    290: When this program calls another one,
                    291: correct etiquette suggests making sure the same conditions
                    292: hold.
                    293: Neither
                    294: .UL fork
                    295: nor the
                    296: .UL exec
                    297: calls affects open files in any way.
                    298: If the parent is buffering output
                    299: that must come out before output from the child,
                    300: the parent must flush its buffers
                    301: before the
                    302: .UL execl .
                    303: Conversely,
                    304: if a caller buffers an input stream,
                    305: the called program will lose any information
                    306: that has been read by the caller.
                    307: .NH 2
                    308: Pipes
                    309: .PP
                    310: A
                    311: .ul
                    312: pipe
                    313: is an I/O channel intended for use
                    314: between two cooperating processes:
                    315: one process writes into the pipe,
                    316: while the other reads.
                    317: The system looks after buffering the data and synchronizing
                    318: the two processes.
                    319: Most pipes are created by the shell,
                    320: as in
                    321: .P1
                    322: ls | pr
                    323: .P2
                    324: which connects the standard output of
                    325: .UL ls
                    326: to the standard input of
                    327: .UL pr .
                    328: Sometimes, however, it is most convenient
                    329: for a process to set up its own plumbing;
                    330: in this section, we will illustrate how
                    331: the pipe connection is established and used.
                    332: .PP
                    333: The system call
                    334: .UL pipe
                    335: creates a pipe.
                    336: Since a pipe is used for both reading and writing,
                    337: two file descriptors are returned;
                    338: the actual usage is like this:
                    339: .P1
                    340: int    fd[2];
                    341: 
                    342: stat = pipe(fd);
                    343: if (stat == -1)
                    344:        /* there was an error ... */
                    345: .P2
                    346: .UL fd
                    347: is an array of two file descriptors, where
                    348: .UL fd[0]
                    349: is the read side of the pipe and
                    350: .UL fd[1] 
                    351: is for writing.
                    352: These may be used in
                    353: .UL read ,
                    354: .UL write
                    355: and
                    356: .UL close
                    357: calls just like any other file descriptors.
                    358: .PP
                    359: If a process reads a pipe which is empty,
                    360: it will wait until data arrives;
                    361: if a process writes into a pipe which
                    362: is too full, it will wait until the pipe empties somewhat.
                    363: If the write side of the pipe is closed,
                    364: a subsequent
                    365: .UL  read 
                    366: will encounter end of file.
                    367: .PP
                    368: To illustrate the use of pipes in a realistic setting,
                    369: let us write a function called
                    370: .UL popen(cmd,\ mode) ,
                    371: which creates a process
                    372: .UL cmd
                    373: (just as
                    374: .UL system 
                    375: does),
                    376: and returns a file descriptor that will either
                    377: read or write that process, according to 
                    378: .UL mode .
                    379: That is,
                    380: the call
                    381: .P1
                    382: fout = popen("pr", WRITE);
                    383: .P2
                    384: creates a process that executes
                    385: the
                    386: .UL pr
                    387: command;
                    388: subsequent
                    389: .UL write
                    390: calls using the file descriptor
                    391: .UL fout
                    392: will send their data to that process
                    393: through the pipe.
                    394: .PP
                    395: .UL popen
                    396: first creates the
                    397: the pipe with a
                    398: .UL pipe
                    399: system call;
                    400: it then
                    401: .UL fork s
                    402: to create two copies of itself.
                    403: The child decides whether it is supposed to read or write,
                    404: closes the other side of the pipe,
                    405: then calls the shell (via
                    406: .UL execl )
                    407: to run the desired process.
                    408: The parent likewise closes the end of the pipe it does not use.
                    409: These closes are necessary to make end-of-file tests work properly.
                    410: For example, if a child that intends to read
                    411: fails to close the write end of the pipe, it will never
                    412: see the end of the pipe file, just because there is one writer
                    413: potentially active.
                    414: .P1
                    415: #include <stdio.h>
                    416: 
                    417: #define        READ    0
                    418: #define        WRITE   1
                    419: #define        tst(a, b)       (mode == READ ? (b) : (a))
                    420: static int     popen_pid;
                    421: 
                    422: popen(cmd, mode)
                    423: char   *cmd;
                    424: int    mode;
                    425: {
                    426:        int p[2];
                    427: 
                    428:        if (pipe(p) < 0)
                    429:                return(NULL);
                    430:        if ((popen_pid = fork()) == 0) {
                    431:                close(tst(p[WRITE], p[READ]));
                    432:                close(tst(0, 1));
                    433:                dup(tst(p[READ], p[WRITE]));
                    434:                close(tst(p[READ], p[WRITE]));
                    435:                execl("/bin/sh", "sh", "-c", cmd, 0);
                    436:                _exit(1);       /* disaster has occurred if we get here */
                    437:        }
                    438:        if (popen_pid == -1)
                    439:                return(NULL);
                    440:        close(tst(p[READ], p[WRITE]));
                    441:        return(tst(p[WRITE], p[READ]));
                    442: }
                    443: .P2
                    444: The sequence of
                    445: .UL close s
                    446: in the child
                    447: is a bit tricky.
                    448: Suppose
                    449: that the task is to create a child process that will read data from the parent.
                    450: Then the first
                    451: .UL close
                    452: closes the write side of the pipe,
                    453: leaving the read side open.
                    454: The lines
                    455: .P1
                    456: close(tst(0, 1));
                    457: dup(tst(p[READ], p[WRITE]));
                    458: .P2
                    459: are the conventional way to associate the pipe descriptor
                    460: with the standard input of the child.
                    461: The 
                    462: .UL close
                    463: closes file descriptor 0,
                    464: that is, the standard input.
                    465: .UL dup
                    466: is a system call that
                    467: returns a duplicate of an already open file descriptor.
                    468: File descriptors are assigned in increasing order
                    469: and the first available one is returned,
                    470: so
                    471: the effect of the
                    472: .UL dup
                    473: is to copy the file descriptor for the pipe (read side)
                    474: to file descriptor 0;
                    475: thus the read side of the pipe becomes the standard input.
                    476: (Yes, this is a bit tricky, but it's a standard idiom.)
                    477: Finally, the old read side of the pipe is closed.
                    478: .PP
                    479: A similar sequence of operations takes place
                    480: when the child process is supposed to write
                    481: from the parent instead of reading.
                    482: You may find it a useful exercise to step through that case.
                    483: .PP
                    484: The job is not quite done,
                    485: for we still need a function
                    486: .UL pclose
                    487: to close the pipe created by
                    488: .UL popen .
                    489: The main reason for using a separate function rather than
                    490: .UL close
                    491: is that it is desirable to wait for the termination of the child process.
                    492: First, the return value from
                    493: .UL pclose
                    494: indicates whether the process succeeded.
                    495: Equally important when a process creates several children
                    496: is that only a bounded number of unwaited-for children
                    497: can exist, even if some of them have terminated;
                    498: performing the
                    499: .UL wait
                    500: lays the child to rest.
                    501: Thus:
                    502: .P1
                    503: #include <signal.h>
                    504: 
                    505: pclose(fd)     /* close pipe fd */
                    506: int fd;
                    507: {
                    508:        register r, (*hstat)(), (*istat)(), (*qstat)();
                    509:        int      status;
                    510:        extern int popen_pid;
                    511: 
                    512:        close(fd);
                    513:        istat = signal(SIGINT, SIG_IGN);
                    514:        qstat = signal(SIGQUIT, SIG_IGN);
                    515:        hstat = signal(SIGHUP, SIG_IGN);
                    516:        while ((r = wait(&status)) != popen_pid && r != -1);
                    517:        if (r == -1)
                    518:                status = -1;
                    519:        signal(SIGINT, istat);
                    520:        signal(SIGQUIT, qstat);
                    521:        signal(SIGHUP, hstat);
                    522:        return(status);
                    523: }
                    524: .P2
                    525: The calls to
                    526: .UL signal
                    527: make sure that no interrupts, etc.,
                    528: interfere with the waiting process;
                    529: this is the topic of the next section.
                    530: .PP
                    531: The routine as written has the limitation that only one pipe may
                    532: be open at once, because of the single shared variable
                    533: .UL popen_pid ;
                    534: it really should be an array indexed by file descriptor.
                    535: A
                    536: .UL popen
                    537: function, with slightly different arguments and return value is available
                    538: as part of the standard I/O library discussed below.
                    539: As currently written, it shares the same limitation.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.