Processes


The UNIX and Windows process models are very different. However, because these differences are hidden by the Interix subsystem, it is possible to migrate UNIX code to Interix with few process code modifications.

The following sections confirm the similarities between UNIX and Interix process functions and highlight the few areas that need to be changed when migrating code.

Creating a New Process

Interix supports the UNIX process creation APIs, fork() , and vfork() . Code that uses these calls does not require any modifications to compile under Interix.

For an example of code that ports to Interix without change, see Creating a Process in UNIX Using fork and exec in Chapter 9, Win32 Code Conversion.

Replacing a Process Image (exec)

Because Interix supports all six exec calls ” exec() , execl , execle() , execlp() , execv() , execve () , and execvp() ” code that uses these calls does not need to be modified.

However, if the exec call is used with a setuid() call, the code must be modified. In this case, replace the exec() and setuid() combination with an Interix exec*_asuser() call.

Note  

In Interix, man setuid produces the setuid manual page.

For more detailed information, see the section The exec*_asuser Functions under Users, Groups, and Security, later in this chapter.

For an example of code that ports to Interix without change, see Replacing a Process Image in UNIX Using exec in Chapter 9, Win32 Code Conversion.

Process Hierarchy

In UNIX, processes have a parent-child relationship. This hierarchical arrangement is used to manage processes within applications.

The Win32 subsystem does not use a process hierarchy.

However, Interix does maintain a process hierarchy, and even tracks the parent-child relationship of Win32 processes on the same system. The Interix command ps “efi displays processes and their relationship to each other. (The -i option is specific to Interix and shows the process hierarchy.)

The following shows sample output from ps “efi , showing Interix processes followed by Win32 processes:

 UID    PID    PPID    STIME     TTY    TIME     CMD ...     joeuser    2049   1         Jun  4   n00    0:00.59/bin/csh -l     joeuser    9545   2049      06:31:58        n00    0:00.01 ps ef ... +SYSTEM 8      0      Jun  4    S00    1:14.33 SystemProcess +SYSTEM 152    8      Jun  4    S00    0:00.86   \SystemRoot\System32\smss.exe +SYSTEM 176    152    Jun  4    S00    3:53.04     C:\WINNT\system32\csrss.exe C: +SYSTEM 1040   152    Jun  4    S00    0:23.39     C:\WINNT\system32\psxss.exe C: +SYSTEM 196    152    Jun  4    S00    0:24.47     C:\WINNT\system32\winlogon.exe +SYSTEM 236    196    Jun  4    S00    0:48.41       C:\WINNT\system32\lsass.exe +SYSTEM 224    196    Jun  4    S00    0:47.00       C:\WINNT\system32\services.ex 

Waiting for a Child Process

Interix supports most of the wait-for-process-termination calls, including wait() and waitpid() . It does not support calls in the style of Berkley Software Distribution (BSD). When BSD-style wait calls are used, modify code to use the suggested equivalents in Interix, as shown in Table 10.3.

Table 10.3: BSD-style Calls and Interix Equivalents

Function Name

Description

Suggested Interix Replacement

wait3(*status, options, NULL)

Waits for process termination

waitpid (-1, *status, options)

wait3(*status, options, *r_usage)

Waits for process termination

cpid = waitpid (-1, *status, options)
getrusage (cpid, *r_usage)

wait4(pid, *status, options, NULL)

Waits for process termination

waitpid (pid, *status, options)

wait4(pid, *status, options, *r_usage)

Waits for process termination

waitpid (pid, *status, options)
getrusage (pid, *r_usage)

The functions supported by Interix are defined by the POSIX and UNIX standards and will be more portable than the older forms they replace.

Combining waitpid() with getrusage() doesn t produce the same results as wait3() or wait4() without taking some additional steps in the ported application. The idea is to capture getrusage(RUSAGE_CHILDREN,) information at some instant before the child process has terminated ; after the child terminates and has been waited for, capture a second set of getrusage(RUSAGE_CHILDREN,) information and compute the difference between the data contained in the two structures.

Managing Process Resource Limits

As stated in the Chapter 9, Win32 Code Conversion, the UNIX getrlimit function returns the process resource limits, getrusage returns current usage, and setrlimit sets new limits. Interix supports these three functions and the common limit names. The common limit names are shown in Table 10.4.

Table 10.4: Process Resource Limit Names

Limit

Description

RLIMIT_CORE

Maximum size , in bytes, of a core file created by this process. If the core file will be larger than RLIMIT_CORE, the write is terminated at this value. If the limit is set to 0, then no core files are created.

RLIMIT_CPU

Maximum CPU time, in seconds, that a process can use. If the process exceeds this time, the system generates SIGXCPU for the process.

RLIMIT_DATA

Maximum size, in bytes, of a process data segment. If the data segmentgrows larger than this value, the functions brk , malloc , and sbrk fail.

RLIMIT_FSIZE

Maximum size, in bytes, of a file created by a process. If the limit is 0, the process cannot create a file. If a write or truncate call exceeds the limit, further attempts fail.

RLIMIT_NOFILE

Highest possible value for a file descriptor, plus one. This limits the numberof file descriptors a process can allocate. If more than RLIMIT_NOFILE filesare allocated, functions allocating new file descriptors can fail and generate the error EMFILE.

RLIMIT_STACK

Maximum size, in bytes, of a process stack. The stack will not automatically grow past this limit. If a process tries to exceed the limit, the system generates the SIGSEGV error for the process.

RLIMIT_AS

Maximum size, in bytes, of total available memory for a process. If this limitis exceeded, the memory functions brk , malloc , mmap , and sbrk fail with errno set to ENOMEM, and automatic stack growth fails as described for RLIMIT_STACK.

Some other resource limit names that are sometimes used in UNIX code are not available in Interix. These names are shown in Table 10.5. For these names, modify code to use the suggested replacements shown in the table.

Table 10.5: Process Resource Limit Names Not Available in Interix

Limit

Description

Suggested Interix Replacement

RLIMIT_MEMLOCK

Maximum locked-in-memory address space, in bytes.

Interix has no mechanism for determining or enforcing limits on this resource.

RLIMIT_NPROC

Maximum number of processes.

sysconf (_SC_CHILD_MAX) is the only Interix equivalent that provides programmatic information on process limits, but this is not an exact equivalent.

RLIMIT_RSS

Maximum resident set size, in bytes, of address space in a process s address space in bytes.

Interix has no mechanism for determining or enforcing limits on this resource.

RLIMIT_VMEM

Maximum size, in bytes, of mapped address space in a process s mapped address space in bytes. If this limit is exceeded, the brk and mmap functions fail with errno set to ENOMEM. In addition, the automatic stack growth fails as described for RLIMIT_STACK.

Interix has no mechanism for determining or enforcing limits on this resource.

Process Groups

Functions in this category provide support for the management of processes as a group. Because the functions in this group are not supported by Interix, code must be modified to use the recommended replacement functions shown in Table 10.6.

Table 10.6: Process Group Functions Not Supported by Interix

Function Name

Description

Suggested Interix Replacement

getpgid(0)

Gets process group ID of the calling process.

getpgrp ()

getpgid(pid)

Gets process group ID for process PID.

Replace with the getpgid (pid) function (see the description paragraph that follows this table).

setpgrp()

Sets process group ID of the calling process.

setpgid(0,0)

tcgetsid

Gets process group ID for session leader for controlling terminal.

struct utmpx *getutxid (const struct utmpx *id)

As noted, Interix does not support the getpgid(pid) function, which returns the process group ID for a given process. This information can be obtained, but you would need to use the /proc mechanism, which allows a program to retrieve a variety of information about any running process. An implementation of sucha function might look like this:

 #include <stdio.h> #include <unistd.h> #include <errno.h> extern int errno; pid_t getpgid(pid_t pid) {     char procfile[25];     char stat_rec[40];     char inbuf[110];     char field1[10], field2[100];     FILE *in;     sprintf(procfile, "/proc/%d/stat", pid);     in = fopen(procfile, "r");     if (in == NULL) {         errno = ESRCH;       /* No such process */         return(-1);     } //Scan file for "pgid" entry     while(fgets(inbuf, sizeof(inbuf), in))     {         sscanf(inbuf, "%s\t%s\n", field1, field2);         if (strcmp(field1,"pgid") == 0)             return((pid_t) atoi(field2));     }     errno = ENOSYS;     /* Function not implemented */     return(-1); } 

Process Management

Functions in this category provide support for the scheduling and priority management of processes. These functions are getpriority() , setpriority () , and nice() . These functions operate on a nice value, an integer in the range of “ 20 to +20, where a nice of “ 20 means that the process has the highest possible priority. Interix maps nice values to Windows process scheduling priorities accordingto the following rules:

  • A nice value of 0 corresponds to the default Windows scheduling priority 10.

  • Positive nice values are applied as a reduction in Windows scheduling priority; for example, assigning a process a nice value of +4 would result in the process being given a Windows scheduling priority of 6.

  • Negative nice values are applied as an increase in Windows scheduling priority;a process nice value of “ 4 would cause the process to have a Windows scheduling priority of 14.

Regardless of nice value, the lowest Windows priority Interix applies to a processis 1; the highest Windows priority assigned by Interix is 30. Microsoft recommends that no process be assigned a priority higher than 15 ” that is, a nice value of “ 5. The Interix subsystem itself runs at a Windows priority of 15. Setting a higher priority on any application yields unpredictable results.

Any Interix process can lower the Windows priority of any process owned by the same user (that is, increase its nice value). The effective user of a process must have been granted the SE_INC_BASE_PRIORITY_NAME Windows privilege to increase the Windows scheduling priority of any process owned by the same user (that is, decrease its nice value). The effective user of a process must have been granted the SE_TCB_NAME Windows privilege to affect any process owned by any other user .




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