Technical Notes
OverviewAn entire environment block appears as follows:
varstr1 , 0, varstr2 , 0, ..., varstrn , 0, 0, 1, 0, tailstr1 , 0, avail
where varstr1 through varstrn represent n ASCII environment variable strings, tailstr1 represents a single environment tail string, and avail represents available environment space. Note that the tail string count word in the sample above has a value of one. This value is undefined for versions of DOS below 3.0. From 3.0 to 4.01, this value is always set to one by DOS and the first and only tail string is the pathname of the program which owns the environment.
Each environment variable string appears as follows:
varname=value,0
where varname is the name of the environment variable and value is the value of that variable. The PATH and COMSPEC environment variables are common examples of this.
The root environment is the environment assigned to the primary copy of COMMAND.COM. It is the environment which is inherited by all programs executed by the primary copy of COMMAND.COM.
The active environment is the environment assigned to the active copy of COMMAND.COM. (The most recently executed copy of COMMAND.COM is the active copy.) The active environment is the environment which is inherited by all programs executed from the command line. Note that when there are no secondary copies of COMMAND.COM, the active environment and the root environment are one and the same.
The parent environment is the environment of the parent program which executed a given program. If a program is executed from the command line or from a batch file, the parent program is the active copy of COMMAND.COM and the parent environment and the active environment are one and the same.
The inherited environment is the immediate environment assigned to a given program. If a program is executed from the command line or from a batch file, the inherited environment is a copy of the active environment. If a program is executed from within another program, the inherited environment is either a copy of the parent environment or a copy of an environment defined by the parent. Note that the inherited environment is always a copy of some other environment. No two programs ever share the same environment. Inherited environments are always discarded when a program terminates.
The location of the environment assigned to a copy of COMMAND.COM varies from one version of DOS to another. It also depends on whether a particular copy of COMMAND.COM is a primary or secondary copy. These functions return the correct environment address in all cases.
_get_env searches a specified environment for a variable and returns a pointer to the value of that variable in the environment. The returned pointer should only be used to read the environment variable. Writing an environment variable directly (instead of using _set_env) may corrupt the environment.
_set_env searches a specified environment for a variable and sets the value of the variable to a specified string. If the variable does not exist in the environment, it is added. If it exists, its value is changed. If the specified value is a NULL string, the variable is deleted from the environment.
_environ_len determines the length of the environment string in a specified environment. This length includes the double NULL termination but not the environment tail. The _environ_size function returns the size of the DOS memory block which has been allocated for a specified environment. These two functions are most commonly used when copying or creating environments for use with a child program.
The _copy_envblk and _create_envblk functions create simulated environment blocks. Simulated environment blocks act in all respects like true environment blocks, but they are not linked into the DOS memory chain and are not associated with any specific application. Simulated environments are useful for creating custom environments to be passed to child programs. Environments created by these two functions may be operated on by any of the program control environment functions.
_arg_count determines the number of arguments which are present on the command line. _arg_nth returns a specified command line argument, and _arg_next returns the argument which follows the last argument returned. If no arguments have been returned or if _arg_reset is called, _arg_next the first command line argument. Arguments may be read from the command line in sequential or random order.
Arguments are returned by copying them into a specified buffer in ASCIIZ format. In addition, the most significant character which terminates the argument is reported in the argument chr. (When the terminating character is reported, switch characters and significant separator characters take precedence over insignificant separator characters. See Setting the Command Line Parsing Syntax, below, for a discussion of the different types of separating characters.)
_set_cmdln sets the command line address to a specified location. _reset_cmdln resets the command line address to the default program command line location at offset 0x81 in the PSP. Both of these functions reset the command line pointer to the start of the command line when the new command line address is established. The use of these functions is optional. The default program command line is parsed if no other address is specified.
cmdln_start and cmdln_next are the actual variables used by the command line parsing functions to keep track of the current and starting command line positions. These variables may be read ormodified at any time. If they are modified, the new command line address takes effect immediately. These variables are usually used for processing nested command lines (i.e., for processing "@" files which contain additional command line information).
By default, the command line functions support the same command line syntax supported by most DOS commands. A custom parsing syntax may be specified by calling _set_argtbls. The parsing syntax may be changed at any time. _reset_argtbls resets the parsing syntax to the default syntax.
The command line parsing syntax is specified using three tables which identify switch characters and argument separators. Each table is an ASCIIZ string and must reside in DGROUP (global or static non-far data). These tables are used to parse the command line as follows:
Insignificant Separator Table. Command line characters found in this table are skipped when they appear before or after an argument. They also terminate an argument. They are not copied into the buffer.
Significant Separator Table. Command line characters found in this table terminate an argument. They are never skipped and they are not copied into the buffer.
Switch Character Table. Command line characters found in this table mark the beginning of a new argument and end any previous argument. They are copied into the buffer as the first character of an argument.
When a command line character is processed, these tables are searched in the following order: Switch Character Table, Significant Separator Table, Insignificant Separator Table. The character is then compared against CR and NULL to check for the end of the command line. The meaning of the CR character may be modified by placing CR in one of the three parsing tables. If the first character in a table is a NULL, that table is ignored.
The default parsing tables emulate the command line parsing syntax supported by most DOS commands. The default parsing tables are defined as follows:
char Insig_Sep_Table[] = " \t"; (Space, Tab)
char Sig_Sep_Table[] = ",;+"; (Comma, Semicolon, Plus)
char Switch_Char_Table[] = "/"; (Forward Slash)
If INHERIT_PTR is specified for any of the table pointers passed to the _set_argtbl function, the currently-installed table remains installed. INHERIT_PTR is defined in SA_DEF.H.
When a command line argument is returned by _arg_next or _arg_nth, the most significant terminating character is also reported in chr. If a command line argument is followed by insignificant separators as well as a switch or significant separator, then only the switch or significant separator is reported. This allows parsing logic to depend on the most significant characters used to separate arguments.
The following example demonstrates the use of custom parsing tables. This example installs a custom switch character table which includes the hyphen as well as the backslash character. The other two tables remain unchanged.
#include
#include
#include
static char custom_ssep[] = ",;+-"; /* new signif. sep. table */
char arg_buf[128]; /* command line argument buffer */
void main()
{
char chr;
int args;
_put_str("\n\rNumber of arguments: ");
_put_str(_i_to_dec(_arg_count(), arg_buf)); /* get number of arguments */
_put_str("\n\rSecond argument: ");
_put_str(_arg_nth(arg_buf, 2, &chr));
_put_str("\n\rTerminating character: "); _put_chr(chr);
_set_argtbls(INHERIT_PTR,custom_ssep,INHERIT_PTR);
_put_str("\n\n\rUsing Argument Tables...\n");
_put_str("\n\Rnumber of arguments: ");
_put_str(_i_to_dec(_arg_count(), arg_buf)); /* get number of arguments */
_put_str("\n\Rsecond argument: ");
_put_str(_arg_nth(arg_buf, 2, &chr));
_put_str("\n\Rterminating character: "); _put_chr(chr);
_reset_argtbls(); _put_newline(); /* restore default tables */
}
When the following command line is passed to the PROGNAME program:
progname file1 file2-file3 , file4;
then the above example parses this command line as follows:
_exec_prog and _exec_proge execute a specific child program with a specified command line. The child program is passed either an exact copy of the current program environment (_exec_prog) or an exact copy of a specified environment (_exec_proge). The child program must be either a .COM or .EXE file and it must reside in the directory which is specified by the name of the program. These functions return an exit a success or fail value and on success the termcode argument is modified to report the type of termination (normal termination, TSR, critical error, or ctrl-break) to the current program when the child program terminates.
_exec_sys and _exec_syse execute a system command (DOS command, batch file, or program) by invoking the command processor defined by the COMSPEC environment variable. The command processor is usually COMMAND.COM. The command processor is passed either an exact copy of the current program environment (_exec_sys) or an exact copy of a specified environment (_exec_syse). The system command is specified on a command line which is passed to the command processor. This command line may contain switches to control the command processor, the name of the system command, and any command line information required by the command. If a batch file or program is to be executed, it is located using the path specified in the environment. Control returns to the current program after the command is executed.
_exit_to_dos passes control to the command processor, displays a command prompt, and waits for input. Control returns to the calling program when "EXIT" is typed on the command line. This is equivalent to calling _exec_syse with a NULL command string.
All of these functions restore the state of the calling program when the child program is executed, including the Ctrl-Break state and DTA.
Microsoft C:
Determining the Name and Path of the Executing Program
This function returns the name and path of the executing program. The returned pathname includes a drive specifier, full path, the program filename, and a terminal NULL. This information is retrieved from the end of the inherited environment and is usually available under DOS versions 3.0 and later. If the name and path cannot be retrieved from the environment for any reason, a NULL path is returned and -1 is returned.
Executing Child Programs
These functions load and execute child programs, DOS commands, and batch files from within the current program.
Miscellaneous Program Control Functions
_get_psp and _psp provide access to the address of the current program's Program Segment Prefix. _get_psp returns the address of the PSP in all memory models without issuing any DOS calls.
Sample Program
The sample program shown below uses of a number of program control functions and demonstrates the following program control features: defining and installing a custom parsing table, getting the first command line argument, getting the segment address of the DOS environment, using that environment address to search for a "PATH" variable string, and concatenating the command line argument to the current "PATH". The program is listed in its entirety.
The sample program shown above (PATHADD.C) is provided on the distribution diskettes and may be compiled and linked using the following Microsoft C and Borland C command lines:
#include
Borland C:
cl /c /I\msc\include /I\sa\include pathadd.c
link pathadd,pathadd,,\sa\lib\_sas \msc\lib\slibce
bcc /c /ms /I\bc\include /I\sa\include pathadd.c
tlink \bc\lib\c0s pathadd,pathadd,,\sa\lib\_sas \bc\lib\cs