In this chapter, we’ll see how the main function is called when the program is executed, how command-line arguments are passed to the new program, what the typical memory layout looks like, how to allocate additional memory, how the process can use environment variables, and various ways for the process to terminate. Additionally, we’ll look at the longjmp and setjmp functions and their interaction with the stack. We finish the chapter by examining the resource limits of a process.

1 main Function

A C program starts execution with a function called main. The prototype for the main function is

1
int main(int argc, char *argv[]);

2 Process Termination

There are eight ways for a process to terminate. Normal termination occurs in five ways:

  1. Return from main
  2. Calling exit
  3. Calling _exit or _Exit
  4. Return of the last thread from its start routine
  5. Calling pthread_exit from the last thread

Abnormal termination occurs in three ways:

  1. Calling abort
  2. Receipt of a signal
  3. Response of the last thread to a cancellation request

2.1 Exit Functions

Three functions terminate a program normally: _exit and _Exit, which return to the kernel immediately, and exit, which performs certain cleanup processing and then returns to the kernel.

1
2
3
void exit(int status); 
void _Exit(int status);
void _exit(int status);

Historically, the exit function has always performed a clean shutdown of the standard I/O library: the fclose function is called for all open streams.

exit(0) is the same as return(0) from the main function.

2.2 atexit Function

With ISO C, a process can register at least 32 functions that are automatically called by exit. These are called exit handlers and are registered by calling the atexit function.

3 Command-Line Arguments

When a program is executed, the process that does the exec can pass command-line arguments to the new program.

4 Environment List

Each program is also passed an environment list. Like the argument list, the environment list is an array of character pointers, with each pointer containing the address of a null-terminated C string. The address of the array of pointers is contained in the global variable environ:

1
extern char **environ;

For example, if the environment consisted of five strings, it could look like Figure 7.5. Here we explicitly show the null bytes at the end of each string. We’ll call environ the environment pointer, the array of pointers the environment list, and the strings they point to the environment strings.

5 Memory Layout of a C Program

6 Shared Libraries

Shared libraries remove the common library routines from the executable file, instead maintaining a single copy of the library routine somewhere in memory that all processes reference.This reduces the size of each executable file but may add some runtime overhead, either when the program is first executed or the first time each shared library function is called. Another advantage of shared libraries is that library functions can be replaced with new versions without having to relink edit every program that uses the library (assuming that the number and type of arguments haven’t changed).

7 Memory Allocation

ISO C specifies three functions for memory allocation:

  1. malloc, which allocates a specified number of bytes of memory. The initial value of the memory is indeterminate.
  2. calloc, which allocates space for a specified number of objects of a specified size. The space is initialized to all 0 bits.
  3. realloc, which increases or decreases the size of a previously allocated area.
1
2
3
void *malloc(size_t size);
void *calloc(size_t nobj, size_t size);
void *realloc(void *ptr, size_t newsize);

8 Environment Variables

the environment strings are usually of the form:

name=value

The UNIX kernel never looks at these strings; their interpretation is up to the various applications. The shells, for example, use numerous environment variables. Some, such as HOME and USER, are set automatically at login; others are left for us to set. We normally set environment variables in a shell start-up file to control the shell’s actions.

ISO C defines a function that we can use to fetch values from the environment.

1
char *getenv(const char *name);

In addition to fetching the value of an environment variable, sometimes we may want to set an environment variable.

9 setjmp and longjmp Functions

In C, we can’t goto a label that’s in another function. Instead, we must use the setjmp and longjmp functions to perform this type of branching.

10 getrlimit and setrlimit Functions

Every process has a set of resource limits, some of which can be queried and changed by the getrlimit and setrlimit functions.

1
2
int getrlimit(int resource, struct rlimit *rlptr);
int setrlimit(int resource, const struct rlimit *rlptr);