Process
creation on Unix-like machines is normally done in two stages. Firstly, fork()
is
called. This creates a child process, which is a clone of the calling (parent)
process. The child process is identical (except for a few details) to the
parent. Secondly, a call to one of the exec()
family functions
is invoked by the child which changes the program being executed by that process.
For more information about fork()
or exec()
,
see Open Group.
P.I.P.S.
does not support fork()
and exec()
and the
reasons for the same are described in the following sections. However, there
are industry standard alternatives supported by P.I.P.S. and are detailed
in the following sections:
Omission of fork()
A Unix-like kernel is designed with the two stage process creation in mind. On the Symbian platform (and Microsoft Windows®), the kernel was designed to create a process, which runs a single executable, in a single step.
P.I.P.S. does not implement
the fork()
operation because this would require an entirely
new way of dealing with processes in the kernel and memory model. For example,
duplicating the address space of an existing process was not something that
was considered in the Symbian platform kernel's design. Symbian took this
decision as the effort involved in customising this feature would be more
than the benefit of providing the fork()
function, especially
in the provision of Pthreads. For more information about Pthreads, see the Pthread
Wikipage.
Omission of exec()
On Unix-like systems, exec()
is
the standard way to load a process image into memory. Only the initialisation
process is loaded directly into a new address space (special case code in
the kernel), all other processes are loaded into an existing address space
which was initially created by forking.
On the Symbian
platform, the only way to load a process image into memory is using the loader.
It assumes that the image is being loaded as a new process - one that owns
no resources, has no open handles and so on. The change to the loader and
any associated kernel changes, to support the exec()
function
were deemed to be too risky.
Generic IPC
P.I.P.S. supports two types of Inter-Process Communication (IPC) between processes or threads:
Pipes (named and unnamed): Unnamed pipes are created using pipe() and named pipes are created using mkfifo(). Pipe-based communication is also possible between a parent and a child process when the child is created using popen() or popen3().
Local file sockets: These correspond to sockets created with AF_LOCAL/PF_LOCAL/AF_UNIX
as
the address family. The semantics of their use are similar to those of their
Unix equivalents.
fork()
and exec()
while
creating child processes. The scenarios are discussed in the following sections:fork()
, which then does not make a subsequent exec()
call. The result of this is that the parent and child processes
run the same executable. The child may communicate with the parent
using pipes. One example of a system which does this is the email
software program Exim (www.exim.org). In addition to forking without exec()
, it can also re-exec()
itself to
regain dropped root privileges.