|< Windows Process & Threads: C Run-Time 2 | Main | Windows Process & Threads: C Run-Time 4 >| Site Index | Download |


 

 

 

 

MODULE R2

PROCESSES AND THREADS: C RUN-TIME

Part 3:  Story And Program Examples

 

 

 

 

What are in this Module?

  1. _spawn() and _exec() Function Families

  2. _spawn(), _wspawn() Functions

  3. Some Remarks

  4. Generic-Text Function Mappings

  5. Return Value

  6. Arguments for the Spawned Process

  7. Environment of the Spawned Process

 

 

 

 

 

 

 

 

 

 

 

 

 

My Training Period: xx hours. Before you begin, read some instruction here.

 

The expected abilities:

_spawn() and _exec() Function Families

 

The following Table lists _spawn() and _exec() function families.

 

Functions

Use PATH variable to locate file

Argument-passing convention

Environment settings

_execl(), _spawnl()

No

List

Inherited from calling process.

_execle(), _spawnle()

No

List

Pointer to environment table for new process passed as last argument.

_execlp(), _spawnlp()

Yes

List

Inherited from calling process.

_execlpe(), _spawnlpe()

Yes

List

Pointer to environment table for new process passed as last argument.

_execv(), _spawnv()

No

Array

Inherited from calling process

_execve(), _spawnve()

No

Array

Pointer to environment table for new process passed as last argument.

_execvp(), _spawnvp()

Yes

Array

Inherited from calling process.

_execvpe(), _spawnvpe()

Yes

Array

Pointer to environment table for new process passed as last argument.

 

Table 8

 

_spawn(), _wspawn() Functions

 

Each of the _spawn() functions creates and executes a new process. Its family is shown in the following Table.

 

Spawn family

_spawnl(), _wspawnl()

_spawnv(), _wspawnv()

_spawnle(), _wspawnle()

_spawnve(), _wspawnve()

_spawnlp(), _wspawnlp()

_spawnvp(), _wspawnvp()

_spawnlpe(), _wspawnlpe()

_spawnvpe(), _wspawnvpe()

 

Table 9

 

The letter(s) at the end of the function name determine the variation. It look similar to the _exec() family and also available in Standard C with the same function name without the prefixed underscore and variations.

 

_spawn() function suffix

Description

e

envp, array of pointers to environment settings, is passed to new process.

l

Command-line arguments are passed individually to _spawn() function. This suffix is typically used when number of parameters to new process is known in advance

p

PATH environment variable is used to find file to execute.

v

argv, array of pointers to command-line arguments, is passed to _spawn() function. This suffix is typically used when number of parameters to new process is variable.

 

Table 10

 

Some Remarks

 

The _spawn() functions each create and execute a new process. They automatically handle multibyte-character string arguments as appropriate, recognizing multibyte-character sequences according to the multibyte code page currently in use. The _wspawn functions are wide-character versions of the _spawn() functions; they do not handle multibyte-character strings. Otherwise, the _wspawn() functions behave identically to their _spawn() counterparts.

 

Generic-Text Function Mappings

 

The following Table lists the generic-text function mappings for _spawn() family used in Microsoft C.

 

TCHAR.H routine

_UNICODE & _MBCS not defined

_MBCS defined

_UNICODE defined

_tspawnl()

_spawnl()

_spawnl()

_wspawnl()

_tspawnle()

_spawnle()

_spawnle()

_wspawnle()

_tspawnlp()

_spawnlp()

_spawnlp()

_wspawnlp()

_tspawnlpe()

_spawnlpe()

_spawnlpe()

_wspawnlpe()

_tspawnv()

_spawnv()

_spawnv()

_wspawnv()

_tspawnve()

_spawnve()

_spawnve()

_wspawnve()

_tspawnvp()

_spawnvp()

_spawnvp()

_wspawnvp()

_tspawnvpe()

_spawnvpe()

_spawnvpe()

_wspawnvpe()

 

Table 11

 

The following Table lists the needed information in order to use the _spawn() functions family.

 

Information

Description

The function

_spawn() family.

The use

Create and execute a new process.

The prototype

intptr_t _spawnl(int mode, const char *cmdname, const char *arg0, const char *arg1, ... const char *argn, NULL);

intptr_t _wspawnl(int mode, const wchar_t *cmdname, const wchar_t *arg0, const wchar_t *arg1, ... const  wchar_t *argn, NULL);

 

intptr_t _spawnle(int mode, const char *cmdname, const char *arg0, const char *arg1, ... const char *argn, NULL, const char *const *envp);

intptr_t _wspawnle(int mode, const wchar_t *cmdname, const wchar_t *arg0, const wchar_t *arg1, ... const wchar_t *argn, NULL, const wchar_t *const *envp);

 

intptr_t _spawnlp(int mode, const char *cmdname, const char *arg0, const char *arg1, ... const char *argn, NULL);

intptr_t _wspawnlp(int mode, const wchar_t *cmdname, const wchar_t *arg0, const wchar_t *arg1, ... const wchar_t *argn, NULL);

 

intptr_t _spawnlpe(int mode, const char *cmdname, const char *arg0, const char *arg1, ... const char *argn, NULL, const char *const *envp);

intptr_t _wspawnlpe(int mode, const wchar_t *cmdname, const wchar_t *arg0, const wchar_t *arg1, ... const wchar_t *argn, NULL, const wchar_t *const *envp);

 

intptr_t _spawnv(int mode, const char *cmdname, const char *const *argv);

intptr_t _wspawnv(int mode, const wchar_t *cmdname, const wchar_t *const *argv);

 

intptr_t _spawnve(int mode, const char *cmdname, const char *const *argv, const char *const *envp);

intptr_t _wspawnve(int mode, const wchar_t *cmdname, const wchar_t *const *argv, const wchar_t *const *envp);

 

intptr_t _spawnvp(int mode, const char *cmdname, const char *const *argv);

intptr_t _wspawnvp(int mode, const wchar_t *cmdname, const wchar_t *const *argv);

 

intptr_t _spawnvpe(int mode, const char *cmdname, const char *const *argv, const char *const *envp);

intptr_t _wspawnvpe(int mode, const wchar_t *cmdname, const wchar_t *const *argv, const wchar_t *const *envp);

Example

-

The parameters

mode - Execution mode for calling process.

cmdname - Path of file to be executed.

arg0, arg1, ... argn - List of pointers to arguments.

envp - Array of pointers to environment settings.

argv - Array of pointers to arguments.

The return value

See below.

The header file

_spawnl(), _spawnle(), _spawnlp(), _spawnlpe(), _spawnv(), _spawnve(), _spawnvp(), _spawnvpe() - <process.h>.

_wspawnl(), _wspawnle(), _wspawnlp(), _wspawnlpe(), _wspawnv(), _wspawnve(), _wspawnvp(), _wspawnvpe() - <stdio.h> or <wchar.h>.

Remarks

Each of these functions creates and executes a new process, passing each command-line argument as a separate parameter.

 

Table 12

 

Return Value

 

The return value from a synchronous _spawnl() or _wspawnl() (_P_WAIT specified for mode) is the exit status of the new process. The return value from an asynchronous _spawnl() or _wspawnl() (_P_NOWAIT or _P_NOWAITO specified for mode) is the process handle. The exit status is 0 if the process terminated normally. You can set the exit status to a nonzero value if the spawned process specifically calls the exit routine with a nonzero argument. If the new process did not explicitly set a positive exit status, a positive exit status indicates an abnormal exit with an abort or an interrupt. A return value of –1 indicates an error (the new process is not started). In this case, errno is set to one of the following values:

 

Value

Description

E2BIG

Argument list exceeds 1024 bytes.

EINVAL

mode argument is invalid.

ENOENT

File or path is not found.

ENOEXEC

Specified file is not executable or has invalid executable-file format.

ENOMEM

Not enough memory is available to execute new process.

 

Table 13

 

Enough memory must be available for loading and executing the new process. The mode argument determines the action taken by the calling process before and during _spawn(). The following values for mode are defined in process.h:

 

Mode value

Description

_P_OVERLAY

Overlays calling process with new process, destroying the calling process (same effect as _exec() calls).

_P_WAIT

Suspends calling thread until execution of new process is complete (synchronous _spawn()).

_P_NOWAIT or _P_NOWAITO

Continues to execute calling process concurrently with new process (asynchronous _spawn()).

_P_DETACH

Continues to execute the calling process; new process is run in the background with no access to the console or keyboard. Calls to _cwait() against the new process will fail (asynchronous _spawn()).

 

Table 14

 

The cmdname argument specifies the file that is executed as the new process and can specify a full path (from the root), a partial path (from the current working directory), or just a filename. If cmdname does not have a filename extension or does not end with a period (.), the _spawn() function first tries the .com extension, then the .exe extension, the .bat extension, and finally the .cmd extension.

If cmdname has an extension, only that extension is used. If cmdname ends with a period, the _spawn() call searches for cmdname with no extension. The _spawnlp(), _spawnlpe(), _spawnvp(), and _spawnvpe() functions search for cmdname (using the same procedures) in the directories specified by the PATH environment variable. If cmdname contains a drive specifier or any slashes (that is, if it is a relative path), the _spawn() call searches only for the specified file; no path searching is done. Note that to ensure proper overlay initialization and termination, do not use the setjmp() or longjmp() function to enter or leave an overlay routine.

 

Arguments for the Spawned Process

 

To pass arguments to the new process, give one or more pointers to character strings as arguments in the _spawn() call. These character strings form the argument list for the spawned process. The combined length of the strings forming the argument list for the new process must not exceed 1024 bytes. The terminating null character ('\0') for each string is not included in the count, but space characters (automatically inserted to separate arguments) are included. You can pass argument pointers as separate arguments (in _spawnl(), _spawnle(), _spawnlp(), and _spawnlpe()) or as an array of pointers (in _spawnv(), _spawnve(), _spawnvp(), and _spawnvpe()). You must pass at least one argument, arg0 or argv[0], to the spawned process. By convention, this argument is the name of the program as you would type it on the command line. A different value does not produce an error.

The _spawnl(), _spawnle(), _spawnlp(), and _spawnlpe() calls are typically used in cases where the number of arguments is known in advance. The arg0 argument is usually a pointer to cmdname. The arguments arg1 through argn are pointers to the character strings forming the new argument list. Following argn, there must be a NULL pointer to mark the end of the argument list.

The _spawnv(), _spawnve(), _spawnvp(), and _spawnvpe() calls are useful when there is a variable number of arguments to the new process. Pointers to the arguments are passed as an array, argv. The argument argv[0] is usually a pointer to a path in real mode or to the program name in protected mode, and argv[1] through argv[n] are pointers to the character strings forming the new argument list. The argument argv[n +1] must be a NULL pointer to mark the end of the argument list.

 

Environment of the Spawned Process

 

Files that are open when a _spawn() call is made remain open in the new process. In the _spawnl(), _spawnlp(), _spawnv(), and _spawnvp() calls, the new process inherits the environment of the calling process. You can use the _spawnle(), _spawnlpe(), _spawnve(), and _spawnvpe() calls to alter the environment for the new process by passing a list of environment settings through the envp argument. The argument envp is an array of character pointers, each element (except the final element) of which points to a null-terminated string defining an environment variable. Such a string usually has the form: NAME=value. Where NAME is the name of an environment variable and value is the string value to which that variable is set. (Note that value is not enclosed in double quotation marks.) The final element of the envp array should be NULL. When envp itself is NULL, the spawned process inherits the environment settings of the parent process.

The _spawn() functions can pass all information about open files, including the translation mode, to the new process. This information is passed in real mode through the C_FILE_INFO entry in the environment. The startup code normally processes this entry and then deletes it from the environment. However, if a _spawn() function spawns a non-C process, this entry remains in the environment. Printing the environment shows graphics characters in the definition string for this entry because the environment information is passed in binary form in real mode. It should not have any other effect on normal operations. In protected mode, the environment information is passed in text form and therefore contains no graphics characters. You must explicitly flush (using fflush() or _flushall()) or close any stream before calling a _spawn() function. You can control whether the open file information of a process is passed to its spawned processes. The external variable _fileinfo (declared in stdlib.h) controls the passing of C_FILE_INFO information. If _fileinfo is 0 (the default), the C_FILE_INFO information is not passed to the new processes. If _fileinfo() is not 0, C_FILE_INFO is passed to new processes. You can modify the default value of _fileinfo in one of two ways: link the supplied object file, fileinfo.obj, into the program, or set the _fileinfo variable to a nonzero value directly in the C program. New processes created by calls to _spawn() routines do not preserve signal settings. Instead, the spawned process resets signal settings to the default.

 

// Project name: myspawnpro, File name: myspawnsrc.cpp

/* This program accepts a number in the range

 * 1-8 from the command line. Based on the number it receives,

 * it executes one of the eight different procedures that

 * spawn the process named child. For some of these procedures,

 * the child.exe file must be in the same directory; for

 * others, it only has to be in the same path. */

#include <stdio.h>

#include <process.h>

 

char *my_env[ ] =

{

   "This=environment will be",

   "passed=to child.exe by the",

   "_spawnle()=and",

   "_spawnlpe()=and",

   "_spawnve()=and",

   "_spawnvpe()=functions",

   NULL

};

 

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

{

       /* Array storage for argument strings... */

   char *args[4];

   /* Set up parameters to be sent: */

   args[0] = "child";

   args[1] = "spawn??";

   args[2] = "two";

   args[3] = NULL;

   if (argc <= 2)

   {

      /*             argv[0] argv[1]           argv[2] */

      printf("Usage: %s  <child_program_name> <1-8>.\n", argv[0]);

      exit(1);

   }

   /* Based on first letter of argument */

   switch (argv[2][0])

   {

   case '1':

       _spawnl(_P_WAIT, argv[1], argv[1], "_spawnl", "two", NULL);

      break;

   case '2':

      _spawnle(_P_WAIT, argv[1], argv[1], "_spawnle", "two", NULL, my_env);

      break;

   case '3':

      _spawnlp(_P_NOWAIT, argv[1], argv[1], "_spawnlp", "two", NULL);

      break;

   case '4':

      _spawnlpe(_P_NOWAIT, argv[1], argv[1], "_spawnlpe", "two", NULL, my_env);

      break;

   case '5':

      _spawnv(_P_OVERLAY, argv[1], args);

      break;

   case '6':

      _spawnve(_P_OVERLAY, argv[1], args, my_env);

      break;

   case '7':

      _spawnvp(_P_OVERLAY, argv[1], args);

      break;

   case '8':

      _spawnvpe(_P_OVERLAY, argv[1], args, my_env);

      break;

   default:

          printf("");

          printf("Usage: %s <child_program_name> <number [1-8]>.\n", argv[0]);

      exit (1);

   }

   return 0;

}

 

By using our previously created program in exec() example, the crtprocess.exe, the following are some of the output samples. Here we give the full path of the ‘child.exe’.

F:\myproject\myspawnpro\Release>myspawnpro

Usage: myspawnpro  <child_program_name> <1-8>.

 

F:\myproject\myspawnpro\Release>myspawnpro c:\windows\system32\crtprocess.exe

Usage: myspawnpro  <child_program_name> <1-8>.

 

F:\myproject\myspawnpro\Release>myspawnpro c:\windows\system32\crtprocess.exe 2

Command-line arguments:

  argv[0]   c:\windows\system32\crtprocess.exe

  argv[1]   _spawnle

  argv[2]   two

Environment variables:

  This=environment will be

  passed=to child.exe by the

  _spawnle()=and

  _spawnlpe()=and

  _spawnve()=and

  _spawnvpe()=functions

 

F:\myproject\myspawnpro\Release>myspawnpro c:\windows\system32\crtprocess.exe 3

 

F:\myproject\myspawnpro\Release>

Command-line arguments:

  argv[0]   c:\windows\system32\crtprocess.exe

  argv[1]   _spawnlp

  argv[2]   two

 

Environment variables:

  ALLUSERSPROFILE=C:\Documents and Settings\All Users.WINDOWS

  APPDATA=C:\Documents and Settings\Johnny\Application Data

  ... [trimmed]

  ...

  TMP=C:\DOCUME~1\Johnny\LOCALS~1\Temp

  USERDOMAIN=MYPERSONAL

  USERNAME=Johnny

  USERPROFILE=C:\Documents and Settings\Johnny

  VS71COMNTOOLS=c:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\

  windir=C:\WINDOWS

 

F:\myproject\myspawnpro\Release>

Another output example...

F:\myproject\myspawnpro\Release>myspawnpro c:\windows\system32\cmd.exe 1

Microsoft Windows XP [Version 5.1.2600]

(C) Copyright 1985-2001 Microsoft Corp.

 

F:\myproject\myspawnpro\Release>myspawnpro c:\windows\system32\mem.exe 2

 

    655360 bytes total conventional memory

    655360 bytes available to MS-DOS

    599120 largest executable program size

 

   1048576 bytes total contiguous extended memory

         0 bytes available contiguous extended memory

    941056 bytes available XMS memory

           MS-DOS resident in High Memory Area

 

F:\myproject\myspawnpro\Release>myspawnpro c:\windows\system32\cmd.exe 5

 

F:\myproject\myspawnpro\Release>Microsoft Windows XP [Version 5.1.2600]

(C) Copyright 1985-2001 Microsoft Corp.

 

F:\myproject\myspawnpro\Release>myspawnpro c:\windows\system32\mem.exe 7

 

    655360 bytes total conventional memory

    655360 bytes available to MS-DOS

    598224 largest executable program size

 

   1048576 bytes total contiguous extended memory

         0 bytes available contiguous extended memory

    941056 bytes available XMS memory

           MS-DOS resident in High Memory Area

 

F:\myproject\myspawnpro\Release>exit

 

F:\myproject\myspawnpro\Release>exit

 

F:\myproject\myspawnpro\Release>

 

 

-------------------------------------End Windows CRT, Process & thread Story---------------------------------

 

 

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Microsoft Visual C++, online MSDN.
  2. For Multibytes, Unicode characters and Localization please refer to Locale, wide characters & Unicode (Story) and Windows users & groups programming tutorials (Implementation).
  3. Structure, enum, union and typedef story can be found C/C++ struct, enum, union & typedef.
  4. Check the best selling C / C++ and Windows books at Amazon.com.

 

 

 

 

 

 

 

|< Windows Process & Threads: C Run-Time 2 | Main | Windows Process & Threads: C Run-Time 4 >| Site Index | Download |