The Process Environment


Some of the key elements in the process environment differ between UNIX and Interix. This section discusses these key elements and how you implement them in Interix:

  • Environment variables

  • Using stdarg and varargs

  • Temporary files

  • Computer information

  • Logging system messages

Environment Variables

An environment block is a block of memory allocated within the process address space. Each block contains a set of name value pairs. All UNIX variants support process environment blocks. The particular differences between Interix and other UNIX variants depend on which UNIX variant is being ported to Interix. For example, some UNIX variants do not support either the setenv or unsetenv function calls, whereas Interix does.

There are usually no issues in porting calls to environment variable functions to Interix. However, when porting System V Interface Definition (SVID) code, instead of the process environment being defined as a third argument to main() , it is defined as extern char **environ . To modify the environment for the current process, use getenv() and putenv() . To modify the environment to be passed to a child process, use getenv() , setenv() , and putenv() , or build a new environment and pass it to the child by using the envp argument of exec () .

For an example of UNIX code using these functions that ports to Interix without modification, see Environment Variables in Chapter 9, Win32 Code Conversion.

Using stdarg and varargs

Rather than conflict with the historical routines in varargs.h, the International Standards Organization/American National Standards Institute (ISO/ANSI) C standard defines stdarg.h, a new mechanism for dealing with variable argument lists. The varargs mechanism uses a magic name, va_alist , for the first argumentin a list; stdarg uses the last required argument. This means that stdarg must haveat least one named parameter. The Interix SDK ships both headers, so there is no need to convert from one to the other. For ANSI standard code, convert from varargs to stdarg .

Usually, it is possible to translate easily from varargs to stdarg because most functions with variable argument lists have a known first-argument type.

The following examples show how code using varargs is rewritten to use stdarg . The first example is a trivial, error-printing function that uses the varargs mechanism:

 #include <varargs.h> printerror(va_alist); void printerror (va_alist) va_dcl {    va_list ap;    char *fmt;    va_start(ap);    fmt = va_arg(ap, char *);    vprintf(stderr, fmt, ap);    va_end(ap); } 

The next example shows how the code is changed when stdarg is used to replace varargs . Because the function in the previous example uses a format string as its first argument, it can easily be used as the known argument in the function in the following example:

 #include <stdarg.h> void printerror (char *fmt, ...) {    va_start(ap, fmt);    vfprintf(stderr, fmt, ap);    va_end(ap); } 

The first argument must be given a name, even when the routine takes a terminated list and no fixed arguments. For example, the following function prints a set of strings, but the first argument is entirely artificial, created to meet the needs of the stdarg package:

 #include <stdarg.h> pr_str(char *first, ...) {    char * current;    va_list argp;    va_start(argp,first);    current = first;    while (current != NULL){    fputs(current,stdout);    current = va_arg(argp, char *);    }    va_end(argp); } 

The following examples show the use of conditional compilation that uses the ANSI flag to provide backward compatibility.

The original application, var.c , passes a variable number of arguments by using va_start , va_arg , va_end , va_list , and va_dcl (UNIX only):

 /* var.c: The program below illustrates passing a variable  * number of arguments using the following macros:  *      va_start            va_arg              va_end  *      va_list             va_dcl (UNIX only) */ #include <stdio.h> #include <varargs.h> int average(va_list); int main(void) {    /* Call with 3 integers (-1 is used as terminator). */    printf("Average is: %d\n", average(2, 3, 4, -1));    /* Call with 4 integers. */    printf("Average is: %d\n", average(5, 7, 9, 11, -1));    /* Call with just -1 terminator. */    printf("Average is: %d\n", average(-1)); } /* Returns the average of a variable list of integers. */ int average(va_alist) va_dcl {    int count = 0, sum = 0, i ;    va_list marker;    i = va_arg(marker, int);    va_start(marker);    while(i != -1)    {       sum += i;       count++;       i = va_arg(marker, int);    }    va_end(marker);              /* Reset variable arguments.      */    return(sum ? (sum / count) : 0); } 

When compiled, the following errors are displayed. The errors occur because Interix does not support the pre-ANSI version of args available in varargs.h.

 var.c: In function 


UNIX Application Migration Guide
Unix Application Migration Guide (Patterns & Practices)
ISBN: 0735618380
EAN: 2147483647
Year: 2003
Pages: 134

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net