execl+forkでシェルを起動したとき、
起動したシェルから返ってくる結果はどうやってとれるのでしょうか。

==============
pid_t pid_c;

if(pid_c == 0)
{
int ret = execl(shell,shell, id, NULL);
if(ret != 0)
{
exit(1);
}
}
else if (pid_c < 0)
{
exit(1);
}

A 回答 (3件)

質問に答え損ねてましたね。

&はANDをとる演算子です。
ちょっと気になるのは、子プロのexit値が1とか2のとき
100とか200になるってことですが、使ってるマシンはなん
ですか?Pentium系でしょうか?Pentium系の場合、バイト
エンディアンはリトルエンディアンなので、このビット演算
のところが違うかもしれません。

エンディアンについて(ご存じかもしれませんが...)
intが4バイト整数の処理系の場合、
 SPARCやRISC等のビッグエンディアンの場合、ビット並びは
 +-+-+-+-+
 |1|2|3|4| ですが、
 +-+-+-+-+
 Pentiumなどの場合、
 +-+-+-+-+
 |4|3|2|1| となっています。
 +-+-+-+-+
 
私の書いたビット演算とシフトは、リトルエンディアンの場合、
違ってくる(かも)しれません。

いずれにしろ、statusの4バイトのうち、どこか1バイトにexit値が
隠れているはずですから、参考になる資料が手元になければ、試しに
いろいろやってみるうちに見つかるでしょう。
#なんていい加減な回答なんでしょう(^^; 他の詳しい専門家が見たら
#怒られるでしょうね...。
    • good
    • 0
この回答へのお礼

ありがとうございます。
さらに調べたところ、WEXITSTATUS(status)というマクロもあるみたいです。

お礼日時:2001/07/27 19:35

mar328です。

うまくいって何よりです。

statusの計算処理ですが、あれはビット演算を施して、int値のstatus
(うちの処理系では32bit)から子プロの返すステータス値を取り出している
のです。(マシンはSun Sparcで、これはビッグエンディアンマシンです。)

wait(&status)で帰ってくるstatusには、いろいろな情報が入っていて、
それらはビット単位で格納されています。
(0~NビットまではXX、N+1~Mまでは○○、っていうかんじで)
細かい内容は忘れてしまい、資料も手許にないので、詳しいことが説明できない
のですが、そういうことです。
(※ソースから見ると、上位から3バイト目の8ビットに格納されている値を取り
出すために0x0000ff00とマスクをかけて、それをintに格納するために8ビット
分、右へシフトしているってところでしょうか)

昔私が使っていた本で、「UNIXシステムプログラミング」という本があって、
それにはわりとわかりやすく解説がありました。
(たぶん、羽山博著、オーム社だったと...)
まぁ、同じような本には載っているとは思いますが...。

こんな感じで、後は調べて見てください。

ただ、子プロセスを扱うプログラムは、親子で同期をとったり、また親子が同時に
動作しないといけないとか、いろいろ条件が複雑ですので、実際にシビアな使い方
をする場合は、よく仕様等を確認、テストしてくださいね。私も自信があまりない
ので、もし不具合等のトラブルがあっても、困りますので。
    • good
    • 0

こんにちは。

ずいぶん昔にUNIXでマルチプロセスのプログラム書いた経験の
あるものです。
もう当時のプログラムもCリファレンスも手許にないので...、うろ覚えで
かつ、断片的な情報ですが、こんなのでも調べる何かのヒントになればと思い、
書きます。

親側で、wait()を使って子プロを待ち、調べたのではないかと思います。
確かこんな感じ...
int status;
wait(&status);
呼び出したプログラムのstatus値(exitの値)は、
stat = (status & 0x0000ff00) >> 8;
みたいな感じで計算すれば、取得できたのでは...。
詳しくは、UNIXのシステムコールリファレンスなんかを読めば載っていると
思います。

間違えてる可能性もあるので、よく確かめてくださいね。やってみて、あってたら
ラッキーってくらいに考えてください。
不確かな情報で申し訳ないです。

この回答への補足

うまくいきました。ありがとうございます。
ところで、
stat = (status & 0x0000ff00) >> 8;
って具体的に何をしてるんでしょうか。
&ってANDをとってるんでしたっけ?
戻り値が1のときstatus=100
2のときstatus=200って感じになってるのはわかったんですけど。

補足日時:2001/07/19 17:08
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

Qif ( fp == NULL ){ を if ( fp == 0){ へ変更した場合

http://oshiete.goo.ne.jp/qa/8897349.html
 ですが
if ( fp == NULL ){ を
if ( fp == 0){
 fopen dekina と表示してくれるのでしょうか?
  試す環境がございませんので
 よろしくお願いいたします。

Aベストアンサー

>if ( fp == 0){
> fopen dekina と表示してくれるのでしょうか?

はい、表示してくれます。
NULLは、通常、(void*)0 の値が定義されていますので、実体は0と同じです。
しかし、NULLはポインターに対して定義されているのなので、
if ( fp == NULL) と書いたほうがよいでしょう。
一方、0は数値を表すので、
if (fp == 0)とは、書かないほうがよいでしょう。
int a;
が定義されていたとき、
if (a ==0) は、a(という数値を表す変数)の値が0か否かを判断するので、これでよいですが
if ( a== NULL) は、a(という数値を表す変数)の値がNULLか否かを判断するので、
違和感がありますから、使用しないほうが良いでしょう。

Qint nII[10] = { 0 }について

久々にCを使ってプログラムを組んでいるのですが、基本的な構文を思い出せず
いくつか教えていただきたく質問させていただきました。

1)配列すべてを初期化するのに、宣言時に

int nII[10] = { 0 };

で大丈夫だった(全ての要素が0で初期化)と記憶しているのですが、間違いないでしょうか?

2)構造体の初期化は

struct tm tm;
memset(&tm, 0, sizeof(struct tm))

で大丈夫でしょうか?

3)構造体の宣言は

typedef struct{
int a;
}HOGE, *LPHOGE;

HOGE st; // <- struct HOGE stと同じ
LPHOGE pst; // <- struct HOGE* pstと同じ

で問題ないでしょうか?

以上、3つ質問になって申し訳ないのですが、よろしくお願いします。

Aベストアンサー

1)OK
2)たぶんOK
3)HOGEという名前の構造体はない(当該の構造体には名前がない)ので、
// 以下のコメント記述が誤っています。ただし、

HOGE st;
LPHOGE pst;
という定義そのものはOK

QSendMessage(hW,WM_CREATE,0,0);を

SendMessage(hW,WM_CREATE,0,0);
を実行するとシステムがWM_DOWNやWM_CHARを発行しなくなるみたいです
というのはそれ以降キー入力を無視するようになるのです
いったんアプリをアイコン化してウィンドウ化するとWM_DOWNやWM_CHARを発行するようになります
WM_CREATEを送ってもWM_DOWNやWM_CHARを発行しなくなるのを阻止するために何か方法はないでしょうか?

Aベストアンサー

>プログラムのイニシャライズのために送ったのですが送らないで住むプログラムに変更しました

普通はそんな方法はとりません。
システムが何をするか分からないからです。

自分でメッセージを定義して、初期化処理を行うようするためのメッセージを送るほうが無難です。
WM_CREATEと同じ処理を初期化処理として行わせたいのであれば、初期化処理を関数化して自分で定義したメッセージでも呼び出せばいいのですし。


>作ったプッシュボタンを押してシステムがWM_COMMANDを送ってきた後キー関係のメッセージを送ってくれなくなります

プッシュボタンがキーボードフォーカスを持ってのるでは?

ボタンがキーボードフォーカスを持っていてもキー関連のメッセージを親ウィンドウが受け取りたいのであれば、サブクラス化をするしかないでしょう。


人気Q&Aランキング

おすすめ情報