summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.patch2475
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));