C-Execute-Command (summary of responses)

Steve Yelvington steve at thelake.UUCP
Thu Dec 7 05:17:24 AEST 1989


I received many interesting responses to the followup in which I raised a
couple of questions. (Thanks to all who responded.) Here is a summary,
with apologies if I've mangled anybody's explanations:

In article <1103891355263101 at thelake.UUCP> I wrote:

>1. On the net, I often see (non-code) references to functions with numbers
>   inside the parens, as in system(3) and exec(2). 

These numbers refer to sections of the Un*x manual. For non-Un*x
programmers, their primary utility is to serve as a warning that the
writer may be making Un*x assumptions as opposed to MS-DOS or whatever
assumptions. :-)

>2. Can someone explain or (*explain) the differences between the spawn,
>   exec and fork families of process-control functions? K&R 1, Harbison 
>   & Steele, and the lesser reference works that I have are of no help
>   on this issue. What does the new standard include?

The most important thing I learned is this: If you are interested in C
portability, the whole area of process control is a minefield. It is 
heavily dependent on the capabilities of the operating system. The
draft ANSI C standard doesn't provide either spawn or fork/exec.

POSIX addresses the issue, but as Peter da Silva notes (in another msg
thread), 

> POSIX is a standard for the UNIX OS interface. It is not implementable
> on most personal computers, for example. There is a huge gap between 
> what ANSI specifies and what's useful on most systems, and another 
> huge gap between that and POSIX.

Fork/exec/wait is the standard way of calling another program under Unix:
fork() makes an exact duplicate of a running process, running
concurrently; exec() (called by the child) overlays the (child) process
with another program that slips comfortably into its process slot; and
wait() (called by the parent) suspends the parent process until the child
exits.

Since MS-DOS doesn't have a fork() system call, most MS-DOS implementations 
supply the spawn() family of functions to call another process and wait 
for it to terminate without overlaying the current process. Some also
provide exec(), which wipes out the parent -- there is no return, and
wait() with such an implementation won't work.

Some libraries for single-tasking systems (Mark Williams C on the Atari
ST, for instance) provide neither fork nor spawn families. Others (such as
dLibs) attempt to provide as much fork/exec/wait functionality as is
possible in the host environment, but don't use the spawn() method employed
by the MS-DOS compilers.

The system() call is most likely to be portable, although it too is not
without potential trouble. H&S (p.364) notes that it passes its argument
to a command processor for execution in an implementation-defined way. On
most systems, this will load a new command processor (which takes time and
memory). Others may allow the argument to be passed backward to an
original or parent shell.

In ANSI C, system((char*) NULL) should return 0 if there is no command
processor present -- as might be the case with, for example, GEM or the
Macintosh environments. 

I have three C compilers for my machine; running system("Hello") will work
dependably (if the hello program is present) on two of them and fail on
the third unless its proprietary shell is present.

Conclusion: Expect headaches when porting any program that wants to
execute other processes.

-- Steve Yelvington at the (almost frozen enough to skate) lake in Minnesota
   UUCP: ... pwcs.StPaul.GOV!stag!thelake!steve



More information about the Comp.lang.c mailing list