aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys/unix/erl_child_setup.c
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2015-08-27 10:56:15 +0200
committerLukas Larsson <[email protected]>2015-12-15 10:05:45 +0100
commit3599b995428032eb26e8b7cc6ac52bc5260ee454 (patch)
treea1d0757e32d682e3bc91e7d5db462742fca18330 /erts/emulator/sys/unix/erl_child_setup.c
parent05823de18bd48b70b398a6b6fd756a0f71587283 (diff)
downloadotp-3599b995428032eb26e8b7cc6ac52bc5260ee454.tar.gz
otp-3599b995428032eb26e8b7cc6ac52bc5260ee454.tar.bz2
otp-3599b995428032eb26e8b7cc6ac52bc5260ee454.zip
erts: Make child_setup work with large environments
Diffstat (limited to 'erts/emulator/sys/unix/erl_child_setup.c')
-rw-r--r--erts/emulator/sys/unix/erl_child_setup.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c
index 8bec36be60..6e0a7c143f 100644
--- a/erts/emulator/sys/unix/erl_child_setup.c
+++ b/erts/emulator/sys/unix/erl_child_setup.c
@@ -109,7 +109,7 @@ static int sigchld_pipe[2];
static int
start_new_child(int pipes[])
{
- int size, res, i;
+ int size, res, i, pos = 0;
char *buff, *o_buff;
char *cmd, *wd, **new_environ, **args = NULL, cbuff[1];
@@ -126,10 +126,19 @@ start_new_child(int pipes[])
DEBUG_PRINT("size = %d", size);
- if ((res = read(pipes[0], buff, size)) != size) {
- ABORT("Failed to read %d bytes from %d (%d,%d)",
- size, pipes[0], res, errno);
- }
+ do {
+ if ((res = read(pipes[0], buff + pos, size - pos)) < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ ABORT("Failed to read %d bytes from %d (%d,%d)",
+ size, pipes[0], res, errno);
+ }
+ if (res == 0) {
+ errno = EPIPE;
+ goto child_error;
+ }
+ pos += res;
+ } while(size - pos != 0);
o_buff = buff;
@@ -154,6 +163,7 @@ start_new_child(int pipes[])
buff += sizeof(Sint32);
new_environ = malloc(sizeof(char*)*(cnt + 1));
+ DEBUG_PRINT("env_len = %ld", cnt);
for (i = 0; i < cnt; i++, buff++) {
new_environ[i] = buff;
while(*buff != '\0') buff++;
@@ -176,6 +186,7 @@ start_new_child(int pipes[])
ABORT("Buff error: %p, %p:%p", o_buff, o_buff+size, buff);
}
+ DEBUG_PRINT("read ack");
if (read(pipes[0], cbuff, 1) < 1)
goto child_error;
@@ -230,7 +241,8 @@ start_new_child(int pipes[])
execle(SHELL, "sh", "-c", cmd, (char *) NULL, new_environ);
}
child_error:
- _exit(1);
+ DEBUG_PRINT("exec error: %d\r\n",errno);
+ _exit(128 + errno);
}
@@ -392,7 +404,7 @@ main(int argc, char *argv[])
int ibuff[2];
char buff[256];
res = read(sigchld_pipe[0], ibuff, sizeof(ibuff));
- if (res < 0) {
+ if (res <= 0) {
if (errno == EINTR)
continue;
ABORT("Failed to read from sigchld pipe: %d (%d)", res, errno);