xref: /openbsd/gnu/usr.bin/perl/doio.c (revision 264ca280)
1 /*    doio.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4  *    2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  */
10 
11 /*
12  *  Far below them they saw the white waters pour into a foaming bowl, and
13  *  then swirl darkly about a deep oval basin in the rocks, until they found
14  *  their way out again through a narrow gate, and flowed away, fuming and
15  *  chattering, into calmer and more level reaches.
16  *
17  *     [p.684 of _The Lord of the Rings_, IV/vi: "The Forbidden Pool"]
18  */
19 
20 /* This file contains functions that do the actual I/O on behalf of ops.
21  * For example, pp_print() calls the do_print() function in this file for
22  * each argument needing printing.
23  */
24 
25 #include "EXTERN.h"
26 #define PERL_IN_DOIO_C
27 #include "perl.h"
28 
29 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
30 #ifndef HAS_SEM
31 #include <sys/ipc.h>
32 #endif
33 #ifdef HAS_MSG
34 #include <sys/msg.h>
35 #endif
36 #ifdef HAS_SHM
37 #include <sys/shm.h>
38 # ifndef HAS_SHMAT_PROTOTYPE
39     extern Shmat_t shmat (int, char *, int);
40 # endif
41 #endif
42 #endif
43 
44 #ifdef I_UTIME
45 #  if defined(_MSC_VER) || defined(__MINGW32__)
46 #    include <sys/utime.h>
47 #  else
48 #    include <utime.h>
49 #  endif
50 #endif
51 
52 #ifdef O_EXCL
53 #  define OPEN_EXCL O_EXCL
54 #else
55 #  define OPEN_EXCL 0
56 #endif
57 
58 #define PERL_MODE_MAX 8
59 #define PERL_FLAGS_MAX 10
60 
61 #include <signal.h>
62 
63 static IO *
64 S_openn_setup(pTHX_ GV *gv, char *mode, PerlIO **saveifp, PerlIO **saveofp,
65               int *savefd,  char *savetype)
66 {
67     dVAR;
68     IO * const io = GvIOn(gv);
69 
70     PERL_ARGS_ASSERT_OPENN_SETUP;
71 
72     *saveifp = NULL;
73     *saveofp = NULL;
74     *savefd = -1;
75     *savetype = IoTYPE_CLOSED;
76 
77     Zero(mode,sizeof(mode),char);
78     PL_forkprocess = 1;		/* assume true if no fork */
79 
80     /* If currently open - close before we re-open */
81     if (IoIFP(io)) {
82 	if (IoTYPE(io) == IoTYPE_STD) {
83 	    /* This is a clone of one of STD* handles */
84 	}
85 	else {
86             const int old_fd = PerlIO_fileno(IoIFP(io));
87 
88             if (old_fd >= 0 && old_fd <= PL_maxsysfd) {
89                 /* This is one of the original STD* handles */
90                 *saveifp  = IoIFP(io);
91                 *saveofp  = IoOFP(io);
92                 *savetype = IoTYPE(io);
93                 *savefd   = old_fd;
94             }
95             else {
96                 int result;
97 
98                 if (IoTYPE(io) == IoTYPE_PIPE)
99                     result = PerlProc_pclose(IoIFP(io));
100                 else if (IoIFP(io) != IoOFP(io)) {
101                     if (IoOFP(io)) {
102                         result = PerlIO_close(IoOFP(io));
103                         PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */
104                     }
105                     else
106                         result = PerlIO_close(IoIFP(io));
107                 }
108                 else
109                     result = PerlIO_close(IoIFP(io));
110 
111                 if (result == EOF && old_fd > PL_maxsysfd) {
112                     /* Why is this not Perl_warn*() call ? */
113                     PerlIO_printf(Perl_error_log,
114                                   "Warning: unable to close filehandle %"HEKf" properly.\n",
115                                   HEKfARG(GvENAME_HEK(gv))
116                         );
117                 }
118             }
119         }
120 	IoOFP(io) = IoIFP(io) = NULL;
121     }
122     return io;
123 }
124 
125 bool
126 Perl_do_openn(pTHX_ GV *gv, const char *oname, I32 len, int as_raw,
127 	      int rawmode, int rawperm, PerlIO *supplied_fp, SV **svp,
128 	      I32 num_svs)
129 {
130     PERL_ARGS_ASSERT_DO_OPENN;
131 
132     if (as_raw) {
133         /* sysopen style args, i.e. integer mode and permissions */
134 
135 	if (num_svs != 0) {
136 	    Perl_croak(aTHX_ "panic: sysopen with multiple args, num_svs=%ld",
137 		       (long) num_svs);
138 	}
139         return do_open_raw(gv, oname, len, rawmode, rawperm);
140     }
141     return do_open6(gv, oname, len, supplied_fp, svp, num_svs);
142 }
143 
144 bool
145 Perl_do_open_raw(pTHX_ GV *gv, const char *oname, STRLEN len,
146                  int rawmode, int rawperm)
147 {
148     dVAR;
149     PerlIO *saveifp;
150     PerlIO *saveofp;
151     int savefd;
152     char savetype;
153     char mode[PERL_MODE_MAX];	/* file mode ("r\0", "rb\0", "ab\0" etc.) */
154     IO * const io = openn_setup(gv, mode, &saveifp, &saveofp, &savefd, &savetype);
155     int writing = 0;
156     PerlIO *fp;
157 
158     PERL_ARGS_ASSERT_DO_OPEN_RAW;
159 
160     /* For ease of blame back to 5.000, keep the existing indenting. */
161     {
162         /* sysopen style args, i.e. integer mode and permissions */
163 	STRLEN ix = 0;
164 	const int appendtrunc =
165 	     0
166 #ifdef O_APPEND	/* Not fully portable. */
167 	     |O_APPEND
168 #endif
169 #ifdef O_TRUNC	/* Not fully portable. */
170 	     |O_TRUNC
171 #endif
172 	     ;
173 	const int modifyingmode = O_WRONLY|O_RDWR|O_CREAT|appendtrunc;
174 	int ismodifying;
175         SV *namesv;
176 
177 	/* It's not always
178 
179 	   O_RDONLY 0
180 	   O_WRONLY 1
181 	   O_RDWR   2
182 
183 	   It might be (in OS/390 and Mac OS Classic it is)
184 
185 	   O_WRONLY 1
186 	   O_RDONLY 2
187 	   O_RDWR   3
188 
189 	   This means that simple & with O_RDWR would look
190 	   like O_RDONLY is present.  Therefore we have to
191 	   be more careful.
192 	*/
193 	if ((ismodifying = (rawmode & modifyingmode))) {
194 	     if ((ismodifying & O_WRONLY) == O_WRONLY ||
195 		 (ismodifying & O_RDWR)   == O_RDWR   ||
196 		 (ismodifying & (O_CREAT|appendtrunc)))
197 		  TAINT_PROPER("sysopen");
198 	}
199 	mode[ix++] = IoTYPE_NUMERIC; /* Marker to openn to use numeric "sysopen" */
200 
201 #if defined(USE_64_BIT_RAWIO) && defined(O_LARGEFILE)
202 	rawmode |= O_LARGEFILE;	/* Transparently largefiley. */
203 #endif
204 
205         IoTYPE(io) = PerlIO_intmode2str(rawmode, &mode[ix], &writing);
206 
207 	namesv = newSVpvn_flags(oname, len, SVs_TEMP);
208 	fp = PerlIO_openn(aTHX_ NULL, mode, -1, rawmode, rawperm, NULL, 1, &namesv);
209     }
210     return openn_cleanup(gv, io, fp, mode, oname, saveifp, saveofp, savefd,
211                          savetype, writing, 0, NULL);
212 }
213 
214 bool
215 Perl_do_open6(pTHX_ GV *gv, const char *oname, STRLEN len,
216               PerlIO *supplied_fp, SV **svp, U32 num_svs)
217 {
218     dVAR;
219     PerlIO *saveifp;
220     PerlIO *saveofp;
221     int savefd;
222     char savetype;
223     char mode[PERL_MODE_MAX];	/* file mode ("r\0", "rb\0", "ab\0" etc.) */
224     IO * const io = openn_setup(gv, mode, &saveifp, &saveofp, &savefd, &savetype);
225     int writing = 0;
226     PerlIO *fp;
227     bool was_fdopen = FALSE;
228     char *type  = NULL;
229 
230     PERL_ARGS_ASSERT_DO_OPEN6;
231 
232     /* For ease of blame back to 5.000, keep the existing indenting. */
233     {
234 	/* Regular (non-sys) open */
235 	char *name;
236 	STRLEN olen = len;
237 	char *tend;
238 	int dodup = 0;
239         bool in_raw = 0, in_crlf = 0, out_raw = 0, out_crlf = 0;
240 
241         /* Collect default raw/crlf info from the op */
242         if (PL_op && PL_op->op_type == OP_OPEN) {
243             /* set up IO layers */
244             const U8 flags = PL_op->op_private;
245             in_raw = (flags & OPpOPEN_IN_RAW);
246             in_crlf = (flags & OPpOPEN_IN_CRLF);
247             out_raw = (flags & OPpOPEN_OUT_RAW);
248             out_crlf = (flags & OPpOPEN_OUT_CRLF);
249         }
250 
251 	type = savepvn(oname, len);
252 	tend = type+len;
253 	SAVEFREEPV(type);
254 
255         /* Lose leading and trailing white space */
256 	while (isSPACE(*type))
257 	    type++;
258         while (tend > type && isSPACE(tend[-1]))
259 	    *--tend = '\0';
260 
261 	if (num_svs) {
262             const char *p;
263             STRLEN nlen = 0;
264 	    /* New style explicit name, type is just mode and layer info */
265 #ifdef USE_STDIO
266 	    if (SvROK(*svp) && !strchr(oname,'&')) {
267 		if (ckWARN(WARN_IO))
268 		    Perl_warner(aTHX_ packWARN(WARN_IO),
269 			    "Can't open a reference");
270 		SETERRNO(EINVAL, LIB_INVARG);
271                 fp = NULL;
272 		goto say_false;
273 	    }
274 #endif /* USE_STDIO */
275             p = (SvOK(*svp) || SvGMAGICAL(*svp)) ? SvPV(*svp, nlen) : NULL;
276 
277             if (p && !IS_SAFE_PATHNAME(p, nlen, "open")) {
278                 fp = NULL;
279                 goto say_false;
280             }
281 
282 	    name = p ? savepvn(p, nlen) : savepvs("");
283 
284 	    SAVEFREEPV(name);
285 	}
286 	else {
287 	    name = type;
288 	    len  = tend-type;
289 	}
290 	IoTYPE(io) = *type;
291 	if ((*type == IoTYPE_RDWR) && /* scary */
292            (*(type+1) == IoTYPE_RDONLY || *(type+1) == IoTYPE_WRONLY) &&
293 	    ((!num_svs || (tend > type+1 && tend[-1] != IoTYPE_PIPE)))) {
294 	    TAINT_PROPER("open");
295 	    mode[1] = *type++;
296 	    writing = 1;
297 	}
298 
299 	if (*type == IoTYPE_PIPE) {
300 	    if (num_svs) {
301 		if (type[1] != IoTYPE_STD) {
302 	          unknown_open_mode:
303 		    Perl_croak(aTHX_ "Unknown open() mode '%.*s'", (int)olen, oname);
304 		}
305 		type++;
306 	    }
307 	    do {
308 		type++;
309 	    } while (isSPACE(*type));
310 	    if (!num_svs) {
311 		name = type;
312 		len = tend-type;
313 	    }
314 	    if (*name == '\0') {
315 		/* command is missing 19990114 */
316 		if (ckWARN(WARN_PIPE))
317 		    Perl_warner(aTHX_ packWARN(WARN_PIPE), "Missing command in piped open");
318 		errno = EPIPE;
319                 fp = NULL;
320 		goto say_false;
321 	    }
322 	    if (!(*name == '-' && name[1] == '\0') || num_svs)
323 		TAINT_ENV();
324 	    TAINT_PROPER("piped open");
325 	    if (!num_svs && name[len-1] == '|') {
326 		name[--len] = '\0' ;
327 		if (ckWARN(WARN_PIPE))
328 		    Perl_warner(aTHX_ packWARN(WARN_PIPE), "Can't open bidirectional pipe");
329 	    }
330 	    mode[0] = 'w';
331 	    writing = 1;
332             if (out_raw)
333 		mode[1] = 'b';
334             else if (out_crlf)
335 		mode[1] = 't';
336 	    if (num_svs > 1) {
337 		fp = PerlProc_popen_list(mode, num_svs, svp);
338 	    }
339 	    else {
340 		fp = PerlProc_popen(name,mode);
341 	    }
342 	    if (num_svs) {
343 		if (*type) {
344 		    if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
345                         fp = NULL;
346 			goto say_false;
347 		    }
348 		}
349 	    }
350 	} /* IoTYPE_PIPE */
351 	else if (*type == IoTYPE_WRONLY) {
352 	    TAINT_PROPER("open");
353 	    type++;
354 	    if (*type == IoTYPE_WRONLY) {
355 		/* Two IoTYPE_WRONLYs in a row make for an IoTYPE_APPEND. */
356 		mode[0] = IoTYPE(io) = IoTYPE_APPEND;
357 		type++;
358 	    }
359 	    else {
360 		mode[0] = 'w';
361 	    }
362 	    writing = 1;
363 
364             if (out_raw)
365 		mode[1] = 'b';
366             else if (out_crlf)
367 		mode[1] = 't';
368 	    if (*type == '&') {
369 	      duplicity:
370 		dodup = PERLIO_DUP_FD;
371 		type++;
372 		if (*type == '=') {
373 		    dodup = 0;
374 		    type++;
375 		}
376 		if (!num_svs && !*type && supplied_fp) {
377 		    /* "<+&" etc. is used by typemaps */
378 		    fp = supplied_fp;
379 		}
380 		else {
381 		    PerlIO *that_fp = NULL;
382                     int wanted_fd;
383 		    if (num_svs > 1) {
384 			/* diag_listed_as: More than one argument to '%s' open */
385 			Perl_croak(aTHX_ "More than one argument to '%c&' open",IoTYPE(io));
386 		    }
387 		    while (isSPACE(*type))
388 			type++;
389 		    if (num_svs && (
390 			     SvIOK(*svp)
391 			  || (SvPOKp(*svp) && looks_like_number(*svp))
392 		       )) {
393                         wanted_fd = SvUV(*svp);
394 			num_svs = 0;
395 		    }
396 		    else if (isDIGIT(*type)) {
397                         wanted_fd = atoi(type);
398 		    }
399 		    else {
400 			const IO* thatio;
401 			if (num_svs) {
402 			    thatio = sv_2io(*svp);
403 			}
404 			else {
405 			    GV * const thatgv = gv_fetchpvn_flags(type, tend - type,
406 						       0, SVt_PVIO);
407 			    thatio = GvIO(thatgv);
408 			}
409 			if (!thatio) {
410 #ifdef EINVAL
411 			    SETERRNO(EINVAL,SS_IVCHAN);
412 #endif
413                             fp = NULL;
414 			    goto say_false;
415 			}
416 			if ((that_fp = IoIFP(thatio))) {
417 			    /* Flush stdio buffer before dup. --mjd
418 			     * Unfortunately SEEK_CURing 0 seems to
419 			     * be optimized away on most platforms;
420 			     * only Solaris and Linux seem to flush
421 			     * on that. --jhi */
422 			    /* On the other hand, do all platforms
423 			     * take gracefully to flushing a read-only
424 			     * filehandle?  Perhaps we should do
425 			     * fsetpos(src)+fgetpos(dst)?  --nik */
426 			    PerlIO_flush(that_fp);
427 			    wanted_fd = PerlIO_fileno(that_fp);
428 			    /* When dup()ing STDIN, STDOUT or STDERR
429 			     * explicitly set appropriate access mode */
430 			    if (that_fp == PerlIO_stdout()
431 				|| that_fp == PerlIO_stderr())
432 			        IoTYPE(io) = IoTYPE_WRONLY;
433 			    else if (that_fp == PerlIO_stdin())
434                                 IoTYPE(io) = IoTYPE_RDONLY;
435 			    /* When dup()ing a socket, say result is
436 			     * one as well */
437 			    else if (IoTYPE(thatio) == IoTYPE_SOCKET)
438 				IoTYPE(io) = IoTYPE_SOCKET;
439 			}
440 			else
441 			    wanted_fd = -1;
442 		    }
443 		    if (!num_svs)
444 			type = NULL;
445 		    if (that_fp) {
446 			fp = PerlIO_fdupopen(aTHX_ that_fp, NULL, dodup);
447 		    }
448 		    else {
449 			if (dodup)
450                             wanted_fd = PerlLIO_dup(wanted_fd);
451 			else
452 			    was_fdopen = TRUE;
453                         if (!(fp = PerlIO_openn(aTHX_ type,mode,wanted_fd,0,0,NULL,num_svs,svp))) {
454                             if (dodup && wanted_fd >= 0)
455                                 PerlLIO_close(wanted_fd);
456 			}
457 		    }
458 		}
459 	    } /* & */
460 	    else {
461 		while (isSPACE(*type))
462 		    type++;
463 		if (*type == IoTYPE_STD && (!type[1] || isSPACE(type[1]) || type[1] == ':')) {
464 		    type++;
465 		    fp = PerlIO_stdout();
466 		    IoTYPE(io) = IoTYPE_STD;
467 		    if (num_svs > 1) {
468 			/* diag_listed_as: More than one argument to '%s' open */
469 			Perl_croak(aTHX_ "More than one argument to '>%c' open",IoTYPE_STD);
470 		    }
471 		}
472 		else  {
473 		    if (num_svs) {
474                         fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
475                     }
476                     else {
477                         SV *namesv = newSVpvn_flags(type, tend - type, SVs_TEMP);
478 		        type = NULL;
479                         fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,1,&namesv);
480 		    }
481 		}
482 	    } /* !& */
483 	    if (!fp && type && *type && *type != ':' && !isIDFIRST(*type))
484 	       goto unknown_open_mode;
485 	} /* IoTYPE_WRONLY */
486 	else if (*type == IoTYPE_RDONLY) {
487 	    do {
488 		type++;
489 	    } while (isSPACE(*type));
490 	    mode[0] = 'r';
491             if (in_raw)
492 		mode[1] = 'b';
493             else if (in_crlf)
494 		mode[1] = 't';
495 	    if (*type == '&') {
496 		goto duplicity;
497 	    }
498 	    if (*type == IoTYPE_STD && (!type[1] || isSPACE(type[1]) || type[1] == ':')) {
499 		type++;
500 		fp = PerlIO_stdin();
501 		IoTYPE(io) = IoTYPE_STD;
502 		if (num_svs > 1) {
503 		    /* diag_listed_as: More than one argument to '%s' open */
504 		    Perl_croak(aTHX_ "More than one argument to '<%c' open",IoTYPE_STD);
505 		}
506 	    }
507 	    else {
508 		if (num_svs) {
509                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
510                 }
511                 else {
512                     SV *namesv  = newSVpvn_flags(type, tend - type, SVs_TEMP);
513 		    type = NULL;
514                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,1,&namesv);
515 		}
516 	    }
517 	    if (!fp && type && *type && *type != ':' && !isIDFIRST(*type))
518 	       goto unknown_open_mode;
519 	} /* IoTYPE_RDONLY */
520 	else if ((num_svs && /* '-|...' or '...|' */
521 		  type[0] == IoTYPE_STD && type[1] == IoTYPE_PIPE) ||
522 	         (!num_svs && tend > type+1 && tend[-1] == IoTYPE_PIPE)) {
523 	    if (num_svs) {
524 		type += 2;   /* skip over '-|' */
525 	    }
526 	    else {
527 		*--tend = '\0';
528 		while (tend > type && isSPACE(tend[-1]))
529 		    *--tend = '\0';
530 		for (; isSPACE(*type); type++)
531 		    ;
532 		name = type;
533 	        len  = tend-type;
534 	    }
535 	    if (*name == '\0') {
536 		/* command is missing 19990114 */
537 		if (ckWARN(WARN_PIPE))
538 		    Perl_warner(aTHX_ packWARN(WARN_PIPE), "Missing command in piped open");
539 		errno = EPIPE;
540                 fp = NULL;
541 		goto say_false;
542 	    }
543 	    if (!(*name == '-' && name[1] == '\0') || num_svs)
544 		TAINT_ENV();
545 	    TAINT_PROPER("piped open");
546 	    mode[0] = 'r';
547 
548             if (in_raw)
549 		mode[1] = 'b';
550             else if (in_crlf)
551 		mode[1] = 't';
552 
553 	    if (num_svs > 1) {
554 		fp = PerlProc_popen_list(mode,num_svs,svp);
555 	    }
556 	    else {
557 		fp = PerlProc_popen(name,mode);
558 	    }
559 	    IoTYPE(io) = IoTYPE_PIPE;
560 	    if (num_svs) {
561 		while (isSPACE(*type))
562 		    type++;
563 		if (*type) {
564 		    if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
565                         fp = NULL;
566 			goto say_false;
567 		    }
568 		}
569 	    }
570 	}
571 	else { /* layer(Args) */
572 	    if (num_svs)
573 		goto unknown_open_mode;
574 	    name = type;
575 	    IoTYPE(io) = IoTYPE_RDONLY;
576 	    for (; isSPACE(*name); name++)
577 		;
578 	    mode[0] = 'r';
579 
580             if (in_raw)
581 		mode[1] = 'b';
582             else if (in_crlf)
583 		mode[1] = 't';
584 
585 	    if (*name == '-' && name[1] == '\0') {
586 		fp = PerlIO_stdin();
587 		IoTYPE(io) = IoTYPE_STD;
588 	    }
589 	    else {
590 		if (num_svs) {
591                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
592                 }
593                 else {
594 		    SV *namesv = newSVpvn_flags(type, tend - type, SVs_TEMP);
595 		    type = NULL;
596                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,1,&namesv);
597 		}
598 	    }
599 	}
600     }
601 
602   say_false:
603     return openn_cleanup(gv, io, fp, mode, oname, saveifp, saveofp, savefd,
604                          savetype, writing, was_fdopen, type);
605 }
606 
607 /* Yes, this is ugly, but it's private, and I don't see a cleaner way to
608    simplify the two-headed public interface of do_openn. */
609 static bool
610 S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname,
611                 PerlIO *saveifp, PerlIO *saveofp, int savefd, char savetype,
612                 int writing, bool was_fdopen, const char *type)
613 {
614     int fd;
615 
616     PERL_ARGS_ASSERT_OPENN_CLEANUP;
617 
618     if (!fp) {
619 	if (IoTYPE(io) == IoTYPE_RDONLY && ckWARN(WARN_NEWLINE)
620 	    && strchr(oname, '\n')
621 
622 	)
623         {
624             GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */
625 	    Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
626             GCC_DIAG_RESTORE;
627         }
628 	goto say_false;
629     }
630 
631     if (ckWARN(WARN_IO)) {
632 	if ((IoTYPE(io) == IoTYPE_RDONLY) &&
633 	    (fp == PerlIO_stdout() || fp == PerlIO_stderr())) {
634 		Perl_warner(aTHX_ packWARN(WARN_IO),
635 			    "Filehandle STD%s reopened as %"HEKf
636 			    " only for input",
637 			    ((fp == PerlIO_stdout()) ? "OUT" : "ERR"),
638 			    HEKfARG(GvENAME_HEK(gv)));
639 	}
640 	else if ((IoTYPE(io) == IoTYPE_WRONLY) && fp == PerlIO_stdin()) {
641 		Perl_warner(aTHX_ packWARN(WARN_IO),
642 		    "Filehandle STDIN reopened as %"HEKf" only for output",
643 		     HEKfARG(GvENAME_HEK(gv))
644 		);
645 	}
646     }
647 
648     fd = PerlIO_fileno(fp);
649     /* If there is no fd (e.g. PerlIO::scalar) assume it isn't a
650      * socket - this covers PerlIO::scalar - otherwise unless we "know" the
651      * type probe for socket-ness.
652      */
653     if (IoTYPE(io) && IoTYPE(io) != IoTYPE_PIPE && IoTYPE(io) != IoTYPE_STD && fd >= 0) {
654 	if (PerlLIO_fstat(fd,&PL_statbuf) < 0) {
655 	    /* If PerlIO claims to have fd we had better be able to fstat() it. */
656 	    (void) PerlIO_close(fp);
657 	    goto say_false;
658 	}
659 #ifndef PERL_MICRO
660 	if (S_ISSOCK(PL_statbuf.st_mode))
661 	    IoTYPE(io) = IoTYPE_SOCKET;	/* in case a socket was passed in to us */
662 #ifdef HAS_SOCKET
663 	else if (
664 	    !(PL_statbuf.st_mode & S_IFMT)
665 	    && IoTYPE(io) != IoTYPE_WRONLY  /* Dups of STD* filehandles already have */
666 	    && IoTYPE(io) != IoTYPE_RDONLY  /* type so they aren't marked as sockets */
667 	) {				    /* on OS's that return 0 on fstat()ed pipe */
668 	     char tmpbuf[256];
669 	     Sock_size_t buflen = sizeof tmpbuf;
670 	     if (PerlSock_getsockname(fd, (struct sockaddr *)tmpbuf, &buflen) >= 0
671 		      || errno != ENOTSOCK)
672 		    IoTYPE(io) = IoTYPE_SOCKET; /* some OS's return 0 on fstat()ed socket */
673 				                /* but some return 0 for streams too, sigh */
674 	}
675 #endif /* HAS_SOCKET */
676 #endif /* !PERL_MICRO */
677     }
678 
679     /* Eeek - FIXME !!!
680      * If this is a standard handle we discard all the layer stuff
681      * and just dup the fd into whatever was on the handle before !
682      */
683 
684     if (saveifp) {		/* must use old fp? */
685         /* If fd is less that PL_maxsysfd i.e. STDIN..STDERR
686            then dup the new fileno down
687          */
688 	if (saveofp) {
689 	    PerlIO_flush(saveofp);	/* emulate PerlIO_close() */
690 	    if (saveofp != saveifp) {	/* was a socket? */
691 		PerlIO_close(saveofp);
692 	    }
693 	}
694 	if (savefd != fd) {
695 	    /* Still a small can-of-worms here if (say) PerlIO::scalar
696 	       is assigned to (say) STDOUT - for now let dup2() fail
697 	       and provide the error
698 	     */
699 	    if (PerlLIO_dup2(fd, savefd) < 0) {
700 		(void)PerlIO_close(fp);
701 		goto say_false;
702 	    }
703 #ifdef VMS
704 	    if (savefd != PerlIO_fileno(PerlIO_stdin())) {
705                 char newname[FILENAME_MAX+1];
706                 if (PerlIO_getname(fp, newname)) {
707                     if (fd == PerlIO_fileno(PerlIO_stdout()))
708                         vmssetuserlnm("SYS$OUTPUT", newname);
709                     if (fd == PerlIO_fileno(PerlIO_stderr()))
710                         vmssetuserlnm("SYS$ERROR", newname);
711                 }
712 	    }
713 #endif
714 
715 #if !defined(WIN32)
716            /* PL_fdpid isn't used on Windows, so avoid this useless work.
717             * XXX Probably the same for a lot of other places. */
718             {
719                 Pid_t pid;
720                 SV *sv;
721 
722                 sv = *av_fetch(PL_fdpid,fd,TRUE);
723                 SvUPGRADE(sv, SVt_IV);
724                 pid = SvIVX(sv);
725                 SvIV_set(sv, 0);
726                 sv = *av_fetch(PL_fdpid,savefd,TRUE);
727                 SvUPGRADE(sv, SVt_IV);
728                 SvIV_set(sv, pid);
729             }
730 #endif
731 
732 	    if (was_fdopen) {
733                 /* need to close fp without closing underlying fd */
734                 int ofd = PerlIO_fileno(fp);
735                 int dupfd = PerlLIO_dup(ofd);
736 #if defined(HAS_FCNTL) && defined(F_SETFD)
737 		/* Assume if we have F_SETFD we have F_GETFD */
738                 int coe = fcntl(ofd,F_GETFD);
739 #endif
740                 PerlIO_close(fp);
741                 PerlLIO_dup2(dupfd,ofd);
742 #if defined(HAS_FCNTL) && defined(F_SETFD)
743 		/* The dup trick has lost close-on-exec on ofd */
744 		fcntl(ofd,F_SETFD, coe);
745 #endif
746                 PerlLIO_close(dupfd);
747 	    }
748             else
749 		PerlIO_close(fp);
750 	}
751 	fp = saveifp;
752 	PerlIO_clearerr(fp);
753 	fd = PerlIO_fileno(fp);
754     }
755 #if defined(HAS_FCNTL) && defined(F_SETFD)
756     if (fd >= 0) {
757 	dSAVE_ERRNO;
758 	fcntl(fd,F_SETFD,fd > PL_maxsysfd); /* can change errno */
759 	RESTORE_ERRNO;
760     }
761 #endif
762     IoIFP(io) = fp;
763 
764     IoFLAGS(io) &= ~IOf_NOLINE;
765     if (writing) {
766 	if (IoTYPE(io) == IoTYPE_SOCKET
767 	    || (IoTYPE(io) == IoTYPE_WRONLY && fd >= 0 && S_ISCHR(PL_statbuf.st_mode)) ) {
768 	    char *s = mode;
769 	    if (*s == IoTYPE_IMPLICIT || *s == IoTYPE_NUMERIC)
770 	      s++;
771 	    *s = 'w';
772 	    if (!(IoOFP(io) = PerlIO_openn(aTHX_ type,s,fd,0,0,NULL,0,NULL))) {
773 		PerlIO_close(fp);
774 		IoIFP(io) = NULL;
775 		goto say_false;
776 	    }
777 	}
778 	else
779 	    IoOFP(io) = fp;
780     }
781     return TRUE;
782 
783 say_false:
784     IoIFP(io) = saveifp;
785     IoOFP(io) = saveofp;
786     IoTYPE(io) = savetype;
787     return FALSE;
788 }
789 
790 PerlIO *
791 Perl_nextargv(pTHX_ GV *gv)
792 {
793     dVAR;
794     IO * const io = GvIOp(gv);
795 
796     PERL_ARGS_ASSERT_NEXTARGV;
797 
798     if (!PL_argvoutgv)
799 	PL_argvoutgv = gv_fetchpvs("ARGVOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
800     if (io && (IoFLAGS(io) & IOf_ARGV) && (IoFLAGS(io) & IOf_START)) {
801 	IoFLAGS(io) &= ~IOf_START;
802 	if (PL_inplace) {
803 	    assert(PL_defoutgv);
804 	    Perl_av_create_and_push(aTHX_ &PL_argvout_stack,
805 				    SvREFCNT_inc_simple_NN(PL_defoutgv));
806 	}
807     }
808     if (PL_filemode & (S_ISUID|S_ISGID)) {
809 	PerlIO_flush(IoIFP(GvIOn(PL_argvoutgv)));  /* chmod must follow last write */
810 #ifdef HAS_FCHMOD
811 	if (PL_lastfd != -1)
812 	    (void)fchmod(PL_lastfd,PL_filemode);
813 #else
814 	(void)PerlLIO_chmod(PL_oldname,PL_filemode);
815 #endif
816     }
817     PL_lastfd = -1;
818     PL_filemode = 0;
819     if (!GvAV(gv))
820 	return NULL;
821     while (av_tindex(GvAV(gv)) >= 0) {
822 	STRLEN oldlen;
823         SV *const sv = av_shift(GvAV(gv));
824 	SAVEFREESV(sv);
825 	SvTAINTED_off(GvSVn(gv)); /* previous tainting irrelevant */
826 	sv_setsv(GvSVn(gv),sv);
827 	SvSETMAGIC(GvSV(gv));
828 	PL_oldname = SvPVx(GvSV(gv), oldlen);
829         if (LIKELY(!PL_inplace)) {
830             if (do_open6(gv, PL_oldname, oldlen, NULL, NULL, 0)) {
831                 return IoIFP(GvIOp(gv));
832             }
833         }
834         else {
835             /* This very long block ends with return IoIFP(GvIOp(gv));
836                Both this block and the block above fall through on open
837                failure to the warning code, and then the while loop above tries
838                the next entry. */
839             if (do_open_raw(gv, PL_oldname, oldlen, O_RDONLY, 0)) {
840 #ifndef FLEXFILENAMES
841                 int filedev;
842                 int fileino;
843 #endif
844                 Uid_t fileuid;
845                 Gid_t filegid;
846 
847 		TAINT_PROPER("inplace open");
848 		if (oldlen == 1 && *PL_oldname == '-') {
849 		    setdefout(gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL,
850 					  SVt_PVIO));
851 		    return IoIFP(GvIOp(gv));
852 		}
853 #ifndef FLEXFILENAMES
854 		filedev = PL_statbuf.st_dev;
855 		fileino = PL_statbuf.st_ino;
856 #endif
857 		PL_filemode = PL_statbuf.st_mode;
858 		fileuid = PL_statbuf.st_uid;
859 		filegid = PL_statbuf.st_gid;
860 		if (!S_ISREG(PL_filemode)) {
861 		    Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE),
862 				     "Can't do inplace edit: %s is not a regular file",
863 				     PL_oldname );
864 		    do_close(gv,FALSE);
865 		    continue;
866 		}
867 		if (*PL_inplace && strNE(PL_inplace, "*")) {
868 		    const char *star = strchr(PL_inplace, '*');
869 		    if (star) {
870 			const char *begin = PL_inplace;
871 			sv_setpvs(sv, "");
872 			do {
873 			    sv_catpvn(sv, begin, star - begin);
874 			    sv_catpvn(sv, PL_oldname, oldlen);
875 			    begin = ++star;
876 			} while ((star = strchr(begin, '*')));
877 			if (*begin)
878 			    sv_catpv(sv,begin);
879 		    }
880 		    else {
881 			sv_catpv(sv,PL_inplace);
882 		    }
883 #ifndef FLEXFILENAMES
884 		    if ((PerlLIO_stat(SvPVX_const(sv),&PL_statbuf) >= 0
885 			 && PL_statbuf.st_dev == filedev
886 			 && PL_statbuf.st_ino == fileino)
887 #ifdef DJGPP
888 			|| ((_djstat_fail_bits & _STFAIL_TRUENAME)!=0)
889 #endif
890                       )
891 		    {
892 			Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE),
893 					 "Can't do inplace edit: %"SVf" would not be unique",
894 					 SVfARG(sv));
895 			do_close(gv,FALSE);
896 			continue;
897 		    }
898 #endif
899 #ifdef HAS_RENAME
900 #if !defined(DOSISH) && !defined(__CYGWIN__)
901 		    if (PerlLIO_rename(PL_oldname,SvPVX_const(sv)) < 0) {
902 			Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE),
903 					 "Can't rename %s to %"SVf": %s, skipping file",
904 					 PL_oldname, SVfARG(sv), Strerror(errno));
905 			do_close(gv,FALSE);
906 			continue;
907 		    }
908 #else
909 		    do_close(gv,FALSE);
910 		    (void)PerlLIO_unlink(SvPVX_const(sv));
911 		    (void)PerlLIO_rename(PL_oldname,SvPVX_const(sv));
912 		    do_open_raw(gv, SvPVX_const(sv), SvCUR(sv), O_RDONLY, 0);
913 #endif /* DOSISH */
914 #else
915 		    (void)UNLINK(SvPVX_const(sv));
916 		    if (link(PL_oldname,SvPVX_const(sv)) < 0) {
917 			Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE),
918 					 "Can't rename %s to %"SVf": %s, skipping file",
919 					 PL_oldname, SVfARG(sv), Strerror(errno) );
920 			do_close(gv,FALSE);
921 			continue;
922 		    }
923 		    (void)UNLINK(PL_oldname);
924 #endif
925 		}
926 		else {
927 #if !defined(DOSISH) && !defined(AMIGAOS)
928 #  ifndef VMS  /* Don't delete; use automatic file versioning */
929 		    if (UNLINK(PL_oldname) < 0) {
930 			Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE),
931 					 "Can't remove %s: %s, skipping file",
932 					 PL_oldname, Strerror(errno) );
933 			do_close(gv,FALSE);
934 			continue;
935 		    }
936 #  endif
937 #else
938 		    Perl_croak(aTHX_ "Can't do inplace edit without backup");
939 #endif
940 		}
941 
942 		sv_setpvn(sv,PL_oldname,oldlen);
943 		SETERRNO(0,0);		/* in case sprintf set errno */
944 		if (!Perl_do_open_raw(aTHX_ PL_argvoutgv, SvPVX_const(sv),
945                                       SvCUR(sv),
946 #ifdef VMS
947                                       O_WRONLY|O_CREAT|O_TRUNC, 0
948 #else
949                                       O_WRONLY|O_CREAT|OPEN_EXCL, 0600
950 #endif
951                         )) {
952 		    Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE), "Can't do inplace edit on %s: %s",
953 				     PL_oldname, Strerror(errno) );
954 		    do_close(gv,FALSE);
955 		    continue;
956 		}
957 		setdefout(PL_argvoutgv);
958 		PL_lastfd = PerlIO_fileno(IoIFP(GvIOp(PL_argvoutgv)));
959 		(void)PerlLIO_fstat(PL_lastfd,&PL_statbuf);
960 #ifdef HAS_FCHMOD
961 		(void)fchmod(PL_lastfd,PL_filemode);
962 #else
963 		(void)PerlLIO_chmod(PL_oldname,PL_filemode);
964 #endif
965 		if (fileuid != PL_statbuf.st_uid || filegid != PL_statbuf.st_gid) {
966 		    /* XXX silently ignore failures */
967 #ifdef HAS_FCHOWN
968 		    PERL_UNUSED_RESULT(fchown(PL_lastfd,fileuid,filegid));
969 #else
970 #ifdef HAS_CHOWN
971 		    PERL_UNUSED_RESULT(PerlLIO_chown(PL_oldname,fileuid,filegid));
972 #endif
973 #endif
974 		}
975                 return IoIFP(GvIOp(gv));
976 	    }
977 	} /* successful do_open_raw(), PL_inplace non-NULL */
978 
979         if (ckWARN_d(WARN_INPLACE)) {
980             const int eno = errno;
981             if (PerlLIO_stat(PL_oldname, &PL_statbuf) >= 0
982                 && !S_ISREG(PL_statbuf.st_mode)) {
983                 Perl_warner(aTHX_ packWARN(WARN_INPLACE),
984                             "Can't do inplace edit: %s is not a regular file",
985                             PL_oldname);
986             }
987             else {
988                 Perl_warner(aTHX_ packWARN(WARN_INPLACE), "Can't open %s: %s",
989                             PL_oldname, Strerror(eno));
990             }
991 	}
992     }
993     if (io && (IoFLAGS(io) & IOf_ARGV))
994 	IoFLAGS(io) |= IOf_START;
995     if (PL_inplace) {
996 	(void)do_close(PL_argvoutgv,FALSE);
997 	if (io && (IoFLAGS(io) & IOf_ARGV)
998 	    && PL_argvout_stack && AvFILLp(PL_argvout_stack) >= 0)
999 	{
1000 	    GV * const oldout = MUTABLE_GV(av_pop(PL_argvout_stack));
1001 	    setdefout(oldout);
1002 	    SvREFCNT_dec_NN(oldout);
1003 	    return NULL;
1004 	}
1005 	setdefout(gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO));
1006     }
1007     return NULL;
1008 }
1009 
1010 /* explicit renamed to avoid C++ conflict    -- kja */
1011 bool
1012 Perl_do_close(pTHX_ GV *gv, bool not_implicit)
1013 {
1014     dVAR;
1015     bool retval;
1016     IO *io;
1017 
1018     if (!gv)
1019 	gv = PL_argvgv;
1020     if (!gv || !isGV_with_GP(gv)) {
1021 	if (not_implicit)
1022 	    SETERRNO(EBADF,SS_IVCHAN);
1023 	return FALSE;
1024     }
1025     io = GvIO(gv);
1026     if (!io) {		/* never opened */
1027 	if (not_implicit) {
1028 	    report_evil_fh(gv);
1029 	    SETERRNO(EBADF,SS_IVCHAN);
1030 	}
1031 	return FALSE;
1032     }
1033     retval = io_close(io, not_implicit);
1034     if (not_implicit) {
1035 	IoLINES(io) = 0;
1036 	IoPAGE(io) = 0;
1037 	IoLINES_LEFT(io) = IoPAGE_LEN(io);
1038     }
1039     IoTYPE(io) = IoTYPE_CLOSED;
1040     return retval;
1041 }
1042 
1043 bool
1044 Perl_io_close(pTHX_ IO *io, bool not_implicit)
1045 {
1046     dVAR;
1047     bool retval = FALSE;
1048 
1049     PERL_ARGS_ASSERT_IO_CLOSE;
1050 
1051     if (IoIFP(io)) {
1052 	if (IoTYPE(io) == IoTYPE_PIPE) {
1053 	    const int status = PerlProc_pclose(IoIFP(io));
1054 	    if (not_implicit) {
1055 		STATUS_NATIVE_CHILD_SET(status);
1056 		retval = (STATUS_UNIX == 0);
1057 	    }
1058 	    else {
1059 		retval = (status != -1);
1060 	    }
1061 	}
1062 	else if (IoTYPE(io) == IoTYPE_STD)
1063 	    retval = TRUE;
1064 	else {
1065 	    if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {		/* a socket */
1066 		const bool prev_err = PerlIO_error(IoOFP(io));
1067 		retval = (PerlIO_close(IoOFP(io)) != EOF && !prev_err);
1068 		PerlIO_close(IoIFP(io));	/* clear stdio, fd already closed */
1069 	    }
1070 	    else {
1071 		const bool prev_err = PerlIO_error(IoIFP(io));
1072 		retval = (PerlIO_close(IoIFP(io)) != EOF && !prev_err);
1073 	    }
1074 	}
1075 	IoOFP(io) = IoIFP(io) = NULL;
1076     }
1077     else if (not_implicit) {
1078 	SETERRNO(EBADF,SS_IVCHAN);
1079     }
1080 
1081     return retval;
1082 }
1083 
1084 bool
1085 Perl_do_eof(pTHX_ GV *gv)
1086 {
1087     dVAR;
1088     IO * const io = GvIO(gv);
1089 
1090     PERL_ARGS_ASSERT_DO_EOF;
1091 
1092     if (!io)
1093 	return TRUE;
1094     else if (IoTYPE(io) == IoTYPE_WRONLY)
1095 	report_wrongway_fh(gv, '>');
1096 
1097     while (IoIFP(io)) {
1098         if (PerlIO_has_cntptr(IoIFP(io))) {	/* (the code works without this) */
1099 	    if (PerlIO_get_cnt(IoIFP(io)) > 0)	/* cheat a little, since */
1100 		return FALSE;			/* this is the most usual case */
1101         }
1102 
1103 	{
1104 	     /* getc and ungetc can stomp on errno */
1105 	    dSAVE_ERRNO;
1106 	    const int ch = PerlIO_getc(IoIFP(io));
1107 	    if (ch != EOF) {
1108 		(void)PerlIO_ungetc(IoIFP(io),ch);
1109 		RESTORE_ERRNO;
1110 		return FALSE;
1111 	    }
1112 	    RESTORE_ERRNO;
1113 	}
1114 
1115         if (PerlIO_has_cntptr(IoIFP(io)) && PerlIO_canset_cnt(IoIFP(io))) {
1116 	    if (PerlIO_get_cnt(IoIFP(io)) < -1)
1117 		PerlIO_set_cnt(IoIFP(io),-1);
1118 	}
1119 	if (PL_op->op_flags & OPf_SPECIAL) { /* not necessarily a real EOF yet? */
1120 	    if (gv != PL_argvgv || !nextargv(gv))	/* get another fp handy */
1121 		return TRUE;
1122 	}
1123 	else
1124 	    return TRUE;		/* normal fp, definitely end of file */
1125     }
1126     return TRUE;
1127 }
1128 
1129 Off_t
1130 Perl_do_tell(pTHX_ GV *gv)
1131 {
1132     dVAR;
1133     IO *const io = GvIO(gv);
1134     PerlIO *fp;
1135 
1136     PERL_ARGS_ASSERT_DO_TELL;
1137 
1138     if (io && (fp = IoIFP(io))) {
1139 	return PerlIO_tell(fp);
1140     }
1141     report_evil_fh(gv);
1142     SETERRNO(EBADF,RMS_IFI);
1143     return (Off_t)-1;
1144 }
1145 
1146 bool
1147 Perl_do_seek(pTHX_ GV *gv, Off_t pos, int whence)
1148 {
1149     dVAR;
1150     IO *const io = GvIO(gv);
1151     PerlIO *fp;
1152 
1153     if (io && (fp = IoIFP(io))) {
1154 	return PerlIO_seek(fp, pos, whence) >= 0;
1155     }
1156     report_evil_fh(gv);
1157     SETERRNO(EBADF,RMS_IFI);
1158     return FALSE;
1159 }
1160 
1161 Off_t
1162 Perl_do_sysseek(pTHX_ GV *gv, Off_t pos, int whence)
1163 {
1164     dVAR;
1165     IO *const io = GvIO(gv);
1166     PerlIO *fp;
1167 
1168     PERL_ARGS_ASSERT_DO_SYSSEEK;
1169 
1170     if (io && (fp = IoIFP(io)))
1171 	return PerlLIO_lseek(PerlIO_fileno(fp), pos, whence);
1172     report_evil_fh(gv);
1173     SETERRNO(EBADF,RMS_IFI);
1174     return (Off_t)-1;
1175 }
1176 
1177 int
1178 Perl_mode_from_discipline(pTHX_ const char *s, STRLEN len)
1179 {
1180     int mode = O_BINARY;
1181     if (s) {
1182 	while (*s) {
1183 	    if (*s == ':') {
1184 		switch (s[1]) {
1185 		case 'r':
1186 		    if (s[2] == 'a' && s[3] == 'w'
1187 			&& (!s[4] || s[4] == ':' || isSPACE(s[4])))
1188 		    {
1189 			mode = O_BINARY;
1190 			s += 4;
1191 			len -= 4;
1192 			break;
1193 		    }
1194 		    /* FALL THROUGH */
1195 		case 'c':
1196 		    if (s[2] == 'r' && s[3] == 'l' && s[4] == 'f'
1197 			&& (!s[5] || s[5] == ':' || isSPACE(s[5])))
1198 		    {
1199 			mode = O_TEXT;
1200 			s += 5;
1201 			len -= 5;
1202 			break;
1203 		    }
1204 		    /* FALL THROUGH */
1205 		default:
1206 		    goto fail_discipline;
1207 		}
1208 	    }
1209 	    else if (isSPACE(*s)) {
1210 		++s;
1211 		--len;
1212 	    }
1213 	    else {
1214 		const char *end;
1215 fail_discipline:
1216 		end = strchr(s+1, ':');
1217 		if (!end)
1218 		    end = s+len;
1219 #ifndef PERLIO_LAYERS
1220 		Perl_croak(aTHX_ "IO layers (like '%.*s') unavailable", end-s, s);
1221 #else
1222 		len -= end-s;
1223 		s = end;
1224 #endif
1225 	    }
1226 	}
1227     }
1228     return mode;
1229 }
1230 
1231 #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE)
1232 I32
1233 my_chsize(int fd, Off_t length)
1234 {
1235 #ifdef F_FREESP
1236 	/* code courtesy of William Kucharski */
1237 #define HAS_CHSIZE
1238 
1239     Stat_t filebuf;
1240 
1241     if (PerlLIO_fstat(fd, &filebuf) < 0)
1242 	return -1;
1243 
1244     if (filebuf.st_size < length) {
1245 
1246 	/* extend file length */
1247 
1248 	if ((PerlLIO_lseek(fd, (length - 1), 0)) < 0)
1249 	    return -1;
1250 
1251 	/* write a "0" byte */
1252 
1253 	if ((PerlLIO_write(fd, "", 1)) != 1)
1254 	    return -1;
1255     }
1256     else {
1257 	/* truncate length */
1258 	struct flock fl;
1259 	fl.l_whence = 0;
1260 	fl.l_len = 0;
1261 	fl.l_start = length;
1262 	fl.l_type = F_WRLCK;    /* write lock on file space */
1263 
1264 	/*
1265 	* This relies on the UNDOCUMENTED F_FREESP argument to
1266 	* fcntl(2), which truncates the file so that it ends at the
1267 	* position indicated by fl.l_start.
1268 	*
1269 	* Will minor miracles never cease?
1270 	*/
1271 
1272 	if (fcntl(fd, F_FREESP, &fl) < 0)
1273 	    return -1;
1274 
1275     }
1276     return 0;
1277 #else
1278     Perl_croak_nocontext("truncate not implemented");
1279 #endif /* F_FREESP */
1280     return -1;
1281 }
1282 #endif /* !HAS_TRUNCATE && !HAS_CHSIZE */
1283 
1284 bool
1285 Perl_do_print(pTHX_ SV *sv, PerlIO *fp)
1286 {
1287     dVAR;
1288 
1289     PERL_ARGS_ASSERT_DO_PRINT;
1290 
1291     /* assuming fp is checked earlier */
1292     if (!sv)
1293 	return TRUE;
1294     if (SvTYPE(sv) == SVt_IV && SvIOK(sv)) {
1295 	assert(!SvGMAGICAL(sv));
1296 	if (SvIsUV(sv))
1297 	    PerlIO_printf(fp, "%"UVuf, (UV)SvUVX(sv));
1298 	else
1299 	    PerlIO_printf(fp, "%"IVdf, (IV)SvIVX(sv));
1300 	return !PerlIO_error(fp);
1301     }
1302     else {
1303 	STRLEN len;
1304 	/* Do this first to trigger any overloading.  */
1305 	const char *tmps = SvPV_const(sv, len);
1306 	U8 *tmpbuf = NULL;
1307 	bool happy = TRUE;
1308 
1309 	if (PerlIO_isutf8(fp)) { /* If the stream is utf8 ... */
1310 	    if (!SvUTF8(sv)) {	/* Convert to utf8 if necessary */
1311 		/* We don't modify the original scalar.  */
1312 		tmpbuf = bytes_to_utf8((const U8*) tmps, &len);
1313 		tmps = (char *) tmpbuf;
1314 	    }
1315 	    else if (ckWARN4_d(WARN_UTF8, WARN_SURROGATE, WARN_NON_UNICODE, WARN_NONCHAR)) {
1316 		(void) check_utf8_print((const U8*) tmps, len);
1317 	    }
1318 	} /* else stream isn't utf8 */
1319 	else if (DO_UTF8(sv)) { /* But if is utf8 internally, attempt to
1320 				   convert to bytes */
1321 	    STRLEN tmplen = len;
1322 	    bool utf8 = TRUE;
1323 	    U8 * const result = bytes_from_utf8((const U8*) tmps, &tmplen, &utf8);
1324 	    if (!utf8) {
1325 
1326 		/* Here, succeeded in downgrading from utf8.  Set up to below
1327 		 * output the converted value */
1328 		tmpbuf = result;
1329 		tmps = (char *) tmpbuf;
1330 		len = tmplen;
1331 	    }
1332 	    else {  /* Non-utf8 output stream, but string only representable in
1333 		       utf8 */
1334 		assert((char *)result == tmps);
1335 		Perl_ck_warner_d(aTHX_ packWARN(WARN_UTF8),
1336 				 "Wide character in %s",
1337 				   PL_op ? OP_DESC(PL_op) : "print"
1338 				);
1339 		    /* Could also check that isn't one of the things to avoid
1340 		     * in utf8 by using check_utf8_print(), but not doing so,
1341 		     * since the stream isn't a UTF8 stream */
1342 	    }
1343 	}
1344 	/* To detect whether the process is about to overstep its
1345 	 * filesize limit we would need getrlimit().  We could then
1346 	 * also transparently raise the limit with setrlimit() --
1347 	 * but only until the system hard limit/the filesystem limit,
1348 	 * at which we would get EPERM.  Note that when using buffered
1349 	 * io the write failure can be delayed until the flush/close. --jhi */
1350 	if (len && (PerlIO_write(fp,tmps,len) == 0))
1351 	    happy = FALSE;
1352 	Safefree(tmpbuf);
1353 	return happy ? !PerlIO_error(fp) : FALSE;
1354     }
1355 }
1356 
1357 I32
1358 Perl_my_stat_flags(pTHX_ const U32 flags)
1359 {
1360     dVAR;
1361     dSP;
1362     IO *io;
1363     GV* gv;
1364 
1365     if (PL_op->op_flags & OPf_REF) {
1366 	gv = cGVOP_gv;
1367       do_fstat:
1368         if (gv == PL_defgv)
1369             return PL_laststatval;
1370 	io = GvIO(gv);
1371         do_fstat_have_io:
1372         PL_laststype = OP_STAT;
1373         PL_statgv = gv ? gv : (GV *)io;
1374         sv_setpvs(PL_statname, "");
1375         if(io) {
1376 	    if (IoIFP(io)) {
1377 	        return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache));
1378             } else if (IoDIRP(io)) {
1379                 return (PL_laststatval = PerlLIO_fstat(my_dirfd(IoDIRP(io)), &PL_statcache));
1380             }
1381         }
1382 	PL_laststatval = -1;
1383 	report_evil_fh(gv);
1384 	return -1;
1385     }
1386     else if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t))
1387 	     == OPpFT_STACKED)
1388 	return PL_laststatval;
1389     else {
1390 	SV* const sv = TOPs;
1391 	const char *s;
1392 	STRLEN len;
1393 	if ((gv = MAYBE_DEREF_GV_flags(sv,flags))) {
1394 	    goto do_fstat;
1395 	}
1396         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) {
1397             io = MUTABLE_IO(SvRV(sv));
1398 	    gv = NULL;
1399             goto do_fstat_have_io;
1400         }
1401 
1402 	s = SvPV_flags_const(sv, len, flags);
1403 	PL_statgv = NULL;
1404 	sv_setpvn(PL_statname, s, len);
1405 	s = SvPVX_const(PL_statname);		/* s now NUL-terminated */
1406 	PL_laststype = OP_STAT;
1407 	PL_laststatval = PerlLIO_stat(s, &PL_statcache);
1408 	if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(s, '\n')) {
1409             GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */
1410 	    Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
1411             GCC_DIAG_RESTORE;
1412         }
1413 	return PL_laststatval;
1414     }
1415 }
1416 
1417 
1418 I32
1419 Perl_my_lstat_flags(pTHX_ const U32 flags)
1420 {
1421     dVAR;
1422     static const char* const no_prev_lstat = "The stat preceding -l _ wasn't an lstat";
1423     dSP;
1424     const char *file;
1425     SV* const sv = TOPs;
1426     bool isio = FALSE;
1427     if (PL_op->op_flags & OPf_REF) {
1428 	if (cGVOP_gv == PL_defgv) {
1429 	    if (PL_laststype != OP_LSTAT)
1430 		Perl_croak(aTHX_ "%s", no_prev_lstat);
1431 	    return PL_laststatval;
1432 	}
1433 	PL_laststatval = -1;
1434 	if (ckWARN(WARN_IO)) {
1435 	    /* diag_listed_as: Use of -l on filehandle%s */
1436 	    Perl_warner(aTHX_ packWARN(WARN_IO),
1437 		 	     "Use of -l on filehandle %"HEKf,
1438 			      HEKfARG(GvENAME_HEK(cGVOP_gv)));
1439 	}
1440 	return -1;
1441     }
1442     if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t))
1443 	     == OPpFT_STACKED) {
1444       if (PL_laststype != OP_LSTAT)
1445 	Perl_croak(aTHX_ "%s", no_prev_lstat);
1446       return PL_laststatval;
1447     }
1448 
1449     PL_laststype = OP_LSTAT;
1450     PL_statgv = NULL;
1451     if ( (  (SvROK(sv) && (  isGV_with_GP(SvRV(sv))
1452                           || (isio = SvTYPE(SvRV(sv)) == SVt_PVIO)  )
1453             )
1454          || isGV_with_GP(sv)
1455          )
1456       && ckWARN(WARN_IO)) {
1457         if (isio)
1458 	    /* diag_listed_as: Use of -l on filehandle%s */
1459             Perl_warner(aTHX_ packWARN(WARN_IO),
1460                              "Use of -l on filehandle");
1461         else
1462 	    /* diag_listed_as: Use of -l on filehandle%s */
1463             Perl_warner(aTHX_ packWARN(WARN_IO),
1464                              "Use of -l on filehandle %"HEKf,
1465                               GvENAME_HEK((const GV *)
1466                                           (SvROK(sv) ? SvRV(sv) : sv)));
1467     }
1468     file = SvPV_flags_const_nolen(sv, flags);
1469     sv_setpv(PL_statname,file);
1470     PL_laststatval = PerlLIO_lstat(file,&PL_statcache);
1471     if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(file, '\n')) {
1472         GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */
1473         Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
1474         GCC_DIAG_RESTORE;
1475     }
1476     return PL_laststatval;
1477 }
1478 
1479 static void
1480 S_exec_failed(pTHX_ const char *cmd, int fd, int do_report)
1481 {
1482     const int e = errno;
1483     PERL_ARGS_ASSERT_EXEC_FAILED;
1484     if (ckWARN(WARN_EXEC))
1485 	Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
1486 		    cmd, Strerror(e));
1487     if (do_report) {
1488         /* XXX silently ignore failures */
1489         PERL_UNUSED_RESULT(PerlLIO_write(fd, (void*)&e, sizeof(int)));
1490 	PerlLIO_close(fd);
1491     }
1492 }
1493 
1494 bool
1495 Perl_do_aexec5(pTHX_ SV *really, SV **mark, SV **sp,
1496 	       int fd, int do_report)
1497 {
1498     dVAR;
1499     PERL_ARGS_ASSERT_DO_AEXEC5;
1500 #if defined(__SYMBIAN32__) || defined(__LIBCATAMOUNT__)
1501     Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
1502 #else
1503     if (sp > mark) {
1504 	const char **a;
1505 	const char *tmps = NULL;
1506 	Newx(PL_Argv, sp - mark + 1, const char*);
1507 	a = PL_Argv;
1508 
1509 	while (++mark <= sp) {
1510 	    if (*mark)
1511 		*a++ = SvPV_nolen_const(*mark);
1512 	    else
1513 		*a++ = "";
1514 	}
1515 	*a = NULL;
1516 	if (really)
1517 	    tmps = SvPV_nolen_const(really);
1518 	if ((!really && *PL_Argv[0] != '/') ||
1519 	    (really && *tmps != '/'))		/* will execvp use PATH? */
1520 	    TAINT_ENV();		/* testing IFS here is overkill, probably */
1521 	PERL_FPU_PRE_EXEC
1522 	if (really && *tmps)
1523 	    PerlProc_execvp(tmps,EXEC_ARGV_CAST(PL_Argv));
1524 	else
1525 	    PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
1526 	PERL_FPU_POST_EXEC
1527  	S_exec_failed(aTHX_ (really ? tmps : PL_Argv[0]), fd, do_report);
1528     }
1529     do_execfree();
1530 #endif
1531     return FALSE;
1532 }
1533 
1534 void
1535 Perl_do_execfree(pTHX)
1536 {
1537     dVAR;
1538     Safefree(PL_Argv);
1539     PL_Argv = NULL;
1540     Safefree(PL_Cmd);
1541     PL_Cmd = NULL;
1542 }
1543 
1544 #ifdef PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
1545 
1546 bool
1547 Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
1548 {
1549     dVAR;
1550     const char **a;
1551     char *s;
1552     char *buf;
1553     char *cmd;
1554     /* Make a copy so we can change it */
1555     const Size_t cmdlen = strlen(incmd) + 1;
1556 
1557     PERL_ARGS_ASSERT_DO_EXEC3;
1558 
1559     Newx(buf, cmdlen, char);
1560     cmd = buf;
1561     memcpy(cmd, incmd, cmdlen);
1562 
1563     while (*cmd && isSPACE(*cmd))
1564 	cmd++;
1565 
1566     /* save an extra exec if possible */
1567 
1568 #ifdef CSH
1569     {
1570         char flags[PERL_FLAGS_MAX];
1571 	if (strnEQ(cmd,PL_cshname,PL_cshlen) &&
1572 	    strnEQ(cmd+PL_cshlen," -c",3)) {
1573           my_strlcpy(flags, "-c", PERL_FLAGS_MAX);
1574 	  s = cmd+PL_cshlen+3;
1575 	  if (*s == 'f') {
1576 	      s++;
1577               my_strlcat(flags, "f", PERL_FLAGS_MAX - 2);
1578 	  }
1579 	  if (*s == ' ')
1580 	      s++;
1581 	  if (*s++ == '\'') {
1582 	      char * const ncmd = s;
1583 
1584 	      while (*s)
1585 		  s++;
1586 	      if (s[-1] == '\n')
1587 		  *--s = '\0';
1588 	      if (s[-1] == '\'') {
1589 		  *--s = '\0';
1590 		  PERL_FPU_PRE_EXEC
1591 		  PerlProc_execl(PL_cshname, "csh", flags, ncmd, (char*)NULL);
1592 		  PERL_FPU_POST_EXEC
1593 		  *s = '\'';
1594  		  S_exec_failed(aTHX_ PL_cshname, fd, do_report);
1595 		  Safefree(buf);
1596 		  return FALSE;
1597 	      }
1598 	  }
1599 	}
1600     }
1601 #endif /* CSH */
1602 
1603     /* see if there are shell metacharacters in it */
1604 
1605     if (*cmd == '.' && isSPACE(cmd[1]))
1606 	goto doshell;
1607 
1608     if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
1609 	goto doshell;
1610 
1611     s = cmd;
1612     while (isWORDCHAR(*s))
1613 	s++;	/* catch VAR=val gizmo */
1614     if (*s == '=')
1615 	goto doshell;
1616 
1617     for (s = cmd; *s; s++) {
1618 	if (*s != ' ' && !isALPHA(*s) &&
1619 	    strchr("$&*(){}[]'\";\\|?<>~`\n",*s)) {
1620 	    if (*s == '\n' && !s[1]) {
1621 		*s = '\0';
1622 		break;
1623 	    }
1624 	    /* handle the 2>&1 construct at the end */
1625 	    if (*s == '>' && s[1] == '&' && s[2] == '1'
1626 		&& s > cmd + 1 && s[-1] == '2' && isSPACE(s[-2])
1627 		&& (!s[3] || isSPACE(s[3])))
1628 	    {
1629                 const char *t = s + 3;
1630 
1631 		while (*t && isSPACE(*t))
1632 		    ++t;
1633 		if (!*t && (PerlLIO_dup2(1,2) != -1)) {
1634 		    s[-2] = '\0';
1635 		    break;
1636 		}
1637 	    }
1638 	  doshell:
1639 	    PERL_FPU_PRE_EXEC
1640 	    PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char *)NULL);
1641 	    PERL_FPU_POST_EXEC
1642  	    S_exec_failed(aTHX_ PL_sh_path, fd, do_report);
1643 	    Safefree(buf);
1644 	    return FALSE;
1645 	}
1646     }
1647 
1648     Newx(PL_Argv, (s - cmd) / 2 + 2, const char*);
1649     PL_Cmd = savepvn(cmd, s-cmd);
1650     a = PL_Argv;
1651     for (s = PL_Cmd; *s;) {
1652 	while (isSPACE(*s))
1653 	    s++;
1654 	if (*s)
1655 	    *(a++) = s;
1656 	while (*s && !isSPACE(*s))
1657 	    s++;
1658 	if (*s)
1659 	    *s++ = '\0';
1660     }
1661     *a = NULL;
1662     if (PL_Argv[0]) {
1663 	PERL_FPU_PRE_EXEC
1664 	PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
1665 	PERL_FPU_POST_EXEC
1666 	if (errno == ENOEXEC) {		/* for system V NIH syndrome */
1667 	    do_execfree();
1668 	    goto doshell;
1669 	}
1670  	S_exec_failed(aTHX_ PL_Argv[0], fd, do_report);
1671     }
1672     do_execfree();
1673     Safefree(buf);
1674     return FALSE;
1675 }
1676 
1677 #endif /* OS2 || WIN32 */
1678 
1679 #ifdef VMS
1680 #include <starlet.h> /* for sys$delprc */
1681 #endif
1682 
1683 I32
1684 Perl_apply(pTHX_ I32 type, SV **mark, SV **sp)
1685 {
1686     dVAR;
1687     I32 val;
1688     I32 tot = 0;
1689     const char *const what = PL_op_name[type];
1690     const char *s;
1691     STRLEN len;
1692     SV ** const oldmark = mark;
1693     bool killgp = FALSE;
1694 
1695     PERL_ARGS_ASSERT_APPLY;
1696 
1697     PERL_UNUSED_VAR(what); /* may not be used depending on compile options */
1698 
1699     /* Doing this ahead of the switch statement preserves the old behaviour,
1700        where attempting to use kill as a taint test test would fail on
1701        platforms where kill was not defined.  */
1702 #ifndef HAS_KILL
1703     if (type == OP_KILL)
1704 	Perl_die(aTHX_ PL_no_func, what);
1705 #endif
1706 #ifndef HAS_CHOWN
1707     if (type == OP_CHOWN)
1708 	Perl_die(aTHX_ PL_no_func, what);
1709 #endif
1710 
1711 
1712 #define APPLY_TAINT_PROPER() \
1713     STMT_START {							\
1714 	if (TAINT_get) { TAINT_PROPER(what); }				\
1715     } STMT_END
1716 
1717     /* This is a first heuristic; it doesn't catch tainting magic. */
1718     if (TAINTING_get) {
1719 	while (++mark <= sp) {
1720 	    if (SvTAINTED(*mark)) {
1721 		TAINT;
1722 		break;
1723 	    }
1724 	}
1725 	mark = oldmark;
1726     }
1727     switch (type) {
1728     case OP_CHMOD:
1729 	APPLY_TAINT_PROPER();
1730 	if (++mark <= sp) {
1731 	    val = SvIV(*mark);
1732 	    APPLY_TAINT_PROPER();
1733 	    tot = sp - mark;
1734 	    while (++mark <= sp) {
1735                 GV* gv;
1736                 if ((gv = MAYBE_DEREF_GV(*mark))) {
1737 		    if (GvIO(gv) && IoIFP(GvIOp(gv))) {
1738 #ifdef HAS_FCHMOD
1739 			APPLY_TAINT_PROPER();
1740 			if (fchmod(PerlIO_fileno(IoIFP(GvIOn(gv))), val))
1741 			    tot--;
1742 #else
1743 			Perl_die(aTHX_ PL_no_func, "fchmod");
1744 #endif
1745 		    }
1746 		    else {
1747 			tot--;
1748 		    }
1749 		}
1750 		else {
1751 		    const char *name = SvPV_nomg_const(*mark, len);
1752 		    APPLY_TAINT_PROPER();
1753                     if (!IS_SAFE_PATHNAME(name, len, "chmod") ||
1754                         PerlLIO_chmod(name, val)) {
1755                         tot--;
1756                     }
1757 		}
1758 	    }
1759 	}
1760 	break;
1761 #ifdef HAS_CHOWN
1762     case OP_CHOWN:
1763 	APPLY_TAINT_PROPER();
1764 	if (sp - mark > 2) {
1765             I32 val2;
1766 	    val = SvIVx(*++mark);
1767 	    val2 = SvIVx(*++mark);
1768 	    APPLY_TAINT_PROPER();
1769 	    tot = sp - mark;
1770 	    while (++mark <= sp) {
1771                 GV* gv;
1772 		if ((gv = MAYBE_DEREF_GV(*mark))) {
1773 		    if (GvIO(gv) && IoIFP(GvIOp(gv))) {
1774 #ifdef HAS_FCHOWN
1775 			APPLY_TAINT_PROPER();
1776 			if (fchown(PerlIO_fileno(IoIFP(GvIOn(gv))), val, val2))
1777 			    tot--;
1778 #else
1779 			Perl_die(aTHX_ PL_no_func, "fchown");
1780 #endif
1781 		    }
1782 		    else {
1783 			tot--;
1784 		    }
1785 		}
1786 		else {
1787 		    const char *name = SvPV_nomg_const(*mark, len);
1788 		    APPLY_TAINT_PROPER();
1789                     if (!IS_SAFE_PATHNAME(name, len, "chown") ||
1790                         PerlLIO_chown(name, val, val2)) {
1791 			tot--;
1792                     }
1793 		}
1794 	    }
1795 	}
1796 	break;
1797 #endif
1798 /*
1799 XXX Should we make lchown() directly available from perl?
1800 For now, we'll let Configure test for HAS_LCHOWN, but do
1801 nothing in the core.
1802     --AD  5/1998
1803 */
1804 #ifdef HAS_KILL
1805     case OP_KILL:
1806 	APPLY_TAINT_PROPER();
1807 	if (mark == sp)
1808 	    break;
1809 	s = SvPVx_const(*++mark, len);
1810 	if (*s == '-' && isALPHA(s[1]))
1811 	{
1812 	    s++;
1813 	    len--;
1814             killgp = TRUE;
1815 	}
1816 	if (isALPHA(*s)) {
1817 	    if (*s == 'S' && s[1] == 'I' && s[2] == 'G') {
1818 		s += 3;
1819                 len -= 3;
1820             }
1821            if ((val = whichsig_pvn(s, len)) < 0)
1822                Perl_croak(aTHX_ "Unrecognized signal name \"%"SVf"\"", SVfARG(*mark));
1823 	}
1824 	else
1825 	{
1826 	    val = SvIV(*mark);
1827 	    if (val < 0)
1828 	    {
1829 		killgp = TRUE;
1830                 val = -val;
1831 	    }
1832 	}
1833 	APPLY_TAINT_PROPER();
1834 	tot = sp - mark;
1835 #ifdef VMS
1836 	/* kill() doesn't do process groups (job trees?) under VMS */
1837 	if (val == SIGKILL) {
1838 	    /* Use native sys$delprc() to insure that target process is
1839 	     * deleted; supervisor-mode images don't pay attention to
1840 	     * CRTL's emulation of Unix-style signals and kill()
1841 	     */
1842 	    while (++mark <= sp) {
1843 		I32 proc;
1844 		unsigned long int __vmssts;
1845 		SvGETMAGIC(*mark);
1846 		if (!(SvIOK(*mark) || SvNOK(*mark) || looks_like_number(*mark)))
1847 		    Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
1848 		proc = SvIV_nomg(*mark);
1849 		APPLY_TAINT_PROPER();
1850 		if (!((__vmssts = sys$delprc(&proc,0)) & 1)) {
1851 		    tot--;
1852 		    switch (__vmssts) {
1853 			case SS$_NONEXPR:
1854 			case SS$_NOSUCHNODE:
1855 			    SETERRNO(ESRCH,__vmssts);
1856 			    break;
1857 			case SS$_NOPRIV:
1858 			    SETERRNO(EPERM,__vmssts);
1859 			    break;
1860 			default:
1861 			    SETERRNO(EVMSERR,__vmssts);
1862 		    }
1863 		}
1864 	    }
1865 	    PERL_ASYNC_CHECK();
1866 	    break;
1867 	}
1868 #endif
1869 	while (++mark <= sp) {
1870 	    Pid_t proc;
1871 	    SvGETMAGIC(*mark);
1872 	    if (!(SvNIOK(*mark) || looks_like_number(*mark)))
1873 		Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
1874 	    proc = SvIV_nomg(*mark);
1875 	    APPLY_TAINT_PROPER();
1876 #ifdef HAS_KILLPG
1877             /* use killpg in preference, as the killpg() wrapper for Win32
1878              * understands process groups, but the kill() wrapper doesn't */
1879             if (killgp ? PerlProc_killpg(proc, val)
1880                        : PerlProc_kill(proc, val))
1881 #else
1882             if (PerlProc_kill(killgp ? -proc: proc, val))
1883 #endif
1884 		tot--;
1885 	}
1886 	PERL_ASYNC_CHECK();
1887 	break;
1888 #endif
1889     case OP_UNLINK:
1890 	APPLY_TAINT_PROPER();
1891 	tot = sp - mark;
1892 	while (++mark <= sp) {
1893 	    s = SvPV_const(*mark, len);
1894 	    APPLY_TAINT_PROPER();
1895 	    if (!IS_SAFE_PATHNAME(s, len, "unlink")) {
1896                 tot--;
1897             }
1898 	    else if (PL_unsafe) {
1899 		if (UNLINK(s))
1900 		    tot--;
1901 	    }
1902 	    else {	/* don't let root wipe out directories without -U */
1903 		if (PerlLIO_lstat(s,&PL_statbuf) < 0)
1904 		    tot--;
1905 		else if (S_ISDIR(PL_statbuf.st_mode)) {
1906 		    tot--;
1907 		    SETERRNO(EISDIR, SS$_NOPRIV);
1908 		}
1909 		else {
1910 		    if (UNLINK(s))
1911 			tot--;
1912 		}
1913 	    }
1914 	}
1915 	break;
1916 #if defined(HAS_UTIME) || defined(HAS_FUTIMES)
1917     case OP_UTIME:
1918 	APPLY_TAINT_PROPER();
1919 	if (sp - mark > 2) {
1920 #if defined(HAS_FUTIMES)
1921 	    struct timeval utbuf[2];
1922 	    void *utbufp = utbuf;
1923 #elif defined(I_UTIME) || defined(VMS)
1924 	    struct utimbuf utbuf;
1925 	    struct utimbuf *utbufp = &utbuf;
1926 #else
1927 	    struct {
1928 		Time_t	actime;
1929 		Time_t	modtime;
1930 	    } utbuf;
1931 	    void *utbufp = &utbuf;
1932 #endif
1933 
1934 	   SV* const accessed = *++mark;
1935 	   SV* const modified = *++mark;
1936 
1937            /* Be like C, and if both times are undefined, let the C
1938             * library figure out what to do.  This usually means
1939             * "current time". */
1940 
1941            if ( accessed == &PL_sv_undef && modified == &PL_sv_undef )
1942                 utbufp = NULL;
1943            else {
1944                 Zero(&utbuf, sizeof utbuf, char);
1945 #ifdef HAS_FUTIMES
1946 		utbuf[0].tv_sec = (long)SvIV(accessed);  /* time accessed */
1947 		utbuf[0].tv_usec = 0;
1948 		utbuf[1].tv_sec = (long)SvIV(modified);  /* time modified */
1949 		utbuf[1].tv_usec = 0;
1950 #elif defined(BIG_TIME)
1951                 utbuf.actime = (Time_t)SvNV(accessed);  /* time accessed */
1952                 utbuf.modtime = (Time_t)SvNV(modified); /* time modified */
1953 #else
1954                 utbuf.actime = (Time_t)SvIV(accessed);  /* time accessed */
1955                 utbuf.modtime = (Time_t)SvIV(modified); /* time modified */
1956 #endif
1957             }
1958 	    APPLY_TAINT_PROPER();
1959 	    tot = sp - mark;
1960 	    while (++mark <= sp) {
1961                 GV* gv;
1962                 if ((gv = MAYBE_DEREF_GV(*mark))) {
1963 		    if (GvIO(gv) && IoIFP(GvIOp(gv))) {
1964 #ifdef HAS_FUTIMES
1965 			APPLY_TAINT_PROPER();
1966 			if (futimes(PerlIO_fileno(IoIFP(GvIOn(gv))),
1967                             (struct timeval *) utbufp))
1968 			    tot--;
1969 #else
1970 			Perl_die(aTHX_ PL_no_func, "futimes");
1971 #endif
1972 		    }
1973 		    else {
1974 			tot--;
1975 		    }
1976 		}
1977 		else {
1978 		    const char * const name = SvPV_nomg_const(*mark, len);
1979 		    APPLY_TAINT_PROPER();
1980 		    if (!IS_SAFE_PATHNAME(name, len, "utime")) {
1981                         tot--;
1982                     }
1983                     else
1984 #ifdef HAS_FUTIMES
1985 		    if (utimes(name, (struct timeval *)utbufp))
1986 #else
1987 		    if (PerlLIO_utime(name, utbufp))
1988 #endif
1989 			tot--;
1990 		}
1991 
1992 	    }
1993 	}
1994 	else
1995 	    tot = 0;
1996 	break;
1997 #endif
1998     }
1999     return tot;
2000 
2001 #undef APPLY_TAINT_PROPER
2002 }
2003 
2004 /* Do the permissions allow some operation?  Assumes statcache already set. */
2005 #ifndef VMS /* VMS' cando is in vms.c */
2006 bool
2007 Perl_cando(pTHX_ Mode_t mode, bool effective, const Stat_t *statbufp)
2008 /* effective is a flag, true for EUID, or for checking if the effective gid
2009  *  is in the list of groups returned from getgroups().
2010  */
2011 {
2012     dVAR;
2013 
2014     PERL_ARGS_ASSERT_CANDO;
2015 
2016 #ifdef DOSISH
2017     /* [Comments and code from Len Reed]
2018      * MS-DOS "user" is similar to UNIX's "superuser," but can't write
2019      * to write-protected files.  The execute permission bit is set
2020      * by the Microsoft C library stat() function for the following:
2021      *		.exe files
2022      *		.com files
2023      *		.bat files
2024      *		directories
2025      * All files and directories are readable.
2026      * Directories and special files, e.g. "CON", cannot be
2027      * write-protected.
2028      * [Comment by Tom Dinger -- a directory can have the write-protect
2029      *		bit set in the file system, but DOS permits changes to
2030      *		the directory anyway.  In addition, all bets are off
2031      *		here for networked software, such as Novell and
2032      *		Sun's PC-NFS.]
2033      */
2034 
2035      /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
2036       * too so it will actually look into the files for magic numbers
2037       */
2038      return (mode & statbufp->st_mode) ? TRUE : FALSE;
2039 
2040 #else /* ! DOSISH */
2041 # ifdef __CYGWIN__
2042     if (ingroup(544,effective)) {     /* member of Administrators */
2043 # else
2044     if ((effective ? PerlProc_geteuid() : PerlProc_getuid()) == 0) {	/* root is special */
2045 # endif
2046 	if (mode == S_IXUSR) {
2047 	    if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))
2048 		return TRUE;
2049 	}
2050 	else
2051 	    return TRUE;		/* root reads and writes anything */
2052 	return FALSE;
2053     }
2054     if (statbufp->st_uid == (effective ? PerlProc_geteuid() : PerlProc_getuid()) ) {
2055 	if (statbufp->st_mode & mode)
2056 	    return TRUE;	/* ok as "user" */
2057     }
2058     else if (ingroup(statbufp->st_gid,effective)) {
2059 	if (statbufp->st_mode & mode >> 3)
2060 	    return TRUE;	/* ok as "group" */
2061     }
2062     else if (statbufp->st_mode & mode >> 6)
2063 	return TRUE;	/* ok as "other" */
2064     return FALSE;
2065 #endif /* ! DOSISH */
2066 }
2067 #endif /* ! VMS */
2068 
2069 static bool
2070 S_ingroup(pTHX_ Gid_t testgid, bool effective)
2071 {
2072     dVAR;
2073     if (testgid == (effective ? PerlProc_getegid() : PerlProc_getgid()))
2074 	return TRUE;
2075 #ifdef HAS_GETGROUPS
2076     {
2077 	Groups_t *gary = NULL;
2078 	I32 anum;
2079         bool rc = FALSE;
2080 
2081 	anum = getgroups(0, gary);
2082         Newx(gary, anum, Groups_t);
2083         anum = getgroups(anum, gary);
2084 	while (--anum >= 0)
2085 	    if (gary[anum] == testgid) {
2086                 rc = TRUE;
2087                 break;
2088             }
2089 
2090         Safefree(gary);
2091         return rc;
2092     }
2093 #else
2094     return FALSE;
2095 #endif
2096 }
2097 
2098 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
2099 
2100 I32
2101 Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
2102 {
2103     dVAR;
2104     const key_t key = (key_t)SvNVx(*++mark);
2105     SV *nsv = optype == OP_MSGGET ? NULL : *++mark;
2106     const I32 flags = SvIVx(*++mark);
2107 
2108     PERL_ARGS_ASSERT_DO_IPCGET;
2109     PERL_UNUSED_ARG(sp);
2110 
2111     SETERRNO(0,0);
2112     switch (optype)
2113     {
2114 #ifdef HAS_MSG
2115     case OP_MSGGET:
2116 	return msgget(key, flags);
2117 #endif
2118 #ifdef HAS_SEM
2119     case OP_SEMGET:
2120 	return semget(key, (int) SvIV(nsv), flags);
2121 #endif
2122 #ifdef HAS_SHM
2123     case OP_SHMGET:
2124 	return shmget(key, (size_t) SvUV(nsv), flags);
2125 #endif
2126 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
2127     default:
2128         /* diag_listed_as: msg%s not implemented */
2129 	Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2130 #endif
2131     }
2132     return -1;			/* should never happen */
2133 }
2134 
2135 I32
2136 Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
2137 {
2138     dVAR;
2139     char *a;
2140     I32 ret = -1;
2141     const I32 id  = SvIVx(*++mark);
2142 #ifdef Semctl
2143     const I32 n   = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
2144 #endif
2145     const I32 cmd = SvIVx(*++mark);
2146     SV * const astr = *++mark;
2147     STRLEN infosize = 0;
2148     I32 getinfo = (cmd == IPC_STAT);
2149 
2150     PERL_ARGS_ASSERT_DO_IPCCTL;
2151     PERL_UNUSED_ARG(sp);
2152 
2153     switch (optype)
2154     {
2155 #ifdef HAS_MSG
2156     case OP_MSGCTL:
2157 	if (cmd == IPC_STAT || cmd == IPC_SET)
2158 	    infosize = sizeof(struct msqid_ds);
2159 	break;
2160 #endif
2161 #ifdef HAS_SHM
2162     case OP_SHMCTL:
2163 	if (cmd == IPC_STAT || cmd == IPC_SET)
2164 	    infosize = sizeof(struct shmid_ds);
2165 	break;
2166 #endif
2167 #ifdef HAS_SEM
2168     case OP_SEMCTL:
2169 #ifdef Semctl
2170 	if (cmd == IPC_STAT || cmd == IPC_SET)
2171 	    infosize = sizeof(struct semid_ds);
2172 	else if (cmd == GETALL || cmd == SETALL)
2173 	{
2174 	    struct semid_ds semds;
2175 	    union semun semun;
2176 #ifdef EXTRA_F_IN_SEMUN_BUF
2177             semun.buff = &semds;
2178 #else
2179             semun.buf = &semds;
2180 #endif
2181 	    getinfo = (cmd == GETALL);
2182 	    if (Semctl(id, 0, IPC_STAT, semun) == -1)
2183 		return -1;
2184 	    infosize = semds.sem_nsems * sizeof(short);
2185 		/* "short" is technically wrong but much more portable
2186 		   than guessing about u_?short(_t)? */
2187 	}
2188 #else
2189         /* diag_listed_as: sem%s not implemented */
2190 	Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2191 #endif
2192 	break;
2193 #endif
2194 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
2195     default:
2196         /* diag_listed_as: shm%s not implemented */
2197 	Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2198 #endif
2199     }
2200 
2201     if (infosize)
2202     {
2203 	if (getinfo)
2204 	{
2205 	    SvPV_force_nolen(astr);
2206 	    a = SvGROW(astr, infosize+1);
2207 	}
2208 	else
2209 	{
2210 	    STRLEN len;
2211 	    a = SvPV(astr, len);
2212 	    if (len != infosize)
2213 		Perl_croak(aTHX_ "Bad arg length for %s, is %lu, should be %ld",
2214 		      PL_op_desc[optype],
2215 		      (unsigned long)len,
2216 		      (long)infosize);
2217 	}
2218     }
2219     else
2220     {
2221 	const IV i = SvIV(astr);
2222 	a = INT2PTR(char *,i);		/* ouch */
2223     }
2224     SETERRNO(0,0);
2225     switch (optype)
2226     {
2227 #ifdef HAS_MSG
2228     case OP_MSGCTL:
2229 	ret = msgctl(id, cmd, (struct msqid_ds *)a);
2230 	break;
2231 #endif
2232 #ifdef HAS_SEM
2233     case OP_SEMCTL: {
2234 #ifdef Semctl
2235             union semun unsemds;
2236 
2237             if(cmd == SETVAL) {
2238                 unsemds.val = PTR2nat(a);
2239             }
2240             else {
2241 #ifdef EXTRA_F_IN_SEMUN_BUF
2242                 unsemds.buff = (struct semid_ds *)a;
2243 #else
2244                 unsemds.buf = (struct semid_ds *)a;
2245 #endif
2246             }
2247 	    ret = Semctl(id, n, cmd, unsemds);
2248 #else
2249 	    /* diag_listed_as: sem%s not implemented */
2250 	    Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2251 #endif
2252         }
2253 	break;
2254 #endif
2255 #ifdef HAS_SHM
2256     case OP_SHMCTL:
2257 	ret = shmctl(id, cmd, (struct shmid_ds *)a);
2258 	break;
2259 #endif
2260     }
2261     if (getinfo && ret >= 0) {
2262 	SvCUR_set(astr, infosize);
2263 	*SvEND(astr) = '\0';
2264 	SvSETMAGIC(astr);
2265     }
2266     return ret;
2267 }
2268 
2269 I32
2270 Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
2271 {
2272     dVAR;
2273 #ifdef HAS_MSG
2274     STRLEN len;
2275     const I32 id = SvIVx(*++mark);
2276     SV * const mstr = *++mark;
2277     const I32 flags = SvIVx(*++mark);
2278     const char * const mbuf = SvPV_const(mstr, len);
2279     const I32 msize = len - sizeof(long);
2280 
2281     PERL_ARGS_ASSERT_DO_MSGSND;
2282     PERL_UNUSED_ARG(sp);
2283 
2284     if (msize < 0)
2285 	Perl_croak(aTHX_ "Arg too short for msgsnd");
2286     SETERRNO(0,0);
2287     return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
2288 #else
2289     PERL_UNUSED_ARG(sp);
2290     PERL_UNUSED_ARG(mark);
2291     /* diag_listed_as: msg%s not implemented */
2292     Perl_croak(aTHX_ "msgsnd not implemented");
2293     return -1;
2294 #endif
2295 }
2296 
2297 I32
2298 Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
2299 {
2300 #ifdef HAS_MSG
2301     dVAR;
2302     char *mbuf;
2303     long mtype;
2304     I32 msize, flags, ret;
2305     const I32 id = SvIVx(*++mark);
2306     SV * const mstr = *++mark;
2307 
2308     PERL_ARGS_ASSERT_DO_MSGRCV;
2309     PERL_UNUSED_ARG(sp);
2310 
2311     /* suppress warning when reading into undef var --jhi */
2312     if (! SvOK(mstr))
2313 	sv_setpvs(mstr, "");
2314     msize = SvIVx(*++mark);
2315     mtype = (long)SvIVx(*++mark);
2316     flags = SvIVx(*++mark);
2317     SvPV_force_nolen(mstr);
2318     mbuf = SvGROW(mstr, sizeof(long)+msize+1);
2319 
2320     SETERRNO(0,0);
2321     ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
2322     if (ret >= 0) {
2323 	SvCUR_set(mstr, sizeof(long)+ret);
2324 	*SvEND(mstr) = '\0';
2325 	/* who knows who has been playing with this message? */
2326 	SvTAINTED_on(mstr);
2327     }
2328     return ret;
2329 #else
2330     PERL_UNUSED_ARG(sp);
2331     PERL_UNUSED_ARG(mark);
2332     /* diag_listed_as: msg%s not implemented */
2333     Perl_croak(aTHX_ "msgrcv not implemented");
2334     return -1;
2335 #endif
2336 }
2337 
2338 I32
2339 Perl_do_semop(pTHX_ SV **mark, SV **sp)
2340 {
2341 #ifdef HAS_SEM
2342     dVAR;
2343     STRLEN opsize;
2344     const I32 id = SvIVx(*++mark);
2345     SV * const opstr = *++mark;
2346     const char * const opbuf = SvPV_const(opstr, opsize);
2347 
2348     PERL_ARGS_ASSERT_DO_SEMOP;
2349     PERL_UNUSED_ARG(sp);
2350 
2351     if (opsize < 3 * SHORTSIZE
2352 	|| (opsize % (3 * SHORTSIZE))) {
2353 	SETERRNO(EINVAL,LIB_INVARG);
2354 	return -1;
2355     }
2356     SETERRNO(0,0);
2357     /* We can't assume that sizeof(struct sembuf) == 3 * sizeof(short). */
2358     {
2359         const int nsops  = opsize / (3 * sizeof (short));
2360         int i      = nsops;
2361         short * const ops = (short *) opbuf;
2362         short *o   = ops;
2363         struct sembuf *temps, *t;
2364         I32 result;
2365 
2366         Newx (temps, nsops, struct sembuf);
2367         t = temps;
2368         while (i--) {
2369             t->sem_num = *o++;
2370             t->sem_op  = *o++;
2371             t->sem_flg = *o++;
2372             t++;
2373         }
2374         result = semop(id, temps, nsops);
2375         Safefree(temps);
2376         return result;
2377     }
2378 #else
2379     /* diag_listed_as: sem%s not implemented */
2380     Perl_croak(aTHX_ "semop not implemented");
2381 #endif
2382 }
2383 
2384 I32
2385 Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
2386 {
2387 #ifdef HAS_SHM
2388     dVAR;
2389     char *shm;
2390     struct shmid_ds shmds;
2391     const I32 id = SvIVx(*++mark);
2392     SV * const mstr = *++mark;
2393     const I32 mpos = SvIVx(*++mark);
2394     const I32 msize = SvIVx(*++mark);
2395 
2396     PERL_ARGS_ASSERT_DO_SHMIO;
2397     PERL_UNUSED_ARG(sp);
2398 
2399     SETERRNO(0,0);
2400     if (shmctl(id, IPC_STAT, &shmds) == -1)
2401 	return -1;
2402     if (mpos < 0 || msize < 0
2403 	|| (size_t)mpos + msize > (size_t)shmds.shm_segsz) {
2404 	SETERRNO(EFAULT,SS_ACCVIO);		/* can't do as caller requested */
2405 	return -1;
2406     }
2407     shm = (char *)shmat(id, NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
2408     if (shm == (char *)-1)	/* I hate System V IPC, I really do */
2409 	return -1;
2410     if (optype == OP_SHMREAD) {
2411 	char *mbuf;
2412 	/* suppress warning when reading into undef var (tchrist 3/Mar/00) */
2413 	SvGETMAGIC(mstr);
2414 	SvUPGRADE(mstr, SVt_PV);
2415 	if (! SvOK(mstr))
2416 	    sv_setpvs(mstr, "");
2417 	SvPOK_only(mstr);
2418 	mbuf = SvGROW(mstr, (STRLEN)msize+1);
2419 
2420 	Copy(shm + mpos, mbuf, msize, char);
2421 	SvCUR_set(mstr, msize);
2422 	*SvEND(mstr) = '\0';
2423 	SvSETMAGIC(mstr);
2424 	/* who knows who has been playing with this shared memory? */
2425 	SvTAINTED_on(mstr);
2426     }
2427     else {
2428 	STRLEN len;
2429 
2430 	const char *mbuf = SvPV_const(mstr, len);
2431 	const I32 n = ((I32)len > msize) ? msize : (I32)len;
2432 	Copy(mbuf, shm + mpos, n, char);
2433 	if (n < msize)
2434 	    memzero(shm + mpos + n, msize - n);
2435     }
2436     return shmdt(shm);
2437 #else
2438     /* diag_listed_as: shm%s not implemented */
2439     Perl_croak(aTHX_ "shm I/O not implemented");
2440     return -1;
2441 #endif
2442 }
2443 
2444 #endif /* SYSV IPC */
2445 
2446 /*
2447 =head1 IO Functions
2448 
2449 =for apidoc start_glob
2450 
2451 Function called by C<do_readline> to spawn a glob (or do the glob inside
2452 perl on VMS).  This code used to be inline, but now perl uses C<File::Glob>
2453 this glob starter is only used by miniperl during the build process.
2454 Moving it away shrinks pp_hot.c; shrinking pp_hot.c helps speed perl up.
2455 
2456 =cut
2457 */
2458 
2459 PerlIO *
2460 Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
2461 {
2462     dVAR;
2463     SV * const tmpcmd = newSV(0);
2464     PerlIO *fp;
2465     STRLEN len;
2466     const char *s = SvPV(tmpglob, len);
2467 
2468     PERL_ARGS_ASSERT_START_GLOB;
2469 
2470     if (!IS_SAFE_SYSCALL(s, len, "pattern", "glob"))
2471         return NULL;
2472 
2473     ENTER;
2474     SAVEFREESV(tmpcmd);
2475 #ifdef VMS /* expand the wildcards right here, rather than opening a pipe, */
2476            /* since spawning off a process is a real performance hit */
2477 
2478 PerlIO *
2479 Perl_vms_start_glob
2480    (pTHX_ SV *tmpglob,
2481     IO *io);
2482 
2483     fp = Perl_vms_start_glob(aTHX_ tmpglob, io);
2484 
2485 #else /* !VMS */
2486 #ifdef DOSISH
2487 #ifdef OS2
2488     sv_setpv(tmpcmd, "for a in ");
2489     sv_catsv(tmpcmd, tmpglob);
2490     sv_catpv(tmpcmd, "; do echo \"$a\\0\\c\"; done |");
2491 #else
2492 #ifdef DJGPP
2493     sv_setpv(tmpcmd, "/dev/dosglob/"); /* File System Extension */
2494     sv_catsv(tmpcmd, tmpglob);
2495 #else
2496     sv_setpv(tmpcmd, "perlglob ");
2497     sv_catsv(tmpcmd, tmpglob);
2498     sv_catpv(tmpcmd, " |");
2499 #endif /* !DJGPP */
2500 #endif /* !OS2 */
2501 #else /* !DOSISH */
2502 #if defined(CSH)
2503     sv_setpvn(tmpcmd, PL_cshname, PL_cshlen);
2504     sv_catpv(tmpcmd, " -cf 'set nonomatch; glob ");
2505     sv_catsv(tmpcmd, tmpglob);
2506     sv_catpv(tmpcmd, "' 2>/dev/null |");
2507 #else
2508     sv_setpv(tmpcmd, "echo ");
2509     sv_catsv(tmpcmd, tmpglob);
2510     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|");
2511 #endif /* !CSH */
2512 #endif /* !DOSISH */
2513     {
2514 	GV * const envgv = gv_fetchpvs("ENV", 0, SVt_PVHV);
2515 	SV ** const home = hv_fetchs(GvHV(envgv), "HOME", 0);
2516 	SV ** const path = hv_fetchs(GvHV(envgv), "PATH", 0);
2517 	if (home && *home) SvGETMAGIC(*home);
2518 	if (path && *path) SvGETMAGIC(*path);
2519 	save_hash(gv_fetchpvs("ENV", 0, SVt_PVHV));
2520 	if (home && *home) SvSETMAGIC(*home);
2521 	if (path && *path) SvSETMAGIC(*path);
2522     }
2523     (void)do_open6(PL_last_in_gv, SvPVX_const(tmpcmd), SvCUR(tmpcmd),
2524                    NULL, NULL, 0);
2525     fp = IoIFP(io);
2526 #endif /* !VMS */
2527     LEAVE;
2528 
2529     if (!fp && ckWARN(WARN_GLOB)) {
2530         Perl_warner(aTHX_ packWARN(WARN_GLOB), "glob failed (can't start child: %s)",
2531                     Strerror(errno));
2532     }
2533 
2534     return fp;
2535 }
2536 
2537 /*
2538  * Local variables:
2539  * c-indentation-style: bsd
2540  * c-basic-offset: 4
2541  * indent-tabs-mode: nil
2542  * End:
2543  *
2544  * ex: set ts=8 sts=4 sw=4 et:
2545  */
2546