1 |
bicatali 08/11/05 22:13:59 |
2 |
|
3 |
Added: funtools-1.4.0-makefiles.patch |
4 |
funtools-1.4.0-ds9-5.4.patch |
5 |
Log: |
6 |
Initial import |
7 |
(Portage version: 2.2_rc11/cvs/Linux 2.6.25-gentoo-r7 x86_64) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 sci-astronomy/funtools/files/funtools-1.4.0-makefiles.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/sci-astronomy/funtools/files/funtools-1.4.0-makefiles.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/sci-astronomy/funtools/files/funtools-1.4.0-makefiles.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: funtools-1.4.0-makefiles.patch |
16 |
=================================================================== |
17 |
--- ./Makefile.in.orig 2008-11-02 20:13:46.000000000 +0000 |
18 |
+++ ./Makefile.in 2008-11-02 21:20:42.000000000 +0000 |
19 |
@@ -28,6 +28,11 @@ |
20 |
|
21 |
prefix = @prefix@ |
22 |
exec_prefix = @exec_prefix@ |
23 |
+bindir = @bindir@ |
24 |
+includedir = @includedir@ |
25 |
+mandir = @mandir@ |
26 |
+datadir = @datadir@ |
27 |
+libdir = @libdir@ |
28 |
|
29 |
# The following definition can be set to non-null for special systems |
30 |
# like AFS with replication. It allows the pathnames used for installation |
31 |
@@ -37,19 +42,19 @@ |
32 |
INSTALL_ROOT = |
33 |
|
34 |
# Directory in which to install the .a or .so binary for the FUNTOOLS library: |
35 |
-LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib |
36 |
+LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) |
37 |
|
38 |
# Directory in which to install the program wish: |
39 |
-BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin |
40 |
+BIN_INSTALL_DIR = $(INSTALL_ROOT)$(bindir) |
41 |
|
42 |
# Directory in which to install the funtools.h include file: |
43 |
-INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include |
44 |
+INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir)/funtools |
45 |
|
46 |
# Top-level directory for manual entries: |
47 |
-MAN_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/man |
48 |
+MAN_INSTALL_DIR = $(INSTALL_ROOT)$(mandir) |
49 |
|
50 |
# Top-level directory for share entries: |
51 |
-MAN_SHARE_DIR = $(INSTALL_ROOT)$(prefix)/share/funtools |
52 |
+MAN_SHARE_DIR = $(INSTALL_ROOT)$(datadir)/funtools |
53 |
|
54 |
# util files are in the util subdirectory |
55 |
UTIL_INC = -I./util |
56 |
@@ -60,7 +65,7 @@ |
57 |
# FITSY_LIBS = -L./fitsy -lfitsy |
58 |
|
59 |
# wcs files are in the wcs subdirectory |
60 |
-WCS_INC = -I./wcs |
61 |
+WCS_INC = -I/usr/include/wcs |
62 |
# WCS_LIBS = -L./wcs -lwcs |
63 |
|
64 |
# filter files are in the filter subdirectory |
65 |
@@ -225,7 +230,7 @@ |
66 |
echo $(PROGS) | ./mkfunmainlib > funmainlib.c; |
67 |
|
68 |
shlib: sublib $(LIBOBJS) |
69 |
- @(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \ |
70 |
+ @(rm -rf $(PACKAGE)tmp; mkdir -p $(PACKAGE)tmp; \ |
71 |
(cd $(PACKAGE)tmp && ar x ../$(LIB)); \ |
72 |
CC='$(CC)' CXX=$(CXX) \ |
73 |
./mklib -o $(PACKAGE) $(PACKAGE)tmp/*.o; \ |
74 |
@@ -237,7 +242,7 @@ |
75 |
$(RANLIB) lib$(PACKAGE)MainLib.a) |
76 |
|
77 |
shmainlib: mainlib |
78 |
- @(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \ |
79 |
+ @(rm -rf $(PACKAGE)tmp; mkdir -p $(PACKAGE)tmp; \ |
80 |
(cd $(PACKAGE)tmp && ar x ../lib$(PACKAGE)MainLib.a); \ |
81 |
CC='$(CC)' CXX='$(CXX)' \ |
82 |
./mklib -o $(PACKAGE)MainLib -L. -lfuntools $(PACKAGE)tmp/*.o;\ |
83 |
@@ -248,7 +253,7 @@ |
84 |
$(RANLIB) libtclfun.a) |
85 |
|
86 |
shtclfun: tclfun |
87 |
- @(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \ |
88 |
+ @(rm -rf $(PACKAGE)tmp; mkdir -p $(PACKAGE)tmp; \ |
89 |
(cd $(PACKAGE)tmp && ar x ../$(LIB) && ar x ../libtclfun.a); \ |
90 |
CC='$(CC)' CXX='$(CXX)' \ |
91 |
./mklib -o tclfun $(PACKAGE)tmp/*.o; \ |
92 |
@@ -422,7 +427,7 @@ |
93 |
do \ |
94 |
if [ ! -d $$i ] ; then \ |
95 |
echo "Making directory $$i"; \ |
96 |
- mkdir $$i; \ |
97 |
+ mkdir -p $$i; \ |
98 |
chmod 755 $$i; \ |
99 |
else true; \ |
100 |
fi; \ |
101 |
@@ -462,7 +467,7 @@ |
102 |
install-man: |
103 |
@if [ ! -d $(MAN_INSTALL_DIR) ] ; then \ |
104 |
echo "Making directory $(MAN_INSTALL_DIR)"; \ |
105 |
- mkdir $(MAN_INSTALL_DIR); \ |
106 |
+ mkdir -p $(MAN_INSTALL_DIR); \ |
107 |
chmod 755 $(MAN_INSTALL_DIR); \ |
108 |
else true; \ |
109 |
fi; |
110 |
@@ -473,7 +478,7 @@ |
111 |
M="$(MAN_INSTALL_DIR)/man$$E"; \ |
112 |
if [ ! -d $$M ] ; then \ |
113 |
echo "Making directory $$M"; \ |
114 |
- mkdir $$M; \ |
115 |
+ mkdir -p $$M; \ |
116 |
chmod 755 $$M; \ |
117 |
else true; \ |
118 |
fi; \ |
119 |
--- ./filter/Makefile.in.orig 2008-11-02 20:43:46.000000000 +0000 |
120 |
+++ ./filter/Makefile.in 2008-11-03 10:54:33.000000000 +0000 |
121 |
@@ -29,6 +29,9 @@ |
122 |
|
123 |
prefix = @prefix@ |
124 |
exec_prefix = @exec_prefix@ |
125 |
+bindir = @bindir@ |
126 |
+includedir = @includedir@ |
127 |
+libdir = @libdir@ |
128 |
|
129 |
# The following definition can be set to non-null for special systems |
130 |
# like AFS with replication. It allows the pathnames used for installation |
131 |
@@ -38,13 +41,13 @@ |
132 |
INSTALL_ROOT = |
133 |
|
134 |
# Directory in which to install the .a, .so, and .o files: |
135 |
-LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib |
136 |
+LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) |
137 |
|
138 |
# Directory in which to install the programs: |
139 |
-BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin |
140 |
+BIN_INSTALL_DIR = $(INSTALL_ROOT)$(bindir) |
141 |
|
142 |
# Directory in which to install the include files: |
143 |
-INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include |
144 |
+INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir)/funtools/filter |
145 |
|
146 |
# util files are in the util directory at same level |
147 |
UTIL_INC = -I../util |
148 |
@@ -55,7 +58,7 @@ |
149 |
#FITSY_LIBS = -L../fitsy |
150 |
|
151 |
# wcs files are in the wcs subdirectory |
152 |
-WCS_INC = -I../wcs |
153 |
+WCS_INC = -I/usr/include/wcs |
154 |
#WCS_LIBS = -L../wcs -lwcs |
155 |
|
156 |
# extra includes for compiling |
157 |
@@ -161,7 +164,7 @@ |
158 |
do \ |
159 |
if [ ! -d $$i ] ; then \ |
160 |
echo "Making directory $$i"; \ |
161 |
- mkdir $$i; \ |
162 |
+ mkdir -p $$i; \ |
163 |
chmod 755 $$i; \ |
164 |
else true; \ |
165 |
fi; \ |
166 |
@@ -211,7 +214,7 @@ |
167 |
.c.o: |
168 |
$(CC) -c $(CC_SWITCHES) $< |
169 |
|
170 |
-filtprog_c.o: filtprog_c.c regions_h.h xalloc_c.h \ |
171 |
+filtprog_c.o: filtprog_c.c regions_h.h xalloc_c.h swap_c.h \ |
172 |
events_c.h image_c.h evregions_c.h imregions_c.h filter.h |
173 |
$(CC) -c $(CC_SWITCHES) -DOBJPATH="$(OBJPATH)" \ |
174 |
-DFILTER_CC="$(FILTER_CC)" -DFILTER_CFLAGS="$(FILTER_CFLAGS)" \ |
175 |
@@ -226,6 +229,10 @@ |
176 |
$(RM) xalloc_c.h |
177 |
./inc.sed XALLOC_C < ../util/xalloc.c > xalloc_c.h |
178 |
|
179 |
+swap_c.h: swap.c inc.sed |
180 |
+ $(RM) swap_c.h |
181 |
+ ./inc.sed SWAP_C < swap.c > swap_c.h |
182 |
+ |
183 |
events_c.h: evfilter.c inc.sed |
184 |
$(RM) events_c.h |
185 |
./inc.sed EVENTS_C < evfilter.c > events_c.h |
186 |
@@ -250,7 +257,7 @@ |
187 |
$(RM) imregions_c.h |
188 |
./inc.sed IMREGIONS_C < imregions.c > imregions_c.h |
189 |
|
190 |
-headers: regions_h.h xalloc_c.h \ |
191 |
+headers: regions_h.h xalloc_c.h swap_c.h \ |
192 |
events_c.h image_c.h evregions_c.h imregions_c.h |
193 |
|
194 |
# remake the parser |
195 |
--- ./fitsy/Makefile.in.orig 2008-11-02 20:50:20.000000000 +0000 |
196 |
+++ ./fitsy/Makefile.in 2008-11-02 21:21:32.000000000 +0000 |
197 |
@@ -28,6 +28,11 @@ |
198 |
|
199 |
prefix = @prefix@ |
200 |
exec_prefix = @exec_prefix@ |
201 |
+bindir = @bindir@ |
202 |
+includedir = @includedir@ |
203 |
+mandir = @mandir@ |
204 |
+datadir = @datadir@ |
205 |
+libdir = @libdir@ |
206 |
|
207 |
# The following definition can be set to non-null for special systems |
208 |
# like AFS with replication. It allows the pathnames used for installation |
209 |
@@ -37,13 +42,13 @@ |
210 |
INSTALL_ROOT = |
211 |
|
212 |
# Directory in which to install the .a, .so, and .o files: |
213 |
-LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib |
214 |
+LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) |
215 |
|
216 |
# Directory in which to install the programs: |
217 |
-BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin |
218 |
+BIN_INSTALL_DIR = $(INSTALL_ROOT)$(bindir) |
219 |
|
220 |
# Directory in which to install the include files: |
221 |
-INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include |
222 |
+INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir)/funtools/fitsy |
223 |
|
224 |
# There are just too many different versions of "install" around; |
225 |
# better to use the install-sh script that comes with the distribution, |
226 |
@@ -186,7 +191,7 @@ |
227 |
do \ |
228 |
if [ ! -d $$i ] ; then \ |
229 |
echo "Making directory $$i"; \ |
230 |
- mkdir $$i; \ |
231 |
+ mkdir -p $$i; \ |
232 |
chmod 755 $$i; \ |
233 |
else true; \ |
234 |
fi; \ |
235 |
@@ -200,6 +205,8 @@ |
236 |
fi; |
237 |
@echo "Installing fitsy.h" |
238 |
@$(INSTALL_DATA) fitsy.h $(INCLUDE_INSTALL_DIR)/fitsy.h |
239 |
+ @echo "Installing xfile.h" |
240 |
+ @$(INSTALL_DATA) xfile.h $(INCLUDE_INSTALL_DIR)/xfile.h |
241 |
# @for i in $(PROGS) ; \ |
242 |
# do \ |
243 |
# if [ -f $$i ] ; then \ |
244 |
--- ./util/Makefile.in.orig 2008-11-02 20:55:57.000000000 +0000 |
245 |
+++ ./util/Makefile.in 2008-11-02 21:22:30.000000000 +0000 |
246 |
@@ -29,6 +29,11 @@ |
247 |
|
248 |
prefix = @prefix@ |
249 |
exec_prefix = @exec_prefix@ |
250 |
+bindir = @bindir@ |
251 |
+includedir = @includedir@ |
252 |
+mandir = @mandir@ |
253 |
+datadir = @datadir@ |
254 |
+libdir = @libdir@ |
255 |
|
256 |
# The following definition can be set to non-null for special systems |
257 |
# like AFS with replication. It allows the pathnames used for installation |
258 |
@@ -38,13 +43,13 @@ |
259 |
INSTALL_ROOT = |
260 |
|
261 |
# Directory in which to install the .a, .so, and .o files: |
262 |
-LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib |
263 |
+LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) |
264 |
|
265 |
# Directory in which to install the programs: |
266 |
-BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin |
267 |
+BIN_INSTALL_DIR = $(INSTALL_ROOT)$(bindir) |
268 |
|
269 |
# Directory in which to install the include files: |
270 |
-INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include |
271 |
+INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir)/funtools/util |
272 |
|
273 |
# extra includes for compiling |
274 |
INCLUDES = |
275 |
@@ -127,7 +132,7 @@ |
276 |
# the actual library we are building (if this is a subpackage) |
277 |
LIB = @LIB@ |
278 |
|
279 |
-TESTPROGS = tparse |
280 |
+TESTPROGS = tparse tlaunch tlaunch2 |
281 |
|
282 |
PROGS = gcat |
283 |
|
284 |
@@ -189,12 +194,24 @@ |
285 |
$(CC) $(LDFLAGS) tparse.o parse.o -o tparse $(LIB) $(LIBS) \ |
286 |
$(EXTRA_LIBS) |
287 |
|
288 |
+tlaunch.o: tlaunch.c |
289 |
+ |
290 |
+tlaunch: tlaunch.o launch.o $(LIB) |
291 |
+ $(CC) $(LDFLAGS) tlaunch.o launch.o -o tlaunch $(LIB) $(LIBS) \ |
292 |
+ $(EXTRA_LIBS) |
293 |
+ |
294 |
+tlaunch2.o: tlaunch2.c |
295 |
+ |
296 |
+tlaunch2: tlaunch2.o |
297 |
+ $(CC) $(LDFLAGS) tlaunch2.o -o tlaunch2 |
298 |
+ |
299 |
+ |
300 |
install-binaries: $(LIB) $(PROGS) |
301 |
@for i in $(LIB_INSTALL_DIR) $(INCLUDE_INSTALL_DIR) $(BIN_INSTALL_DIR) ; \ |
302 |
do \ |
303 |
if [ ! -d $$i ] ; then \ |
304 |
echo "Making directory $$i"; \ |
305 |
- mkdir $$i; \ |
306 |
+ mkdir -p $$i; \ |
307 |
chmod 755 $$i; \ |
308 |
else true; \ |
309 |
fi; \ |
310 |
@@ -254,4 +271,11 @@ |
311 |
configure: configure.in |
312 |
autoconf configure.in |
313 |
|
314 |
+pure: tlaunch.pure |
315 |
+ |
316 |
+tlaunch.pure: tlaunch.o launch.o $(LIB) |
317 |
+ purift $(CC) $(LDFLAGS) tlaunch.o launch.o -o tlaunch \ |
318 |
+ $(LIB) $(LIBS) $(EXTRA_LIBS) |
319 |
+ |
320 |
+ |
321 |
# DO NOT DELETE THIS LINE -- make depend depends on it. |
322 |
--- ./gnu/Makefile.in.orig 2008-11-02 20:53:04.000000000 +0000 |
323 |
+++ ./gnu/Makefile.in 2008-11-02 20:55:46.000000000 +0000 |
324 |
@@ -21,6 +21,11 @@ |
325 |
|
326 |
prefix = @prefix@ |
327 |
exec_prefix = @exec_prefix@ |
328 |
+bindir = @bindir@ |
329 |
+includedir = @includedir@ |
330 |
+mandir = @mandir@ |
331 |
+datadir = @datadir@ |
332 |
+libdir = @libdir@ |
333 |
|
334 |
# The following definition can be set to non-null for special systems |
335 |
# like AFS with replication. It allows the pathnames used for installation |
336 |
@@ -53,13 +58,13 @@ |
337 |
EXTRA_OBJS = @EXTRA_OBJS@ |
338 |
|
339 |
# Directory in which to install the .a, .so, and .o files: |
340 |
-LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib |
341 |
+LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) |
342 |
|
343 |
# Directory in which to install the programs: |
344 |
-BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin |
345 |
+BIN_INSTALL_DIR = $(INSTALL_ROOT)$(bindir) |
346 |
|
347 |
# Directory in which to install the include files: |
348 |
-INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include |
349 |
+INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir) |
350 |
|
351 |
# There are just too many different versions of "install" around; |
352 |
# better to use the install-sh script that comes with the distribution, |
353 |
@@ -95,14 +100,14 @@ |
354 |
|
355 |
OBJS = sort.o |
356 |
|
357 |
-PROGS = _sort |
358 |
+PROGS = _funsort |
359 |
|
360 |
TESTPROGS = sorttest |
361 |
|
362 |
all: $(PROGS) |
363 |
|
364 |
-_sort: $(OBJS) |
365 |
- $(CC) $(LDFLAGS) $(OBJS) -o _sort |
366 |
+_funsort: $(OBJS) |
367 |
+ $(CC) $(LDFLAGS) $(OBJS) -o _funsort |
368 |
|
369 |
sorttest: sorttest.o |
370 |
$(CC) $(LDFLAGS) sorttest.o -o sorttest -L.. -lfuntools |
371 |
@@ -141,10 +146,10 @@ |
372 |
done; |
373 |
|
374 |
|
375 |
-pure: _sort.pure |
376 |
+pure: _funsort.pure |
377 |
|
378 |
-_sort.pure: $(FUNLIB) sort.o |
379 |
- purify $(CC) $(LDFLAGS) sort.o -o _sort.pure \ |
380 |
+_funsort.pure: $(FUNLIB) sort.o |
381 |
+ purify $(CC) $(LDFLAGS) sort.o -o _funsort.pure \ |
382 |
$(FUNLIB) $(LIBS) |
383 |
|
384 |
# DO NOT DELETE THIS LINE -- make depend depends on it. |
385 |
|
386 |
|
387 |
|
388 |
1.1 sci-astronomy/funtools/files/funtools-1.4.0-ds9-5.4.patch |
389 |
|
390 |
file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/sci-astronomy/funtools/files/funtools-1.4.0-ds9-5.4.patch?rev=1.1&view=markup |
391 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/sci-astronomy/funtools/files/funtools-1.4.0-ds9-5.4.patch?rev=1.1&content-type=text/plain |
392 |
|
393 |
Index: funtools-1.4.0-ds9-5.4.patch |
394 |
=================================================================== |
395 |
--- filter/evfilter.c.orig 2005-12-07 21:29:34.000000000 +0000 |
396 |
+++ filter/evfilter.c 2007-12-18 20:10:26.000000000 +0000 |
397 |
@@ -65,6 +65,9 @@ |
398 |
g->masks = _masks; |
399 |
} |
400 |
/* initialize shapes -- but check to make sure eptr is OK */ |
401 |
+#if DO_FILTER_SWAP |
402 |
+ memset(_swf, 0, EVSIZE); |
403 |
+#endif |
404 |
if( eptr ) FINIT; |
405 |
/* these also must be defined if EVSECT is being used */ |
406 |
g->tlminx = TLMINX; |
407 |
@@ -115,6 +118,9 @@ |
408 |
/* do the filtering on each event */ |
409 |
for(rptr=rbuf, eptr=ebuf; ne--; rptr++, eptr += esize){ |
410 |
g->rid = 0; |
411 |
+#if DO_FILTER_SWAP |
412 |
+ memset(_swf, 0, EVSIZE); |
413 |
+#endif |
414 |
*rptr = ((FILTER) ? (g->rid ? g->rid : -1) : 0); |
415 |
} |
416 |
return (void *)g; |
417 |
@@ -123,14 +129,48 @@ |
418 |
|
419 |
int main(int argc, char **argv) |
420 |
{ |
421 |
- char *ebuf, *etop; |
422 |
- int *rbuf; |
423 |
+ int i; |
424 |
+ int pipes[4]; |
425 |
int get, got; |
426 |
+#if DO_FILTER_SWAP |
427 |
+ int sgot; |
428 |
+#endif |
429 |
int n; |
430 |
+ int *rbuf; |
431 |
+ char *ebuf, *etop; |
432 |
+ char *s=NULL, *t=NULL, *u=NULL; |
433 |
void *g=NULL; |
434 |
|
435 |
+ /* Launch() sometimes rearranges passed pipes to be stdin/stdout */ |
436 |
+ if( (s=getenv("LAUNCH_PIPES")) ){ |
437 |
+ t = (char *)strdup(s); |
438 |
+ for(i=0, u=(char *)strtok(t, ","); i<4 && u; |
439 |
+ i++, u=(char *)strtok(NULL,",")){ |
440 |
+ pipes[i] = atoi(u); |
441 |
+ } |
442 |
+ if( t ) free(t); |
443 |
+ if( i < 4 ) return(1); |
444 |
+ close(pipes[0]); |
445 |
+ close(pipes[3]); |
446 |
+ dup2(pipes[2], 0); close(pipes[2]); |
447 |
+ dup2(pipes[1], 1); close(pipes[1]); |
448 |
+ } |
449 |
+ |
450 |
/* read and filter events */ |
451 |
while( read(0, &get, sizeof(int)) >0 ){ |
452 |
+#if DO_FILTER_SWAP |
453 |
+ switch(sizeof(int)){ |
454 |
+ case 2: |
455 |
+ _sw2((char *)&get,2,NULL,0); |
456 |
+ break; |
457 |
+ case 4: |
458 |
+ _sw4((char *)&get,4,NULL,0); |
459 |
+ break; |
460 |
+ case 8: |
461 |
+ _sw8((char *)&get,8,NULL,0); |
462 |
+ break; |
463 |
+ } |
464 |
+#endif |
465 |
ebuf = (char *)calloc(get, sizeof(char)); |
466 |
for(n=0, etop=ebuf; get>0; etop += got, get -= got){ |
467 |
if( (got=read(0, etop, get)) <=0 ) |
468 |
@@ -144,7 +184,36 @@ |
469 |
g = EVFILTRTN(g, ebuf, n, EVSIZE, rbuf); |
470 |
/* write results */ |
471 |
got = n*sizeof(int); |
472 |
+#if DO_FILTER_SWAP |
473 |
+ sgot = got; |
474 |
+ switch(sizeof(int)){ |
475 |
+ case 2: |
476 |
+ _sw2((char *)&sgot,2,NULL,0); |
477 |
+ break; |
478 |
+ case 4: |
479 |
+ _sw4((char *)&sgot,4,NULL,0); |
480 |
+ break; |
481 |
+ case 8: |
482 |
+ _sw8((char *)&sgot,8,NULL,0); |
483 |
+ break; |
484 |
+ } |
485 |
+ write(1, &sgot, sizeof(int)); |
486 |
+#else |
487 |
write(1, &got, sizeof(int)); |
488 |
+#endif |
489 |
+#if DO_FILTER_SWAP |
490 |
+ switch(sizeof(int)){ |
491 |
+ case 2: |
492 |
+ _sw2((char *)rbuf,got,NULL,0); |
493 |
+ break; |
494 |
+ case 4: |
495 |
+ _sw4((char *)rbuf,got,NULL,0); |
496 |
+ break; |
497 |
+ case 8: |
498 |
+ _sw8((char *)rbuf,got,NULL,0); |
499 |
+ break; |
500 |
+ } |
501 |
+#endif |
502 |
write(1, rbuf, got); |
503 |
if( ebuf) free(ebuf); |
504 |
if( rbuf ) free(rbuf); |
505 |
--- filter/filter.c.orig 2007-04-13 18:18:34.000000000 +0100 |
506 |
+++ filter/filter.c 2007-12-18 20:10:26.000000000 +0000 |
507 |
@@ -215,7 +215,6 @@ |
508 |
int got=0; |
509 |
char *s, *t; |
510 |
char tbuf[SZ_LINE]; |
511 |
- char *argv[3]; |
512 |
Filter filter; |
513 |
char *filtstr; |
514 |
|
515 |
@@ -471,11 +470,7 @@ |
516 |
switch(filter->ptype){ |
517 |
case PTYPE_PROCESS: |
518 |
case PTYPE_CONTAINED: |
519 |
- /* now start the filter process we just readied */ |
520 |
- argv[0] = filter->prog; |
521 |
- argv[1] = filter->args; |
522 |
- argv[2] = NULL; |
523 |
- if( !ProcessOpen(filter->prog, argv, |
524 |
+ if( !ProcessOpen(filter->prog, |
525 |
&(filter->ichan), &(filter->ochan), &(filter->pid)) ) |
526 |
goto error; |
527 |
break; |
528 |
@@ -785,7 +780,6 @@ |
529 |
if( filter->shflags ) xfree(filter->shflags); |
530 |
if( filter->code ) xfree(filter->code); |
531 |
if( filter->prog ) xfree(filter->prog); |
532 |
- if( filter->args ) xfree(filter->args); |
533 |
if( filter->string ) xfree(filter->string); |
534 |
if( filter->xbin ) xfree(filter->xbin); |
535 |
if( filter->ybin ) xfree(filter->ybin); |
536 |
--- filter/filtprog_c.c.orig 2006-12-12 21:39:07.000000000 +0000 |
537 |
+++ filter/filtprog_c.c 2007-12-18 20:10:26.000000000 +0000 |
538 |
@@ -16,6 +16,7 @@ |
539 |
#include <evregions_c.h> |
540 |
#include <imregions_c.h> |
541 |
#include <xalloc_c.h> |
542 |
+#include <swap_c.h> |
543 |
|
544 |
/* |
545 |
* |
546 |
@@ -316,6 +317,14 @@ |
547 |
break; |
548 |
} |
549 |
|
550 |
+ /* we want the byte order up at the top */ |
551 |
+ if( is_bigendian() ){ |
552 |
+ fprintf(fd, "#define MYBYTE_ORDER 4321\n"); |
553 |
+ } |
554 |
+ else{ |
555 |
+ fprintf(fd, "#define MYBYTE_ORDER 1234\n"); |
556 |
+ } |
557 |
+ |
558 |
/* prepend the filter header */ |
559 |
contents = REGIONS_H; |
560 |
if( (contents != NULL) && (*contents != '\0') ){ |
561 |
@@ -418,6 +427,7 @@ |
562 |
if( (contents != NULL) && (*contents != '\0') ){ |
563 |
fprintf(fd, "%s\n", contents); |
564 |
} |
565 |
+ /* region routines if not linking against previously compiled code */ |
566 |
switch( filter->type ){ |
567 |
case TYPE_EVENTS: |
568 |
/* normally, we filter events analytically using evregions.o */ |
569 |
@@ -446,6 +456,12 @@ |
570 |
break; |
571 |
} |
572 |
|
573 |
+ /* always need the swap routines (they're part of the filter) */ |
574 |
+ contents = SWAP_C; |
575 |
+ if( (contents != NULL) && (*contents != '\0') ){ |
576 |
+ fprintf(fd, "%s\n", contents); |
577 |
+ } |
578 |
+ |
579 |
/* output counts of shapes */ |
580 |
fprintf(fd, "#define NSHAPE %d\n", |
581 |
FilterShapeCount()); |
582 |
@@ -533,10 +549,13 @@ |
583 |
t = ""; |
584 |
} |
585 |
if( fhd->table->col[sp->idx].n == 1 ){ |
586 |
- fprintf(fd, "#define %s %s*((%s *)(eptr+%d))%s\n", |
587 |
+ fprintf(fd, "#define %s %s*((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", |
588 |
sp->name, |
589 |
s, |
590 |
GetType((int)fhd->table->col[sp->idx].type), |
591 |
+ dsize, |
592 |
+ offset, |
593 |
+ dsize, |
594 |
offset, |
595 |
t); |
596 |
} |
597 |
@@ -548,18 +567,21 @@ |
598 |
sp->name, s, "unsigned char", offset, t); |
599 |
break; |
600 |
case 16: |
601 |
- fprintf(fd, "#define %s %s*((%s *)(eptr+%d))%s\n", |
602 |
- sp->name, s, "unsigned short", offset, t); |
603 |
+ fprintf(fd, "#define %s %s*((%s *)(SW2(eptr+%d,%d,_swf,%d)))%s\n", |
604 |
+ sp->name, s, "unsigned short", offset, 2, offset, t); |
605 |
break; |
606 |
case 32: |
607 |
- fprintf(fd, "#define %s %s*((%s *)(eptr+%d))%s\n", |
608 |
- sp->name, s, "unsigned int", offset, t); |
609 |
+ fprintf(fd, "#define %s %s*((%s *)(SW4(eptr+%d,%d,_swf,%d)))%s\n", |
610 |
+ sp->name, s, "unsigned int", offset, 4, offset, t); |
611 |
break; |
612 |
default: |
613 |
- fprintf(fd, "#define %s %s((%s *)(eptr+%d))%s\n", |
614 |
+ fprintf(fd, "#define %s %s((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", |
615 |
sp->name, |
616 |
s, |
617 |
GetType((int)fhd->table->col[sp->idx].type), |
618 |
+ dsize, |
619 |
+ offset, |
620 |
+ dsize, |
621 |
offset, |
622 |
t); |
623 |
} |
624 |
@@ -571,10 +593,13 @@ |
625 |
fhd->table->col[sp->idx].n); |
626 |
} |
627 |
else{ |
628 |
- fprintf(fd, "#define %s %s((%s *)(eptr+%d))%s\n", |
629 |
+ fprintf(fd, "#define %s %s((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", |
630 |
sp->name, |
631 |
s, |
632 |
GetType((int)fhd->table->col[sp->idx].type), |
633 |
+ dsize, |
634 |
+ offset, |
635 |
+ dsize, |
636 |
offset, |
637 |
t); |
638 |
} |
639 |
@@ -628,6 +653,7 @@ |
640 |
if( evsize <=0 ) evsize = 1; |
641 |
/* output the size of the filter record */ |
642 |
fprintf(fd, "#define EVSIZE %d\n", evsize); |
643 |
+ fprintf(fd, "static char _swf[%d];\n", evsize); |
644 |
/* save for later use */ |
645 |
filter->evsize = evsize; |
646 |
break; |
647 |
@@ -829,7 +855,7 @@ |
648 |
stdfiles[0] = NULL; |
649 |
stdfiles[1] = "/dev/null"; |
650 |
stdfiles[2] = log; |
651 |
- got = launch(tbuf, 1, stdfiles); |
652 |
+ got = Launch(tbuf, 1, stdfiles, NULL); |
653 |
#else |
654 |
got = system(tbuf); |
655 |
#endif |
656 |
@@ -860,7 +886,7 @@ |
657 |
} |
658 |
else{ |
659 |
s = FileContents(log, 0, &len); |
660 |
- if( *s && len ){ |
661 |
+ if( s && *s && len ){ |
662 |
fprintf(stderr, "Compilation error message:\n%s\n", s); |
663 |
} |
664 |
if( !keep ){ |
665 |
--- filter/idxacts.c.orig 2007-01-05 17:35:25.000000000 +0000 |
666 |
+++ filter/idxacts.c 2007-12-18 20:10:26.000000000 +0000 |
667 |
@@ -179,9 +179,8 @@ |
668 |
int *pid; |
669 |
#endif |
670 |
{ |
671 |
- int i=0; |
672 |
char *s; |
673 |
- char *pargs[SZ_LINE]; |
674 |
+ char cmd[SZ_LINE]; |
675 |
|
676 |
if( !idxsort ){ |
677 |
if( idxpath ) return 0; |
678 |
@@ -190,28 +189,27 @@ |
679 |
} |
680 |
if( !(idxsort=Find(IDX_SORTPROG, "x", NULL, idxpath)) && |
681 |
!(idxsort=Find(IDX_SORTPROG, "x", NULL, ".")) ){ |
682 |
+ idxerror("index sort program cannot be found"); |
683 |
return 0; |
684 |
} |
685 |
} |
686 |
- /* construct argument list for sort program */ |
687 |
- pargs[i++] = (char *)idxsort; |
688 |
- pargs[i++] = "-B4"; |
689 |
- pargs[i++] = "+i0"; |
690 |
+ /* construct command line for sort program */ |
691 |
switch(type){ |
692 |
case IDX_SORT: |
693 |
+ snprintf(cmd, SZ_LINE-1, "%s -B4 +i0", idxsort); |
694 |
break; |
695 |
case IDX_OR_SORT: |
696 |
- pargs[i++] = "-u"; |
697 |
+ snprintf(cmd, SZ_LINE-1, "%s -B4 +i0 -u", idxsort); |
698 |
break; |
699 |
case IDX_AND_SORT: |
700 |
- pargs[i++] = "-D"; |
701 |
+ snprintf(cmd, SZ_LINE-1, "%s -B4 +i0 -D", idxsort); |
702 |
break; |
703 |
default: |
704 |
+ snprintf(cmd, SZ_LINE-1, "%s -B4 +i0", idxsort); |
705 |
break; |
706 |
} |
707 |
- pargs[i++] = NULL; |
708 |
/* start the sort program */ |
709 |
- if( !ProcessOpen(idxsort, pargs, ichan, ochan, pid) ){ |
710 |
+ if( !ProcessOpen(cmd, ichan, ochan, pid) ){ |
711 |
idxerror("index sort process cannot be started"); |
712 |
return 0; |
713 |
} |
714 |
--- filter/idx.h.orig 2007-01-04 17:34:57.000000000 +0000 |
715 |
+++ filter/idx.h 2007-12-18 20:10:26.000000000 +0000 |
716 |
@@ -54,7 +54,7 @@ |
717 |
#define IDX_ROW_INC 32 |
718 |
|
719 |
/* sort program */ |
720 |
-#define IDX_SORTPROG "_sort" |
721 |
+#define IDX_SORTPROG "_funsort" |
722 |
|
723 |
/* idxinfo which values */ |
724 |
#define IDX_COLNAME 1 |
725 |
--- filter/imfilter.c.orig 2004-02-05 00:24:45.000000000 +0000 |
726 |
+++ filter/imfilter.c 2007-12-18 20:10:26.000000000 +0000 |
727 |
@@ -192,19 +192,50 @@ |
728 |
|
729 |
int main(int argc, char **argv) |
730 |
{ |
731 |
-#ifdef TEST |
732 |
int i; |
733 |
+ int get, got; |
734 |
+#if DO_FILTER_SWAP |
735 |
+ int sgot; |
736 |
#endif |
737 |
- int get; |
738 |
- int got; |
739 |
+ int pipes[4]; |
740 |
int txmin, txmax, tymin, tymax, tblock; |
741 |
char tbuf[SZ_LINE]; |
742 |
+ char *s=NULL, *t=NULL, *u=NULL; |
743 |
+ |
744 |
+ /* Launch() sometimes rearranges passed pipes to be stdin/stdout */ |
745 |
+ if( (s=getenv("LAUNCH_PIPES")) ){ |
746 |
+ t = (char *)strdup(s); |
747 |
+ for(i=0, u=(char *)strtok(t, ","); i<4 && u; |
748 |
+ i++, u=(char *)strtok(NULL,",")){ |
749 |
+ pipes[i] = atoi(u); |
750 |
+ } |
751 |
+ if( t ) free(t); |
752 |
+ if( i < 4 ) return(1); |
753 |
+ close(pipes[0]); |
754 |
+ close(pipes[3]); |
755 |
+ dup2(pipes[2], 0); close(pipes[2]); |
756 |
+ dup2(pipes[1], 1); close(pipes[1]); |
757 |
+ } |
758 |
|
759 |
/* process requests for region information for sections of the image */ |
760 |
#ifdef TEST |
761 |
while( fgets(tbuf, SZ_LINE, stdin) ){ |
762 |
#else |
763 |
- while( (read(0, &get, sizeof(int)) >0) && (read(0, tbuf, get)==get) ){ |
764 |
+ while( (read(0, &get, sizeof(int)) >0) ){ |
765 |
+#if DO_FILTER_SWAP |
766 |
+ switch(sizeof(int)){ |
767 |
+ case 2: |
768 |
+ _sw2((char *)&get,2,NULL,0); |
769 |
+ break; |
770 |
+ case 4: |
771 |
+ _sw4((char *)&get,4,NULL,0); |
772 |
+ break; |
773 |
+ case 8: |
774 |
+ _sw8((char *)&get,8,NULL,0); |
775 |
+ break; |
776 |
+ } |
777 |
+#endif |
778 |
+ if(read(0, tbuf, get) != get) break; |
779 |
#endif |
780 |
if(sscanf(tbuf, "%d %d %d %d %d", |
781 |
&txmin, &txmax, &tymin, &tymax, &tblock)!=5){ |
782 |
@@ -222,7 +253,36 @@ |
783 |
#else |
784 |
/* calculate size of data we will write */ |
785 |
got = got * sizeof(FilterMaskRec); |
786 |
- write(1, &got, 4); |
787 |
+#if DO_FILTER_SWAP |
788 |
+ sgot = got; |
789 |
+ switch(sizeof(int)){ |
790 |
+ case 2: |
791 |
+ _sw2((char *)&sgot,2,NULL,0); |
792 |
+ break; |
793 |
+ case 4: |
794 |
+ _sw4((char *)&sgot,4,NULL,0); |
795 |
+ break; |
796 |
+ case 8: |
797 |
+ _sw8((char *)&sgot,8,NULL,0); |
798 |
+ break; |
799 |
+ } |
800 |
+ write(1, &sgot, sizeof(int)); |
801 |
+#else |
802 |
+ write(1, &got, sizeof(int)); |
803 |
+#endif |
804 |
+#if DO_FILTER_SWAP |
805 |
+ switch(sizeof(int)){ |
806 |
+ case 2: |
807 |
+ _sw2((char *)masks,got,NULL,0); |
808 |
+ break; |
809 |
+ case 4: |
810 |
+ _sw4((char *)masks,got,NULL,0); |
811 |
+ break; |
812 |
+ case 8: |
813 |
+ _sw8((char *)masks,got,NULL,0); |
814 |
+ break; |
815 |
+ } |
816 |
+#endif |
817 |
write(1, masks, got); |
818 |
#endif |
819 |
/* free mask records */ |
820 |
--- filter/swap.c.orig 1970-01-01 01:00:00.000000000 +0100 |
821 |
+++ filter/swap.c 2007-12-18 20:10:26.000000000 +0000 |
822 |
@@ -0,0 +1,90 @@ |
823 |
+#if __DARWIN_BYTE_ORDER |
824 |
+#define XBYTE_ORDER __DARWIN_BYTE_ORDER |
825 |
+#else |
826 |
+#define XBYTE_ORDER 0 |
827 |
+#endif |
828 |
+ |
829 |
+#ifndef MYBYTE_ORDER |
830 |
+#define MYBYTE_ORDER XBYTE_ORDER |
831 |
+#endif |
832 |
+ |
833 |
+#ifndef DO_FILTER_SWAP |
834 |
+#if (XBYTE_ORDER !=0) && (XBYTE_ORDER != MYBYTE_ORDER) |
835 |
+#define DO_FILTER_SWAP 1 |
836 |
+#endif |
837 |
+#endif |
838 |
+ |
839 |
+#if DO_FILTER_SWAP |
840 |
+char *_sw2(char *s, int n, char *_swf, int off) |
841 |
+{ |
842 |
+ char c; |
843 |
+ char *t=s; |
844 |
+ size_t i; |
845 |
+ if( !_swf || !_swf[off]++ ){ |
846 |
+ for (i=0; i<n; i += 2, s += 2) { |
847 |
+ c = *s; |
848 |
+ *(s) = *(s+1); |
849 |
+ *(s+1) = c; |
850 |
+ } |
851 |
+ } |
852 |
+ return t; |
853 |
+} |
854 |
+ |
855 |
+char *_sw4(char *s, int n, char *_swf, int off) |
856 |
+{ |
857 |
+ char c; |
858 |
+ char *t=s; |
859 |
+ size_t i; |
860 |
+ if( !_swf || !_swf[off]++ ){ |
861 |
+ for (i=0; i<n; i += 4, s += 4) { |
862 |
+ c = *s; |
863 |
+ *s = *(s+3); |
864 |
+ *(s+3) = c; |
865 |
+ c = *(s+1); |
866 |
+ *(s+1) = *(s+2); |
867 |
+ *(s+2) = c; |
868 |
+ } |
869 |
+ } |
870 |
+ return t; |
871 |
+} |
872 |
+ |
873 |
+char *_sw8(char *s, int n, char *_swf, int off) |
874 |
+{ |
875 |
+ char c; |
876 |
+ char *t=s; |
877 |
+ size_t i; |
878 |
+ if( !_swf || !_swf[off]++ ){ |
879 |
+ for (i=0; i<n; i += 8, s += 8) { |
880 |
+ c = *(s+0); |
881 |
+ *(s+0) = *(s+7); |
882 |
+ *(s+7) = c; |
883 |
+ c = *(s+1); |
884 |
+ *(s+1) = *(s+6); |
885 |
+ *(s+6) = c; |
886 |
+ c = *(s+2); |
887 |
+ *(s+2) = *(s+5); |
888 |
+ *(s+5) = c; |
889 |
+ c = *(s+3); |
890 |
+ *(s+3) = *(s+4); |
891 |
+ *(s+4) = c; |
892 |
+ } |
893 |
+ } |
894 |
+ return t; |
895 |
+} |
896 |
+ |
897 |
+#define SW2(a,n,b,i) _sw2(a,n,b,i) |
898 |
+#define SW4(a,n,b,i) _sw4(a,n,b,i) |
899 |
+#define SW8(a,n,b,i) _sw8(a,n,b,i) |
900 |
+ |
901 |
+#if defined(FILTER_PTYPE) && (FILTER_PTYPE != c) |
902 |
+#error "FILTER_PTYPE environment variable must be 'c' when running with Rosetta" |
903 |
+#endif |
904 |
+ |
905 |
+#else |
906 |
+ |
907 |
+#define SW2(a,n,b,i) a |
908 |
+#define SW4(a,n,b,i) a |
909 |
+#define SW8(a,n,b,i) a |
910 |
+ |
911 |
+#endif |
912 |
+ |
913 |
|
914 |
--- fitsy/fitsy.h.orig 2007-01-04 22:49:41.000000000 +0000 |
915 |
+++ fitsy/fitsy.h 2007-12-18 20:10:26.000000000 +0000 |
916 |
@@ -11,7 +11,7 @@ |
917 |
#if USE_XFILEIO |
918 |
#include <xfileio.h> |
919 |
#else |
920 |
-#include "xfile.h" |
921 |
+#include <xfile.h> |
922 |
#endif |
923 |
|
924 |
#ifdef __STDC__ |
925 |
@@ -30,7 +30,7 @@ |
926 |
|
927 |
#include <ctype.h> |
928 |
|
929 |
-#include "longlong.h" |
930 |
+#include <longlong.h> |
931 |
|
932 |
#ifndef NULL |
933 |
#define NULL 0 |
934 |
--- funcalc.c.orig 2007-03-01 18:12:12.000000000 +0000 |
935 |
+++ funcalc.c 2007-12-18 20:10:26.000000000 +0000 |
936 |
@@ -230,7 +230,7 @@ |
937 |
stdfiles[0] = NULL; |
938 |
stdfiles[1] = "/dev/null"; |
939 |
stdfiles[2] = log; |
940 |
- got = launch(cmd, 1, stdfiles); |
941 |
+ got = Launch(cmd, 1, stdfiles, NULL); |
942 |
#else |
943 |
snprintf(tbuf, SZ_LINE-1, " 1>/dev/null 2>%s", log); |
944 |
strcat(cmd, tbuf); |
945 |
@@ -286,7 +286,7 @@ |
946 |
s = NULL; |
947 |
} |
948 |
s = FileContents(log, 0, &len); |
949 |
- if( *s && len ) |
950 |
+ if( s && *s && len ) |
951 |
fprintf(stderr, "Compilation error message:\n%s\n", s); |
952 |
error = 1; |
953 |
goto endgame; |
954 |
--- funtable.c.orig 2007-06-11 22:18:31.000000000 +0100 |
955 |
+++ funtable.c 2007-12-18 20:10:26.000000000 +0000 |
956 |
@@ -11,7 +11,7 @@ |
957 |
static int maxrow=MAXROW; |
958 |
static char macrobuf[SZ_LINE]; |
959 |
|
960 |
-#define SORTPROG "_sort" |
961 |
+#define SORTPROG "_funsort" |
962 |
|
963 |
typedef struct rowstruct{ |
964 |
int x, y; |
965 |
@@ -90,6 +90,7 @@ |
966 |
int dtype, doffset, dmode, dn; |
967 |
int plen, elen, flen; |
968 |
int epad, ppad; |
969 |
+ int rlen; |
970 |
double dval; |
971 |
char *iname=NULL; |
972 |
char *oname=NULL; |
973 |
@@ -108,7 +109,7 @@ |
974 |
char *extn=NULL; |
975 |
char col[SZ_LINE]; |
976 |
char tbuf[SZ_LINE]; |
977 |
- char *pargs[SZ_LINE]; |
978 |
+ char cmd[SZ_LINE]; |
979 |
double *dbuf=NULL; |
980 |
FILE *ifile; |
981 |
Fun fun, tfun=NULL; |
982 |
@@ -280,20 +281,21 @@ |
983 |
/* if we specified columns, we also can specify "mask=transparent" |
984 |
and get all events, with the regionid (assuming we specified |
985 |
the region column to display as well) */ |
986 |
- if( argc >= 4 ) |
987 |
- mode = argv[optind+3]; |
988 |
+ if( args >= 4 ) mode = argv[optind+3]; |
989 |
+ |
990 |
/* set up sorting, if necessary */ |
991 |
if( dosort ){ |
992 |
/* look for sort program */ |
993 |
path = (char *)getenv("PATH"); |
994 |
if( !(prog=Find(SORTPROG, "x", NULL, path)) ) |
995 |
gerror(stderr, "can't locate sort program: %s\n", SORTPROG); |
996 |
+ /* allow commas as delims */ |
997 |
+ newdtable(","); |
998 |
/* get the size of the input record */ |
999 |
FunInfoGet(fun, FUN_ROWSIZE, &isize, 0); |
1000 |
/* construct argument list for sort program */ |
1001 |
- pargs[0] = (char *)prog; |
1002 |
- snprintf(tbuf, SZ_LINE-1, "-B%d", isize); |
1003 |
- pargs[1] = (char *)xstrdup(tbuf); |
1004 |
+ snprintf(cmd, SZ_LINE-1, "%s -B%d", prog, isize); |
1005 |
+ rlen = SZ_LINE - strlen(cmd) - 1; |
1006 |
for(ncol=0; word(sortcols, col, &ip); ncol++ ){ |
1007 |
if( !FunColumnLookup(fun, col, 0, NULL, &dtype, &dmode, &doffset, &dn, |
1008 |
NULL) ){ |
1009 |
@@ -333,15 +335,18 @@ |
1010 |
default: |
1011 |
gerror(stderr, "unsupported sort data type for column %s\n", tbuf); |
1012 |
} |
1013 |
- pargs[ncol+2] = (char *)xstrdup(tbuf); |
1014 |
- if( ncol > (SZ_LINE-3) ){ |
1015 |
- gerror(stderr, "ERROR: too many sort column arguments: %d\n", ncol); |
1016 |
+ strncat(cmd, " ", rlen); |
1017 |
+ rlen--; |
1018 |
+ strncat(cmd, tbuf, rlen); |
1019 |
+ rlen -= strlen(tbuf); |
1020 |
+ if( rlen <=0 ){ |
1021 |
+ gerror(stderr, "too many arguments for sort\n"); |
1022 |
+ exit(1); |
1023 |
} |
1024 |
} |
1025 |
- /* null terminate arg list */ |
1026 |
- pargs[ncol+2] = NULL; |
1027 |
+ freedtable(); |
1028 |
/* start the sort program */ |
1029 |
- if( !ProcessOpen(prog, pargs, &ichan, &ochan, &pid) ){ |
1030 |
+ if( !ProcessOpen(cmd, &ichan, &ochan, &pid) ){ |
1031 |
gerror(stderr, "ERROR: can't start sort program: %s\n", prog); |
1032 |
} |
1033 |
} |
1034 |
@@ -450,8 +455,6 @@ |
1035 |
fclose(ifile); |
1036 |
if( sortcols ) xfree(sortcols); |
1037 |
if( ebuf ) xfree(ebuf); |
1038 |
- for(i=0; i<ncol+2; i++) |
1039 |
- if( pargs[i] ) xfree(pargs[i]); |
1040 |
} |
1041 |
/* write out heap space, if it exists -- this quick hack needs cleanup! */ |
1042 |
if( fun->header && (ft_pcount(fun->header) > 0) ){ |
1043 |
--- gnu/sort.c.orig 2007-01-04 22:38:51.000000000 +0000 |
1044 |
+++ gnu/sort.c 2007-12-18 20:10:27.000000000 +0000 |
1045 |
@@ -2332,8 +2332,30 @@ |
1046 |
#ifdef _POSIX_VERSION |
1047 |
struct sigaction oldact, newact; |
1048 |
#endif /* _POSIX_VERSION */ |
1049 |
+#ifdef SAOMOD_FIX |
1050 |
+ int pipes[4]; |
1051 |
+ char *ss=NULL, *tt=NULL, *uu=NULL; |
1052 |
+#endif |
1053 |
|
1054 |
program_name = argv[0]; |
1055 |
+ |
1056 |
+#ifdef SAOMOD_FIX |
1057 |
+ /* Launch() sometimes rearranges passed pipes to be stdin/stdout */ |
1058 |
+ if( (ss=getenv("LAUNCH_PIPES")) ){ |
1059 |
+ tt = (char *)strdup(ss); |
1060 |
+ for(i=0, uu=(char *)strtok(tt, ","); i<4 && uu; |
1061 |
+ i++, uu=(char *)strtok(NULL,",")){ |
1062 |
+ pipes[i] = atoi(uu); |
1063 |
+ } |
1064 |
+ if( tt ) free(tt); |
1065 |
+ if( i < 4 ) return(1); |
1066 |
+ close(pipes[0]); |
1067 |
+ close(pipes[3]); |
1068 |
+ dup2(pipes[2], 0); close(pipes[2]); |
1069 |
+ dup2(pipes[1], 1); close(pipes[1]); |
1070 |
+ } |
1071 |
+#endif |
1072 |
+ |
1073 |
#ifdef SAOMOD_FIX |
1074 |
if ( (program_name = (char *)strrchr(program_name, '/')) ) |
1075 |
program_name++; |
1076 |
--- gnu/sorttest.c.orig 2004-02-04 14:14:19.000000000 +0000 |
1077 |
+++ gnu/sorttest.c 2007-12-18 20:10:27.000000000 +0000 |
1078 |
@@ -1,6 +1,6 @@ |
1079 |
/* |
1080 |
export EVENTS="(dval:D,fval:E,ival:J,uival:V,sval:I,cval:B,cval2:B)" |
1081 |
- sorttest | _sort -B24 +... | fundisp "stdin[EVENTS()]" |
1082 |
+ sorttest | _funsort -B24 +... | fundisp "stdin[EVENTS()]" |
1083 |
*/ |
1084 |
|
1085 |
#include <stdio.h> |
1086 |
@@ -52,16 +52,15 @@ |
1087 |
int c; |
1088 |
int ival; |
1089 |
int ichan, ochan, pid, status; |
1090 |
+ int rlen; |
1091 |
int nrec=NREC; |
1092 |
int dodouble=0; |
1093 |
int doxeq=0; |
1094 |
- int narg=0; |
1095 |
- char *prog="_sort"; |
1096 |
+ char *prog="_funsort"; |
1097 |
char *slist=NULL; |
1098 |
char *s; |
1099 |
char tbuf[SZ_LINE]; |
1100 |
char cmd[SZ_LINE]; |
1101 |
- char *args[SZ_LINE]; |
1102 |
FILE *fp=stdout; |
1103 |
Binary b; |
1104 |
|
1105 |
@@ -89,9 +88,8 @@ |
1106 |
|
1107 |
/* generate sort parameters and start sort program */ |
1108 |
if( doxeq ){ |
1109 |
- args[narg++] = (char *)NewString(prog); |
1110 |
- sprintf(tbuf, "-B%d", sizeof(Binary)); |
1111 |
- args[narg++] = (char *)NewString(tbuf); |
1112 |
+ snprintf(cmd, SZ_LINE-1, "%s -B%d %s", prog, sizeof(Binary), tbuf); |
1113 |
+ rlen = SZ_LINE - strlen(cmd); |
1114 |
if( !slist ){ |
1115 |
slist = (char *)NewString("d"); |
1116 |
} |
1117 |
@@ -99,39 +97,36 @@ |
1118 |
switch(*s){ |
1119 |
case 'd': |
1120 |
sprintf(tbuf, "+d0"); |
1121 |
- args[narg++] = (char *)NewString(tbuf); |
1122 |
break; |
1123 |
case 'f': |
1124 |
sprintf(tbuf, "+f8"); |
1125 |
- args[narg++] = (char *)NewString(tbuf); |
1126 |
break; |
1127 |
case 'i': |
1128 |
sprintf(tbuf, "+i12"); |
1129 |
- args[narg++] = (char *)NewString(tbuf); |
1130 |
break; |
1131 |
case 'I': |
1132 |
sprintf(tbuf, "+I16"); |
1133 |
- args[narg++] = (char *)NewString(tbuf); |
1134 |
break; |
1135 |
case 's': |
1136 |
sprintf(tbuf, "+s20"); |
1137 |
- args[narg++] = (char *)NewString(tbuf); |
1138 |
break; |
1139 |
case 'c': |
1140 |
sprintf(tbuf, "+c22"); |
1141 |
- args[narg++] = (char *)NewString(tbuf); |
1142 |
break; |
1143 |
default: |
1144 |
fprintf(stderr, "ERROR: unknown sort type: %s\n", s); |
1145 |
exit(1); |
1146 |
} |
1147 |
- if( narg > (SZ_LINE-2) ){ |
1148 |
- fprintf(stderr, "ERROR: too many arguments: %d\n", narg); |
1149 |
+ strncat(cmd, " ", rlen); |
1150 |
+ rlen--; |
1151 |
+ strncat(cmd, tbuf, rlen); |
1152 |
+ rlen -= strlen(tbuf); |
1153 |
+ if( rlen <=0 ){ |
1154 |
+ fprintf(stderr, "ERROR: too many arguments\n"); |
1155 |
exit(1); |
1156 |
} |
1157 |
} |
1158 |
- args[narg] = NULL; |
1159 |
- if( !ProcessOpen(prog, args, &ichan, &ochan, &pid) ){ |
1160 |
+ if( !ProcessOpen(cmd, &ichan, &ochan, &pid) ){ |
1161 |
fprintf(stderr, "ERROR: can't start %s\n", prog); |
1162 |
exit(1); |
1163 |
} |
1164 |
--- util/configure.ac.orig 2007-05-22 19:11:26.000000000 +0100 |
1165 |
+++ util/configure.ac 2007-12-18 20:10:27.000000000 +0000 |
1166 |
@@ -41,7 +41,7 @@ |
1167 |
|
1168 |
AC_C_CONST |
1169 |
|
1170 |
-AC_CHECK_FUNCS(strchr memcpy snprintf ftello fseeko) |
1171 |
+AC_CHECK_FUNCS(strchr memcpy snprintf ftello fseeko setenv) |
1172 |
|
1173 |
AC_CHECK_FUNC(connect) |
1174 |
if test $ac_cv_func_connect = no; then |
1175 |
@@ -119,6 +119,14 @@ |
1176 |
fi |
1177 |
AC_SUBST(USE_DL) |
1178 |
|
1179 |
+AC_MSG_CHECKING(for request to use posix_spawn) |
1180 |
+AC_ARG_ENABLE(posix_spawn, [ --enable-posix_spawn use posix_spawn() if available], |
1181 |
+ [fun_ok=$enableval], [fun_ok=no]) |
1182 |
+AC_MSG_RESULT($fun_ok) |
1183 |
+if test "$fun_ok" = "yes"; then |
1184 |
+ AC_CHECK_FUNCS(posix_spawn) |
1185 |
+fi |
1186 |
+ |
1187 |
SC_PATH_TCLCONFIG |
1188 |
if test x"${no_tcl}" = x ; then |
1189 |
AC_DEFINE(HAVE_TCL) |
1190 |
--- util/iraf_zprocess.c.orig 1970-01-01 01:00:00.000000000 +0100 |
1191 |
+++ util/iraf_zprocess.c 2007-12-18 20:10:27.000000000 +0000 |
1192 |
@@ -0,0 +1,469 @@ |
1193 |
+/* |
1194 |
+ * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory |
1195 |
+ */ |
1196 |
+ |
1197 |
+/* |
1198 |
+ * |
1199 |
+ * zprocess.c -- routines to start up and communicate with a slave process |
1200 |
+ * |
1201 |
+ * based on zfiopr.c from NOAO IRAF system |
1202 |
+ * |
1203 |
+ */ |
1204 |
+ |
1205 |
+#include <zprocess.h> |
1206 |
+ |
1207 |
+#ifndef min |
1208 |
+#define min(a,b) (((a)<(b))?(a):(b)) |
1209 |
+#endif |
1210 |
+ |
1211 |
+/* |
1212 |
+ * |
1213 |
+ * Private Routines |
1214 |
+ * |
1215 |
+ * |
1216 |
+ */ |
1217 |
+ |
1218 |
+static int pr_debug = 0; |
1219 |
+ |
1220 |
+/* |
1221 |
+ * |
1222 |
+ * Process table management code |
1223 |
+ * |
1224 |
+ */ |
1225 |
+ |
1226 |
+#define MAXPROCS 512 |
1227 |
+ |
1228 |
+static struct proctable { |
1229 |
+ int pr_pid; /* process id */ |
1230 |
+ int pr_active; /* if YES, process is still active */ |
1231 |
+ int pr_inchan; /* input IPC channel */ |
1232 |
+ int pr_outchan; /* output IPC channel */ |
1233 |
+ int pr_exit_status; /* process exit_status */ |
1234 |
+} prtable[MAXPROCS]; |
1235 |
+ |
1236 |
+/* PR_FINDPID -- Search the process table for a process. NULL is returned if |
1237 |
+ * the process cannot be found, otherwise a pointer to the table entry is |
1238 |
+ * returned. |
1239 |
+ */ |
1240 |
+#ifdef ANSI_FUNC |
1241 |
+static struct proctable *pr_findpid(int pid) |
1242 |
+#else |
1243 |
+static struct proctable *pr_findpid(pid) |
1244 |
+ int pid; |
1245 |
+#endif |
1246 |
+{ |
1247 |
+ register int pr; |
1248 |
+ |
1249 |
+ for (pr=0; pr<MAXPROCS; pr++){ |
1250 |
+ if (prtable[pr].pr_pid == pid) |
1251 |
+ return (&prtable[pr]); |
1252 |
+ } |
1253 |
+ return (NULL); |
1254 |
+} |
1255 |
+ |
1256 |
+/* PR_ENTER -- Make a new entry in the process table. Something is very wrong |
1257 |
+ * if the table overflows. |
1258 |
+ */ |
1259 |
+#ifdef ANSI_FUNC |
1260 |
+static int |
1261 |
+pr_enter(int pid, int inchan, int outchan) |
1262 |
+#else |
1263 |
+static int pr_enter(pid, inchan, outchan) |
1264 |
+ int pid; |
1265 |
+ int inchan, outchan; |
1266 |
+#endif |
1267 |
+{ |
1268 |
+ int pr; |
1269 |
+ |
1270 |
+ for (pr=0; pr<MAXPROCS; pr++){ |
1271 |
+ if (prtable[pr].pr_pid == 0){ |
1272 |
+ prtable[pr].pr_pid = pid; |
1273 |
+ prtable[pr].pr_active = 1; |
1274 |
+ prtable[pr].pr_inchan = inchan; |
1275 |
+ prtable[pr].pr_outchan = outchan; |
1276 |
+ return(1); |
1277 |
+ } |
1278 |
+ } |
1279 |
+ return(0); |
1280 |
+} |
1281 |
+ |
1282 |
+/* PR_GETCHAN -- Get the codes for the IPC channels assigned to a process. |
1283 |
+ */ |
1284 |
+#ifdef ANSI_FUNC |
1285 |
+static int pr_getchan (int pid, int *inchan, int *outchan) |
1286 |
+#else |
1287 |
+static int pr_getchan (pid, inchan, outchan) |
1288 |
+ int pid; |
1289 |
+ int *inchan, *outchan; |
1290 |
+#endif |
1291 |
+{ |
1292 |
+ register struct proctable *pr; |
1293 |
+ |
1294 |
+ /* Lookup process in table. Return an error if there is no entry. |
1295 |
+ */ |
1296 |
+ if ((pr = pr_findpid(pid)) == NULL) |
1297 |
+ return(-1); |
1298 |
+ else { |
1299 |
+ *inchan = pr->pr_inchan; |
1300 |
+ *outchan = pr->pr_outchan; |
1301 |
+ return (pid); |
1302 |
+ } |
1303 |
+} |
1304 |
+ |
1305 |
+/* PR_RELEASE -- Release the table entry for the process. Used when a process |
1306 |
+ * is killed and we do not wish to wait for process termination. |
1307 |
+ */ |
1308 |
+#ifdef ANSI_FUNC |
1309 |
+static void |
1310 |
+pr_release (int pid) |
1311 |
+#else |
1312 |
+static void pr_release (pid) |
1313 |
+ int pid; |
1314 |
+#endif |
1315 |
+{ |
1316 |
+ register struct proctable *pr; |
1317 |
+ |
1318 |
+ if ((pr = pr_findpid (pid)) != NULL){ |
1319 |
+ pr->pr_pid = 0; |
1320 |
+ pr->pr_active = 0; |
1321 |
+ pr->pr_inchan = 0; |
1322 |
+ pr->pr_outchan = 0; |
1323 |
+ } |
1324 |
+} |
1325 |
+ |
1326 |
+/* |
1327 |
+ *---------------------------------------------------------------------------- |
1328 |
+ * |
1329 |
+ * Routine: PRSleep |
1330 |
+ * |
1331 |
+ * Purpose: sleep for specified milliseconds |
1332 |
+ * |
1333 |
+ * Returns: none |
1334 |
+ * |
1335 |
+ *---------------------------------------------------------------------------- |
1336 |
+ */ |
1337 |
+#ifdef ANSI_FUNC |
1338 |
+static void |
1339 |
+PRSleep (int msec) |
1340 |
+#else |
1341 |
+static void PRSleep(msec) |
1342 |
+ int msec; |
1343 |
+#endif |
1344 |
+{ |
1345 |
+ struct timeval tv; |
1346 |
+ |
1347 |
+ if( msec > 0 ){ |
1348 |
+ tv.tv_sec = msec / 1000; |
1349 |
+ tv.tv_usec = (msec % 1000) * 1000; |
1350 |
+ select(1, NULL, NULL, NULL, &tv); |
1351 |
+ } |
1352 |
+} |
1353 |
+ |
1354 |
+/* |
1355 |
+ * |
1356 |
+ * Public Routines |
1357 |
+ * |
1358 |
+ * |
1359 |
+ */ |
1360 |
+ |
1361 |
+/* |
1362 |
+ * |
1363 |
+ * ProcessOpen -- |
1364 |
+ * Open a connected subprocess. Spawn process and open bidirectional |
1365 |
+ * IPC channels, implemented with pipes for this version of Berkeley UNIX. |
1366 |
+ * |
1367 |
+ */ |
1368 |
+#ifdef ANSI_FUNC |
1369 |
+int |
1370 |
+ProcessOpen(char *osfn, char **argv, int *inchan, int *outchan, int *pid) |
1371 |
+#else |
1372 |
+int ProcessOpen(osfn, argv, inchan, outchan, pid) |
1373 |
+ char *osfn; /* name of executable file */ |
1374 |
+ char **argv; /* argument list */ |
1375 |
+ int *inchan, *outchan; /* IPC channels (parent reads inchan) */ |
1376 |
+ int *pid; /* returned process id */ |
1377 |
+#endif |
1378 |
+{ |
1379 |
+ int pin[2], pout[2]; |
1380 |
+ int maxforks = 3; |
1381 |
+ char **targv; |
1382 |
+ char *args[2]; |
1383 |
+ char *prog=NULL; |
1384 |
+ static char *path; |
1385 |
+ |
1386 |
+ if (pr_debug) |
1387 |
+ fprintf (stderr, "ProcessOpen: '%s'", (char *)osfn); |
1388 |
+ |
1389 |
+ if( path == NULL ){ |
1390 |
+ path = (char *)getenv("PATH"); |
1391 |
+ } |
1392 |
+ |
1393 |
+ /* Check that the process file exists and is executable. |
1394 |
+ */ |
1395 |
+ if( (prog = Find(osfn, "x", NULL, path)) == NULL ){ |
1396 |
+ *pid = 0; |
1397 |
+ return(0); |
1398 |
+ } |
1399 |
+ |
1400 |
+ /* open pipes */ |
1401 |
+ pipe(pin); |
1402 |
+ if( pipe(pout) != 0){ |
1403 |
+ *pid = 0; |
1404 |
+ return(0); |
1405 |
+ } |
1406 |
+ |
1407 |
+ /* Create child process. The child inherits the open stdio files. |
1408 |
+ * The fork can fail if swap space is full or if we have too many processes. |
1409 |
+ */ |
1410 |
+ while ((*pid = fork()) == -1) { |
1411 |
+ if (--maxforks == 0) { |
1412 |
+ close (pin[0]); close (pin[1]); |
1413 |
+ close (pout[0]); close (pout[1]); |
1414 |
+ *pid = 0; |
1415 |
+ return(0); |
1416 |
+ } |
1417 |
+ sleep (2); |
1418 |
+ } |
1419 |
+ |
1420 |
+ if (*pid == 0) { |
1421 |
+ |
1422 |
+ /* New child process. Make child think the pipe is its stdin/out. |
1423 |
+ */ |
1424 |
+ close (pin[0]); |
1425 |
+ close (pout[1]); |
1426 |
+ close (0); dup (pout[0]); close (pout[0]); |
1427 |
+ close (1); dup (pin[1]); close (pin[1]); |
1428 |
+ |
1429 |
+#ifdef IRAF_ONLY |
1430 |
+ /* Disable SIGINT so that child process does not die when the |
1431 |
+ * parent process is interrupted. The child should get an EOF |
1432 |
+ * on reading or writing and clean itself up. |
1433 |
+ */ |
1434 |
+ signal (SIGINT, SIG_IGN); |
1435 |
+#endif |
1436 |
+ |
1437 |
+ /* Exec the new process. Will not return if successful. |
1438 |
+ */ |
1439 |
+ if( argv != NULL ){ |
1440 |
+ targv = argv; |
1441 |
+ } |
1442 |
+ else { |
1443 |
+ targv = args; |
1444 |
+ args[0] = prog; |
1445 |
+ args[1] = NULL; |
1446 |
+ } |
1447 |
+ execv(prog, (void *)targv); |
1448 |
+ |
1449 |
+ /* If we get here the new process could not be executed for some |
1450 |
+ * reason. Shutdown, calling _exit to avoid flushing parent's |
1451 |
+ * io buffers. |
1452 |
+ */ |
1453 |
+ _exit (1); |
1454 |
+ |
1455 |
+ } else { |
1456 |
+ |
1457 |
+ /* Existing, parent process. */ |
1458 |
+ close (pin[1]); |
1459 |
+ close (pout[0]); |
1460 |
+ *inchan = pin[0]; |
1461 |
+ *outchan = pout[1]; |
1462 |
+ |
1463 |
+ /* Save pid in parent's process table. Entry cleared when |
1464 |
+ * CloseProcess is called to wait for process to terminate. Also save |
1465 |
+ * channel numbers in process table since only the pid is passed |
1466 |
+ * when the process is closed. |
1467 |
+ */ |
1468 |
+ pr_enter (*pid, pin[0], pout[1]); |
1469 |
+ |
1470 |
+ if (pr_debug) |
1471 |
+ fprintf (stderr, " [%d]\n", *pid); |
1472 |
+ |
1473 |
+ /* clean up and return */ |
1474 |
+ if( prog ) free(prog); |
1475 |
+ return(1); |
1476 |
+ |
1477 |
+ } |
1478 |
+ return(1); |
1479 |
+} |
1480 |
+ |
1481 |
+ |
1482 |
+/* |
1483 |
+ * |
1484 |
+ * ProcessClose -- Close a connected subprocess and |
1485 |
+ * wait for subprocess to terminate. |
1486 |
+ * |
1487 |
+ */ |
1488 |
+#ifdef ANSI_FUNC |
1489 |
+int |
1490 |
+ProcessClose(int pid, int *exit_status) |
1491 |
+#else |
1492 |
+int ProcessClose(pid, exit_status) |
1493 |
+ int pid; |
1494 |
+ int *exit_status; |
1495 |
+#endif |
1496 |
+{ |
1497 |
+ int inchan, outchan; |
1498 |
+ int tries=0; |
1499 |
+ |
1500 |
+ if (pr_getchan (pid, &inchan, &outchan) == -1) |
1501 |
+ *exit_status = 0; |
1502 |
+ else { |
1503 |
+ close (outchan); |
1504 |
+ close (inchan); |
1505 |
+ pr_release(pid); |
1506 |
+retry: |
1507 |
+ if( (waitpid(pid, exit_status, WNOHANG)==0) && (tries<10) ){ |
1508 |
+ PRSleep(10); |
1509 |
+ tries++; |
1510 |
+ goto retry; |
1511 |
+ } |
1512 |
+ } |
1513 |
+ |
1514 |
+ if (pr_debug) |
1515 |
+ fprintf (stderr, "[%d] terminated, exit code %d\n", |
1516 |
+ pid, *exit_status); |
1517 |
+ return(*exit_status); |
1518 |
+} |
1519 |
+ |
1520 |
+ |
1521 |
+/* |
1522 |
+ * |
1523 |
+ * ProcessRead -- Read next record from an IPC channel. |
1524 |
+ * |
1525 |
+ * Since UNIX pipes are byte streams we must take special measures to |
1526 |
+ * transmit data through a pipe in records. |
1527 |
+ * Each block of data is preceded by a header of sizeof(int) consisting |
1528 |
+ * containing the number of bytes in the block. |
1529 |
+ * To read a block we must read the count and then issue successive read |
1530 |
+ * requests until the entire block has been read. |
1531 |
+ * |
1532 |
+*/ |
1533 |
+#ifdef ANSI_FUNC |
1534 |
+void * |
1535 |
+ProcessRead(int fd, void *buf, int maxbytes, int *got) |
1536 |
+#else |
1537 |
+void *ProcessRead(fd, buf, maxbytes, got) |
1538 |
+ int fd; |
1539 |
+ void *buf; |
1540 |
+ int maxbytes; |
1541 |
+ int *got; |
1542 |
+#endif |
1543 |
+{ |
1544 |
+ register char *op; |
1545 |
+ register int nbytes; |
1546 |
+ char *obuf; |
1547 |
+ int record_length, status; |
1548 |
+ int temp; |
1549 |
+ |
1550 |
+ /* no data read as yet */ |
1551 |
+ *got = 0; |
1552 |
+ |
1553 |
+ if (pr_debug) |
1554 |
+ fprintf (stderr, |
1555 |
+ "[%d] initiate read for %d bytes from IPC channel %d\n", |
1556 |
+ (int)getpid(), maxbytes, fd); |
1557 |
+ |
1558 |
+ /* Get byte count of record. |
1559 |
+ */ |
1560 |
+ if (read (fd, &temp, sizeof(int)) != sizeof(int)) |
1561 |
+ return NULL; |
1562 |
+ |
1563 |
+ record_length = temp; |
1564 |
+ if( maxbytes >= 0 ) |
1565 |
+ nbytes = min(record_length, maxbytes); |
1566 |
+ else |
1567 |
+ nbytes = record_length; |
1568 |
+ |
1569 |
+ /* allocate output buffer, if necessary */ |
1570 |
+ if( buf ) |
1571 |
+ obuf = buf; |
1572 |
+ else{ |
1573 |
+ obuf = (char *)malloc(nbytes); |
1574 |
+ if( !obuf ) |
1575 |
+ return NULL; |
1576 |
+ } |
1577 |
+ op = (char *)obuf; |
1578 |
+ |
1579 |
+ /* Now read exactly nbytes of data from channel into user buffer. |
1580 |
+ * Return actual byte count if EOF is seen. If an error is seen, return. |
1581 |
+ * If necessary multiple read requests are issued to read the |
1582 |
+ * entire record. |
1583 |
+ */ |
1584 |
+ while (nbytes > 0) |
1585 |
+ switch (status = read (fd, op, nbytes)) { |
1586 |
+ case -1: |
1587 |
+ if( !buf ) free(obuf); |
1588 |
+ *got = 0; |
1589 |
+ return NULL; |
1590 |
+ case 0: |
1591 |
+ return(obuf); |
1592 |
+ default: |
1593 |
+ nbytes -= status; |
1594 |
+ *got += status; |
1595 |
+ op += status; |
1596 |
+ } |
1597 |
+ |
1598 |
+ if (pr_debug) { |
1599 |
+ fprintf (stderr, "[%d] read %d bytes from IPC channel %d:\n", |
1600 |
+ (int)getpid(), (int)(op - (char *)buf), fd); |
1601 |
+ } |
1602 |
+ |
1603 |
+ /* If the record is larger than maxbytes, we must read and discard |
1604 |
+ * the additional bytes. The method used is inefficient but it is |
1605 |
+ * unlikely that we will be called to read less than a full record. |
1606 |
+ */ |
1607 |
+ if( maxbytes >= 0 ){ |
1608 |
+ for (nbytes = maxbytes; nbytes < record_length; nbytes++) |
1609 |
+ if (read (fd, &temp, 1) <= 0) |
1610 |
+ break; |
1611 |
+ } |
1612 |
+ |
1613 |
+ return(obuf); |
1614 |
+} |
1615 |
+ |
1616 |
+/* |
1617 |
+ * |
1618 |
+ * ProcessWrite -- Write to an IPC channel. |
1619 |
+ * Write the IPC block header followed by the data block. |
1620 |
+ * |
1621 |
+*/ |
1622 |
+#ifdef ANSI_FUNC |
1623 |
+int |
1624 |
+ProcessWrite(int fd, void *buf, int nbytes) |
1625 |
+#else |
1626 |
+int ProcessWrite(fd, buf, nbytes) |
1627 |
+ int fd; |
1628 |
+ void *buf; |
1629 |
+ int nbytes; |
1630 |
+#endif |
1631 |
+{ |
1632 |
+ int got; |
1633 |
+ |
1634 |
+ /* write byte count */ |
1635 |
+ write(fd, &nbytes, sizeof(int)); |
1636 |
+ |
1637 |
+ /* write data block */ |
1638 |
+ got = write(fd, buf, nbytes); |
1639 |
+ |
1640 |
+ if (pr_debug) { |
1641 |
+ fprintf (stderr, "[%d] wrote %d bytes to IPC channel %d:\n", |
1642 |
+ (int)getpid(), (int)nbytes, fd); |
1643 |
+ } |
1644 |
+ |
1645 |
+ return(got); |
1646 |
+} |
1647 |
+ |
1648 |
+/* |
1649 |
+ * ProcessGetChan -- Get the codes for the IPC channels assigned to a process. |
1650 |
+ */ |
1651 |
+#ifdef ANSI_FUNC |
1652 |
+int |
1653 |
+ProcessGetChan (int pid, int *inchan, int *outchan) |
1654 |
+#else |
1655 |
+int ProcessGetChan (pid, inchan, outchan) |
1656 |
+ int pid; |
1657 |
+ int *inchan, *outchan; |
1658 |
+#endif |
1659 |
+{ |
1660 |
+ return pr_getchan(pid, inchan, outchan); |
1661 |
+} |
1662 |
--- util/launch.c.orig 2007-06-28 21:29:06.000000000 +0100 |
1663 |
+++ util/launch.c 2007-12-18 20:10:27.000000000 +0000 |
1664 |
@@ -1,35 +1,9 @@ |
1665 |
/* |
1666 |
- * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory |
1667 |
+ * Copyright (c) 1999-2007 Smithsonian Astrophysical Observatory |
1668 |
*/ |
1669 |
|
1670 |
#include <launch.h> |
1671 |
|
1672 |
-#define LAUNCHARGS 1024 |
1673 |
- |
1674 |
-/* we one of these must be defined ... */ |
1675 |
-#if !defined(USE_PIPE) && !defined(USE_WAITPID) |
1676 |
-#define USE_PIPE 1 |
1677 |
-#endif |
1678 |
-/* ... but not both */ |
1679 |
-#if defined(USE_PIPE) && defined(USE_WAITPID) |
1680 |
-#error "USE_PIPE and USE_WAITPID are mutually exclusive" |
1681 |
-#endif |
1682 |
- |
1683 |
-#ifdef USE_WAITPID |
1684 |
-#define WAIT_TRIES 100 |
1685 |
-#define WAIT_MSEC 5000 |
1686 |
-#endif |
1687 |
- |
1688 |
-#ifndef WAIT_MSEC |
1689 |
-#define WAIT_MSEC 5000 |
1690 |
-#endif |
1691 |
- |
1692 |
-static pid_t _launchpid=0; |
1693 |
- |
1694 |
-/* spawnvp seems to be broken on cygwin as of 1/06, so just use fork/exec */ |
1695 |
-#if HAVE_CYGWIN |
1696 |
-#define HAVE_CYGWIN_USE_SPAWNVP 0 |
1697 |
-#endif |
1698 |
/* |
1699 |
*---------------------------------------------------------------------------- |
1700 |
* |
1701 |
@@ -40,98 +14,104 @@ |
1702 |
*---------------------------------------------------------------------------- |
1703 |
*/ |
1704 |
|
1705 |
-#if HAVE_CYGWIN||HAVE_MINGW32 |
1706 |
-#if HAVE_CYGWIN_USE_SPAWNVP |
1707 |
+static pid_t pid=0; |
1708 |
|
1709 |
+/* wait for child process to start, using waitpid() */ |
1710 |
#ifdef ANSI_FUNC |
1711 |
-static int launch_win32(char *cmdstring, int attach, char **stdfiles) |
1712 |
+static int launch_pipes(int *pipes, int flag) |
1713 |
#else |
1714 |
-static int launch_win32(cmdstring, attach, stdfiles) |
1715 |
- char *cmdstring; |
1716 |
- int attach; |
1717 |
- char **stdfiles; |
1718 |
+static int launch_pipes(pipes, flag) |
1719 |
+ int *pipes; |
1720 |
+ int flag; |
1721 |
#endif |
1722 |
{ |
1723 |
- int i, j; |
1724 |
- int len; |
1725 |
- int got; |
1726 |
- int status; |
1727 |
- char *argv[LAUNCHARGS+1]; |
1728 |
- char *path=NULL; |
1729 |
- char *s=NULL, *t=NULL; |
1730 |
- struct timeval tv; |
1731 |
- |
1732 |
- /* for now, we can't support stdfiles */ |
1733 |
- if( stdfiles ) |
1734 |
- return(-1); |
1735 |
- |
1736 |
- /* package up the arguments for new process */ |
1737 |
- t = (char *)xstrdup(cmdstring); |
1738 |
- for(i=0, got=0, s=(char *)strtok(t, " \t"); s; |
1739 |
- i++, s=(char *)strtok(NULL," \t")){ |
1740 |
- if( i < LAUNCHARGS ){ |
1741 |
- /* save argument */ |
1742 |
- argv[i] = xstrdup(s); |
1743 |
- /* change back special char to spaces, if necessary */ |
1744 |
- len = strlen(argv[i]); |
1745 |
- for(j=0; j<len; j++){ |
1746 |
- if( argv[i][j] == LAUNCH_SPACE){ |
1747 |
- argv[i][j] = ' '; |
1748 |
- } |
1749 |
- } |
1750 |
- argv[i+1] = NULL; |
1751 |
- /* save program name */ |
1752 |
- if( i == 0 ) path = (char *)argv[i]; |
1753 |
- got++; |
1754 |
+ int i; |
1755 |
+ char tbuf[SZ_LINE]; |
1756 |
+ if( pipes ){ |
1757 |
+ for(i=0; i<4; i++){ |
1758 |
+ pipes[i] = -1; |
1759 |
+ } |
1760 |
+ if( (pipe(&pipes[0]) < 0) || (pipe(&pipes[2]) < 0) ) return -1; |
1761 |
+ if( flag ){ |
1762 |
+#if HAVE_SETENV |
1763 |
+ snprintf(tbuf, SZ_LINE-1, "%d,%d,%d,%d", |
1764 |
+ pipes[0], pipes[1], pipes[2], pipes[3]); |
1765 |
+ setenv("LAUNCH_PIPES", tbuf, 1); |
1766 |
+#else |
1767 |
+ snprintf(tbuf, SZ_LINE-1, "LAUNCH_PIPES=%d,%d,%d,%d", |
1768 |
+ pipes[0], pipes[1], pipes[2], pipes[3]); |
1769 |
+ putenv(xstrdup(tbuf)); |
1770 |
+#endif |
1771 |
} |
1772 |
} |
1773 |
- if( t ) xfree(t); |
1774 |
- if( attach ) |
1775 |
- i = _P_WAIT; |
1776 |
- else |
1777 |
- i = _P_NOWAIT; |
1778 |
- if((status = spawnvp(i, path, (void *)argv)) != -1){ |
1779 |
- status = 0; |
1780 |
- /* wait for child to start */ |
1781 |
- tv.tv_sec = 0; |
1782 |
- tv.tv_usec = WAIT_MSEC; |
1783 |
- xselect(1, NULL, NULL, NULL, &tv); |
1784 |
- } |
1785 |
- for(i=0; i<got; i++) |
1786 |
- if( argv[i] ) xfree((char *)argv[i]); |
1787 |
- return(status); |
1788 |
+ return 0; |
1789 |
} |
1790 |
|
1791 |
+#ifdef ANSI_FUNC |
1792 |
+static int cleanup_pipes(int *pipes) |
1793 |
+#else |
1794 |
+static int cleanup_pipes(pipes) |
1795 |
+ int *pipes; |
1796 |
#endif |
1797 |
-#endif |
1798 |
- |
1799 |
-/* |
1800 |
- *---------------------------------------------------------------------------- |
1801 |
- * |
1802 |
- * |
1803 |
- * Public Routines and Data |
1804 |
- * |
1805 |
- * |
1806 |
- *---------------------------------------------------------------------------- |
1807 |
- */ |
1808 |
+{ |
1809 |
+ if( pipes ){ |
1810 |
+ /* close child pipes */ |
1811 |
+ close(pipes[1]); |
1812 |
+ close(pipes[2]); |
1813 |
+ /* move parent write into slot 1 */ |
1814 |
+ pipes[1] = pipes[3]; |
1815 |
+ /* set unused pipes to impossible value */ |
1816 |
+ pipes[2] = -1; |
1817 |
+ pipes[3] = -1; |
1818 |
+ } |
1819 |
+ return 0; |
1820 |
+} |
1821 |
|
1822 |
-/* |
1823 |
- * |
1824 |
- * launchpid() -- return pid of last launched process |
1825 |
- * |
1826 |
- */ |
1827 |
+#if LAUNCH_USE_WAITPID |
1828 |
+/* wait for child process to start, using waitpid() */ |
1829 |
#ifdef ANSI_FUNC |
1830 |
-pid_t launchpid(void) |
1831 |
+static int launch_waitstart(pid_t pid) |
1832 |
#else |
1833 |
-pid_t launchpid() |
1834 |
+static int launch_waitstart(pid) |
1835 |
+ pid_t pid; |
1836 |
#endif |
1837 |
{ |
1838 |
- return _launchpid; |
1839 |
+ int i, got; |
1840 |
+ int status=0; |
1841 |
+ struct timeval tv; |
1842 |
+ /* wait up to LAUNCH_WAIT_TRIES millisec to make sure the child started, |
1843 |
+ but if we get an error, we can exit immediately */ |
1844 |
+ for(i=0; i<LAUNCH_WAIT_TRIES; i++){ |
1845 |
+ errno = 0; |
1846 |
+ got=waitpid(pid, &status, WNOHANG); |
1847 |
+ /* look for error termination */ |
1848 |
+ if( (got < 0) || ((got == 0) && xerrno) ){ |
1849 |
+ got = -1; |
1850 |
+ /* make sure status shows error */ |
1851 |
+ if( status == 0 ) |
1852 |
+ status = -1; |
1853 |
+ break; |
1854 |
} |
1855 |
- |
1856 |
-#if HAVE_MINGW32==0 |
1857 |
+ /* look for normal termination */ |
1858 |
+ else if( got > 0 ){ |
1859 |
+ break; |
1860 |
+ } |
1861 |
+ /* no termination, sleep and wait some more */ |
1862 |
+ else{ |
1863 |
+ tv.tv_sec = 0; |
1864 |
+ tv.tv_usec = LAUNCH_WAIT_MSEC; |
1865 |
+ xselect(1, NULL, NULL, NULL, &tv); |
1866 |
+ } |
1867 |
+ } |
1868 |
+ /* no termination means the child is still running */ |
1869 |
+ if( got == 0 ) status = 0; |
1870 |
+ /* return the news */ |
1871 |
+ return status; |
1872 |
+} |
1873 |
+#endif |
1874 |
|
1875 |
/* |
1876 |
+ * standard unix version of launch: |
1877 |
* adapted from the system() code in: |
1878 |
* W. Richard Stevens |
1879 |
* "Advanced Programming in the Unix Environment" |
1880 |
@@ -139,71 +119,86 @@ |
1881 |
* p. 314 |
1882 |
*/ |
1883 |
#ifdef ANSI_FUNC |
1884 |
-int launch(char *cmdstring, int attach, char **stdfiles) |
1885 |
+static int launch_fork_exec(char *cmdstring, int attach, |
1886 |
+ char **stdfiles, int *pipes) |
1887 |
#else |
1888 |
-int launch(cmdstring, attach, stdfiles) |
1889 |
+ static int launch_fork_exec(cmdstring, attach, stdfiles, pipes) |
1890 |
char *cmdstring; |
1891 |
int attach; |
1892 |
char **stdfiles; |
1893 |
+ int *pipes; |
1894 |
#endif |
1895 |
{ |
1896 |
int status; |
1897 |
- pid_t pid; |
1898 |
+ int tpipes[4]; |
1899 |
struct sigaction ignore, saveintr, savequit; |
1900 |
sigset_t chldmask, savemask; |
1901 |
-#ifdef USE_PIPE |
1902 |
+#if LAUNCH_USE_PIPE |
1903 |
int fd[2]; |
1904 |
#endif |
1905 |
|
1906 |
/* return false if no command is specified */ |
1907 |
- if( !cmdstring || !*cmdstring ) |
1908 |
- return(-1); |
1909 |
+ if( !cmdstring || !*cmdstring ) return -1; |
1910 |
|
1911 |
ignore.sa_handler = SIG_IGN; /* ignore SIGINT and SIGQUIT */ |
1912 |
sigemptyset(&ignore.sa_mask); |
1913 |
ignore.sa_flags = 0; |
1914 |
if (sigaction(SIGINT, &ignore, &saveintr) < 0) |
1915 |
- return(-1); |
1916 |
+ return -1; |
1917 |
if (sigaction(SIGQUIT, &ignore, &savequit) < 0) |
1918 |
- return(-1); |
1919 |
+ return -1; |
1920 |
|
1921 |
sigemptyset(&chldmask); /* now block SIGCHLD */ |
1922 |
sigaddset(&chldmask, SIGCHLD); |
1923 |
if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0) |
1924 |
- return(-1); |
1925 |
+ return -1; |
1926 |
|
1927 |
-#if HAVE_CYGWIN_USE_SPAWNVP |
1928 |
- /* if we are on the Cygwin platform, use fork/exec only if we are |
1929 |
- redirecting stdfiles. Otherwise use spawnvp(), which works better. */ |
1930 |
- if( stdfiles ){ |
1931 |
-#endif |
1932 |
- |
1933 |
-#ifdef USE_PIPE |
1934 |
+#if LAUNCH_USE_PIPE |
1935 |
/* open a pipe so parent can hear if the child fails to exec */ |
1936 |
if( !attach ){ |
1937 |
if( pipe(fd) < 0 ) |
1938 |
- return(-1); |
1939 |
+ return -1; |
1940 |
xfcntl(fd[0], F_SETFD, FD_CLOEXEC); |
1941 |
xfcntl(fd[1], F_SETFD, FD_CLOEXEC); |
1942 |
} |
1943 |
#endif |
1944 |
|
1945 |
+ /* create temp ipc pipes if necessary */ |
1946 |
+ if( pipes ){ |
1947 |
+ if( launch_pipes(tpipes, 0) < 0 ) return -1; |
1948 |
+ } |
1949 |
+ |
1950 |
/* start new process */ |
1951 |
if( (pid = fork()) < 0 ){ |
1952 |
-#ifdef USE_PIPE |
1953 |
+#if LAUNCH_USE_PIPE |
1954 |
if( !attach ){ |
1955 |
close(fd[0]); |
1956 |
close(fd[1]); |
1957 |
} |
1958 |
#endif |
1959 |
+ if( pipes ){ |
1960 |
+ close(tpipes[0]); |
1961 |
+ close(tpipes[1]); |
1962 |
+ close(tpipes[2]); |
1963 |
+ close(tpipes[3]); |
1964 |
+ } |
1965 |
status = -1; /* ERROR: probably out of processes */ |
1966 |
- |
1967 |
} else if( pid == 0 ){ /* child */ |
1968 |
int i, j, len; |
1969 |
- char *argv[LAUNCHARGS+1]; |
1970 |
+ char *argv[LAUNCH_ARGS+1]; |
1971 |
char *path=NULL; |
1972 |
char *s=NULL, *t=NULL; |
1973 |
|
1974 |
+ /* reset pipes, if necessary */ |
1975 |
+ if( pipes ){ |
1976 |
+ /* close parent's read/write pipes */ |
1977 |
+ close(tpipes[0]); |
1978 |
+ close(tpipes[3]); |
1979 |
+ /* change child's stdin/stdout to use the passed pipes to parent */ |
1980 |
+ dup2(tpipes[2], 0); close(tpipes[2]); |
1981 |
+ dup2(tpipes[1], 1); close(tpipes[1]); |
1982 |
+ } |
1983 |
+ |
1984 |
/* close and reopen stdio files, if necessary */ |
1985 |
if( stdfiles ){ |
1986 |
for(i=0; i<3; i++){ |
1987 |
@@ -243,7 +238,7 @@ |
1988 |
sigaction(SIGQUIT, &savequit, NULL); |
1989 |
sigprocmask(SIG_SETMASK, &savemask, NULL); |
1990 |
} |
1991 |
-#ifdef USE_PIPE |
1992 |
+#if LAUNCH_USE_PIPE |
1993 |
/* child closes reader -- only writes status */ |
1994 |
else{ |
1995 |
close(fd[0]); |
1996 |
@@ -254,7 +249,7 @@ |
1997 |
t = (char *)xstrdup(cmdstring); |
1998 |
for(i=0, s=(char *)strtok(t, " \t"); s; |
1999 |
i++, s=(char *)strtok(NULL," \t")){ |
2000 |
- if( i < LAUNCHARGS ){ |
2001 |
+ if( i < LAUNCH_ARGS ){ |
2002 |
/* save argument */ |
2003 |
argv[i] = xstrdup(s); |
2004 |
/* change back special char to spaces, if necessary */ |
2005 |
@@ -280,7 +275,7 @@ |
2006 |
/* start up the new program */ |
2007 |
if( execvp(path, argv) ){ |
2008 |
status = 127; |
2009 |
-#ifdef USE_PIPE |
2010 |
+#if LAUNCH_USE_PIPE |
2011 |
if( !attach ){ |
2012 |
write(fd[1], &status, 4); |
2013 |
close(fd[1]); |
2014 |
@@ -289,7 +284,6 @@ |
2015 |
_exit(status); /* exec error */ |
2016 |
} |
2017 |
} else { /* parent */ |
2018 |
- _launchpid = pid; |
2019 |
/* wait for program termination from attached process */ |
2020 |
if( attach ){ |
2021 |
while( waitpid(pid, &status, 0) < 0 ){ |
2022 |
@@ -300,38 +294,10 @@ |
2023 |
} |
2024 |
} |
2025 |
else{ |
2026 |
-#ifdef USE_WAITPID |
2027 |
- int i, got; |
2028 |
- struct timeval tv; |
2029 |
- /* we wait up to WAIT_TRIES millisecs to make sure the child started; |
2030 |
- but if we get an error, we can exit immediately */ |
2031 |
- for(i=0; i<WAIT_TRIES; i++){ |
2032 |
- errno = 0; |
2033 |
- got=waitpid(pid, &status, WNOHANG); |
2034 |
- /* look for error termination */ |
2035 |
- if( (got < 0) || ((got == 0) && xerrno) ){ |
2036 |
- got = -1; |
2037 |
- /* make sure status shows error */ |
2038 |
- if( status == 0 ) |
2039 |
- status = -1; |
2040 |
- break; |
2041 |
- } |
2042 |
- /* look for normal termination */ |
2043 |
- else if( got > 0 ){ |
2044 |
- break; |
2045 |
- } |
2046 |
- /* no termination, sleep and wait some more */ |
2047 |
- else{ |
2048 |
- tv.tv_sec = 0; |
2049 |
- tv.tv_usec = WAIT_MSEC; |
2050 |
- xselect(1, NULL, NULL, NULL, &tv); |
2051 |
- } |
2052 |
- } |
2053 |
- /* no termination means the child is still running */ |
2054 |
- if( got == 0 ) |
2055 |
- status = 0; |
2056 |
+#if LAUNCH_USE_WAITPID |
2057 |
+ status = launch_waitstart(pid); |
2058 |
#endif |
2059 |
-#ifdef USE_PIPE |
2060 |
+#if LAUNCH_USE_PIPE |
2061 |
close(fd[1]); |
2062 |
if( read(fd[0], &status, 4) == 0 ){ |
2063 |
status = 0; |
2064 |
@@ -341,37 +307,321 @@ |
2065 |
} |
2066 |
} |
2067 |
|
2068 |
-#if HAVE_CYGWIN_USE_SPAWNVP |
2069 |
+ /* cleanup temp ipc pipes and move into user space */ |
2070 |
+ if( pipes ){ |
2071 |
+ cleanup_pipes(tpipes); |
2072 |
+ pipes[0] = tpipes[0]; |
2073 |
+ pipes[1] = tpipes[1]; |
2074 |
+ } |
2075 |
+ |
2076 |
+ /* restore previous signal actions & reset signal mask */ |
2077 |
+ if( sigaction(SIGINT, &saveintr, NULL) < 0 ) return -1; |
2078 |
+ if( sigaction(SIGQUIT, &savequit, NULL) < 0 ) return -1; |
2079 |
+ if( sigprocmask(SIG_SETMASK, &savemask, NULL) < 0 ) return -1; |
2080 |
+ |
2081 |
+ /* return the news */ |
2082 |
+ return status; |
2083 |
} |
2084 |
- /* for Cygwin, call their spawnvp() routine instead of fork()/exec() */ |
2085 |
+ |
2086 |
+#if HAVE_POSIX_SPAWN |
2087 |
+ |
2088 |
+extern char **environ; |
2089 |
+ |
2090 |
+/* spawn calls POSIX posix_spawn */ |
2091 |
+#ifdef ANSI_FUNC |
2092 |
+static int launch_posix_spawn(char *cmdstring, int attach, |
2093 |
+ char **stdfiles, int *pipes) |
2094 |
+#else |
2095 |
+ static int launch_posix_spawn(cmdstring, attach, stdfiles, pipes) |
2096 |
+ char *cmdstring; |
2097 |
+ int attach; |
2098 |
+ char **stdfiles; |
2099 |
+ int *pipes; |
2100 |
+#endif |
2101 |
+{ |
2102 |
+ int i, j, len; |
2103 |
+ int status=0; |
2104 |
+ int got=0; |
2105 |
+ int tpipes[4]; |
2106 |
+ char *argv[LAUNCH_ARGS+1]; |
2107 |
+ char *path=NULL; |
2108 |
+ char *s=NULL, *t=NULL; |
2109 |
+ posix_spawn_file_actions_t act; |
2110 |
+ posix_spawn_file_actions_t *pact=NULL; |
2111 |
+ |
2112 |
+ /* return false if no command is specified */ |
2113 |
+ if( !cmdstring || !*cmdstring ) |
2114 |
+ return -1; |
2115 |
+ |
2116 |
+ /* create temp ipc pipes if necessary */ |
2117 |
+ if( pipes ){ |
2118 |
+ if( launch_pipes(tpipes, 1) < 0 ) return -1; |
2119 |
+ } |
2120 |
+ |
2121 |
+ /* package up the arguments for new process */ |
2122 |
+ t = (char *)xstrdup(cmdstring); |
2123 |
+ for(i=0, s=(char *)strtok(t, " \t"); s; |
2124 |
+ i++, s=(char *)strtok(NULL," \t")){ |
2125 |
+ if( i < LAUNCH_ARGS ){ |
2126 |
+ /* save argument */ |
2127 |
+ argv[i] = xstrdup(s); |
2128 |
+ /* change back special char to spaces, if necessary */ |
2129 |
+ len = strlen(argv[i]); |
2130 |
+ for(j=0; j<len; j++){ |
2131 |
+ if( argv[i][j] == LAUNCH_SPACE){ |
2132 |
+ argv[i][j] = ' '; |
2133 |
+ } |
2134 |
+ } |
2135 |
+ /* last arg is always a NULL */ |
2136 |
+ argv[i+1] = NULL; |
2137 |
+ /* save program name */ |
2138 |
+ if( i == 0 ) path = argv[i]; |
2139 |
+ /* inc arg count */ |
2140 |
+ got++; |
2141 |
+ } |
2142 |
+ } |
2143 |
+ if( t ) xfree(t); |
2144 |
+ /* arrange stdfiles files, if necessary */ |
2145 |
+ if( stdfiles ){ |
2146 |
+ if( posix_spawn_file_actions_init(&act) != 0) |
2147 |
+ return -1; |
2148 |
+ /* stdin */ |
2149 |
+ if(stdfiles[0] && |
2150 |
+ posix_spawn_file_actions_addopen(&act, 0, stdfiles[0], O_RDONLY, 0)) |
2151 |
+ return -1; |
2152 |
+ /* stdout */ |
2153 |
+ if(stdfiles[1] && |
2154 |
+ posix_spawn_file_actions_addopen(&act, 1, stdfiles[1], O_CREAT|O_WRONLY|O_TRUNC, 0600)) |
2155 |
+ return -1; |
2156 |
+ /* stderr */ |
2157 |
+ if(stdfiles[2] && |
2158 |
+ posix_spawn_file_actions_addopen(&act, 2, stdfiles[2], O_CREAT|O_WRONLY|O_TRUNC, 0600)) |
2159 |
+ return -1; |
2160 |
+ pact = &act; |
2161 |
+ } |
2162 |
+ /* start the new process */ |
2163 |
+ if( (status = posix_spawnp(&pid, path, pact, NULL, argv, environ)) ) |
2164 |
+ return status; |
2165 |
+ /* wait for program termination from attached process */ |
2166 |
+ if( attach ){ |
2167 |
+ while( waitpid(pid, &status, 0) < 0 ){ |
2168 |
+ if( xerrno != EINTR ){ |
2169 |
+ status = -1; /* error other than EINTR from waitpid() */ |
2170 |
+ break; |
2171 |
+ } |
2172 |
+ } |
2173 |
+ } |
2174 |
+#if BIG_DELAY_WHEN_USING_THIS |
2175 |
+ /* wait for child process to start */ |
2176 |
else{ |
2177 |
- status = launch_win32(cmdstring, attach, stdfiles); |
2178 |
+ status = launch_waitstart(pid); |
2179 |
+ } |
2180 |
+#endif |
2181 |
+ /* clean up */ |
2182 |
+ if( stdfiles ) posix_spawn_file_actions_destroy(&act); |
2183 |
+ /* cleanup temp ipc pipes and move into user space */ |
2184 |
+ if( pipes ){ |
2185 |
+ cleanup_pipes(tpipes); |
2186 |
+ pipes[0] = tpipes[0]; |
2187 |
+ pipes[1] = tpipes[1]; |
2188 |
+ } |
2189 |
+ for(i=0; i<got; i++){ |
2190 |
+ if( argv[i] ) xfree((char *)argv[i]); |
2191 |
+ } |
2192 |
+ /* return status */ |
2193 |
+ return status; |
2194 |
} |
2195 |
+ |
2196 |
#endif |
2197 |
|
2198 |
- /* restore previous signal actions & reset signal mask */ |
2199 |
- if( sigaction(SIGINT, &saveintr, NULL) < 0 ) |
2200 |
- return(-1); |
2201 |
- if( sigaction(SIGQUIT, &savequit, NULL) < 0 ) |
2202 |
- return(-1); |
2203 |
- if( sigprocmask(SIG_SETMASK, &savemask, NULL) < 0 ) |
2204 |
- return(-1); |
2205 |
+#if HAVE_SPAWNVP |
2206 |
+ |
2207 |
+#ifdef ANSI_FUNC |
2208 |
+static int launch_spawnvp(char *cmdstring, int attach, |
2209 |
+ char **stdfiles, int *pipes) |
2210 |
+#else |
2211 |
+ static int launch_spawnvp(cmdstring, attach, stdfiles, pipes) |
2212 |
+ char *cmdstring; |
2213 |
+ int attach; |
2214 |
+ char **stdfiles; |
2215 |
+ int *pipes; |
2216 |
+#endif |
2217 |
+{ |
2218 |
+ int i, j; |
2219 |
+ int len; |
2220 |
+ int got; |
2221 |
+ int status; |
2222 |
+ int tpipes[4]; |
2223 |
+ char *argv[LAUNCH_ARGS+1]; |
2224 |
+ char *path=NULL; |
2225 |
+ char *s=NULL, *t=NULL; |
2226 |
+ struct timeval tv; |
2227 |
+ |
2228 |
+ /* return false if no command is specified */ |
2229 |
+ if( !cmdstring || !*cmdstring ) return -1; |
2230 |
+ |
2231 |
+ /* for now, we can't support stdfiles */ |
2232 |
+ if( stdfiles ) return -1; |
2233 |
|
2234 |
- return(status); |
2235 |
+ /* create temp ipc pipes if necessary */ |
2236 |
+ if( pipes ){ |
2237 |
+ if( launch_pipes(tpipes, 1) < 0 ) return -1; |
2238 |
+ } |
2239 |
+ |
2240 |
+ /* package up the arguments for new process */ |
2241 |
+ t = (char *)xstrdup(cmdstring); |
2242 |
+ for(i=0, got=0, s=(char *)strtok(t, " \t"); s; |
2243 |
+ i++, s=(char *)strtok(NULL," \t")){ |
2244 |
+ if( i < LAUNCH_ARGS ){ |
2245 |
+ /* save argument */ |
2246 |
+ argv[i] = xstrdup(s); |
2247 |
+ /* change back special char to spaces, if necessary */ |
2248 |
+ len = strlen(argv[i]); |
2249 |
+ for(j=0; j<len; j++){ |
2250 |
+ if( argv[i][j] == LAUNCH_SPACE){ |
2251 |
+ argv[i][j] = ' '; |
2252 |
+ } |
2253 |
} |
2254 |
+ /* last arg is always a NULL */ |
2255 |
+ argv[i+1] = NULL; |
2256 |
+ /* save program name */ |
2257 |
+ if( i == 0 ) path = (char *)argv[i]; |
2258 |
+ /* inc arg count */ |
2259 |
+ got++; |
2260 |
+ } |
2261 |
+ } |
2262 |
+ if( t ) xfree(t); |
2263 |
+ if( attach ) |
2264 |
+ i = _P_WAIT; |
2265 |
+ else |
2266 |
+ i = _P_NOWAIT; |
2267 |
+ if((status = spawnvp(i, path, (void *)argv)) != -1){ |
2268 |
+ status = 0; |
2269 |
+ /* wait for child to start */ |
2270 |
+ tv.tv_sec = 0; |
2271 |
+ tv.tv_usec = LAUNCH_WAIT_MSEC; |
2272 |
+ xselect(1, NULL, NULL, NULL, &tv); |
2273 |
+ } |
2274 |
+ /* clean up */ |
2275 |
+ for(i=0; i<got; i++){ |
2276 |
+ if( argv[i] ) xfree((char *)argv[i]); |
2277 |
+ } |
2278 |
+ /* cleanup temp ipc pipes and move into user space */ |
2279 |
+ if( pipes ){ |
2280 |
+ cleanup_pipes(tpipes); |
2281 |
+ pipes[0] = tpipes[0]; |
2282 |
+ pipes[1] = tpipes[1]; |
2283 |
+ } |
2284 |
+ return status; |
2285 |
+} |
2286 |
+ |
2287 |
+#endif |
2288 |
|
2289 |
+/* |
2290 |
+ *---------------------------------------------------------------------------- |
2291 |
+ * |
2292 |
+ * |
2293 |
+ * Public Routines and Data |
2294 |
+ * |
2295 |
+ * |
2296 |
+ *---------------------------------------------------------------------------- |
2297 |
+ */ |
2298 |
+ |
2299 |
+/* |
2300 |
+ * |
2301 |
+ * LaunchPid() -- return pid of last launched process |
2302 |
+ * |
2303 |
+ */ |
2304 |
+#ifdef ANSI_FUNC |
2305 |
+pid_t LaunchPid(void) |
2306 |
#else |
2307 |
+pid_t LaunchPid() |
2308 |
+#endif |
2309 |
+{ |
2310 |
+ return pid; |
2311 |
+} |
2312 |
|
2313 |
#ifdef ANSI_FUNC |
2314 |
-int launch(char *cmdstring, int attach, char **stdfiles) |
2315 |
+int Launch(char *cmdstring, int attach, char **stdfiles, int *pipes) |
2316 |
#else |
2317 |
-int launch(cmdstring, attach, stdfiles) |
2318 |
+int Launch(cmdstring, attach, stdfiles, piles) |
2319 |
char *cmdstring; |
2320 |
int attach; |
2321 |
char **stdfiles; |
2322 |
+ int *pipes; |
2323 |
#endif |
2324 |
{ |
2325 |
- return launch_win32(cmdstring, attach, stdfiles); |
2326 |
+ static int which_launch=0; |
2327 |
+ static int which_debug=0; |
2328 |
+ char *s=NULL; |
2329 |
+ |
2330 |
+ /* return false if no command is specified */ |
2331 |
+ if( !cmdstring || !*cmdstring ) return -1; |
2332 |
+ |
2333 |
+ /* sanity check: don't specify stdfiles and pipes simultaneously */ |
2334 |
+ if( stdfiles && pipes ){ |
2335 |
+ fprintf(stderr, |
2336 |
+ "ERROR: stdfiles and pipes are mutually exclusive in Launch()\n"); |
2337 |
+ return -1; |
2338 |
} |
2339 |
|
2340 |
+ /* if pipes are specified, we don't attach */ |
2341 |
+ if( pipes ) attach = 0; |
2342 |
+ |
2343 |
+ /* determine launch method */ |
2344 |
+ if( !which_launch ){ |
2345 |
+ which_launch = LAUNCH_DEFAULT_WHICH; |
2346 |
+ if( (s=getenv("LAUNCH_ROUTINE")) ){ |
2347 |
+ /* fork_exec */ |
2348 |
+ if( !strncasecmp(s, "f", 1) ){ |
2349 |
+ which_launch = 1; |
2350 |
+ if( *s == 'F' ) which_debug = 1; |
2351 |
+ } |
2352 |
+ /* posix_spawn */ |
2353 |
+ else if( !strncasecmp(s, "p", 1) ){ |
2354 |
+ which_launch = 2; |
2355 |
+ if( *s == 'P' ) which_debug = 1; |
2356 |
+ } |
2357 |
+ /* spawnvp */ |
2358 |
+ else if( !strncasecmp(s, "s", 1) ){ |
2359 |
+ which_launch = 3; |
2360 |
+ if( *s == 'S' ) which_debug = 1; |
2361 |
+ } |
2362 |
+ else if( *s == 'V' ) { |
2363 |
+ which_debug = 1; |
2364 |
+ } |
2365 |
+ } |
2366 |
+ } |
2367 |
+ /* call the correct launch method */ |
2368 |
+ switch(which_launch){ |
2369 |
+ case 1: |
2370 |
+ if( which_debug ) fprintf(stderr, "launch_fork_exec: %s\n", cmdstring); |
2371 |
+ return launch_fork_exec(cmdstring, attach, stdfiles, pipes); |
2372 |
+ break; |
2373 |
+ case 2: |
2374 |
+#if HAVE_POSIX_SPAWN |
2375 |
+ if( which_debug ) fprintf(stderr, "launch_posix_spawn: %s\n", cmdstring); |
2376 |
+ return launch_posix_spawn(cmdstring, attach, stdfiles, pipes); |
2377 |
+#else |
2378 |
+ fprintf(stderr, "ERROR: posix_spawn() not available on this host\n"); |
2379 |
+ exit(1); |
2380 |
#endif |
2381 |
+ break; |
2382 |
+ case 3: |
2383 |
+#if HAVE_SPAWNVP |
2384 |
+ if( which_debug ) fprintf(stderr, "launch_spawnvp: %s\n", cmdstring); |
2385 |
+ return launch_spawnvp(cmdstring, attach, stdfiles, pipes); |
2386 |
+#else |
2387 |
+ fprintf(stderr, "ERROR: spawnvp() not available on this host\n"); |
2388 |
+ exit(1); |
2389 |
+#endif |
2390 |
+ break; |
2391 |
+ default: |
2392 |
+ if( which_debug ) fprintf(stderr, "launch_fork_exec: %s\n", cmdstring); |
2393 |
+ return launch_fork_exec(cmdstring, attach, stdfiles, pipes); |
2394 |
+ break; |
2395 |
+ } |
2396 |
+ /* can't happen */ |
2397 |
+ return -1; |
2398 |
+} |
2399 |
+ |
2400 |
--- util/launch.h.orig 2006-01-27 16:25:08.000000000 +0000 |
2401 |
+++ util/launch.h 2007-12-18 20:10:27.000000000 +0000 |
2402 |
@@ -30,17 +30,54 @@ |
2403 |
#if HAVE_UNISTD_H |
2404 |
#include <unistd.h> |
2405 |
#endif |
2406 |
+#if HAVE_POSIX_SPAWN |
2407 |
+#include <spawn.h> |
2408 |
+#endif |
2409 |
#include <xport.h> |
2410 |
#include <word.h> |
2411 |
#include <xalloc.h> |
2412 |
#include <prsetup.h> |
2413 |
|
2414 |
+#define LAUNCH_ARGS 1024 |
2415 |
+ |
2416 |
#define LAUNCH_SPACE '\001' |
2417 |
|
2418 |
+/* for fork/exec, one of these is required to specify the technique to be used |
2419 |
+ by the parent when determining if the child started successfully */ |
2420 |
+#if !defined(LAUNCH_USE_PIPE) && !defined(LAUNCH_USE_WAITPID) |
2421 |
+#define LAUNCH_USE_PIPE 1 |
2422 |
+#endif |
2423 |
+/* ... but not both */ |
2424 |
+#if defined(LAUNCH_USE_PIPE) && defined(LAUNCH_USE_WAITPID) |
2425 |
+#error "LAUNCH_USE_PIPE and LAUNCH_USE_WAITPID are mutually exclusive" |
2426 |
+#endif |
2427 |
+ |
2428 |
+#ifndef LAUNCH_WAIT_TRIES |
2429 |
+#define LAUNCH_WAIT_TRIES 100 |
2430 |
+#endif |
2431 |
+#ifndef LAUNCH_WAIT_MSEC |
2432 |
+#define LAUNCH_WAIT_MSEC 5000 |
2433 |
+#endif |
2434 |
+ |
2435 |
+#if HAVE_MINGW32|HAVE_CYGWIN |
2436 |
+#define HAVE_SPAWNVP 1 |
2437 |
+#endif |
2438 |
+ |
2439 |
+#if HAVE_MINGW32 |
2440 |
+/* for now, ensure that MinGW utilizes spawnvp() */ |
2441 |
+#define LAUNCH_DEFAULT_WHICH 3 |
2442 |
+#elif HAVE_POSIX_SPAWN |
2443 |
+/* use posix_spawn if possible (required for OS X 10.5) */ |
2444 |
+#define LAUNCH_DEFAULT_WHICH 2 |
2445 |
+#else |
2446 |
+/* use our home-grown version */ |
2447 |
+#define LAUNCH_DEFAULT_WHICH 1 |
2448 |
+#endif |
2449 |
+ |
2450 |
_PRbeg |
2451 |
|
2452 |
-int launch _PRx((char *cmdstring, int wait, char **stdfiles)); |
2453 |
-pid_t launchpid _PRx((void)); |
2454 |
+int Launch _PRx((char *cmdstring, int wait, char **stdfiles, int *pipes)); |
2455 |
+pid_t LaunchPid _PRx((void)); |
2456 |
|
2457 |
_PRend |
2458 |
|
2459 |
--- util/tlaunch2.c.orig 1970-01-01 01:00:00.000000000 +0100 |
2460 |
+++ util/tlaunch2.c 2007-12-18 20:10:27.000000000 +0000 |
2461 |
@@ -0,0 +1,59 @@ |
2462 |
+/* |
2463 |
+ * |
2464 |
+ * tlaunch2 -- test launch routine (child routines) |
2465 |
+ * |
2466 |
+ */ |
2467 |
+ |
2468 |
+#define HAVE_CONFIG_H 1 |
2469 |
+ |
2470 |
+#if HAVE_CONFIG_H |
2471 |
+#include <conf.h> |
2472 |
+#endif |
2473 |
+#include <stdio.h> |
2474 |
+#include <ctype.h> |
2475 |
+#if HAVE_STRING_H |
2476 |
+#include <string.h> |
2477 |
+#endif |
2478 |
+#if HAVE_STDLIB_H |
2479 |
+#include <stdlib.h> |
2480 |
+#endif |
2481 |
+#if HAVE_UNISTD_H |
2482 |
+#include <unistd.h> |
2483 |
+#endif |
2484 |
+ |
2485 |
+#ifdef ANSI_FUNC |
2486 |
+int main (int argc, char **argv) |
2487 |
+#else |
2488 |
+int main(argc, argv) |
2489 |
+ int argc; |
2490 |
+ char **argv; |
2491 |
+#endif |
2492 |
+{ |
2493 |
+ int i; |
2494 |
+ char c; |
2495 |
+ char *s, *t, *u; |
2496 |
+ int pipes[4]; |
2497 |
+ if( (s=getenv("LAUNCH_PIPES")) ){ |
2498 |
+ t = (char *)strdup(s); |
2499 |
+ for(i=0, u=(char *)strtok(t, ","); i<4 && u; |
2500 |
+ i++, u=(char *)strtok(NULL,",")){ |
2501 |
+ pipes[i] = atoi(u); |
2502 |
+ fprintf(stderr, "child pipe #%d: %d\n", i, pipes[i]); |
2503 |
+ } |
2504 |
+ if( t ) free(t); |
2505 |
+ if( i < 4 ) return(1); |
2506 |
+ close(pipes[0]); |
2507 |
+ close(pipes[3]); |
2508 |
+ dup2(pipes[2], 0); close(pipes[2]); |
2509 |
+ dup2(pipes[1], 1); close(pipes[1]); |
2510 |
+ } |
2511 |
+ else{ |
2512 |
+ fprintf(stderr, "No LAUNCH_PIPE environment variable\n"); |
2513 |
+ } |
2514 |
+ while( read(0, &c, 1) ){ |
2515 |
+ if( islower((int)c) ) c = toupper((int)c); |
2516 |
+ write(3, &c, 1); |
2517 |
+ write(1, &c, 1); |
2518 |
+ } |
2519 |
+ return 0; |
2520 |
+} |
2521 |
--- util/tlaunch.c.orig 1970-01-01 01:00:00.000000000 +0100 |
2522 |
+++ util/tlaunch.c 2007-12-18 20:10:27.000000000 +0000 |
2523 |
@@ -0,0 +1,98 @@ |
2524 |
+/* |
2525 |
+ * Copyright (c) 2007 Smithsonian Astrophysical Observatory |
2526 |
+ */ |
2527 |
+ |
2528 |
+/* |
2529 |
+ * |
2530 |
+ * tlaunch -- test launch routine |
2531 |
+ * |
2532 |
+ */ |
2533 |
+ |
2534 |
+#define HAVE_CONFIG_H 1 |
2535 |
+#include <launch.h> |
2536 |
+ |
2537 |
+extern char *optarg; |
2538 |
+extern int optind; |
2539 |
+ |
2540 |
+#ifdef ANSI_FUNC |
2541 |
+int main (int argc, char **argv) |
2542 |
+#else |
2543 |
+int main(argc, argv) |
2544 |
+ int argc; |
2545 |
+ char **argv; |
2546 |
+#endif |
2547 |
+{ |
2548 |
+ int c; |
2549 |
+ int got=0; |
2550 |
+ int doattach=0; |
2551 |
+ int dofiles=0; |
2552 |
+ int dopipes=0; |
2553 |
+ int pipes[2]; |
2554 |
+ char *prog=NULL; |
2555 |
+ char *files[3]; |
2556 |
+ char *pfile=NULL; |
2557 |
+ char wbuf[SZ_LINE]; |
2558 |
+ FILE *fd; |
2559 |
+ |
2560 |
+ /* init */ |
2561 |
+ memset(files, 0, sizeof(char *)*3); |
2562 |
+ /* process switch arguments */ |
2563 |
+ while ((c = getopt(argc, argv, "ae:i:o:p:w:")) != -1){ |
2564 |
+ switch(c){ |
2565 |
+ case 'a': |
2566 |
+ doattach = 1; |
2567 |
+ break; |
2568 |
+ case 'e': |
2569 |
+ files[2] = optarg; |
2570 |
+ dofiles |= 4; |
2571 |
+ break; |
2572 |
+ case 'i': |
2573 |
+ files[0] = optarg; |
2574 |
+ dofiles |= 1; |
2575 |
+ break; |
2576 |
+ case 'o': |
2577 |
+ files[1] = optarg; |
2578 |
+ dofiles |= 2; |
2579 |
+ break; |
2580 |
+ case 'p': |
2581 |
+ pfile = optarg; |
2582 |
+ dopipes = 1; |
2583 |
+ break; |
2584 |
+ case 'w': |
2585 |
+ snprintf(wbuf, SZ_LINE, "LAUNCH_ROUTINE=%s", optarg); |
2586 |
+ putenv(wbuf); |
2587 |
+ default: |
2588 |
+ break; |
2589 |
+ } |
2590 |
+ } |
2591 |
+ if( optind >= argc ){ |
2592 |
+ fprintf(stderr, |
2593 |
+ "usage: %s -a -i stdin -o stdout -e stderr -p pfile [command]\n", |
2594 |
+ argv[0]); |
2595 |
+ return 1; |
2596 |
+ } |
2597 |
+ prog = argv[optind++]; |
2598 |
+ if( !strcmp(prog, "tlaunch2") && !dopipes ){ |
2599 |
+ fprintf(stderr, "ERROR: use -p [file] with tlaunch2\n"); |
2600 |
+ return 1; |
2601 |
+ } |
2602 |
+ if( (got = Launch(prog, doattach, dofiles?files:NULL, dopipes?pipes:NULL)) ) |
2603 |
+ fprintf(stderr, "ERROR: got=%d\n", got); |
2604 |
+ else |
2605 |
+ fprintf(stderr, "SUCCESS: got(%x)=%d\n", dofiles, got); |
2606 |
+ /* send pipe file contents to child, read back and display results */ |
2607 |
+ if( pfile ){ |
2608 |
+ if( !(fd = fopen(pfile,"r")) ){ |
2609 |
+ perror("fopen"); |
2610 |
+ return 1; |
2611 |
+ } |
2612 |
+ while( fread(&c, sizeof(char), 1, fd) ){ |
2613 |
+ write(pipes[1], &c, 1); |
2614 |
+ if( read(pipes[0], &c, 1) ){ |
2615 |
+ fwrite(&c, sizeof(char), 1, stdout); |
2616 |
+ } |
2617 |
+ } |
2618 |
+ fclose(fd); |
2619 |
+ } |
2620 |
+ return 0; |
2621 |
+} |
2622 |
--- util/zprocess.c.orig 2006-02-21 16:34:12.000000000 +0000 |
2623 |
+++ util/zprocess.c 2007-12-18 20:10:27.000000000 +0000 |
2624 |
@@ -6,7 +6,8 @@ |
2625 |
* |
2626 |
* zprocess.c -- routines to start up and communicate with a slave process |
2627 |
* |
2628 |
- * based on zfiopr.c from NOAO IRAF system |
2629 |
+ * based on zfiopr.c from NOAO IRAF system (more loosely than previously, |
2630 |
+ * since we replaces the fork/exec with our own Launch()). |
2631 |
* |
2632 |
*/ |
2633 |
|
2634 |
@@ -65,8 +66,7 @@ |
2635 |
* if the table overflows. |
2636 |
*/ |
2637 |
#ifdef ANSI_FUNC |
2638 |
-static int |
2639 |
-pr_enter(int pid, int inchan, int outchan) |
2640 |
+static int pr_enter(int pid, int inchan, int outchan) |
2641 |
#else |
2642 |
static int pr_enter(pid, inchan, outchan) |
2643 |
int pid; |
2644 |
@@ -114,8 +114,7 @@ |
2645 |
* is killed and we do not wish to wait for process termination. |
2646 |
*/ |
2647 |
#ifdef ANSI_FUNC |
2648 |
-static void |
2649 |
-pr_release (int pid) |
2650 |
+static void pr_release (int pid) |
2651 |
#else |
2652 |
static void pr_release (pid) |
2653 |
int pid; |
2654 |
@@ -143,8 +142,7 @@ |
2655 |
*---------------------------------------------------------------------------- |
2656 |
*/ |
2657 |
#ifdef ANSI_FUNC |
2658 |
-static void |
2659 |
-PRSleep (int msec) |
2660 |
+static void PRSleep (int msec) |
2661 |
#else |
2662 |
static void PRSleep(msec) |
2663 |
int msec; |
2664 |
@@ -166,127 +164,36 @@ |
2665 |
* |
2666 |
*/ |
2667 |
|
2668 |
-/* |
2669 |
- * |
2670 |
- * ProcessOpen -- |
2671 |
- * Open a connected subprocess. Spawn process and open bidirectional |
2672 |
- * IPC channels, implemented with pipes for this version of Berkeley UNIX. |
2673 |
- * |
2674 |
- */ |
2675 |
+ |
2676 |
#ifdef ANSI_FUNC |
2677 |
-int |
2678 |
-ProcessOpen(char *osfn, char **argv, int *inchan, int *outchan, int *pid) |
2679 |
+int ProcessOpen(char *cmd, int *inchan, int *outchan, int *pid) |
2680 |
#else |
2681 |
-int ProcessOpen(osfn, argv, inchan, outchan, pid) |
2682 |
- char *osfn; /* name of executable file */ |
2683 |
- char **argv; /* argument list */ |
2684 |
+int ProcessOpen(cmd, argv, inchan, outchan, pid) |
2685 |
+ char *cmd; /* command line to Launch */ |
2686 |
int *inchan, *outchan; /* IPC channels (parent reads inchan) */ |
2687 |
int *pid; /* returned process id */ |
2688 |
#endif |
2689 |
{ |
2690 |
- int pin[2], pout[2]; |
2691 |
- int maxforks = 3; |
2692 |
- char **targv; |
2693 |
- char *args[2]; |
2694 |
- char *prog=NULL; |
2695 |
- static char *path; |
2696 |
- |
2697 |
- if (pr_debug) |
2698 |
- fprintf (stderr, "ProcessOpen: '%s'", (char *)osfn); |
2699 |
- |
2700 |
- if( path == NULL ){ |
2701 |
- path = (char *)getenv("PATH"); |
2702 |
- } |
2703 |
- |
2704 |
- /* Check that the process file exists and is executable. |
2705 |
- */ |
2706 |
- if( (prog = Find(osfn, "x", NULL, path)) == NULL ){ |
2707 |
+ int pipes[2]; |
2708 |
+ if( Launch(cmd, 0, NULL, pipes) != 0 ){ |
2709 |
+ /* failure */ |
2710 |
+ *inchan = -1; |
2711 |
+ *outchan = -1; |
2712 |
*pid = 0; |
2713 |
- return(0); |
2714 |
- } |
2715 |
- |
2716 |
- /* open pipes */ |
2717 |
- pipe(pin); |
2718 |
- if( pipe(pout) != 0){ |
2719 |
- *pid = 0; |
2720 |
- return(0); |
2721 |
- } |
2722 |
- |
2723 |
- /* Create child process. The child inherits the open stdio files. |
2724 |
- * The fork can fail if swap space is full or if we have too many processes. |
2725 |
- */ |
2726 |
- while ((*pid = fork()) == -1) { |
2727 |
- if (--maxforks == 0) { |
2728 |
- close (pin[0]); close (pin[1]); |
2729 |
- close (pout[0]); close (pout[1]); |
2730 |
- *pid = 0; |
2731 |
- return(0); |
2732 |
- } |
2733 |
- sleep (2); |
2734 |
- } |
2735 |
- |
2736 |
- if (*pid == 0) { |
2737 |
- |
2738 |
- /* New child process. Make child think the pipe is its stdin/out. |
2739 |
- */ |
2740 |
- close (pin[0]); |
2741 |
- close (pout[1]); |
2742 |
- close (0); dup (pout[0]); close (pout[0]); |
2743 |
- close (1); dup (pin[1]); close (pin[1]); |
2744 |
- |
2745 |
-#ifdef IRAF_ONLY |
2746 |
- /* Disable SIGINT so that child process does not die when the |
2747 |
- * parent process is interrupted. The child should get an EOF |
2748 |
- * on reading or writing and clean itself up. |
2749 |
- */ |
2750 |
- signal (SIGINT, SIG_IGN); |
2751 |
-#endif |
2752 |
- |
2753 |
- /* Exec the new process. Will not return if successful. |
2754 |
- */ |
2755 |
- if( argv != NULL ){ |
2756 |
- targv = argv; |
2757 |
+ return 0; |
2758 |
} |
2759 |
else { |
2760 |
- targv = args; |
2761 |
- args[0] = prog; |
2762 |
- args[1] = NULL; |
2763 |
- } |
2764 |
- execv(prog, (void *)targv); |
2765 |
- |
2766 |
- /* If we get here the new process could not be executed for some |
2767 |
- * reason. Shutdown, calling _exit to avoid flushing parent's |
2768 |
- * io buffers. |
2769 |
- */ |
2770 |
- _exit (1); |
2771 |
- |
2772 |
- } else { |
2773 |
- |
2774 |
- /* Existing, parent process. */ |
2775 |
- close (pin[1]); |
2776 |
- close (pout[0]); |
2777 |
- *inchan = pin[0]; |
2778 |
- *outchan = pout[1]; |
2779 |
- |
2780 |
- /* Save pid in parent's process table. Entry cleared when |
2781 |
- * CloseProcess is called to wait for process to terminate. Also save |
2782 |
- * channel numbers in process table since only the pid is passed |
2783 |
- * when the process is closed. |
2784 |
- */ |
2785 |
- pr_enter (*pid, pin[0], pout[1]); |
2786 |
- |
2787 |
- if (pr_debug) |
2788 |
- fprintf (stderr, " [%d]\n", *pid); |
2789 |
- |
2790 |
- /* clean up and return */ |
2791 |
- if( prog ) free(prog); |
2792 |
- return(1); |
2793 |
- |
2794 |
+ /* package up process info for return */ |
2795 |
+ *inchan = pipes[0]; |
2796 |
+ *outchan = pipes[1]; |
2797 |
+ *pid = LaunchPid(); |
2798 |
+ /* and also save process info for later */ |
2799 |
+ pr_enter (*pid, *inchan, *outchan); |
2800 |
+ /* success */ |
2801 |
+ return 1; |
2802 |
} |
2803 |
- return(1); |
2804 |
} |
2805 |
|
2806 |
- |
2807 |
/* |
2808 |
* |
2809 |
* ProcessClose -- Close a connected subprocess and |
2810 |
@@ -294,8 +201,7 @@ |
2811 |
* |
2812 |
*/ |
2813 |
#ifdef ANSI_FUNC |
2814 |
-int |
2815 |
-ProcessClose(int pid, int *exit_status) |
2816 |
+int ProcessClose(int pid, int *exit_status) |
2817 |
#else |
2818 |
int ProcessClose(pid, exit_status) |
2819 |
int pid; |
2820 |
@@ -339,8 +245,7 @@ |
2821 |
* |
2822 |
*/ |
2823 |
#ifdef ANSI_FUNC |
2824 |
-void * |
2825 |
-ProcessRead(int fd, void *buf, int maxbytes, int *got) |
2826 |
+void *ProcessRead(int fd, void *buf, int maxbytes, int *got) |
2827 |
#else |
2828 |
void *ProcessRead(fd, buf, maxbytes, got) |
2829 |
int fd; |
2830 |
@@ -428,8 +333,7 @@ |
2831 |
* |
2832 |
*/ |
2833 |
#ifdef ANSI_FUNC |
2834 |
-int |
2835 |
-ProcessWrite(int fd, void *buf, int nbytes) |
2836 |
+int ProcessWrite(int fd, void *buf, int nbytes) |
2837 |
#else |
2838 |
int ProcessWrite(fd, buf, nbytes) |
2839 |
int fd; |
2840 |
@@ -457,8 +361,7 @@ |
2841 |
* ProcessGetChan -- Get the codes for the IPC channels assigned to a process. |
2842 |
*/ |
2843 |
#ifdef ANSI_FUNC |
2844 |
-int |
2845 |
-ProcessGetChan (int pid, int *inchan, int *outchan) |
2846 |
+int ProcessGetChan (int pid, int *inchan, int *outchan) |
2847 |
#else |
2848 |
int ProcessGetChan (pid, inchan, outchan) |
2849 |
int pid; |
2850 |
--- util/zprocess.h.orig 2004-09-18 14:34:51.000000000 +0100 |
2851 |
+++ util/zprocess.h 2007-12-18 20:10:27.000000000 +0000 |
2852 |
@@ -28,15 +28,12 @@ |
2853 |
#endif |
2854 |
#include <sys/time.h> |
2855 |
#include <signal.h> |
2856 |
-#include <prsetup.h> |
2857 |
+#include <launch.h> |
2858 |
#include <find.h> |
2859 |
-#include <xport.h> |
2860 |
-#include <xalloc.h> |
2861 |
|
2862 |
_PRbeg |
2863 |
|
2864 |
-int ProcessOpen _PRx((char *osfn, char **argv, |
2865 |
- int *inchan, int *outchan, int *pid)); |
2866 |
+int ProcessOpen _PRx((char *cmd, int *inchan, int *outchan, int *pid)); |
2867 |
void *ProcessRead _PRx((int fd, void *buf, int maxbytes, int *got)); |
2868 |
int ProcessWrite _PRx((int fd, void *buf, int nbytes)); |
2869 |
int ProcessClose _PRx((int pid, int *exit_status)); |