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