Update of /cvsroot/boost/boost/tools/jam/src
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv12753
Modified Files:
Tag: Boost_Jam_994
execunix.c
Log Message:
Add logic for separating stdout and stderr. This solution is commented out
with #if 0 right now although it has been tested and is fully functional.
The default implementation is to merge stdout and stderr into a single stream.
Index: execunix.c
===================================================================
RCS file: /cvsroot/boost/boost/tools/jam/src/execunix.c,v
retrieving revision 1.10.2.4
retrieving revision 1.10.2.5
diff -u -d -r1.10.2.4 -r1.10.2.5
--- execunix.c 2 Jun 2007 03:38:58 -0000 1.10.2.4
+++ execunix.c 2 Jun 2007 05:47:33 -0000 1.10.2.5
@@ -59,14 +59,17 @@
static int cmdsrunning = 0;
static void (*istat)( int );
+#define OUT 0
+#define ERR 1
+
static struct
{
int pid; /* on win32, a real process handle */
- int fd; /* file descriptors for stdout and stderr */
- FILE *stream; /* child's stderr file stream */
+ int fd[2]; /* file descriptors for stdout and stderr */
+ FILE *stream[2]; /* child's stdout (0) and stderr (1) file stream */
int com_len; /* length of comamnd buffer */
char *command; /* buffer to hold command rule being invoked */
- char *buffer; /* buffer to hold stderr output, if any */
+ char *buffer[2]; /* buffer to hold stdout and stderr, if any */
void (*func)( void *closure, int status, timing_info* );
void *closure;
} cmdtab[ MAXJOBS ] = {{0}};
@@ -95,7 +98,7 @@
char *rule_name,
char *target )
{
- int p[2];
+ int out[2], err[2];
int slot, len;
char *argv[ MAXARGC + 1 ]; /* +1 for NULL */
FILE *stream;
@@ -154,22 +157,31 @@
/* create pipe from child to parent */
- if (pipe(p) < 0)
+ if (pipe(out) < 0)
exit(EXITBAD);
- fcntl(p[0], F_SETFL, O_NONBLOCK);
- fcntl(p[1], F_SETFL, O_NONBLOCK);
-
- /* child writes stderr to p[1], parent reads p[0] */
- cmdtab[slot].fd = p[0];
+ fcntl(out[0], F_SETFL, O_NONBLOCK);
+ fcntl(out[1], F_SETFL, O_NONBLOCK);
+#if 0
+ if (pipe(err) < 0)
+ exit(EXITBAD);
+ fcntl(err[0], F_SETFL, O_NONBLOCK);
+ fcntl(err[1], F_SETFL, O_NONBLOCK);
+#endif
/* Start the command */
if ((cmdtab[slot].pid = vfork()) == 0)
{
- close(p[0]);
- dup2(p[1], STDERR_FILENO);
- dup2(p[1], STDOUT_FILENO);
+ close(out[0]);
+ dup2(out[1], STDOUT_FILENO);
+
+#if 0
+ close(err[0]);
+ dup2(err[1], STDERR_FILENO);
+#else
+ dup2(out[1], STDERR_FILENO);
+#endif
execvp( argv[0], argv );
_exit(127);
@@ -181,13 +193,30 @@
}
/* close write end of pipe, open read end of pipe */
+ close(out[1]);
+#if 0
+ close(err[1]);
+#endif
- close(p[1]);
- cmdtab[slot].stream = fdopen(cmdtab[slot].fd, "rb");
- if (cmdtab[slot].stream == NULL) {
+ /* child writes stdout to out[1], parent reads from out[0]
+ child writes stderr to err[1], parent reads from err[0] */
+ cmdtab[slot].fd[OUT] = out[0];
+#if 0
+ cmdtab[slot].fd[ERR] = err[0];
+#endif
+
+ cmdtab[slot].stream[OUT] = fdopen(cmdtab[slot].fd[OUT], "rb");
+ if (cmdtab[slot].stream[OUT] == NULL) {
perror( "fdopen" );
exit( EXITBAD );
}
+#if 0
+ cmdtab[slot].stream[ERR] = fdopen(cmdtab[slot].fd[ERR], "rb");
+ if (cmdtab[slot].stream[ERR] == NULL) {
+ perror( "fdopen" );
+ exit( EXITBAD );
+ }
+#endif
/* ensure enough room for rule and target name */
@@ -224,31 +253,56 @@
break;
}
-void read_descriptor(int i)
+/* returns 1 if file is closed, 0 if descriptor is still live
+ *
+ * i is index into cmdtab
+ *
+ * s (stream) indexes
+ *
+ * cmdtab[i].stream[s]
+ * cmdtab[i].buffer[s] and
+ * cmdtab[i].fd[s]
+ */
+
+int read_descriptor(int i, int s)
{
int done, ret, len;
char buffer[BUFSIZ];
- while (0 < (ret = fread(buffer, sizeof(char), BUFSIZ-1,
cmdtab[i].stream)))
+ while (0 < (ret = fread(buffer, sizeof(char), BUFSIZ-1,
cmdtab[i].stream[s])))
{
buffer[ret] = 0;
- if (!cmdtab[i].buffer)
+ if (!cmdtab[i].buffer[s])
{
/* never been allocated */
- cmdtab[i].buffer = (char*)malloc(ret+1);
- memcpy(cmdtab[i].buffer, buffer, ret+1);
+ cmdtab[i].buffer[s] = (char*)malloc(ret+1);
+ memcpy(cmdtab[i].buffer[s], buffer, ret+1);
}
else
{
/* previously allocated */
- char *tmp = cmdtab[i].buffer;
+ char *tmp = cmdtab[i].buffer[s];
len = strlen(tmp);
- cmdtab[i].buffer = (char*)malloc(len+ret+1);
- memcpy(cmdtab[i].buffer, tmp, len);
- memcpy(cmdtab[i].buffer+len, buffer, ret+1);
+ cmdtab[i].buffer[s] = (char*)malloc(len+ret+1);
+ memcpy(cmdtab[i].buffer[s], tmp, len);
+ memcpy(cmdtab[i].buffer[s]+len, buffer, ret+1);
free(tmp);
}
}
+
+ if (feof(cmdtab[i].stream[s]))
+ {
+ /* close the stream and pipe descriptor */
+ fclose(cmdtab[i].stream[s]);
+ cmdtab[i].stream[s] = 0;
+
+ close(cmdtab[i].fd[s]);
+ cmdtab[i].fd[s] = 0;
+
+ return 1;
+ }
+
+ return 0;
}
/*
@@ -276,87 +330,106 @@
finished = 0;
while (!finished && cmdsrunning)
{
- /* compute max read file descriptor for use in select */
- fd_max = 0;
- FD_ZERO(&fds);
- for (i=0; i<globs.jobs; ++i)
- if (0 < cmdtab[i].fd)
- {
- fd_max = fd_max < cmdtab[i].fd ? cmdtab[i].fd : fd_max;
- FD_SET(cmdtab[i].fd, &fds);
- }
+ /* compute max read file descriptor for use in select */
+ fd_max = 0;
+ FD_ZERO(&fds);
+ for (i=0; i<globs.jobs; ++i)
+ {
+ if (0 < cmdtab[i].fd[OUT])
+ {
+ fd_max = fd_max < cmdtab[i].fd[OUT] ? cmdtab[i].fd[OUT] :
fd_max;
+ FD_SET(cmdtab[i].fd[OUT], &fds);
+ }
+#if 0
+ if (0 < cmdtab[i].fd[ERR])
+ {
+ fd_max = fd_max < cmdtab[i].fd[ERR] ? cmdtab[i].fd[ERR] :
fd_max;
+ FD_SET(cmdtab[i].fd[ERR], &fds);
+ }
+#endif
+ }
- /* select will wait until io or a signal */
- ret = select(fd_max+1, &fds, 0, 0, 0);
+ /* select will wait until io on a descriptor or a signal */
+ ret = select(fd_max+1, &fds, 0, 0, 0);
- if (0 < ret)
+ if (0 < ret)
+ {
+ for (i=0; i<globs.jobs; ++i)
{
- for (i=0; i<globs.jobs; ++i)
+ int out = 0, err = 0;
+ if (FD_ISSET(cmdtab[i].fd[OUT], &fds))
+ out = read_descriptor(i, OUT);
+#if 0
+ if (FD_ISSET(cmdtab[i].fd[ERR], &fds))
+ err = read_descriptor(i, ERR);
+#endif
+ /* if either descriptor closed, then we're done */
+ if (out || err)
{
- if (FD_ISSET(cmdtab[i].fd, &fds))
+ /* reap the child and release resources */
+ pid = waitpid(cmdtab[i].pid, &status, 0);
+
+ if (pid == cmdtab[i].pid)
{
- read_descriptor(i);
+ finished = 1;
+ pid = 0;
+ cmdtab[i].pid = 0;
- if (feof(cmdtab[i].stream))
- {
- /* close the stream and pipe descriptor */
- fclose(cmdtab[i].stream);
- cmdtab[i].stream = 0;
-
- close(cmdtab[i].fd);
- cmdtab[i].fd = 0;
+ times(&old_time);
- /* reap the child and release resources */
- pid = waitpid(cmdtab[i].pid, &status, 0);
+ /* print out the rule and target name */
+ if (cmdtab[i].command)
+ {
+ printf("%s\n", cmdtab[i].command);
- if (pid == cmdtab[i].pid)
+ /* print out the command output, if any */
+ if (cmdtab[i].buffer[OUT])
{
- finished = 1;
- pid = 0;
- cmdtab[i].pid = 0;
+ printf("%s", cmdtab[i].buffer[OUT]);
+ /* print out rule and target to both stdout
and stderr */
+ if (cmdtab[i].buffer[ERR])
+ fprintf(stderr, "%s\n", cmdtab[i].command);
+ }
- times(&old_time);
+ if (cmdtab[i].buffer[ERR])
+ fprintf(stderr, "%s", cmdtab[i].buffer[ERR]);
+ }
- /* print out the rule and target name */
- if (cmdtab[i].command)
- printf("%s\n", cmdtab[i].command);
+ free(cmdtab[i].buffer[OUT]);
+ cmdtab[i].buffer[OUT] = 0;
- /* print out the command output, if any */
- if (cmdtab[i].buffer)
- printf("%s", cmdtab[i].buffer);
- free(cmdtab[i].buffer);
- cmdtab[i].buffer = 0;
+ free(cmdtab[i].buffer[ERR]);
+ cmdtab[i].buffer[ERR] = 0;
- times(&new_time);
+ times(&new_time);
- time.system = (double)(new_time.tms_cstime -
old_time.tms_cstime) / CLOCKS_PER_SEC;
- time.user = (double)(new_time.tms_cutime -
old_time.tms_cutime) / CLOCKS_PER_SEC;
+ time.system = (double)(new_time.tms_cstime -
old_time.tms_cstime) / CLOCKS_PER_SEC;
+ time.user = (double)(new_time.tms_cutime -
old_time.tms_cutime) / CLOCKS_PER_SEC;
- /* Drive the completion */
+ /* Drive the completion */
- --cmdsrunning;
+ --cmdsrunning;
- if( intr )
- rstat = EXEC_CMD_INTR;
- else if( w == -1 || status != 0 )
- rstat = EXEC_CMD_FAIL;
- else
- rstat = EXEC_CMD_OK;
+ if( intr )
+ rstat = EXEC_CMD_INTR;
+ else if( w == -1 || status != 0 )
+ rstat = EXEC_CMD_FAIL;
+ else
+ rstat = EXEC_CMD_OK;
- (*cmdtab[ i ].func)( cmdtab[ i ].closure,
rstat, &time );
+ (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat, &time
);
- cmdtab[i].func = 0;
- cmdtab[i].closure = 0;
- }
- if (0 != pid)
- {
- printf("pid not one of our processes?\n");
- exit(EXITBAD);
- }
- }
+ cmdtab[i].func = 0;
+ cmdtab[i].closure = 0;
+ }
+ if (0 != pid)
+ {
+ printf("pid not one of our processes?\n");
+ exit(EXITBAD);
}
}
}
+ }
}
return 1;
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs