大于255的ExitCodes,可能吗? [英] ExitCodes bigger than 255, possible?

查看:77
本文介绍了大于255的ExitCodes,可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果是,请在哪个操作系统,shell或其他操作系统上使用

If yes, on which operating system, shell or whatever?

请考虑以下Java程序(我仅以Java为例,此问题适合任何语言,更多有关操作系统):

Consider the following java program (I'm using java just as an example, any language would be good for this question, which is more about operation systems):

public class ExitCode {
    public static void main(String args[]) {
        System.exit(Integer.parseInt(args[0]));
    }
}

在Linux和bash上运行它,它总是返回小于255的值,例如(echo $?打印上一条已执行命令的退出代码)

Running it on Linux and bash, it returns always values less equal 255, e.g. (echo $? prints the exit code of the previous executed command)

> java ExitCode 2; echo $?
2

> java ExitCode 128; echo $?
128

> java ExitCode 255; echo $?
255

> java ExitCode 256; echo $?
0

> java ExitCode 65536; echo $?
0


已下面的(仅到目前为止)答案完全解释了UNIX上发生的情况.我仍然想知道其他操作系统.


EDITED: the (only, so far) answer below fully explain what happens on UNIXes. I'm still wondering about other OSes.

推荐答案

使用wait()waitpid()

在Unix及其衍生版本上,无法使用POSIX函数,例如 wait() waitpid() .返回的退出状态信息由两个8位字段组成,一个包含退出状态,另一个包含有关死亡原因的信息(0表示在程序控制下有序退出,其他值指示信号杀死了它,并指示是否杀死了该信号.堆芯).

Using wait() or waitpid()

It is not possible on Unix and derivatives using POSIX functions like wait() and waitpid(). The exit status information returned consists of two 8-bit fields, one containing the exit status, and the other containing information about the cause of death (0 implying orderly exit under program control, other values indicating that a signal killed it, and indicating whether a core was dumped).

如果您努力工作,请阅读 sigaction() <的POSIX规范. /a>和 <signal.h> 信号操作,您会发现可以使用32位子进程传递给exit()的值.但是,这并不完全简单.

If you work hard, and read the POSIX specification of sigaction() and <signal.h> and Signal Actions, you will find that you can get hold of the 32-bit value passed to exit() by a child process. However, it is not completely straight-forward.

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

static siginfo_t sig_info = { 0 };
static volatile sig_atomic_t sig_num = 0;
static void *sig_ctxt = 0;

static void catcher(int signum, siginfo_t *info, void *vp)
{
    sig_num = signum;
    sig_info = *info;
    sig_ctxt = vp;
}

static void set_handler(int signum)
{
    struct sigaction sa;
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = catcher;
    sigemptyset(&sa.sa_mask);

    if (sigaction(signum, &sa, 0) != 0)
    {
        int errnum = errno;
        fprintf(stderr, "Failed to set signal handler (%d: %s)\n", errnum, strerror(errnum));
        exit(1);
    }
}

static void prt_interrupt(FILE *fp)
{
    if (sig_num != 0)
    {
        fprintf(fp, "Signal %d from PID %d (status 0x%.8X; UID %d)\n",
                sig_info.si_signo, (int)sig_info.si_pid, sig_info.si_status,
                (int)sig_info.si_uid);
        sig_num = 0;
    }
}

static void five_kids(void)
{
    const int base = 0xCC00FF40;
    for (int i = 0; i < 5; i++)
    {
        pid_t pid = fork();
        if (pid < 0)
            break;
        else if (pid == 0)
        {
            printf("PID %d - exiting with status %d (0x%.8X)\n",
                   (int)getpid(), base + i, base + i);
            exit(base + i);
        }
        else
        {
            int status = 0;
            pid_t corpse = wait(&status);
            if (corpse != -1)
                printf("Child: %d; Corpse: %d; Status = 0x%.4X - waited\n", pid, corpse, (status & 0xFFFF));
            struct timespec nap = { .tv_sec = 0, .tv_nsec = 1000000 }; // 1 millisecond
            nanosleep(&nap, 0);
            prt_interrupt(stdout);
            fflush(0);
        }
    }
}

int main(void)
{
    set_handler(SIGCHLD);
    five_kids();
}

运行时(从sigexit73.c编译的程序sigexit73),将产生如下输出:

When run (program sigexit73 compiled from sigexit73.c), this produces output like:

$ sigexit73
PID 26599 - exiting with status -872349888 (0xCC00FF40)
Signal 20 from PID 26599 (status 0xCC00FF40; UID 501)
Child: 26600; Corpse: 26599; Status = 0x4000 - waited
PID 26600 - exiting with status -872349887 (0xCC00FF41)
Signal 20 from PID 26600 (status 0xCC00FF41; UID 501)
Child: 26601; Corpse: 26600; Status = 0x4100 - waited
PID 26601 - exiting with status -872349886 (0xCC00FF42)
Signal 20 from PID 26601 (status 0xCC00FF42; UID 501)
Child: 26602; Corpse: 26601; Status = 0x4200 - waited
PID 26602 - exiting with status -872349885 (0xCC00FF43)
Signal 20 from PID 26602 (status 0xCC00FF43; UID 501)
Child: 26603; Corpse: 26602; Status = 0x4300 - waited
PID 26603 - exiting with status -872349884 (0xCC00FF44)
Signal 20 from PID 26603 (status 0xCC00FF44; UID 501)
$

删除对nanosleep()的一毫秒调用后,输出易于如下所示:

With the one millisecond call to nanosleep() removed, the output is apt to look like:

$ sigexit73
sigexit23
PID 26621 - exiting with status -872349888 (0xCC00FF40)
Signal 20 from PID 26621 (status 0xCC00FF40; UID 501)
Child: 26622; Corpse: 26621; Status = 0x4000 - waited
PID 26622 - exiting with status -872349887 (0xCC00FF41)
PID 26623 - exiting with status -872349886 (0xCC00FF42)
Signal 20 from PID 26622 (status 0xCC00FF41; UID 501)
Child: 26624; Corpse: 26623; Status = 0x4200 - waited
Signal 20 from PID 26623 (status 0xCC00FF42; UID 501)
Child: 26625; Corpse: 26622; Status = 0x4100 - waited
PID 26624 - exiting with status -872349885 (0xCC00FF43)
PID 26625 - exiting with status -872349884 (0xCC00FF44)
$

请注意,这里只有三行以Signal开头,也只有三行以waited结尾;一些信号和退出状态会丢失.这可能是由于SIGCHLD信号被设置为父进程之间的时序问题.

Note that there are only three lines starting Signal here, and also only three lines ending waited; some of the signals and exit statuses are lost. This is likely to be because of timing issues between the SIGCHLD signals being set to the parent process.

但是,关键是当代码使用sigaction()SIGCHLDSA_SIGINFO跟踪状态时,可以在exit()状态下传输4个字节的数据.

However, the key point is that 4 bytes of data can be transmitted in the exit() status when the code uses sigaction(), SIGCHLD, SA_SIGINFO to track the status.

仅作记录,该测试是使用GCC 9.2.0和XCode 11.3.1在运行macOS Mojave 10.14.6的MacBook Pro上进行的.该代码也可以在我的GitHub上的 SOQ (堆栈溢出问题)存储库中以文件sigexit73.c的形式获得. src/so-1843-7779 子-目录.

Just for the record, the testing was performed on a MacBook Pro running macOS Mojave 10.14.6, using GCC 9.2.0 and XCode 11.3.1. The code is also available in my SOQ (Stack Overflow Questions) repository on GitHub as file sigexit73.c in the src/so-1843-7779 sub-directory.

这篇关于大于255的ExitCodes,可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆