_spawn 系関数と _wspawn 系関数
_spawn の各関数は新しいプロセスを作成して実行します :
関数名の最後の文字はの種類を示します。
e
環境設定の envp へのポインター配列が新しいプロセスに渡されます。l
コマンド ライン引数が _spawn 関数に個別に渡されます。このサフィックスは通常は新しいプロセスにいくつかのパラメーターが事前にわかっている場合に使用されます。p
PATH 環境変数を使用して、実行するファイルを検索します。v
argv のコマンド ライン引数へのポインター配列が _spawn の関数に渡されます。このサフィックスは通常は新しいプロセスにいくつかのパラメーターが変化する場合に使用されます。
解説
_spawn は作成および実行する新しいプロセスが。これらは適切な方法で自動的にマルチバイト文字列の引数を処理されるためマルチバイト文字列を現在使用中のマルチバイト コード ページに従って認識します。_wspawn の関数は _spawn の関数のワイド文字バージョンです。;マルチバイト文字を処理しません。それ以外 _wspawn の関数は _spawn の対応するプロパティと同じように動作します。
汎用テキスト ルーチンのマップ
Tchar.h のルーチン |
_UNICODE および _MBCS が未定義の場合 |
_MBCS が定義されている場合 |
_UNICODE が定義されている場合 |
---|---|---|---|
_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 |
十分なメモリが新しいプロセスを読み込んで実行に使用できる必要があります。mode の引数は _spawn の前と実行中は呼び出しプロセスによって実行されるアクションを決定します。mode の値は次の Process.h で定義されています :
_P_OVERLAY
呼び出しプロセス (同じ効果 _exec の呼び出し) を破棄する新しいプロセスと呼び出しプロセスに重なって表示します。_P_WAIT
新しいプロセスの実行が完了するまで呼び出し元スレッドを中断します (同期 _spawn)。_P_NOWAIT または _P_NOWAITO
新しいプロセス (非同期 _spawn) と同時に呼び出し元プロセスを継続します。_P_DETACH
呼び出しプロセスを実行します ; 新しいプロセスはコンソールやキーボードへのアクセスを持たないバックグラウンドで実行されます。新しいプロセスに対する _cwait の呼び出しは失敗します (非同期 _spawn)。
cmdname の引数は新しいプロセスとして実行され完全パス (ルートからのパス)相対パス (現在の作業ディレクトリから)またはファイル名だけを指定するファイルを指定します。次に cmdnameファイル名の拡張子がないためピリオド () がない場合_spawn の関数は最初に .com ファイル拡張子とファイル名拡張子 .exe.bat ファイル拡張子と最終的に .cmd ファイル名拡張子を試みます。
cmdnameファイル名の拡張子がある場合はその拡張子のみが使用されます。cmdname がピリオドであった場合は_spawn の呼び出しはファイル名拡張子なしで cmdname を検索します。_spawnlp_spawnlpe_spawnvp と _spawnvpe の関数は PATH 環境変数で指定されたディレクトリで cmdname (同じ手順を使用して検索します)。
cmdname がドライブ指定子やスラッシュが相対パスである () _spawn 含まれている場合を呼び出すと指定されたファイルのみを検索します ; パスの検索は実行されません。
これまでこれらの機能には成功の errno をゼロに設定します ; 現在の動作はC 規格によって指定されるように触れられていない正常に errno のままです。古い動作をエミュレートする必要がある場合これらの関数を呼び出す直前の errno をゼロに設定します。
[!メモ]
適切なオーバーレイの初期化と終了を確認するにはオーバーレイ ルーチンを入力するか保持するに setjmp または longjmp の関数を使用しないでください。
生成する手順の引数
新しいプロセスに引数を渡すには文字列へのポインターをとして _spawn の呼び出しの引数指定します。これらの文字列は子プロセスの引数リストが構成されます新しいプロセスの引数リストを構成する文字列を合わせた長さが 1024 バイトを超えないようにしてください。各文字列の終端の null 文字 (「 \ 0 ") はカウントされませんが空白文字 (引数の間に自動的に挿入されます) が含まれています。
[!メモ]
文字列に空白が含まれる場合予期しない動作が発生する可能性があります。; たとえば_spawn に "hi there" 文字列を渡すと2"hi" 引数と "there" を派生する新しいプロセスで発生します。新しいプロセスでは "hi there" というファイルを開こうとするため、プロセスは失敗します。この問題を回避するには、"\"hi there\"" のように文字列を引用符で囲みます。
セキュリティに関するメモ |
---|
ユーザー入力のコンテンツを明示的にチェックしないまま _spawn に渡さないでください。_spawn によって CreateProcess が呼び出されます。そのため、パス名が修飾されていない場合、セキュリティ上の脆弱性につながる可能性があります。 |
別の引数として渡される引数のポインター (_spawnl_spawnle_spawnlpポインターの配列として _spawnlpe) または渡すことができます。_spawnv_spawnve_spawnvp と _spawnvpe)。子プロセスに 1 文字以上の引数 arg0または argv[0]渡す必要があります。通常この引数はコマンド ラインで入力するとプログラムの名前です。異なる値ではエラーは発生しません。
引数の数が事前にわかっている場合 _spawnl_spawnle_spawnlp と _spawnlpe の呼び出しが使われます。arg0 の引数は通常 cmdname へのポインターです。argn による引数 arg1 は新しい引数リストを構成する文字列へのポインターです。argn の後に引数リストの終端を示すため NULL のポインターが必要です。
引数の数が新しいプロセスにある場合 _spawnv_spawnve_spawnvp と _spawnvpe の呼び出しが便利です。引数へのポインターは配列argv として渡されます *。*引数 argv[0] 保護モードでリアル通常モードのパスまたはプログラム名に新しい引数リストを構成する文字列へのポインターargvn[入力] から [1] です argv ポインターです。引数 argv[+1]n 引数リストの終端を示すため NULL のポインターである必要があります。
生成するプロセスの環境
_spawn の呼び出しを作成するときに開いたファイルは新しいプロセスに開いたままです。_spawnl_spawnlp_spawnv と _spawnvp の呼び出しでは新しいプロセスは呼び出しプロセスの環境を継承します。_spawnle_spawnlpe_spawnve と envp の引数を使用して環境設定のリストを渡すことで新しいプロセスの環境の変更に _spawnvpe 呼び出しを使用できます。引数 envp は文字のポインターの配列 (環境変数を定義する null で終わる文字列を指す最後の要素を除き各要素です。通常、このような文字列の形式は NAME=value であり、NAME は環境変数名、value はその変数に設定する文字列の値です。value は二重引用符で囲みません。envp 配列の最後の要素は NULL にする必要があります。envp 自体が NULL すると子プロセスは親プロセスの環境設定を継承します。
_spawn の関数は新しいプロセスで開いているファイルに関するすべての情報が変換モードを含めて渡すことができます。この情報は C_FILE_INFO のエントリを通じて環境のリアル モードに渡されます。スタートアップ コードは通常このエントリを処理し環境から削除します。ただし_spawn の関数が非 C プロセスを生成するエントリはこの環境に残ります。環境を印刷するとこのエントリの文字列定義で環境情報がリアル モードにバイナリ形式で渡されるため表示文字を示します。これは通常の操作に対する他の効果が得られるようにします。この保護モードでは環境内の情報はテキスト形式で渡され表示文字は含まれません。
明示的に fflush_flushall(または) を使用するとフラッシュするか_spawn の関数を呼び出す前にストリームを閉じる必要があります。
_spawn ルーチンの呼び出しによって作成された新しいプロセスはシグナル設定は保持されません。代わりに既定値にリセット子プロセスときに設定されます。
出力のリダイレクト
DLL または GUI アプリケーションから _spawn を呼び出してパイプに出力をリダイレクトするには2 とおりの方法があります :
パイプを作成するために Win32 API を使用して呼び出し AllocConsole は開始の構造と呼び出し CreateProcess のハンドル値を設定します。
パイプを作成するとcmd.exe /c 起動します。_popen、_wpopen (または command.exe /c) を使用してアプリケーションを示します。
使用例
// crt_spawn.c
// 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[] )
{
char *args[4];
// Set up parameters to be sent:
args[0] = "child";
args[1] = "spawn??";
args[2] = "two";
args[3] = NULL;
if (argc <= 2)
{
printf( "SYNTAX: SPAWN <1-8> <childprogram>\n" );
exit( 1 );
}
switch (argv[1][0]) // Based on first letter of argument
{
case '1':
_spawnl( _P_WAIT, argv[2], argv[2], "_spawnl", "two", NULL );
break;
case '2':
_spawnle( _P_WAIT, argv[2], argv[2], "_spawnle", "two",
NULL, my_env );
break;
case '3':
_spawnlp( _P_WAIT, argv[2], argv[2], "_spawnlp", "two", NULL );
break;
case '4':
_spawnlpe( _P_WAIT, argv[2], argv[2], "_spawnlpe", "two",
NULL, my_env );
break;
case '5':
_spawnv( _P_OVERLAY, argv[2], args );
break;
case '6':
_spawnve( _P_OVERLAY, argv[2], args, my_env );
break;
case '7':
_spawnvp( _P_OVERLAY, argv[2], args );
break;
case '8':
_spawnvpe( _P_OVERLAY, argv[2], args, my_env );
break;
default:
printf( "SYNTAX: SPAWN <1-8> <childprogram>\n" );
exit( 1 );
}
printf( "from SPAWN!\n" );
}