From d74aaa326dc4ff0f3f99d74421653fdfb10a31a2 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 13 May 2016 19:14:47 +0800 Subject: [PATCH] make exit code of exec/container consist with docker The exit code from `docker run` gives information about why the container failed to run or why it exited. When `docker run` exits with a non-zero code, the exit codes follow the `chroot` standard, see below: **_125_** if the error is with Docker daemon **_itself_** $ docker run --foo busybox; echo $? # flag provided but not defined: --foo See 'docker run --help'. 125 **_126_** if the **_contained command_** cannot be invoked $ docker run busybox /etc; echo $? # docker: Error response from daemon: Container command '/etc' could not be invoked. 126 **_127_** if the **_contained command_** cannot be found $ docker run busybox foo; echo $? # docker: Error response from daemon: Container command 'foo' not found or does not exist. 127 **_Exit code_** of **_contained command_** otherwise $ docker run busybox /bin/sh -c 'exit 3'; echo $? # 3 Signed-off-by: Gao feng --- src/container.c | 9 ++++++++- src/exec.c | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/container.c b/src/container.c index 6a1dd62..99b671c 100644 --- a/src/container.c +++ b/src/container.c @@ -624,8 +624,15 @@ static int hyper_container_init(void *data) execvp(container->exec.argv[0], container->exec.argv); perror("exec container command failed"); + /* the exit codes follow the `chroot` standard, + see docker/docs/reference/run.md#exit-status */ + if (errno == ENOENT) + _exit(127); + else if (errno == EACCES) + _exit(126); + fail: - _exit(-1); + _exit(125); } static int hyper_setup_pty(struct hyper_container *c) diff --git a/src/exec.c b/src/exec.c index 1ad68e8..2c0f121 100644 --- a/src/exec.c +++ b/src/exec.c @@ -590,10 +590,20 @@ static int hyper_do_exec_cmd(void *data) goto exit; } - if (execvp(exec->argv[0], exec->argv) < 0) + if (execvp(exec->argv[0], exec->argv) < 0) { perror("exec failed"); + + /* the exit codes follow the `chroot` standard, + see docker/docs/reference/run.md#exit-status */ + if (errno == ENOENT) + exit(127); + else if (errno == EACCES) + exit(126); + + } + exit: - _exit(ret); + _exit(125); out: hyper_send_type(arg->pipe[1], ret ? ERROR : READY); _exit(ret);