提交 4b2133de 编写于 作者: M martin

6856590: (process) Use RESTARTABLE in UNIXProcess_md.c

Summary: Wrap all system calls with RESTARTABLE
Reviewed-by: michaelm
上级 b8e20275
...@@ -140,6 +140,13 @@ ...@@ -140,6 +140,13 @@
#define FAIL_FILENO (STDERR_FILENO + 1) #define FAIL_FILENO (STDERR_FILENO + 1)
/* TODO: Refactor. */
#define RESTARTABLE(_cmd, _result) do { \
do { \
_result = _cmd; \
} while((_result == -1) && (errno == EINTR)); \
} while(0)
/* This is one of the rare times it's more portable to declare an /* This is one of the rare times it's more portable to declare an
* external symbol explicitly, rather than via a system header. * external symbol explicitly, rather than via a system header.
* The declaration is standardized as part of UNIX98, but there is * The declaration is standardized as part of UNIX98, but there is
...@@ -342,6 +349,36 @@ Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env, ...@@ -342,6 +349,36 @@ Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env,
} }
} }
static ssize_t
restartableWrite(int fd, const void *buf, size_t count)
{
ssize_t result;
RESTARTABLE(write(fd, buf, count), result);
return result;
}
static int
restartableDup2(int fd_from, int fd_to)
{
int err;
RESTARTABLE(dup2(fd_from, fd_to), err);
return err;
}
static int
restartableClose(int fd)
{
int err;
RESTARTABLE(close(fd), err);
return err;
}
static int
closeSafely(int fd)
{
return (fd == -1) ? 0 : restartableClose(fd);
}
static int static int
isAsciiDigit(char c) isAsciiDigit(char c)
{ {
...@@ -362,8 +399,8 @@ closeDescriptors(void) ...@@ -362,8 +399,8 @@ closeDescriptors(void)
* the lowest numbered file descriptor, just like open(). So we * the lowest numbered file descriptor, just like open(). So we
* close a couple explicitly. */ * close a couple explicitly. */
close(from_fd); /* for possible use by opendir() */ restartableClose(from_fd); /* for possible use by opendir() */
close(from_fd + 1); /* another one for good luck */ restartableClose(from_fd + 1); /* another one for good luck */
if ((dp = opendir("/proc/self/fd")) == NULL) if ((dp = opendir("/proc/self/fd")) == NULL)
return 0; return 0;
...@@ -375,7 +412,7 @@ closeDescriptors(void) ...@@ -375,7 +412,7 @@ closeDescriptors(void)
int fd; int fd;
if (isAsciiDigit(dirp->d_name[0]) && if (isAsciiDigit(dirp->d_name[0]) &&
(fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2) (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2)
close(fd); restartableClose(fd);
} }
closedir(dp); closedir(dp);
...@@ -383,13 +420,15 @@ closeDescriptors(void) ...@@ -383,13 +420,15 @@ closeDescriptors(void)
return 1; return 1;
} }
static void static int
moveDescriptor(int fd_from, int fd_to) moveDescriptor(int fd_from, int fd_to)
{ {
if (fd_from != fd_to) { if (fd_from != fd_to) {
dup2(fd_from, fd_to); if ((restartableDup2(fd_from, fd_to) == -1) ||
close(fd_from); (restartableClose(fd_from) == -1))
return -1;
} }
return 0;
} }
static const char * static const char *
...@@ -586,13 +625,6 @@ JDK_execvpe(const char *file, ...@@ -586,13 +625,6 @@ JDK_execvpe(const char *file,
} }
} }
static void
closeSafely(int fd)
{
if (fd != -1)
close(fd);
}
/* /*
* Reads nbyte bytes from file descriptor fd into buf, * Reads nbyte bytes from file descriptor fd into buf,
* The read operation is retried in case of EINTR or partial reads. * The read operation is retried in case of EINTR or partial reads.
...@@ -661,31 +693,40 @@ childProcess(void *arg) ...@@ -661,31 +693,40 @@ childProcess(void *arg)
/* Close the parent sides of the pipes. /* Close the parent sides of the pipes.
Closing pipe fds here is redundant, since closeDescriptors() Closing pipe fds here is redundant, since closeDescriptors()
would do it anyways, but a little paranoia is a good thing. */ would do it anyways, but a little paranoia is a good thing. */
closeSafely(p->in[1]); if ((closeSafely(p->in[1]) == -1) ||
closeSafely(p->out[0]); (closeSafely(p->out[0]) == -1) ||
closeSafely(p->err[0]); (closeSafely(p->err[0]) == -1) ||
closeSafely(p->fail[0]); (closeSafely(p->fail[0]) == -1))
goto WhyCantJohnnyExec;
/* Give the child sides of the pipes the right fileno's. */ /* Give the child sides of the pipes the right fileno's. */
/* Note: it is possible for in[0] == 0 */ /* Note: it is possible for in[0] == 0 */
moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0], STDIN_FILENO); if ((moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0],
moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1], STDOUT_FILENO); STDIN_FILENO) == -1) ||
(moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1],
STDOUT_FILENO) == -1))
goto WhyCantJohnnyExec;
if (p->redirectErrorStream) { if (p->redirectErrorStream) {
closeSafely(p->err[1]); if ((closeSafely(p->err[1]) == -1) ||
dup2(STDOUT_FILENO, STDERR_FILENO); (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1))
goto WhyCantJohnnyExec;
} else { } else {
moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2], STDERR_FILENO); if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2],
STDERR_FILENO) == -1)
goto WhyCantJohnnyExec;
} }
moveDescriptor(p->fail[1], FAIL_FILENO); if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1)
goto WhyCantJohnnyExec;
/* close everything */ /* close everything */
if (closeDescriptors() == 0) { /* failed, close the old way */ if (closeDescriptors() == 0) { /* failed, close the old way */
int max_fd = (int)sysconf(_SC_OPEN_MAX); int max_fd = (int)sysconf(_SC_OPEN_MAX);
int i; int fd;
for (i = FAIL_FILENO + 1; i < max_fd; i++) for (fd = FAIL_FILENO + 1; fd < max_fd; fd++)
close(i); if (restartableClose(fd) == -1 && errno != EBADF)
goto WhyCantJohnnyExec;
} }
/* change to the new working directory */ /* change to the new working directory */
...@@ -710,9 +751,9 @@ childProcess(void *arg) ...@@ -710,9 +751,9 @@ childProcess(void *arg)
*/ */
{ {
int errnum = errno; int errnum = errno;
write(FAIL_FILENO, &errnum, sizeof(errnum)); restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum));
} }
close(FAIL_FILENO); restartableClose(FAIL_FILENO);
_exit(-1); _exit(-1);
return 0; /* Suppress warning "no return value from function" */ return 0; /* Suppress warning "no return value from function" */
} }
...@@ -847,7 +888,7 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, ...@@ -847,7 +888,7 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
goto Catch; goto Catch;
} }
close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */ restartableClose(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */
switch (readFully(fail[0], &errnum, sizeof(errnum))) { switch (readFully(fail[0], &errnum, sizeof(errnum))) {
case 0: break; /* Exec succeeded */ case 0: break; /* Exec succeeded */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册