When a process wants to
spawn a sub-process called the child,
it uses the system call fork.
All fork does is make a copy of the parent process,
so that the child is identical to the parent,
except for the process ID and a couple
of other minor things.
So the child gets unique process ID,
and the fork returns zero to
the child and returns that new PID to the parent,
so the parent knows the PID of the child.
If the parent has any files open,
the child has the moment as well.
If the files have
been partially read or partially written,
when the child tries to read or write them,
it picks up where the parent left off.
There is a way to stop this which we'll mention later on,
but in general unless it's explicitly stopped,
the file descriptors are inherited.
Now, there are time and utilization
information for each process
that's stored with the process.
Those are reset to zero when the child starts,
because the child is not using any resources,
and it hasn't started running yet.
As soon as it starts running,
as soon as it grabbed some memory,
those resources and timing will change.
Now, the child is a copy of the parent,
but usually you don't want that.
Usually you want to run a program.
So you're spawning a child and going to
a different program than
the one you ran to get the parent.
For that, you use a system call called execve
and there are an awful lot of versions of this: execl ,
execlp, execle, execv, and so forth,
but all of them function essentially the same.
Now, when you use execv to run a program,
it overlays the current process.
So the current process says
memory and instructions and everything go away.
The program you're overlaying starts up.
Now, in general, the way you do this is by
giving the name of the program you
want to run. That's execve.
However, in some cases, you may have it open,
and the reason for this we'll talk about later on.
If it is open, you can simply run fexecve and give it
the file descriptor of the executable
that you've got open and that you want to run.
Now, in both cases, execve, or fexecve,
when you call that function,
a system call, the first thing
the system does is check to be
sure that the file is executable.
If the file is not executable, it fails.
If the file is executable,
since it has to be loaded into memory,
it's got to be read.
So if you don't have read permission,
you have to open it with a special
flag O_ EXEC to tell the system,
"Look, this is going
into my memory, but I'm not reading it.
I'm replacing the current process that's running
so don't worry about not having read permission,
I'm just going to execute it."
Also it inherits the environment of the parent,
unless the parent changes that environment,
and that's what the e and execve stands for.
Execve allows the parent to change the environment.
On the next slide, we see how to do this.
When you're writing a program in C,
you see main, and then main takes three arguments.
The first one is the number of arguments.
The second one is an array of those arguments.
It's basically an array of pointers,
and the last pointer is null,
indicating the end of the array.
The third argument is ENVP,
which contains the environment variables and a list,
and of course, the array itself
is an array of pointers to
the individual environment variables, and the values.
Again, it's null-terminated.
The zeroth argument in
the second of the second array argv,
is simply the name by which the program was invoked.
So you can tell,
for example, if you have a program
that you want to treat differently,
if it begins with an argc,
you can tell that by looking at
the first character of argv zero.
Now, with the environment variables,
there are a couple of things you need to be aware
of. There is no checking.
So if the environment variable,
value, or the name,
or the combination of the two name equals value is
now formed, doesn't matter.
It just goes right into that array and
gets passed down to the child.
If you don't have that,
and you need to get to the environment variables,
there's a global variable called char environ,
which is also a pointer
to an array of the pointers to characters.
It works just like ENVP.