diff options
Diffstat (limited to 'sci-astronomy/funtools/files/funtools-1.4.0-ds9-5.4.patch')
-rw-r--r-- | sci-astronomy/funtools/files/funtools-1.4.0-ds9-5.4.patch | 2475 |
1 files changed, 0 insertions, 2475 deletions
diff --git a/sci-astronomy/funtools/files/funtools-1.4.0-ds9-5.4.patch b/sci-astronomy/funtools/files/funtools-1.4.0-ds9-5.4.patch deleted file mode 100644 index da7f5e48c9c6..000000000000 --- a/sci-astronomy/funtools/files/funtools-1.4.0-ds9-5.4.patch +++ /dev/null @@ -1,2475 +0,0 @@ ---- filter/evfilter.c.orig 2005-12-07 21:29:34.000000000 +0000 -+++ filter/evfilter.c 2007-12-18 20:10:26.000000000 +0000 -@@ -65,6 +65,9 @@ - g->masks = _masks; - } - /* initialize shapes -- but check to make sure eptr is OK */ -+#if DO_FILTER_SWAP -+ memset(_swf, 0, EVSIZE); -+#endif - if( eptr ) FINIT; - /* these also must be defined if EVSECT is being used */ - g->tlminx = TLMINX; -@@ -115,6 +118,9 @@ - /* do the filtering on each event */ - for(rptr=rbuf, eptr=ebuf; ne--; rptr++, eptr += esize){ - g->rid = 0; -+#if DO_FILTER_SWAP -+ memset(_swf, 0, EVSIZE); -+#endif - *rptr = ((FILTER) ? (g->rid ? g->rid : -1) : 0); - } - return (void *)g; -@@ -123,14 +129,48 @@ - - int main(int argc, char **argv) - { -- char *ebuf, *etop; -- int *rbuf; -+ int i; -+ int pipes[4]; - int get, got; -+#if DO_FILTER_SWAP -+ int sgot; -+#endif - int n; -+ int *rbuf; -+ char *ebuf, *etop; -+ char *s=NULL, *t=NULL, *u=NULL; - void *g=NULL; - -+ /* Launch() sometimes rearranges passed pipes to be stdin/stdout */ -+ if( (s=getenv("LAUNCH_PIPES")) ){ -+ t = (char *)strdup(s); -+ for(i=0, u=(char *)strtok(t, ","); i<4 && u; -+ i++, u=(char *)strtok(NULL,",")){ -+ pipes[i] = atoi(u); -+ } -+ if( t ) free(t); -+ if( i < 4 ) return(1); -+ close(pipes[0]); -+ close(pipes[3]); -+ dup2(pipes[2], 0); close(pipes[2]); -+ dup2(pipes[1], 1); close(pipes[1]); -+ } -+ - /* read and filter events */ - while( read(0, &get, sizeof(int)) >0 ){ -+#if DO_FILTER_SWAP -+ switch(sizeof(int)){ -+ case 2: -+ _sw2((char *)&get,2,NULL,0); -+ break; -+ case 4: -+ _sw4((char *)&get,4,NULL,0); -+ break; -+ case 8: -+ _sw8((char *)&get,8,NULL,0); -+ break; -+ } -+#endif - ebuf = (char *)calloc(get, sizeof(char)); - for(n=0, etop=ebuf; get>0; etop += got, get -= got){ - if( (got=read(0, etop, get)) <=0 ) -@@ -144,7 +184,36 @@ - g = EVFILTRTN(g, ebuf, n, EVSIZE, rbuf); - /* write results */ - got = n*sizeof(int); -+#if DO_FILTER_SWAP -+ sgot = got; -+ switch(sizeof(int)){ -+ case 2: -+ _sw2((char *)&sgot,2,NULL,0); -+ break; -+ case 4: -+ _sw4((char *)&sgot,4,NULL,0); -+ break; -+ case 8: -+ _sw8((char *)&sgot,8,NULL,0); -+ break; -+ } -+ write(1, &sgot, sizeof(int)); -+#else - write(1, &got, sizeof(int)); -+#endif -+#if DO_FILTER_SWAP -+ switch(sizeof(int)){ -+ case 2: -+ _sw2((char *)rbuf,got,NULL,0); -+ break; -+ case 4: -+ _sw4((char *)rbuf,got,NULL,0); -+ break; -+ case 8: -+ _sw8((char *)rbuf,got,NULL,0); -+ break; -+ } -+#endif - write(1, rbuf, got); - if( ebuf) free(ebuf); - if( rbuf ) free(rbuf); ---- filter/filter.c.orig 2007-04-13 18:18:34.000000000 +0100 -+++ filter/filter.c 2007-12-18 20:10:26.000000000 +0000 -@@ -215,7 +215,6 @@ - int got=0; - char *s, *t; - char tbuf[SZ_LINE]; -- char *argv[3]; - Filter filter; - char *filtstr; - -@@ -471,11 +470,7 @@ - switch(filter->ptype){ - case PTYPE_PROCESS: - case PTYPE_CONTAINED: -- /* now start the filter process we just readied */ -- argv[0] = filter->prog; -- argv[1] = filter->args; -- argv[2] = NULL; -- if( !ProcessOpen(filter->prog, argv, -+ if( !ProcessOpen(filter->prog, - &(filter->ichan), &(filter->ochan), &(filter->pid)) ) - goto error; - break; -@@ -785,7 +780,6 @@ - if( filter->shflags ) xfree(filter->shflags); - if( filter->code ) xfree(filter->code); - if( filter->prog ) xfree(filter->prog); -- if( filter->args ) xfree(filter->args); - if( filter->string ) xfree(filter->string); - if( filter->xbin ) xfree(filter->xbin); - if( filter->ybin ) xfree(filter->ybin); ---- filter/filtprog_c.c.orig 2006-12-12 21:39:07.000000000 +0000 -+++ filter/filtprog_c.c 2007-12-18 20:10:26.000000000 +0000 -@@ -16,6 +16,7 @@ - #include <evregions_c.h> - #include <imregions_c.h> - #include <xalloc_c.h> -+#include <swap_c.h> - - /* - * -@@ -316,6 +317,14 @@ - break; - } - -+ /* we want the byte order up at the top */ -+ if( is_bigendian() ){ -+ fprintf(fd, "#define MYBYTE_ORDER 4321\n"); -+ } -+ else{ -+ fprintf(fd, "#define MYBYTE_ORDER 1234\n"); -+ } -+ - /* prepend the filter header */ - contents = REGIONS_H; - if( (contents != NULL) && (*contents != '\0') ){ -@@ -418,6 +427,7 @@ - if( (contents != NULL) && (*contents != '\0') ){ - fprintf(fd, "%s\n", contents); - } -+ /* region routines if not linking against previously compiled code */ - switch( filter->type ){ - case TYPE_EVENTS: - /* normally, we filter events analytically using evregions.o */ -@@ -446,6 +456,12 @@ - break; - } - -+ /* always need the swap routines (they're part of the filter) */ -+ contents = SWAP_C; -+ if( (contents != NULL) && (*contents != '\0') ){ -+ fprintf(fd, "%s\n", contents); -+ } -+ - /* output counts of shapes */ - fprintf(fd, "#define NSHAPE %d\n", - FilterShapeCount()); -@@ -533,10 +549,13 @@ - t = ""; - } - if( fhd->table->col[sp->idx].n == 1 ){ -- fprintf(fd, "#define %s %s*((%s *)(eptr+%d))%s\n", -+ fprintf(fd, "#define %s %s*((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", - sp->name, - s, - GetType((int)fhd->table->col[sp->idx].type), -+ dsize, -+ offset, -+ dsize, - offset, - t); - } -@@ -548,18 +567,21 @@ - sp->name, s, "unsigned char", offset, t); - break; - case 16: -- fprintf(fd, "#define %s %s*((%s *)(eptr+%d))%s\n", -- sp->name, s, "unsigned short", offset, t); -+ fprintf(fd, "#define %s %s*((%s *)(SW2(eptr+%d,%d,_swf,%d)))%s\n", -+ sp->name, s, "unsigned short", offset, 2, offset, t); - break; - case 32: -- fprintf(fd, "#define %s %s*((%s *)(eptr+%d))%s\n", -- sp->name, s, "unsigned int", offset, t); -+ fprintf(fd, "#define %s %s*((%s *)(SW4(eptr+%d,%d,_swf,%d)))%s\n", -+ sp->name, s, "unsigned int", offset, 4, offset, t); - break; - default: -- fprintf(fd, "#define %s %s((%s *)(eptr+%d))%s\n", -+ fprintf(fd, "#define %s %s((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", - sp->name, - s, - GetType((int)fhd->table->col[sp->idx].type), -+ dsize, -+ offset, -+ dsize, - offset, - t); - } -@@ -571,10 +593,13 @@ - fhd->table->col[sp->idx].n); - } - else{ -- fprintf(fd, "#define %s %s((%s *)(eptr+%d))%s\n", -+ fprintf(fd, "#define %s %s((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", - sp->name, - s, - GetType((int)fhd->table->col[sp->idx].type), -+ dsize, -+ offset, -+ dsize, - offset, - t); - } -@@ -628,6 +653,7 @@ - if( evsize <=0 ) evsize = 1; - /* output the size of the filter record */ - fprintf(fd, "#define EVSIZE %d\n", evsize); -+ fprintf(fd, "static char _swf[%d];\n", evsize); - /* save for later use */ - filter->evsize = evsize; - break; -@@ -829,7 +855,7 @@ - stdfiles[0] = NULL; - stdfiles[1] = "/dev/null"; - stdfiles[2] = log; -- got = launch(tbuf, 1, stdfiles); -+ got = Launch(tbuf, 1, stdfiles, NULL); - #else - got = system(tbuf); - #endif -@@ -860,7 +886,7 @@ - } - else{ - s = FileContents(log, 0, &len); -- if( *s && len ){ -+ if( s && *s && len ){ - fprintf(stderr, "Compilation error message:\n%s\n", s); - } - if( !keep ){ ---- filter/idxacts.c.orig 2007-01-05 17:35:25.000000000 +0000 -+++ filter/idxacts.c 2007-12-18 20:10:26.000000000 +0000 -@@ -179,9 +179,8 @@ - int *pid; - #endif - { -- int i=0; - char *s; -- char *pargs[SZ_LINE]; -+ char cmd[SZ_LINE]; - - if( !idxsort ){ - if( idxpath ) return 0; -@@ -190,28 +189,27 @@ - } - if( !(idxsort=Find(IDX_SORTPROG, "x", NULL, idxpath)) && - !(idxsort=Find(IDX_SORTPROG, "x", NULL, ".")) ){ -+ idxerror("index sort program cannot be found"); - return 0; - } - } -- /* construct argument list for sort program */ -- pargs[i++] = (char *)idxsort; -- pargs[i++] = "-B4"; -- pargs[i++] = "+i0"; -+ /* construct command line for sort program */ - switch(type){ - case IDX_SORT: -+ snprintf(cmd, SZ_LINE-1, "%s -B4 +i0", idxsort); - break; - case IDX_OR_SORT: -- pargs[i++] = "-u"; -+ snprintf(cmd, SZ_LINE-1, "%s -B4 +i0 -u", idxsort); - break; - case IDX_AND_SORT: -- pargs[i++] = "-D"; -+ snprintf(cmd, SZ_LINE-1, "%s -B4 +i0 -D", idxsort); - break; - default: -+ snprintf(cmd, SZ_LINE-1, "%s -B4 +i0", idxsort); - break; - } -- pargs[i++] = NULL; - /* start the sort program */ -- if( !ProcessOpen(idxsort, pargs, ichan, ochan, pid) ){ -+ if( !ProcessOpen(cmd, ichan, ochan, pid) ){ - idxerror("index sort process cannot be started"); - return 0; - } ---- filter/idx.h.orig 2007-01-04 17:34:57.000000000 +0000 -+++ filter/idx.h 2007-12-18 20:10:26.000000000 +0000 -@@ -54,7 +54,7 @@ - #define IDX_ROW_INC 32 - - /* sort program */ --#define IDX_SORTPROG "_sort" -+#define IDX_SORTPROG "_funsort" - - /* idxinfo which values */ - #define IDX_COLNAME 1 ---- filter/imfilter.c.orig 2004-02-05 00:24:45.000000000 +0000 -+++ filter/imfilter.c 2007-12-18 20:10:26.000000000 +0000 -@@ -192,19 +192,50 @@ - - int main(int argc, char **argv) - { --#ifdef TEST - int i; -+ int get, got; -+#if DO_FILTER_SWAP -+ int sgot; - #endif -- int get; -- int got; -+ int pipes[4]; - int txmin, txmax, tymin, tymax, tblock; - char tbuf[SZ_LINE]; -+ char *s=NULL, *t=NULL, *u=NULL; -+ -+ /* Launch() sometimes rearranges passed pipes to be stdin/stdout */ -+ if( (s=getenv("LAUNCH_PIPES")) ){ -+ t = (char *)strdup(s); -+ for(i=0, u=(char *)strtok(t, ","); i<4 && u; -+ i++, u=(char *)strtok(NULL,",")){ -+ pipes[i] = atoi(u); -+ } -+ if( t ) free(t); -+ if( i < 4 ) return(1); -+ close(pipes[0]); -+ close(pipes[3]); -+ dup2(pipes[2], 0); close(pipes[2]); -+ dup2(pipes[1], 1); close(pipes[1]); -+ } - - /* process requests for region information for sections of the image */ - #ifdef TEST - while( fgets(tbuf, SZ_LINE, stdin) ){ - #else -- while( (read(0, &get, sizeof(int)) >0) && (read(0, tbuf, get)==get) ){ -+ while( (read(0, &get, sizeof(int)) >0) ){ -+#if DO_FILTER_SWAP -+ switch(sizeof(int)){ -+ case 2: -+ _sw2((char *)&get,2,NULL,0); -+ break; -+ case 4: -+ _sw4((char *)&get,4,NULL,0); -+ break; -+ case 8: -+ _sw8((char *)&get,8,NULL,0); -+ break; -+ } -+#endif -+ if(read(0, tbuf, get) != get) break; - #endif - if(sscanf(tbuf, "%d %d %d %d %d", - &txmin, &txmax, &tymin, &tymax, &tblock)!=5){ -@@ -222,7 +253,36 @@ - #else - /* calculate size of data we will write */ - got = got * sizeof(FilterMaskRec); -- write(1, &got, 4); -+#if DO_FILTER_SWAP -+ sgot = got; -+ switch(sizeof(int)){ -+ case 2: -+ _sw2((char *)&sgot,2,NULL,0); -+ break; -+ case 4: -+ _sw4((char *)&sgot,4,NULL,0); -+ break; -+ case 8: -+ _sw8((char *)&sgot,8,NULL,0); -+ break; -+ } -+ write(1, &sgot, sizeof(int)); -+#else -+ write(1, &got, sizeof(int)); -+#endif -+#if DO_FILTER_SWAP -+ switch(sizeof(int)){ -+ case 2: -+ _sw2((char *)masks,got,NULL,0); -+ break; -+ case 4: -+ _sw4((char *)masks,got,NULL,0); -+ break; -+ case 8: -+ _sw8((char *)masks,got,NULL,0); -+ break; -+ } -+#endif - write(1, masks, got); - #endif - /* free mask records */ ---- filter/swap.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ filter/swap.c 2007-12-18 20:10:26.000000000 +0000 -@@ -0,0 +1,90 @@ -+#if __DARWIN_BYTE_ORDER -+#define XBYTE_ORDER __DARWIN_BYTE_ORDER -+#else -+#define XBYTE_ORDER 0 -+#endif -+ -+#ifndef MYBYTE_ORDER -+#define MYBYTE_ORDER XBYTE_ORDER -+#endif -+ -+#ifndef DO_FILTER_SWAP -+#if (XBYTE_ORDER !=0) && (XBYTE_ORDER != MYBYTE_ORDER) -+#define DO_FILTER_SWAP 1 -+#endif -+#endif -+ -+#if DO_FILTER_SWAP -+char *_sw2(char *s, int n, char *_swf, int off) -+{ -+ char c; -+ char *t=s; -+ size_t i; -+ if( !_swf || !_swf[off]++ ){ -+ for (i=0; i<n; i += 2, s += 2) { -+ c = *s; -+ *(s) = *(s+1); -+ *(s+1) = c; -+ } -+ } -+ return t; -+} -+ -+char *_sw4(char *s, int n, char *_swf, int off) -+{ -+ char c; -+ char *t=s; -+ size_t i; -+ if( !_swf || !_swf[off]++ ){ -+ for (i=0; i<n; i += 4, s += 4) { -+ c = *s; -+ *s = *(s+3); -+ *(s+3) = c; -+ c = *(s+1); -+ *(s+1) = *(s+2); -+ *(s+2) = c; -+ } -+ } -+ return t; -+} -+ -+char *_sw8(char *s, int n, char *_swf, int off) -+{ -+ char c; -+ char *t=s; -+ size_t i; -+ if( !_swf || !_swf[off]++ ){ -+ for (i=0; i<n; i += 8, s += 8) { -+ c = *(s+0); -+ *(s+0) = *(s+7); -+ *(s+7) = c; -+ c = *(s+1); -+ *(s+1) = *(s+6); -+ *(s+6) = c; -+ c = *(s+2); -+ *(s+2) = *(s+5); -+ *(s+5) = c; -+ c = *(s+3); -+ *(s+3) = *(s+4); -+ *(s+4) = c; -+ } -+ } -+ return t; -+} -+ -+#define SW2(a,n,b,i) _sw2(a,n,b,i) -+#define SW4(a,n,b,i) _sw4(a,n,b,i) -+#define SW8(a,n,b,i) _sw8(a,n,b,i) -+ -+#if defined(FILTER_PTYPE) && (FILTER_PTYPE != c) -+#error "FILTER_PTYPE environment variable must be 'c' when running with Rosetta" -+#endif -+ -+#else -+ -+#define SW2(a,n,b,i) a -+#define SW4(a,n,b,i) a -+#define SW8(a,n,b,i) a -+ -+#endif -+ - ---- fitsy/fitsy.h.orig 2007-01-04 22:49:41.000000000 +0000 -+++ fitsy/fitsy.h 2007-12-18 20:10:26.000000000 +0000 -@@ -11,7 +11,7 @@ - #if USE_XFILEIO - #include <xfileio.h> - #else --#include "xfile.h" -+#include <xfile.h> - #endif - - #ifdef __STDC__ -@@ -30,7 +30,7 @@ - - #include <ctype.h> - --#include "longlong.h" -+#include <longlong.h> - - #ifndef NULL - #define NULL 0 ---- funcalc.c.orig 2007-03-01 18:12:12.000000000 +0000 -+++ funcalc.c 2007-12-18 20:10:26.000000000 +0000 -@@ -230,7 +230,7 @@ - stdfiles[0] = NULL; - stdfiles[1] = "/dev/null"; - stdfiles[2] = log; -- got = launch(cmd, 1, stdfiles); -+ got = Launch(cmd, 1, stdfiles, NULL); - #else - snprintf(tbuf, SZ_LINE-1, " 1>/dev/null 2>%s", log); - strcat(cmd, tbuf); -@@ -286,7 +286,7 @@ - s = NULL; - } - s = FileContents(log, 0, &len); -- if( *s && len ) -+ if( s && *s && len ) - fprintf(stderr, "Compilation error message:\n%s\n", s); - error = 1; - goto endgame; ---- funtable.c.orig 2007-06-11 22:18:31.000000000 +0100 -+++ funtable.c 2007-12-18 20:10:26.000000000 +0000 -@@ -11,7 +11,7 @@ - static int maxrow=MAXROW; - static char macrobuf[SZ_LINE]; - --#define SORTPROG "_sort" -+#define SORTPROG "_funsort" - - typedef struct rowstruct{ - int x, y; -@@ -90,6 +90,7 @@ - int dtype, doffset, dmode, dn; - int plen, elen, flen; - int epad, ppad; -+ int rlen; - double dval; - char *iname=NULL; - char *oname=NULL; -@@ -108,7 +109,7 @@ - char *extn=NULL; - char col[SZ_LINE]; - char tbuf[SZ_LINE]; -- char *pargs[SZ_LINE]; -+ char cmd[SZ_LINE]; - double *dbuf=NULL; - FILE *ifile; - Fun fun, tfun=NULL; -@@ -280,20 +281,21 @@ - /* if we specified columns, we also can specify "mask=transparent" - and get all events, with the regionid (assuming we specified - the region column to display as well) */ -- if( argc >= 4 ) -- mode = argv[optind+3]; -+ if( args >= 4 ) mode = argv[optind+3]; -+ - /* set up sorting, if necessary */ - if( dosort ){ - /* look for sort program */ - path = (char *)getenv("PATH"); - if( !(prog=Find(SORTPROG, "x", NULL, path)) ) - gerror(stderr, "can't locate sort program: %s\n", SORTPROG); -+ /* allow commas as delims */ -+ newdtable(","); - /* get the size of the input record */ - FunInfoGet(fun, FUN_ROWSIZE, &isize, 0); - /* construct argument list for sort program */ -- pargs[0] = (char *)prog; -- snprintf(tbuf, SZ_LINE-1, "-B%d", isize); -- pargs[1] = (char *)xstrdup(tbuf); -+ snprintf(cmd, SZ_LINE-1, "%s -B%d", prog, isize); -+ rlen = SZ_LINE - strlen(cmd) - 1; - for(ncol=0; word(sortcols, col, &ip); ncol++ ){ - if( !FunColumnLookup(fun, col, 0, NULL, &dtype, &dmode, &doffset, &dn, - NULL) ){ -@@ -333,15 +335,18 @@ - default: - gerror(stderr, "unsupported sort data type for column %s\n", tbuf); - } -- pargs[ncol+2] = (char *)xstrdup(tbuf); -- if( ncol > (SZ_LINE-3) ){ -- gerror(stderr, "ERROR: too many sort column arguments: %d\n", ncol); -+ strncat(cmd, " ", rlen); -+ rlen--; -+ strncat(cmd, tbuf, rlen); -+ rlen -= strlen(tbuf); -+ if( rlen <=0 ){ -+ gerror(stderr, "too many arguments for sort\n"); -+ exit(1); - } - } -- /* null terminate arg list */ -- pargs[ncol+2] = NULL; -+ freedtable(); - /* start the sort program */ -- if( !ProcessOpen(prog, pargs, &ichan, &ochan, &pid) ){ -+ if( !ProcessOpen(cmd, &ichan, &ochan, &pid) ){ - gerror(stderr, "ERROR: can't start sort program: %s\n", prog); - } - } -@@ -450,8 +455,6 @@ - fclose(ifile); - if( sortcols ) xfree(sortcols); - if( ebuf ) xfree(ebuf); -- for(i=0; i<ncol+2; i++) -- if( pargs[i] ) xfree(pargs[i]); - } - /* write out heap space, if it exists -- this quick hack needs cleanup! */ - if( fun->header && (ft_pcount(fun->header) > 0) ){ ---- gnu/sort.c.orig 2007-01-04 22:38:51.000000000 +0000 -+++ gnu/sort.c 2007-12-18 20:10:27.000000000 +0000 -@@ -2332,8 +2332,30 @@ - #ifdef _POSIX_VERSION - struct sigaction oldact, newact; - #endif /* _POSIX_VERSION */ -+#ifdef SAOMOD_FIX -+ int pipes[4]; -+ char *ss=NULL, *tt=NULL, *uu=NULL; -+#endif - - program_name = argv[0]; -+ -+#ifdef SAOMOD_FIX -+ /* Launch() sometimes rearranges passed pipes to be stdin/stdout */ -+ if( (ss=getenv("LAUNCH_PIPES")) ){ -+ tt = (char *)strdup(ss); -+ for(i=0, uu=(char *)strtok(tt, ","); i<4 && uu; -+ i++, uu=(char *)strtok(NULL,",")){ -+ pipes[i] = atoi(uu); -+ } -+ if( tt ) free(tt); -+ if( i < 4 ) return(1); -+ close(pipes[0]); -+ close(pipes[3]); -+ dup2(pipes[2], 0); close(pipes[2]); -+ dup2(pipes[1], 1); close(pipes[1]); -+ } -+#endif -+ - #ifdef SAOMOD_FIX - if ( (program_name = (char *)strrchr(program_name, '/')) ) - program_name++; ---- gnu/sorttest.c.orig 2004-02-04 14:14:19.000000000 +0000 -+++ gnu/sorttest.c 2007-12-18 20:10:27.000000000 +0000 -@@ -1,6 +1,6 @@ - /* - export EVENTS="(dval:D,fval:E,ival:J,uival:V,sval:I,cval:B,cval2:B)" -- sorttest | _sort -B24 +... | fundisp "stdin[EVENTS()]" -+ sorttest | _funsort -B24 +... | fundisp "stdin[EVENTS()]" - */ - - #include <stdio.h> -@@ -52,16 +52,15 @@ - int c; - int ival; - int ichan, ochan, pid, status; -+ int rlen; - int nrec=NREC; - int dodouble=0; - int doxeq=0; -- int narg=0; -- char *prog="_sort"; -+ char *prog="_funsort"; - char *slist=NULL; - char *s; - char tbuf[SZ_LINE]; - char cmd[SZ_LINE]; -- char *args[SZ_LINE]; - FILE *fp=stdout; - Binary b; - -@@ -89,9 +88,8 @@ - - /* generate sort parameters and start sort program */ - if( doxeq ){ -- args[narg++] = (char *)NewString(prog); -- sprintf(tbuf, "-B%d", sizeof(Binary)); -- args[narg++] = (char *)NewString(tbuf); -+ snprintf(cmd, SZ_LINE-1, "%s -B%d %s", prog, sizeof(Binary), tbuf); -+ rlen = SZ_LINE - strlen(cmd); - if( !slist ){ - slist = (char *)NewString("d"); - } -@@ -99,39 +97,36 @@ - switch(*s){ - case 'd': - sprintf(tbuf, "+d0"); -- args[narg++] = (char *)NewString(tbuf); - break; - case 'f': - sprintf(tbuf, "+f8"); -- args[narg++] = (char *)NewString(tbuf); - break; - case 'i': - sprintf(tbuf, "+i12"); -- args[narg++] = (char *)NewString(tbuf); - break; - case 'I': - sprintf(tbuf, "+I16"); -- args[narg++] = (char *)NewString(tbuf); - break; - case 's': - sprintf(tbuf, "+s20"); -- args[narg++] = (char *)NewString(tbuf); - break; - case 'c': - sprintf(tbuf, "+c22"); -- args[narg++] = (char *)NewString(tbuf); - break; - default: - fprintf(stderr, "ERROR: unknown sort type: %s\n", s); - exit(1); - } -- if( narg > (SZ_LINE-2) ){ -- fprintf(stderr, "ERROR: too many arguments: %d\n", narg); -+ strncat(cmd, " ", rlen); -+ rlen--; -+ strncat(cmd, tbuf, rlen); -+ rlen -= strlen(tbuf); -+ if( rlen <=0 ){ -+ fprintf(stderr, "ERROR: too many arguments\n"); - exit(1); - } - } -- args[narg] = NULL; -- if( !ProcessOpen(prog, args, &ichan, &ochan, &pid) ){ -+ if( !ProcessOpen(cmd, &ichan, &ochan, &pid) ){ - fprintf(stderr, "ERROR: can't start %s\n", prog); - exit(1); - } ---- util/configure.ac.orig 2007-05-22 19:11:26.000000000 +0100 -+++ util/configure.ac 2007-12-18 20:10:27.000000000 +0000 -@@ -41,7 +41,7 @@ - - AC_C_CONST - --AC_CHECK_FUNCS(strchr memcpy snprintf ftello fseeko) -+AC_CHECK_FUNCS(strchr memcpy snprintf ftello fseeko setenv) - - AC_CHECK_FUNC(connect) - if test $ac_cv_func_connect = no; then -@@ -119,6 +119,14 @@ - fi - AC_SUBST(USE_DL) - -+AC_MSG_CHECKING(for request to use posix_spawn) -+AC_ARG_ENABLE(posix_spawn, [ --enable-posix_spawn use posix_spawn() if available], -+ [fun_ok=$enableval], [fun_ok=no]) -+AC_MSG_RESULT($fun_ok) -+if test "$fun_ok" = "yes"; then -+ AC_CHECK_FUNCS(posix_spawn) -+fi -+ - SC_PATH_TCLCONFIG - if test x"${no_tcl}" = x ; then - AC_DEFINE(HAVE_TCL) ---- util/iraf_zprocess.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ util/iraf_zprocess.c 2007-12-18 20:10:27.000000000 +0000 -@@ -0,0 +1,469 @@ -+/* -+ * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory -+ */ -+ -+/* -+ * -+ * zprocess.c -- routines to start up and communicate with a slave process -+ * -+ * based on zfiopr.c from NOAO IRAF system -+ * -+ */ -+ -+#include <zprocess.h> -+ -+#ifndef min -+#define min(a,b) (((a)<(b))?(a):(b)) -+#endif -+ -+/* -+ * -+ * Private Routines -+ * -+ * -+ */ -+ -+static int pr_debug = 0; -+ -+/* -+ * -+ * Process table management code -+ * -+ */ -+ -+#define MAXPROCS 512 -+ -+static struct proctable { -+ int pr_pid; /* process id */ -+ int pr_active; /* if YES, process is still active */ -+ int pr_inchan; /* input IPC channel */ -+ int pr_outchan; /* output IPC channel */ -+ int pr_exit_status; /* process exit_status */ -+} prtable[MAXPROCS]; -+ -+/* PR_FINDPID -- Search the process table for a process. NULL is returned if -+ * the process cannot be found, otherwise a pointer to the table entry is -+ * returned. -+ */ -+#ifdef ANSI_FUNC -+static struct proctable *pr_findpid(int pid) -+#else -+static struct proctable *pr_findpid(pid) -+ int pid; -+#endif -+{ -+ register int pr; -+ -+ for (pr=0; pr<MAXPROCS; pr++){ -+ if (prtable[pr].pr_pid == pid) -+ return (&prtable[pr]); -+ } -+ return (NULL); -+} -+ -+/* PR_ENTER -- Make a new entry in the process table. Something is very wrong -+ * if the table overflows. -+ */ -+#ifdef ANSI_FUNC -+static int -+pr_enter(int pid, int inchan, int outchan) -+#else -+static int pr_enter(pid, inchan, outchan) -+ int pid; -+ int inchan, outchan; -+#endif -+{ -+ int pr; -+ -+ for (pr=0; pr<MAXPROCS; pr++){ -+ if (prtable[pr].pr_pid == 0){ -+ prtable[pr].pr_pid = pid; -+ prtable[pr].pr_active = 1; -+ prtable[pr].pr_inchan = inchan; -+ prtable[pr].pr_outchan = outchan; -+ return(1); -+ } -+ } -+ return(0); -+} -+ -+/* PR_GETCHAN -- Get the codes for the IPC channels assigned to a process. -+ */ -+#ifdef ANSI_FUNC -+static int pr_getchan (int pid, int *inchan, int *outchan) -+#else -+static int pr_getchan (pid, inchan, outchan) -+ int pid; -+ int *inchan, *outchan; -+#endif -+{ -+ register struct proctable *pr; -+ -+ /* Lookup process in table. Return an error if there is no entry. -+ */ -+ if ((pr = pr_findpid(pid)) == NULL) -+ return(-1); -+ else { -+ *inchan = pr->pr_inchan; -+ *outchan = pr->pr_outchan; -+ return (pid); -+ } -+} -+ -+/* PR_RELEASE -- Release the table entry for the process. Used when a process -+ * is killed and we do not wish to wait for process termination. -+ */ -+#ifdef ANSI_FUNC -+static void -+pr_release (int pid) -+#else -+static void pr_release (pid) -+ int pid; -+#endif -+{ -+ register struct proctable *pr; -+ -+ if ((pr = pr_findpid (pid)) != NULL){ -+ pr->pr_pid = 0; -+ pr->pr_active = 0; -+ pr->pr_inchan = 0; -+ pr->pr_outchan = 0; -+ } -+} -+ -+/* -+ *---------------------------------------------------------------------------- -+ * -+ * Routine: PRSleep -+ * -+ * Purpose: sleep for specified milliseconds -+ * -+ * Returns: none -+ * -+ *---------------------------------------------------------------------------- -+ */ -+#ifdef ANSI_FUNC -+static void -+PRSleep (int msec) -+#else -+static void PRSleep(msec) -+ int msec; -+#endif -+{ -+ struct timeval tv; -+ -+ if( msec > 0 ){ -+ tv.tv_sec = msec / 1000; -+ tv.tv_usec = (msec % 1000) * 1000; -+ select(1, NULL, NULL, NULL, &tv); -+ } -+} -+ -+/* -+ * -+ * Public Routines -+ * -+ * -+ */ -+ -+/* -+ * -+ * ProcessOpen -- -+ * Open a connected subprocess. Spawn process and open bidirectional -+ * IPC channels, implemented with pipes for this version of Berkeley UNIX. -+ * -+ */ -+#ifdef ANSI_FUNC -+int -+ProcessOpen(char *osfn, char **argv, int *inchan, int *outchan, int *pid) -+#else -+int ProcessOpen(osfn, argv, inchan, outchan, pid) -+ char *osfn; /* name of executable file */ -+ char **argv; /* argument list */ -+ int *inchan, *outchan; /* IPC channels (parent reads inchan) */ -+ int *pid; /* returned process id */ -+#endif -+{ -+ int pin[2], pout[2]; -+ int maxforks = 3; -+ char **targv; -+ char *args[2]; -+ char *prog=NULL; -+ static char *path; -+ -+ if (pr_debug) -+ fprintf (stderr, "ProcessOpen: '%s'", (char *)osfn); -+ -+ if( path == NULL ){ -+ path = (char *)getenv("PATH"); -+ } -+ -+ /* Check that the process file exists and is executable. -+ */ -+ if( (prog = Find(osfn, "x", NULL, path)) == NULL ){ -+ *pid = 0; -+ return(0); -+ } -+ -+ /* open pipes */ -+ pipe(pin); -+ if( pipe(pout) != 0){ -+ *pid = 0; -+ return(0); -+ } -+ -+ /* Create child process. The child inherits the open stdio files. -+ * The fork can fail if swap space is full or if we have too many processes. -+ */ -+ while ((*pid = fork()) == -1) { -+ if (--maxforks == 0) { -+ close (pin[0]); close (pin[1]); -+ close (pout[0]); close (pout[1]); -+ *pid = 0; -+ return(0); -+ } -+ sleep (2); -+ } -+ -+ if (*pid == 0) { -+ -+ /* New child process. Make child think the pipe is its stdin/out. -+ */ -+ close (pin[0]); -+ close (pout[1]); -+ close (0); dup (pout[0]); close (pout[0]); -+ close (1); dup (pin[1]); close (pin[1]); -+ -+#ifdef IRAF_ONLY -+ /* Disable SIGINT so that child process does not die when the -+ * parent process is interrupted. The child should get an EOF -+ * on reading or writing and clean itself up. -+ */ -+ signal (SIGINT, SIG_IGN); -+#endif -+ -+ /* Exec the new process. Will not return if successful. -+ */ -+ if( argv != NULL ){ -+ targv = argv; -+ } -+ else { -+ targv = args; -+ args[0] = prog; -+ args[1] = NULL; -+ } -+ execv(prog, (void *)targv); -+ -+ /* If we get here the new process could not be executed for some -+ * reason. Shutdown, calling _exit to avoid flushing parent's -+ * io buffers. -+ */ -+ _exit (1); -+ -+ } else { -+ -+ /* Existing, parent process. */ -+ close (pin[1]); -+ close (pout[0]); -+ *inchan = pin[0]; -+ *outchan = pout[1]; -+ -+ /* Save pid in parent's process table. Entry cleared when -+ * CloseProcess is called to wait for process to terminate. Also save -+ * channel numbers in process table since only the pid is passed -+ * when the process is closed. -+ */ -+ pr_enter (*pid, pin[0], pout[1]); -+ -+ if (pr_debug) -+ fprintf (stderr, " [%d]\n", *pid); -+ -+ /* clean up and return */ -+ if( prog ) free(prog); -+ return(1); -+ -+ } -+ return(1); -+} -+ -+ -+/* -+ * -+ * ProcessClose -- Close a connected subprocess and -+ * wait for subprocess to terminate. -+ * -+ */ -+#ifdef ANSI_FUNC -+int -+ProcessClose(int pid, int *exit_status) -+#else -+int ProcessClose(pid, exit_status) -+ int pid; -+ int *exit_status; -+#endif -+{ -+ int inchan, outchan; -+ int tries=0; -+ -+ if (pr_getchan (pid, &inchan, &outchan) == -1) -+ *exit_status = 0; -+ else { -+ close (outchan); -+ close (inchan); -+ pr_release(pid); -+retry: -+ if( (waitpid(pid, exit_status, WNOHANG)==0) && (tries<10) ){ -+ PRSleep(10); -+ tries++; -+ goto retry; -+ } -+ } -+ -+ if (pr_debug) -+ fprintf (stderr, "[%d] terminated, exit code %d\n", -+ pid, *exit_status); -+ return(*exit_status); -+} -+ -+ -+/* -+ * -+ * ProcessRead -- Read next record from an IPC channel. -+ * -+ * Since UNIX pipes are byte streams we must take special measures to -+ * transmit data through a pipe in records. -+ * Each block of data is preceded by a header of sizeof(int) consisting -+ * containing the number of bytes in the block. -+ * To read a block we must read the count and then issue successive read -+ * requests until the entire block has been read. -+ * -+*/ -+#ifdef ANSI_FUNC -+void * -+ProcessRead(int fd, void *buf, int maxbytes, int *got) -+#else -+void *ProcessRead(fd, buf, maxbytes, got) -+ int fd; -+ void *buf; -+ int maxbytes; -+ int *got; -+#endif -+{ -+ register char *op; -+ register int nbytes; -+ char *obuf; -+ int record_length, status; -+ int temp; -+ -+ /* no data read as yet */ -+ *got = 0; -+ -+ if (pr_debug) -+ fprintf (stderr, -+ "[%d] initiate read for %d bytes from IPC channel %d\n", -+ (int)getpid(), maxbytes, fd); -+ -+ /* Get byte count of record. -+ */ -+ if (read (fd, &temp, sizeof(int)) != sizeof(int)) -+ return NULL; -+ -+ record_length = temp; -+ if( maxbytes >= 0 ) -+ nbytes = min(record_length, maxbytes); -+ else -+ nbytes = record_length; -+ -+ /* allocate output buffer, if necessary */ -+ if( buf ) -+ obuf = buf; -+ else{ -+ obuf = (char *)malloc(nbytes); -+ if( !obuf ) -+ return NULL; -+ } -+ op = (char *)obuf; -+ -+ /* Now read exactly nbytes of data from channel into user buffer. -+ * Return actual byte count if EOF is seen. If an error is seen, return. -+ * If necessary multiple read requests are issued to read the -+ * entire record. -+ */ -+ while (nbytes > 0) -+ switch (status = read (fd, op, nbytes)) { -+ case -1: -+ if( !buf ) free(obuf); -+ *got = 0; -+ return NULL; -+ case 0: -+ return(obuf); -+ default: -+ nbytes -= status; -+ *got += status; -+ op += status; -+ } -+ -+ if (pr_debug) { -+ fprintf (stderr, "[%d] read %d bytes from IPC channel %d:\n", -+ (int)getpid(), (int)(op - (char *)buf), fd); -+ } -+ -+ /* If the record is larger than maxbytes, we must read and discard -+ * the additional bytes. The method used is inefficient but it is -+ * unlikely that we will be called to read less than a full record. -+ */ -+ if( maxbytes >= 0 ){ -+ for (nbytes = maxbytes; nbytes < record_length; nbytes++) -+ if (read (fd, &temp, 1) <= 0) -+ break; -+ } -+ -+ return(obuf); -+} -+ -+/* -+ * -+ * ProcessWrite -- Write to an IPC channel. -+ * Write the IPC block header followed by the data block. -+ * -+*/ -+#ifdef ANSI_FUNC -+int -+ProcessWrite(int fd, void *buf, int nbytes) -+#else -+int ProcessWrite(fd, buf, nbytes) -+ int fd; -+ void *buf; -+ int nbytes; -+#endif -+{ -+ int got; -+ -+ /* write byte count */ -+ write(fd, &nbytes, sizeof(int)); -+ -+ /* write data block */ -+ got = write(fd, buf, nbytes); -+ -+ if (pr_debug) { -+ fprintf (stderr, "[%d] wrote %d bytes to IPC channel %d:\n", -+ (int)getpid(), (int)nbytes, fd); -+ } -+ -+ return(got); -+} -+ -+/* -+ * ProcessGetChan -- Get the codes for the IPC channels assigned to a process. -+ */ -+#ifdef ANSI_FUNC -+int -+ProcessGetChan (int pid, int *inchan, int *outchan) -+#else -+int ProcessGetChan (pid, inchan, outchan) -+ int pid; -+ int *inchan, *outchan; -+#endif -+{ -+ return pr_getchan(pid, inchan, outchan); -+} ---- util/launch.c.orig 2007-06-28 21:29:06.000000000 +0100 -+++ util/launch.c 2007-12-18 20:10:27.000000000 +0000 -@@ -1,35 +1,9 @@ - /* -- * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory -+ * Copyright (c) 1999-2007 Smithsonian Astrophysical Observatory - */ - - #include <launch.h> - --#define LAUNCHARGS 1024 -- --/* we one of these must be defined ... */ --#if !defined(USE_PIPE) && !defined(USE_WAITPID) --#define USE_PIPE 1 --#endif --/* ... but not both */ --#if defined(USE_PIPE) && defined(USE_WAITPID) --#error "USE_PIPE and USE_WAITPID are mutually exclusive" --#endif -- --#ifdef USE_WAITPID --#define WAIT_TRIES 100 --#define WAIT_MSEC 5000 --#endif -- --#ifndef WAIT_MSEC --#define WAIT_MSEC 5000 --#endif -- --static pid_t _launchpid=0; -- --/* spawnvp seems to be broken on cygwin as of 1/06, so just use fork/exec */ --#if HAVE_CYGWIN --#define HAVE_CYGWIN_USE_SPAWNVP 0 --#endif - /* - *---------------------------------------------------------------------------- - * -@@ -40,98 +14,104 @@ - *---------------------------------------------------------------------------- - */ - --#if HAVE_CYGWIN||HAVE_MINGW32 --#if HAVE_CYGWIN_USE_SPAWNVP -+static pid_t pid=0; - -+/* wait for child process to start, using waitpid() */ - #ifdef ANSI_FUNC --static int launch_win32(char *cmdstring, int attach, char **stdfiles) -+static int launch_pipes(int *pipes, int flag) - #else --static int launch_win32(cmdstring, attach, stdfiles) -- char *cmdstring; -- int attach; -- char **stdfiles; -+static int launch_pipes(pipes, flag) -+ int *pipes; -+ int flag; - #endif - { -- int i, j; -- int len; -- int got; -- int status; -- char *argv[LAUNCHARGS+1]; -- char *path=NULL; -- char *s=NULL, *t=NULL; -- struct timeval tv; -- -- /* for now, we can't support stdfiles */ -- if( stdfiles ) -- return(-1); -- -- /* package up the arguments for new process */ -- t = (char *)xstrdup(cmdstring); -- for(i=0, got=0, s=(char *)strtok(t, " \t"); s; -- i++, s=(char *)strtok(NULL," \t")){ -- if( i < LAUNCHARGS ){ -- /* save argument */ -- argv[i] = xstrdup(s); -- /* change back special char to spaces, if necessary */ -- len = strlen(argv[i]); -- for(j=0; j<len; j++){ -- if( argv[i][j] == LAUNCH_SPACE){ -- argv[i][j] = ' '; -- } -- } -- argv[i+1] = NULL; -- /* save program name */ -- if( i == 0 ) path = (char *)argv[i]; -- got++; -+ int i; -+ char tbuf[SZ_LINE]; -+ if( pipes ){ -+ for(i=0; i<4; i++){ -+ pipes[i] = -1; -+ } -+ if( (pipe(&pipes[0]) < 0) || (pipe(&pipes[2]) < 0) ) return -1; -+ if( flag ){ -+#if HAVE_SETENV -+ snprintf(tbuf, SZ_LINE-1, "%d,%d,%d,%d", -+ pipes[0], pipes[1], pipes[2], pipes[3]); -+ setenv("LAUNCH_PIPES", tbuf, 1); -+#else -+ snprintf(tbuf, SZ_LINE-1, "LAUNCH_PIPES=%d,%d,%d,%d", -+ pipes[0], pipes[1], pipes[2], pipes[3]); -+ putenv(xstrdup(tbuf)); -+#endif - } - } -- if( t ) xfree(t); -- if( attach ) -- i = _P_WAIT; -- else -- i = _P_NOWAIT; -- if((status = spawnvp(i, path, (void *)argv)) != -1){ -- status = 0; -- /* wait for child to start */ -- tv.tv_sec = 0; -- tv.tv_usec = WAIT_MSEC; -- xselect(1, NULL, NULL, NULL, &tv); -- } -- for(i=0; i<got; i++) -- if( argv[i] ) xfree((char *)argv[i]); -- return(status); -+ return 0; - } - -+#ifdef ANSI_FUNC -+static int cleanup_pipes(int *pipes) -+#else -+static int cleanup_pipes(pipes) -+ int *pipes; - #endif --#endif -- --/* -- *---------------------------------------------------------------------------- -- * -- * -- * Public Routines and Data -- * -- * -- *---------------------------------------------------------------------------- -- */ -+{ -+ if( pipes ){ -+ /* close child pipes */ -+ close(pipes[1]); -+ close(pipes[2]); -+ /* move parent write into slot 1 */ -+ pipes[1] = pipes[3]; -+ /* set unused pipes to impossible value */ -+ pipes[2] = -1; -+ pipes[3] = -1; -+ } -+ return 0; -+} - --/* -- * -- * launchpid() -- return pid of last launched process -- * -- */ -+#if LAUNCH_USE_WAITPID -+/* wait for child process to start, using waitpid() */ - #ifdef ANSI_FUNC --pid_t launchpid(void) -+static int launch_waitstart(pid_t pid) - #else --pid_t launchpid() -+static int launch_waitstart(pid) -+ pid_t pid; - #endif - { -- return _launchpid; -+ int i, got; -+ int status=0; -+ struct timeval tv; -+ /* wait up to LAUNCH_WAIT_TRIES millisec to make sure the child started, -+ but if we get an error, we can exit immediately */ -+ for(i=0; i<LAUNCH_WAIT_TRIES; i++){ -+ errno = 0; -+ got=waitpid(pid, &status, WNOHANG); -+ /* look for error termination */ -+ if( (got < 0) || ((got == 0) && xerrno) ){ -+ got = -1; -+ /* make sure status shows error */ -+ if( status == 0 ) -+ status = -1; -+ break; - } -- --#if HAVE_MINGW32==0 -+ /* look for normal termination */ -+ else if( got > 0 ){ -+ break; -+ } -+ /* no termination, sleep and wait some more */ -+ else{ -+ tv.tv_sec = 0; -+ tv.tv_usec = LAUNCH_WAIT_MSEC; -+ xselect(1, NULL, NULL, NULL, &tv); -+ } -+ } -+ /* no termination means the child is still running */ -+ if( got == 0 ) status = 0; -+ /* return the news */ -+ return status; -+} -+#endif - - /* -+ * standard unix version of launch: - * adapted from the system() code in: - * W. Richard Stevens - * "Advanced Programming in the Unix Environment" -@@ -139,71 +119,86 @@ - * p. 314 - */ - #ifdef ANSI_FUNC --int launch(char *cmdstring, int attach, char **stdfiles) -+static int launch_fork_exec(char *cmdstring, int attach, -+ char **stdfiles, int *pipes) - #else --int launch(cmdstring, attach, stdfiles) -+ static int launch_fork_exec(cmdstring, attach, stdfiles, pipes) - char *cmdstring; - int attach; - char **stdfiles; -+ int *pipes; - #endif - { - int status; -- pid_t pid; -+ int tpipes[4]; - struct sigaction ignore, saveintr, savequit; - sigset_t chldmask, savemask; --#ifdef USE_PIPE -+#if LAUNCH_USE_PIPE - int fd[2]; - #endif - - /* return false if no command is specified */ -- if( !cmdstring || !*cmdstring ) -- return(-1); -+ if( !cmdstring || !*cmdstring ) return -1; - - ignore.sa_handler = SIG_IGN; /* ignore SIGINT and SIGQUIT */ - sigemptyset(&ignore.sa_mask); - ignore.sa_flags = 0; - if (sigaction(SIGINT, &ignore, &saveintr) < 0) -- return(-1); -+ return -1; - if (sigaction(SIGQUIT, &ignore, &savequit) < 0) -- return(-1); -+ return -1; - - sigemptyset(&chldmask); /* now block SIGCHLD */ - sigaddset(&chldmask, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0) -- return(-1); -+ return -1; - --#if HAVE_CYGWIN_USE_SPAWNVP -- /* if we are on the Cygwin platform, use fork/exec only if we are -- redirecting stdfiles. Otherwise use spawnvp(), which works better. */ -- if( stdfiles ){ --#endif -- --#ifdef USE_PIPE -+#if LAUNCH_USE_PIPE - /* open a pipe so parent can hear if the child fails to exec */ - if( !attach ){ - if( pipe(fd) < 0 ) -- return(-1); -+ return -1; - xfcntl(fd[0], F_SETFD, FD_CLOEXEC); - xfcntl(fd[1], F_SETFD, FD_CLOEXEC); - } - #endif - -+ /* create temp ipc pipes if necessary */ -+ if( pipes ){ -+ if( launch_pipes(tpipes, 0) < 0 ) return -1; -+ } -+ - /* start new process */ - if( (pid = fork()) < 0 ){ --#ifdef USE_PIPE -+#if LAUNCH_USE_PIPE - if( !attach ){ - close(fd[0]); - close(fd[1]); - } - #endif -+ if( pipes ){ -+ close(tpipes[0]); -+ close(tpipes[1]); -+ close(tpipes[2]); -+ close(tpipes[3]); -+ } - status = -1; /* ERROR: probably out of processes */ -- - } else if( pid == 0 ){ /* child */ - int i, j, len; -- char *argv[LAUNCHARGS+1]; -+ char *argv[LAUNCH_ARGS+1]; - char *path=NULL; - char *s=NULL, *t=NULL; - -+ /* reset pipes, if necessary */ -+ if( pipes ){ -+ /* close parent's read/write pipes */ -+ close(tpipes[0]); -+ close(tpipes[3]); -+ /* change child's stdin/stdout to use the passed pipes to parent */ -+ dup2(tpipes[2], 0); close(tpipes[2]); -+ dup2(tpipes[1], 1); close(tpipes[1]); -+ } -+ - /* close and reopen stdio files, if necessary */ - if( stdfiles ){ - for(i=0; i<3; i++){ -@@ -243,7 +238,7 @@ - sigaction(SIGQUIT, &savequit, NULL); - sigprocmask(SIG_SETMASK, &savemask, NULL); - } --#ifdef USE_PIPE -+#if LAUNCH_USE_PIPE - /* child closes reader -- only writes status */ - else{ - close(fd[0]); -@@ -254,7 +249,7 @@ - t = (char *)xstrdup(cmdstring); - for(i=0, s=(char *)strtok(t, " \t"); s; - i++, s=(char *)strtok(NULL," \t")){ -- if( i < LAUNCHARGS ){ -+ if( i < LAUNCH_ARGS ){ - /* save argument */ - argv[i] = xstrdup(s); - /* change back special char to spaces, if necessary */ -@@ -280,7 +275,7 @@ - /* start up the new program */ - if( execvp(path, argv) ){ - status = 127; --#ifdef USE_PIPE -+#if LAUNCH_USE_PIPE - if( !attach ){ - write(fd[1], &status, 4); - close(fd[1]); -@@ -289,7 +284,6 @@ - _exit(status); /* exec error */ - } - } else { /* parent */ -- _launchpid = pid; - /* wait for program termination from attached process */ - if( attach ){ - while( waitpid(pid, &status, 0) < 0 ){ -@@ -300,38 +294,10 @@ - } - } - else{ --#ifdef USE_WAITPID -- int i, got; -- struct timeval tv; -- /* we wait up to WAIT_TRIES millisecs to make sure the child started; -- but if we get an error, we can exit immediately */ -- for(i=0; i<WAIT_TRIES; i++){ -- errno = 0; -- got=waitpid(pid, &status, WNOHANG); -- /* look for error termination */ -- if( (got < 0) || ((got == 0) && xerrno) ){ -- got = -1; -- /* make sure status shows error */ -- if( status == 0 ) -- status = -1; -- break; -- } -- /* look for normal termination */ -- else if( got > 0 ){ -- break; -- } -- /* no termination, sleep and wait some more */ -- else{ -- tv.tv_sec = 0; -- tv.tv_usec = WAIT_MSEC; -- xselect(1, NULL, NULL, NULL, &tv); -- } -- } -- /* no termination means the child is still running */ -- if( got == 0 ) -- status = 0; -+#if LAUNCH_USE_WAITPID -+ status = launch_waitstart(pid); - #endif --#ifdef USE_PIPE -+#if LAUNCH_USE_PIPE - close(fd[1]); - if( read(fd[0], &status, 4) == 0 ){ - status = 0; -@@ -341,37 +307,321 @@ - } - } - --#if HAVE_CYGWIN_USE_SPAWNVP -+ /* cleanup temp ipc pipes and move into user space */ -+ if( pipes ){ -+ cleanup_pipes(tpipes); -+ pipes[0] = tpipes[0]; -+ pipes[1] = tpipes[1]; -+ } -+ -+ /* restore previous signal actions & reset signal mask */ -+ if( sigaction(SIGINT, &saveintr, NULL) < 0 ) return -1; -+ if( sigaction(SIGQUIT, &savequit, NULL) < 0 ) return -1; -+ if( sigprocmask(SIG_SETMASK, &savemask, NULL) < 0 ) return -1; -+ -+ /* return the news */ -+ return status; - } -- /* for Cygwin, call their spawnvp() routine instead of fork()/exec() */ -+ -+#if HAVE_POSIX_SPAWN -+ -+extern char **environ; -+ -+/* spawn calls POSIX posix_spawn */ -+#ifdef ANSI_FUNC -+static int launch_posix_spawn(char *cmdstring, int attach, -+ char **stdfiles, int *pipes) -+#else -+ static int launch_posix_spawn(cmdstring, attach, stdfiles, pipes) -+ char *cmdstring; -+ int attach; -+ char **stdfiles; -+ int *pipes; -+#endif -+{ -+ int i, j, len; -+ int status=0; -+ int got=0; -+ int tpipes[4]; -+ char *argv[LAUNCH_ARGS+1]; -+ char *path=NULL; -+ char *s=NULL, *t=NULL; -+ posix_spawn_file_actions_t act; -+ posix_spawn_file_actions_t *pact=NULL; -+ -+ /* return false if no command is specified */ -+ if( !cmdstring || !*cmdstring ) -+ return -1; -+ -+ /* create temp ipc pipes if necessary */ -+ if( pipes ){ -+ if( launch_pipes(tpipes, 1) < 0 ) return -1; -+ } -+ -+ /* package up the arguments for new process */ -+ t = (char *)xstrdup(cmdstring); -+ for(i=0, s=(char *)strtok(t, " \t"); s; -+ i++, s=(char *)strtok(NULL," \t")){ -+ if( i < LAUNCH_ARGS ){ -+ /* save argument */ -+ argv[i] = xstrdup(s); -+ /* change back special char to spaces, if necessary */ -+ len = strlen(argv[i]); -+ for(j=0; j<len; j++){ -+ if( argv[i][j] == LAUNCH_SPACE){ -+ argv[i][j] = ' '; -+ } -+ } -+ /* last arg is always a NULL */ -+ argv[i+1] = NULL; -+ /* save program name */ -+ if( i == 0 ) path = argv[i]; -+ /* inc arg count */ -+ got++; -+ } -+ } -+ if( t ) xfree(t); -+ /* arrange stdfiles files, if necessary */ -+ if( stdfiles ){ -+ if( posix_spawn_file_actions_init(&act) != 0) -+ return -1; -+ /* stdin */ -+ if(stdfiles[0] && -+ posix_spawn_file_actions_addopen(&act, 0, stdfiles[0], O_RDONLY, 0)) -+ return -1; -+ /* stdout */ -+ if(stdfiles[1] && -+ posix_spawn_file_actions_addopen(&act, 1, stdfiles[1], O_CREAT|O_WRONLY|O_TRUNC, 0600)) -+ return -1; -+ /* stderr */ -+ if(stdfiles[2] && -+ posix_spawn_file_actions_addopen(&act, 2, stdfiles[2], O_CREAT|O_WRONLY|O_TRUNC, 0600)) -+ return -1; -+ pact = &act; -+ } -+ /* start the new process */ -+ if( (status = posix_spawnp(&pid, path, pact, NULL, argv, environ)) ) -+ return status; -+ /* wait for program termination from attached process */ -+ if( attach ){ -+ while( waitpid(pid, &status, 0) < 0 ){ -+ if( xerrno != EINTR ){ -+ status = -1; /* error other than EINTR from waitpid() */ -+ break; -+ } -+ } -+ } -+#if BIG_DELAY_WHEN_USING_THIS -+ /* wait for child process to start */ - else{ -- status = launch_win32(cmdstring, attach, stdfiles); -+ status = launch_waitstart(pid); -+ } -+#endif -+ /* clean up */ -+ if( stdfiles ) posix_spawn_file_actions_destroy(&act); -+ /* cleanup temp ipc pipes and move into user space */ -+ if( pipes ){ -+ cleanup_pipes(tpipes); -+ pipes[0] = tpipes[0]; -+ pipes[1] = tpipes[1]; -+ } -+ for(i=0; i<got; i++){ -+ if( argv[i] ) xfree((char *)argv[i]); -+ } -+ /* return status */ -+ return status; - } -+ - #endif - -- /* restore previous signal actions & reset signal mask */ -- if( sigaction(SIGINT, &saveintr, NULL) < 0 ) -- return(-1); -- if( sigaction(SIGQUIT, &savequit, NULL) < 0 ) -- return(-1); -- if( sigprocmask(SIG_SETMASK, &savemask, NULL) < 0 ) -- return(-1); -+#if HAVE_SPAWNVP -+ -+#ifdef ANSI_FUNC -+static int launch_spawnvp(char *cmdstring, int attach, -+ char **stdfiles, int *pipes) -+#else -+ static int launch_spawnvp(cmdstring, attach, stdfiles, pipes) -+ char *cmdstring; -+ int attach; -+ char **stdfiles; -+ int *pipes; -+#endif -+{ -+ int i, j; -+ int len; -+ int got; -+ int status; -+ int tpipes[4]; -+ char *argv[LAUNCH_ARGS+1]; -+ char *path=NULL; -+ char *s=NULL, *t=NULL; -+ struct timeval tv; -+ -+ /* return false if no command is specified */ -+ if( !cmdstring || !*cmdstring ) return -1; -+ -+ /* for now, we can't support stdfiles */ -+ if( stdfiles ) return -1; - -- return(status); -+ /* create temp ipc pipes if necessary */ -+ if( pipes ){ -+ if( launch_pipes(tpipes, 1) < 0 ) return -1; -+ } -+ -+ /* package up the arguments for new process */ -+ t = (char *)xstrdup(cmdstring); -+ for(i=0, got=0, s=(char *)strtok(t, " \t"); s; -+ i++, s=(char *)strtok(NULL," \t")){ -+ if( i < LAUNCH_ARGS ){ -+ /* save argument */ -+ argv[i] = xstrdup(s); -+ /* change back special char to spaces, if necessary */ -+ len = strlen(argv[i]); -+ for(j=0; j<len; j++){ -+ if( argv[i][j] == LAUNCH_SPACE){ -+ argv[i][j] = ' '; -+ } - } -+ /* last arg is always a NULL */ -+ argv[i+1] = NULL; -+ /* save program name */ -+ if( i == 0 ) path = (char *)argv[i]; -+ /* inc arg count */ -+ got++; -+ } -+ } -+ if( t ) xfree(t); -+ if( attach ) -+ i = _P_WAIT; -+ else -+ i = _P_NOWAIT; -+ if((status = spawnvp(i, path, (void *)argv)) != -1){ -+ status = 0; -+ /* wait for child to start */ -+ tv.tv_sec = 0; -+ tv.tv_usec = LAUNCH_WAIT_MSEC; -+ xselect(1, NULL, NULL, NULL, &tv); -+ } -+ /* clean up */ -+ for(i=0; i<got; i++){ -+ if( argv[i] ) xfree((char *)argv[i]); -+ } -+ /* cleanup temp ipc pipes and move into user space */ -+ if( pipes ){ -+ cleanup_pipes(tpipes); -+ pipes[0] = tpipes[0]; -+ pipes[1] = tpipes[1]; -+ } -+ return status; -+} -+ -+#endif - -+/* -+ *---------------------------------------------------------------------------- -+ * -+ * -+ * Public Routines and Data -+ * -+ * -+ *---------------------------------------------------------------------------- -+ */ -+ -+/* -+ * -+ * LaunchPid() -- return pid of last launched process -+ * -+ */ -+#ifdef ANSI_FUNC -+pid_t LaunchPid(void) - #else -+pid_t LaunchPid() -+#endif -+{ -+ return pid; -+} - - #ifdef ANSI_FUNC --int launch(char *cmdstring, int attach, char **stdfiles) -+int Launch(char *cmdstring, int attach, char **stdfiles, int *pipes) - #else --int launch(cmdstring, attach, stdfiles) -+int Launch(cmdstring, attach, stdfiles, piles) - char *cmdstring; - int attach; - char **stdfiles; -+ int *pipes; - #endif - { -- return launch_win32(cmdstring, attach, stdfiles); -+ static int which_launch=0; -+ static int which_debug=0; -+ char *s=NULL; -+ -+ /* return false if no command is specified */ -+ if( !cmdstring || !*cmdstring ) return -1; -+ -+ /* sanity check: don't specify stdfiles and pipes simultaneously */ -+ if( stdfiles && pipes ){ -+ fprintf(stderr, -+ "ERROR: stdfiles and pipes are mutually exclusive in Launch()\n"); -+ return -1; - } - -+ /* if pipes are specified, we don't attach */ -+ if( pipes ) attach = 0; -+ -+ /* determine launch method */ -+ if( !which_launch ){ -+ which_launch = LAUNCH_DEFAULT_WHICH; -+ if( (s=getenv("LAUNCH_ROUTINE")) ){ -+ /* fork_exec */ -+ if( !strncasecmp(s, "f", 1) ){ -+ which_launch = 1; -+ if( *s == 'F' ) which_debug = 1; -+ } -+ /* posix_spawn */ -+ else if( !strncasecmp(s, "p", 1) ){ -+ which_launch = 2; -+ if( *s == 'P' ) which_debug = 1; -+ } -+ /* spawnvp */ -+ else if( !strncasecmp(s, "s", 1) ){ -+ which_launch = 3; -+ if( *s == 'S' ) which_debug = 1; -+ } -+ else if( *s == 'V' ) { -+ which_debug = 1; -+ } -+ } -+ } -+ /* call the correct launch method */ -+ switch(which_launch){ -+ case 1: -+ if( which_debug ) fprintf(stderr, "launch_fork_exec: %s\n", cmdstring); -+ return launch_fork_exec(cmdstring, attach, stdfiles, pipes); -+ break; -+ case 2: -+#if HAVE_POSIX_SPAWN -+ if( which_debug ) fprintf(stderr, "launch_posix_spawn: %s\n", cmdstring); -+ return launch_posix_spawn(cmdstring, attach, stdfiles, pipes); -+#else -+ fprintf(stderr, "ERROR: posix_spawn() not available on this host\n"); -+ exit(1); - #endif -+ break; -+ case 3: -+#if HAVE_SPAWNVP -+ if( which_debug ) fprintf(stderr, "launch_spawnvp: %s\n", cmdstring); -+ return launch_spawnvp(cmdstring, attach, stdfiles, pipes); -+#else -+ fprintf(stderr, "ERROR: spawnvp() not available on this host\n"); -+ exit(1); -+#endif -+ break; -+ default: -+ if( which_debug ) fprintf(stderr, "launch_fork_exec: %s\n", cmdstring); -+ return launch_fork_exec(cmdstring, attach, stdfiles, pipes); -+ break; -+ } -+ /* can't happen */ -+ return -1; -+} -+ ---- util/launch.h.orig 2006-01-27 16:25:08.000000000 +0000 -+++ util/launch.h 2007-12-18 20:10:27.000000000 +0000 -@@ -30,17 +30,54 @@ - #if HAVE_UNISTD_H - #include <unistd.h> - #endif -+#if HAVE_POSIX_SPAWN -+#include <spawn.h> -+#endif - #include <xport.h> - #include <word.h> - #include <xalloc.h> - #include <prsetup.h> - -+#define LAUNCH_ARGS 1024 -+ - #define LAUNCH_SPACE '\001' - -+/* for fork/exec, one of these is required to specify the technique to be used -+ by the parent when determining if the child started successfully */ -+#if !defined(LAUNCH_USE_PIPE) && !defined(LAUNCH_USE_WAITPID) -+#define LAUNCH_USE_PIPE 1 -+#endif -+/* ... but not both */ -+#if defined(LAUNCH_USE_PIPE) && defined(LAUNCH_USE_WAITPID) -+#error "LAUNCH_USE_PIPE and LAUNCH_USE_WAITPID are mutually exclusive" -+#endif -+ -+#ifndef LAUNCH_WAIT_TRIES -+#define LAUNCH_WAIT_TRIES 100 -+#endif -+#ifndef LAUNCH_WAIT_MSEC -+#define LAUNCH_WAIT_MSEC 5000 -+#endif -+ -+#if HAVE_MINGW32|HAVE_CYGWIN -+#define HAVE_SPAWNVP 1 -+#endif -+ -+#if HAVE_MINGW32 -+/* for now, ensure that MinGW utilizes spawnvp() */ -+#define LAUNCH_DEFAULT_WHICH 3 -+#elif HAVE_POSIX_SPAWN -+/* use posix_spawn if possible (required for OS X 10.5) */ -+#define LAUNCH_DEFAULT_WHICH 2 -+#else -+/* use our home-grown version */ -+#define LAUNCH_DEFAULT_WHICH 1 -+#endif -+ - _PRbeg - --int launch _PRx((char *cmdstring, int wait, char **stdfiles)); --pid_t launchpid _PRx((void)); -+int Launch _PRx((char *cmdstring, int wait, char **stdfiles, int *pipes)); -+pid_t LaunchPid _PRx((void)); - - _PRend - ---- util/tlaunch2.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ util/tlaunch2.c 2007-12-18 20:10:27.000000000 +0000 -@@ -0,0 +1,59 @@ -+/* -+ * -+ * tlaunch2 -- test launch routine (child routines) -+ * -+ */ -+ -+#define HAVE_CONFIG_H 1 -+ -+#if HAVE_CONFIG_H -+#include <conf.h> -+#endif -+#include <stdio.h> -+#include <ctype.h> -+#if HAVE_STRING_H -+#include <string.h> -+#endif -+#if HAVE_STDLIB_H -+#include <stdlib.h> -+#endif -+#if HAVE_UNISTD_H -+#include <unistd.h> -+#endif -+ -+#ifdef ANSI_FUNC -+int main (int argc, char **argv) -+#else -+int main(argc, argv) -+ int argc; -+ char **argv; -+#endif -+{ -+ int i; -+ char c; -+ char *s, *t, *u; -+ int pipes[4]; -+ if( (s=getenv("LAUNCH_PIPES")) ){ -+ t = (char *)strdup(s); -+ for(i=0, u=(char *)strtok(t, ","); i<4 && u; -+ i++, u=(char *)strtok(NULL,",")){ -+ pipes[i] = atoi(u); -+ fprintf(stderr, "child pipe #%d: %d\n", i, pipes[i]); -+ } -+ if( t ) free(t); -+ if( i < 4 ) return(1); -+ close(pipes[0]); -+ close(pipes[3]); -+ dup2(pipes[2], 0); close(pipes[2]); -+ dup2(pipes[1], 1); close(pipes[1]); -+ } -+ else{ -+ fprintf(stderr, "No LAUNCH_PIPE environment variable\n"); -+ } -+ while( read(0, &c, 1) ){ -+ if( islower((int)c) ) c = toupper((int)c); -+ write(3, &c, 1); -+ write(1, &c, 1); -+ } -+ return 0; -+} ---- util/tlaunch.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ util/tlaunch.c 2007-12-18 20:10:27.000000000 +0000 -@@ -0,0 +1,98 @@ -+/* -+ * Copyright (c) 2007 Smithsonian Astrophysical Observatory -+ */ -+ -+/* -+ * -+ * tlaunch -- test launch routine -+ * -+ */ -+ -+#define HAVE_CONFIG_H 1 -+#include <launch.h> -+ -+extern char *optarg; -+extern int optind; -+ -+#ifdef ANSI_FUNC -+int main (int argc, char **argv) -+#else -+int main(argc, argv) -+ int argc; -+ char **argv; -+#endif -+{ -+ int c; -+ int got=0; -+ int doattach=0; -+ int dofiles=0; -+ int dopipes=0; -+ int pipes[2]; -+ char *prog=NULL; -+ char *files[3]; -+ char *pfile=NULL; -+ char wbuf[SZ_LINE]; -+ FILE *fd; -+ -+ /* init */ -+ memset(files, 0, sizeof(char *)*3); -+ /* process switch arguments */ -+ while ((c = getopt(argc, argv, "ae:i:o:p:w:")) != -1){ -+ switch(c){ -+ case 'a': -+ doattach = 1; -+ break; -+ case 'e': -+ files[2] = optarg; -+ dofiles |= 4; -+ break; -+ case 'i': -+ files[0] = optarg; -+ dofiles |= 1; -+ break; -+ case 'o': -+ files[1] = optarg; -+ dofiles |= 2; -+ break; -+ case 'p': -+ pfile = optarg; -+ dopipes = 1; -+ break; -+ case 'w': -+ snprintf(wbuf, SZ_LINE, "LAUNCH_ROUTINE=%s", optarg); -+ putenv(wbuf); -+ default: -+ break; -+ } -+ } -+ if( optind >= argc ){ -+ fprintf(stderr, -+ "usage: %s -a -i stdin -o stdout -e stderr -p pfile [command]\n", -+ argv[0]); -+ return 1; -+ } -+ prog = argv[optind++]; -+ if( !strcmp(prog, "tlaunch2") && !dopipes ){ -+ fprintf(stderr, "ERROR: use -p [file] with tlaunch2\n"); -+ return 1; -+ } -+ if( (got = Launch(prog, doattach, dofiles?files:NULL, dopipes?pipes:NULL)) ) -+ fprintf(stderr, "ERROR: got=%d\n", got); -+ else -+ fprintf(stderr, "SUCCESS: got(%x)=%d\n", dofiles, got); -+ /* send pipe file contents to child, read back and display results */ -+ if( pfile ){ -+ if( !(fd = fopen(pfile,"r")) ){ -+ perror("fopen"); -+ return 1; -+ } -+ while( fread(&c, sizeof(char), 1, fd) ){ -+ write(pipes[1], &c, 1); -+ if( read(pipes[0], &c, 1) ){ -+ fwrite(&c, sizeof(char), 1, stdout); -+ } -+ } -+ fclose(fd); -+ } -+ return 0; -+} ---- util/zprocess.c.orig 2006-02-21 16:34:12.000000000 +0000 -+++ util/zprocess.c 2007-12-18 20:10:27.000000000 +0000 -@@ -6,7 +6,8 @@ - * - * zprocess.c -- routines to start up and communicate with a slave process - * -- * based on zfiopr.c from NOAO IRAF system -+ * based on zfiopr.c from NOAO IRAF system (more loosely than previously, -+ * since we replaces the fork/exec with our own Launch()). - * - */ - -@@ -65,8 +66,7 @@ - * if the table overflows. - */ - #ifdef ANSI_FUNC --static int --pr_enter(int pid, int inchan, int outchan) -+static int pr_enter(int pid, int inchan, int outchan) - #else - static int pr_enter(pid, inchan, outchan) - int pid; -@@ -114,8 +114,7 @@ - * is killed and we do not wish to wait for process termination. - */ - #ifdef ANSI_FUNC --static void --pr_release (int pid) -+static void pr_release (int pid) - #else - static void pr_release (pid) - int pid; -@@ -143,8 +142,7 @@ - *---------------------------------------------------------------------------- - */ - #ifdef ANSI_FUNC --static void --PRSleep (int msec) -+static void PRSleep (int msec) - #else - static void PRSleep(msec) - int msec; -@@ -166,127 +164,36 @@ - * - */ - --/* -- * -- * ProcessOpen -- -- * Open a connected subprocess. Spawn process and open bidirectional -- * IPC channels, implemented with pipes for this version of Berkeley UNIX. -- * -- */ -+ - #ifdef ANSI_FUNC --int --ProcessOpen(char *osfn, char **argv, int *inchan, int *outchan, int *pid) -+int ProcessOpen(char *cmd, int *inchan, int *outchan, int *pid) - #else --int ProcessOpen(osfn, argv, inchan, outchan, pid) -- char *osfn; /* name of executable file */ -- char **argv; /* argument list */ -+int ProcessOpen(cmd, argv, inchan, outchan, pid) -+ char *cmd; /* command line to Launch */ - int *inchan, *outchan; /* IPC channels (parent reads inchan) */ - int *pid; /* returned process id */ - #endif - { -- int pin[2], pout[2]; -- int maxforks = 3; -- char **targv; -- char *args[2]; -- char *prog=NULL; -- static char *path; -- -- if (pr_debug) -- fprintf (stderr, "ProcessOpen: '%s'", (char *)osfn); -- -- if( path == NULL ){ -- path = (char *)getenv("PATH"); -- } -- -- /* Check that the process file exists and is executable. -- */ -- if( (prog = Find(osfn, "x", NULL, path)) == NULL ){ -+ int pipes[2]; -+ if( Launch(cmd, 0, NULL, pipes) != 0 ){ -+ /* failure */ -+ *inchan = -1; -+ *outchan = -1; - *pid = 0; -- return(0); -- } -- -- /* open pipes */ -- pipe(pin); -- if( pipe(pout) != 0){ -- *pid = 0; -- return(0); -- } -- -- /* Create child process. The child inherits the open stdio files. -- * The fork can fail if swap space is full or if we have too many processes. -- */ -- while ((*pid = fork()) == -1) { -- if (--maxforks == 0) { -- close (pin[0]); close (pin[1]); -- close (pout[0]); close (pout[1]); -- *pid = 0; -- return(0); -- } -- sleep (2); -- } -- -- if (*pid == 0) { -- -- /* New child process. Make child think the pipe is its stdin/out. -- */ -- close (pin[0]); -- close (pout[1]); -- close (0); dup (pout[0]); close (pout[0]); -- close (1); dup (pin[1]); close (pin[1]); -- --#ifdef IRAF_ONLY -- /* Disable SIGINT so that child process does not die when the -- * parent process is interrupted. The child should get an EOF -- * on reading or writing and clean itself up. -- */ -- signal (SIGINT, SIG_IGN); --#endif -- -- /* Exec the new process. Will not return if successful. -- */ -- if( argv != NULL ){ -- targv = argv; -+ return 0; - } - else { -- targv = args; -- args[0] = prog; -- args[1] = NULL; -- } -- execv(prog, (void *)targv); -- -- /* If we get here the new process could not be executed for some -- * reason. Shutdown, calling _exit to avoid flushing parent's -- * io buffers. -- */ -- _exit (1); -- -- } else { -- -- /* Existing, parent process. */ -- close (pin[1]); -- close (pout[0]); -- *inchan = pin[0]; -- *outchan = pout[1]; -- -- /* Save pid in parent's process table. Entry cleared when -- * CloseProcess is called to wait for process to terminate. Also save -- * channel numbers in process table since only the pid is passed -- * when the process is closed. -- */ -- pr_enter (*pid, pin[0], pout[1]); -- -- if (pr_debug) -- fprintf (stderr, " [%d]\n", *pid); -- -- /* clean up and return */ -- if( prog ) free(prog); -- return(1); -- -+ /* package up process info for return */ -+ *inchan = pipes[0]; -+ *outchan = pipes[1]; -+ *pid = LaunchPid(); -+ /* and also save process info for later */ -+ pr_enter (*pid, *inchan, *outchan); -+ /* success */ -+ return 1; - } -- return(1); - } - -- - /* - * - * ProcessClose -- Close a connected subprocess and -@@ -294,8 +201,7 @@ - * - */ - #ifdef ANSI_FUNC --int --ProcessClose(int pid, int *exit_status) -+int ProcessClose(int pid, int *exit_status) - #else - int ProcessClose(pid, exit_status) - int pid; -@@ -339,8 +245,7 @@ - * - */ - #ifdef ANSI_FUNC --void * --ProcessRead(int fd, void *buf, int maxbytes, int *got) -+void *ProcessRead(int fd, void *buf, int maxbytes, int *got) - #else - void *ProcessRead(fd, buf, maxbytes, got) - int fd; -@@ -428,8 +333,7 @@ - * - */ - #ifdef ANSI_FUNC --int --ProcessWrite(int fd, void *buf, int nbytes) -+int ProcessWrite(int fd, void *buf, int nbytes) - #else - int ProcessWrite(fd, buf, nbytes) - int fd; -@@ -457,8 +361,7 @@ - * ProcessGetChan -- Get the codes for the IPC channels assigned to a process. - */ - #ifdef ANSI_FUNC --int --ProcessGetChan (int pid, int *inchan, int *outchan) -+int ProcessGetChan (int pid, int *inchan, int *outchan) - #else - int ProcessGetChan (pid, inchan, outchan) - int pid; ---- util/zprocess.h.orig 2004-09-18 14:34:51.000000000 +0100 -+++ util/zprocess.h 2007-12-18 20:10:27.000000000 +0000 -@@ -28,15 +28,12 @@ - #endif - #include <sys/time.h> - #include <signal.h> --#include <prsetup.h> -+#include <launch.h> - #include <find.h> --#include <xport.h> --#include <xalloc.h> - - _PRbeg - --int ProcessOpen _PRx((char *osfn, char **argv, -- int *inchan, int *outchan, int *pid)); -+int ProcessOpen _PRx((char *cmd, int *inchan, int *outchan, int *pid)); - void *ProcessRead _PRx((int fd, void *buf, int maxbytes, int *got)); - int ProcessWrite _PRx((int fd, void *buf, int nbytes)); - int ProcessClose _PRx((int pid, int *exit_status)); |