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