C言語関係掲示板

過去ログ

No.48. 外部コマンドコール方法


旧C言語関係掲示板で、以下の書き込みがありましたので、こちらで
対応いたします。

> はじめまして、kuronekoと申します。

> 今System関数で、外部コマンドをコールしているのですが、
> System関数では外部コマンドが、戻り値を戻すまで待ってしまうので、
> 他の方法を探しているのですが、何かありませんでしょうか?

> よろしくお願いします。

初めまして、kuronekoさん。ともじです。勝手にこっちに移してすみません。

ANSI Cの関数ではないのですが、spawnというのがあります。
通常の処理系では用意されているはずです。

この関数は、「親プロセスから子プロセスを呼び出して実行する。
子プロセスが終了したら親プロセスに戻る」という機能があります。

ですから、systemの代わりに、spawnを使ってはどうでしょうか。

以下、Turbo-C++ V.4 のHelpからの引用です。使用可能なようであれば、
自分の処理系で調べてください。
なお、spawnに関しては、次のような注意事項もあります。

http://www.borland.co.jp/qanda/lang/l0002033.html

+----------+
| spawn... | <PROCESS.H>
+----------+
プログラムに,他のファイルを作成して(子プロセスとして)実行させることを
可能にします。spawn...関数は,子プロセスが終了した時に,制御をプログラム
に戻します。

個別の引数がいくつあるか判るときは,以下のspawn...関数を使って下さい。

宣言:
・ int spawnl (int mode, char *path, char *arg0, ..., NULL);
・ int spawnle (int mode, char *path, char *arg0, ..., NULL, char *envp[]);
・ int spawnlp (int mode, char *path, char *arg0, ..., NULL);
・ int spawnlpe(int mode, char *path, char *arg0, ..., NULL, char *envp[]);

個別の引数がいくつあるか判らないときは,以下のspawn...関数を使って下さ
い。

宣言:
・ int spawnv (int mode, char *path, char *argv[]);
・ int spawnve (int mode, char *path, char *argv[], char *envp[]);
・ int spawnvp (int mode, char *path, char *argv[]);
・ int spawnvpe(int mode, char *path, char *argv[], char *envp[]);

説明:
spawn...ファミリーの関数は,子プロセスとして知られる他のファイルを作成し
て実行します。子プロセスのロードと実行に使えるだけのメモリがなければなり
ません。

spawn...ファミリー名の後ろにつける l, v, e, および p サフィックス は,そ
の関数がどのように動作するかを示しています。

引数 | 意味
----------+----------------------------------------------------------------
mode | 呼び出し関数(親プロセス)が spawn...を呼び出した後で実行する
| 動作を決定します。
path | 呼び出される子プロセスのファイル名。
argN | 独立した引数として渡される引数ポインタ。
argv[N] | ポインタ配列として渡される引数ポインタ。
envp | 文字ポインタの配列。

spawn...関数呼び出しは,標準の DOS 検索アルゴリズムを使って path を検索し
ます。

spawn...関数の呼び出しを行なうと,オープンされているファイルは子プロセス
でもオープンされたままになっています。

子プロセスで,0 以外の引数を使って特別に exit を呼び出すと,その終了ス
テータスを 0 以外の値にすることができます。

戻り値:
・ 実行が成功した場合,spawn...関数は子プロセスの終了ステータス
(正常終了は 0)を返します。
・ エラーの場合は -1 を返し,errno に次のいずれかを設定します。
E2BIG 引数リストが長すぎる
EINVAL 引数が正しくない
ENOENT パスまたはファイル名が見つからない
ENOEXEC exec 書式エラー
ENOMEM メモリ不足


ともじさん、わざわざこちらの掲示板に移していただいて、ありがとう
ございました。

それと、詳しい説明もありがとうございました。
さっそく確認してみます。

本当にありがとうございます。


kuronekoさん、spawn使えましたか?ちょっと気になっています。

肝心なことが抜けていたのですが、MS-DOS環境ですと、spawnのモードの
「P_NOWAIT : 子プロセスの実行中にも親プロセスを実行し続ける。」
というのは使えませんね。MS-DOSはシングルタスクですから。
Windowsの環境でしたら、マルチタスクですから上記モードは使えるはずですが。
あとUNIX系でしたら、forkとexecですね。
http://www.ncad.co.jp/~komata/c-kouza3.htm あたり参考になると思います。

MS-DOS環境はシングルタスクなので、
> 今System関数で、外部コマンドをコールしているのですが、
> System関数では外部コマンドが、戻り値を戻すまで待ってしまうので、
> 他の方法を探しているのですが、何かありませんでしょうか?
の解決方法はないかもしれません。


ともじさん、お気遣いありがとうございます。

私が携わっているのは、UNIXです。
私もfork()とかを調べてみましたが、子プロセスを終了を待たないと、
defunctプロセスになってしまうようです。

なので、system()から外部コマンドをバックグランドで実行すれば、
よろしいかと思っています。

戻る


「初心者のためのポイント学習C言語」 Last modified:2001.10.7
Copyright(c) 2000-2002 TOMOJI All Rights Reserved