# HG changeset patch # User stuefe # Date 1559821935 -7200 # Thu Jun 06 13:52:15 2019 +0200 # Node ID 688623db9df29172a8d3a1f30876d134c8390cef # Parent f74f0d3033a9d28bb2200134aab017fb86ac0774 [mq]: exec-better-error-text diff -r f74f0d3033a9 -r 688623db9df2 src/java.base/unix/native/libjava/childproc.c --- a/src/java.base/unix/native/libjava/childproc.c Wed Jun 05 22:19:09 2019 -0700 +++ b/src/java.base/unix/native/libjava/childproc.c Thu Jun 06 13:52:15 2019 +0200 @@ -309,9 +309,11 @@ * of its address space to be shared with its parent, or to be a copy. * It must not modify global variables such as "environ". */ + #define JOHNNY_CANNOT_EXEC(info) { errctx = context; goto WhyCantJohnnyExec; } int childProcess(void *arg) { + int errctx = 0; const ChildStuff* p = (const ChildStuff*) arg; int fail_pipe_fd = p->fail[1]; @@ -331,7 +333,8 @@ (closeSafely(p->childenv[0]) == -1) || (closeSafely(p->childenv[1]) == -1) || (closeSafely(p->fail[0]) == -1)) - goto WhyCantJohnnyExec; + JOHNNY_CANNOT_EXEC(ERRCTX_CLOSE_MOVE_FD); + /* Give the child sides of the pipes the right fileno's. */ /* Note: it is possible for in[0] == 0 */ @@ -339,20 +342,20 @@ STDIN_FILENO) == -1) || (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1], STDOUT_FILENO) == -1)) - goto WhyCantJohnnyExec; + JOHNNY_CANNOT_EXEC(ERRCTX_CLOSE_MOVE_FD); if (p->redirectErrorStream) { if ((closeSafely(p->err[1]) == -1) || (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1)) - goto WhyCantJohnnyExec; + JOHNNY_CANNOT_EXEC(ERRCTX_CLOSE_MOVE_FD); } else { if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2], STDERR_FILENO) == -1) - goto WhyCantJohnnyExec; + JOHNNY_CANNOT_EXEC(ERRCTX_CLOSE_MOVE_FD); } if (moveDescriptor(fail_pipe_fd, FAIL_FILENO) == -1) - goto WhyCantJohnnyExec; + JOHNNY_CANNOT_EXEC(ERRCTX_CLOSE_MOVE_FD); /* We moved the fail pipe fd */ fail_pipe_fd = FAIL_FILENO; @@ -363,18 +366,21 @@ int fd; for (fd = FAIL_FILENO + 1; fd < max_fd; fd++) if (close(fd) == -1 && errno != EBADF) - goto WhyCantJohnnyExec; + JOHNNY_CANNOT_EXEC(ERRCTX_CLOSE_MOVE_FD); } /* change to the new working directory */ if (p->pdir != NULL && chdir(p->pdir) < 0) - goto WhyCantJohnnyExec; + JOHNNY_CANNOT_EXEC(ERRCTX_CHDIR); if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1) - goto WhyCantJohnnyExec; + JOHNNY_CANNOT_EXEC(ERRCTX_CLOSE_MOVE_FD); JDK_execvpe(p->mode, p->argv[0], p->argv, p->envv); + /* Still here? Exec error. */ + errctx = ERRCTX_EXEC; + WhyCantJohnnyExec: /* We used to go to an awful lot of trouble to predict whether the * child would fail, but there is no reliable way to predict the @@ -387,7 +393,7 @@ * yields EOF when the write ends (we have two of them!) are closed. */ { - int errnum = errno; + int errnum = errno | errctx; restartableWrite(fail_pipe_fd, &errnum, sizeof(errnum)); } close(fail_pipe_fd); diff -r f74f0d3033a9 -r 688623db9df2 src/java.base/unix/native/libjava/childproc.h --- a/src/java.base/unix/native/libjava/childproc.h Wed Jun 05 22:19:09 2019 -0700 +++ b/src/java.base/unix/native/libjava/childproc.h Thu Jun 06 13:52:15 2019 +0200 @@ -122,6 +122,21 @@ * our platforms. */ #define CHILD_IS_ALIVE 65535 +/* Context information to be sent from child to parent in case of an error, + * in addition to the errno; */ +#define ERRCTX_LOWEST CHILD_IS_ALIVE + 1 + +/* Failed to close or dup a file descriptor before exec. */ +#define ERRCTX_CLOSE_MOVE_FD ERRCTX_LOWEST + +/* Failed to change to designated current directory. */ +#define ERRCTX_CHDIR ERRCTX_LOWEST + 1 + +/* The exec call itself failed. */ +#define ERRCTX_EXEC ERRCTX_LOWEST + 2 + +const char* get_error_text(char* buf, size_t buflen, int errctx, int errnum); + /** * The cached and split version of the JDK's effective PATH. * (We don't support putenv("PATH=...") in native code)