6

サブプロセスの終了コードを取得しようとしています。LinuxとFreeBSDでは、次のようにできます。

[0] [ishpeck@kiyoshi /tmp]$ uname
FreeBSD
[0] [ishpeck@kiyoshi /tmp]$ cat tinker.c 
#include <stdio.h>
#include <sys/wait.h>

int main(void)
{
    FILE *proc = popen("ls", "r");
    printf("Exit code: %d\n", WEXITSTATUS(pclose(proc)));
    return 0;
}
[0] [ishpeck@kiyoshi /tmp]$ gcc tinker.c -o tinker
[0] [ishpeck@kiyoshi /tmp]$ ./tinker
Exit code: 0
[0] [ishpeck@kiyoshi /tmp]$ grep WEXITSTATUS /usr/include/sys/wait.h 
#define WEXITSTATUS(x)  (_W_INT(x) >> 8)

しかし、OpenBSDでは、コンパイラから苦情があります...

[0] [ishpeck@ishberk-00 /tmp]$ uname   
OpenBSD
[0] [ishpeck@ishberk-00 /tmp]$ cat tinker.c                                    
#include <stdio.h>
#include <sys/wait.h>

int main(void)
{
    FILE *proc = popen("ls", "r");
    printf("Exit code: %d\n", WEXITSTATUS(pclose(proc)));
    return 0;
}
[0] [ishpeck@ishberk-00 /tmp]$ gcc tinker.c -o tinker                          
tinker.c: In function 'main':
tinker.c:7: error: lvalue required as unary '&' operand
[1] [ishpeck@ishberk-00 /tmp]$ grep WEXITSTATUS /usr/include/sys/wait.h        
#define WEXITSTATUS(x)  (int)(((unsigned)_W_INT(x) >> 8) & 0xff)

私はそれがどのように行われるかは本当に気にしません、私はただ終了コードが必要です。

これにより、Macでもこの問題が発生すると思います:http: //web.archiveorange.com/archive/v/8XiUWJBLMIKYSCRJnZK5#F4GgyRGRAgSCEG1

WEXITSTATUSマクロを使用するためのより移植性の高い方法はありますか?または、よりポータブルな代替手段はありますか?

4

3 に答える 3

9

OpenBSDの実装でWEXITSTATUSは、引数にaddress-of演算子(単項&)を使用しているため、引数にストレージが必要です。ストレージを持たない関数の戻り値を使用して呼び出しているため、コンパイラーは文句を言います。

OpenBSDがPOSIXに準拠しているかどうかは不明ですが、の戻り値を変数WEXITSTATUSに割り当てることで、この問題を簡単に回避できます。pclose()

    int status = pclose(proc);
    printf("Exit code: %d\n", WEXITSTATUS(status));
于 2012-12-02T22:50:01.730 に答える
0

アプリケーションが死亡した場合、または他の方法で強制終了された場合、戻りステータスは偽物です。ステータスをチェックして、終了値が有効かどうかを確認する必要があります。waitpid のマニュアル ページを参照してください。

if(WIFEXITED(status))
{
     use WEXITSTATUS(status);
} else if (WIFSIGNALED(status)) {
     use WTERMSIG(status);
} else {
     oh oh
}
于 2015-03-26T21:09:31.693 に答える