PageRenderTime 35ms CodeModel.GetById 12ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 1ms

/share/doc/psd/04.uprog/p5

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