UNIX Process Environment

The interface of main function
A startup routine receives argc and argv information from the kernel, and prepares them for the C main program. 
A C process can terminate in the following ways.
Normal
returns from main
calling exit from anywhere
calling _exit from anywhere
Abnormal
calling abort
catch a signal
The exit function terminates a process with cleaning up. For example, like closing open files and flushing standard I/O library buffers.
The _exit function does not do the cleaning.
The status returned by the exit function can be retrieved by the calling program (e.g. a shell). We will talk about this when we get to the exec family later.
Please refer to page 164 for an illustration among these routines.
The command line argument argc and argv let the user communicate with your C program.
UNIX uses the "pointer array" for argument list. Each cell is a pointer and the end of array is detected by a NULL value.
The environment variables
The environment variables set up parameters that how a user wants his working environment to be.
Many application assumes that the user will set up a set of environment variables to indicate the preference of the user.
The shell assume that you keep a list of directory for commands in PATH.
The groff allows you to specify the default typesetter by GROFF_TYPESETTER.
The data structure is again a pointer array, with starting address at environ.
Now write a program to do the work of "printenv" in csh.
Programming interface
getenv
Obtain the value of an environment variable.
putenv
Put a new environment variable assignment into the list.
setenv
Assign a new value to a specified environment variable.
unsetenv
Remove an environment variable.
The C runtime environment
A C program requires the following items in memory to run.
A text segment for the program
This is usually read-only.
An initialized data segment, 
For global data that are initialized by the program.
An uninitialized data segment.
The operating system will clean them to 0.
A stack for all local variables.
This grows from the stack and may contain any values.
A heap for all dynamically allocated memory.
From malloc, etc.
We can use the command size to see the size of text, initialized, and uninitialized data segment.
Shared library
It would waste both disk and memory space if we put the code and data of a library into an executable. This is called static linking.
A better way is to put a place holder (or stub function) where the library function will be called (dynamic linking). This reduces the disk requirement to store the executable.
When the program is executed, the stub function will realized that no where in emery the library routine can be found, and the operating system should load it now.
Two processes using the same library can share a single copy of library code image.
Let's compile a program in these two different ways. The details can be found in gcc manual page (-static v.s. -dynamic option).
Memory allocation routines
Be sure to check the return value of these routines. A NULL indicates that the memory requirement cannot be fulfilled. Also the return type is  void*, so it can be assigned to any pointer.
malloc
Allocate a properly aligned memory of specified size.
calloc
Allocate a memory for a specified number of specified size.
realloc
Adjust the size of the memory allocated.
This routine may move the memory around to achieve the bigger size.
free
Return the space back to the pool.
These allocation functions call sbrk system call to increase the heap size if nencessary.
Resource limits for a process
The resources that can be used by a process is limited.
Core size
CPU time
Data size
File size
Number of open file
Number of processes created
Stack size
We can use "limit" under csh to find out and adjust these limits. See the manual page of csh for details.
There are a set of API that can adjust these limits.
getrlimit
Get the current limit. There are two kinds of limits -- soft and hard.
setrlimit
Hard limit can only be lowered. Only a super user can raise the limit.