This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix PerlLIO_chsize() for platforms that don't have chsize()
[perl5.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)
1246 I32 my_chsize(fd, length)
1247 I32 fd;                 /* file descriptor */
1248 Off_t length;           /* length to set file to */
1249 {
1250 #ifdef F_FREESP
1251         /* code courtesy of William Kucharski */
1252 #define HAS_CHSIZE
1253
1254     struct flock fl;
1255     Stat_t filebuf;
1256
1257     if (PerlLIO_fstat(fd, &filebuf) < 0)
1258         return -1;
1259
1260     if (filebuf.st_size < length) {
1261
1262         /* extend file length */
1263
1264         if ((PerlLIO_lseek(fd, (length - 1), 0)) < 0)
1265             return -1;
1266
1267         /* write a "0" byte */
1268
1269         if ((PerlLIO_write(fd, "", 1)) != 1)
1270             return -1;
1271     }
1272     else {
1273         /* truncate length */
1274
1275         fl.l_whence = 0;
1276         fl.l_len = 0;
1277         fl.l_start = length;
1278         fl.l_type = F_WRLCK;    /* write lock on file space */
1279
1280         /*
1281         * This relies on the UNDOCUMENTED F_FREESP argument to
1282         * fcntl(2), which truncates the file so that it ends at the
1283         * position indicated by fl.l_start.
1284         *
1285         * Will minor miracles never cease?
1286         */
1287
1288         if (fcntl(fd, F_FREESP, &fl) < 0)
1289             return -1;
1290
1291     }
1292
1293     return 0;
1294 #else
1295     dTHX;
1296     DIE(aTHX_ "truncate not implemented");
1297 #endif /* F_FREESP */
1298 }
1299 #endif /* !HAS_TRUNCATE && !HAS_CHSIZE */
1300
1301 bool
1302 Perl_do_print(pTHX_ register SV *sv, PerlIO *fp)
1303 {
1304     register const char *tmps;
1305     STRLEN len;
1306
1307     /* assuming fp is checked earlier */
1308     if (!sv)
1309         return TRUE;
1310     if (PL_ofmt) {
1311         if (SvGMAGICAL(sv))
1312             mg_get(sv);
1313         if (SvIOK(sv) && SvIVX(sv) != 0) {
1314             PerlIO_printf(fp, PL_ofmt, (NV)SvIVX(sv));
1315             return !PerlIO_error(fp);
1316         }
1317         if (  (SvNOK(sv) && SvNVX(sv) != 0.0)
1318            || (looks_like_number(sv) && sv_2nv(sv) != 0.0) ) {
1319             PerlIO_printf(fp, PL_ofmt, SvNVX(sv));
1320             return !PerlIO_error(fp);
1321         }
1322     }
1323     switch (SvTYPE(sv)) {
1324     case SVt_NULL:
1325         if (ckWARN(WARN_UNINITIALIZED))
1326             report_uninit(sv);
1327         return TRUE;
1328     case SVt_IV:
1329         if (SvIOK(sv)) {
1330             if (SvGMAGICAL(sv))
1331                 mg_get(sv);
1332             if (SvIsUV(sv))
1333                 PerlIO_printf(fp, "%"UVuf, (UV)SvUVX(sv));
1334             else
1335                 PerlIO_printf(fp, "%"IVdf, (IV)SvIVX(sv));
1336             return !PerlIO_error(fp);
1337         }
1338         /* FALL THROUGH */
1339     default:
1340         if (PerlIO_isutf8(fp)) {
1341             if (!SvUTF8(sv))
1342                 sv_utf8_upgrade_flags(sv = sv_mortalcopy(sv),
1343                                       SV_GMAGIC|SV_UTF8_NO_ENCODING);
1344         }
1345         else if (DO_UTF8(sv)) {
1346             if (!sv_utf8_downgrade((sv = sv_mortalcopy(sv)), TRUE)
1347                 && ckWARN_d(WARN_UTF8))
1348             {
1349                 Perl_warner(aTHX_ packWARN(WARN_UTF8), "Wide character in print");
1350             }
1351         }
1352         tmps = SvPV(sv, len);
1353         break;
1354     }
1355     /* To detect whether the process is about to overstep its
1356      * filesize limit we would need getrlimit().  We could then
1357      * also transparently raise the limit with setrlimit() --
1358      * but only until the system hard limit/the filesystem limit,
1359      * at which we would get EPERM.  Note that when using buffered
1360      * io the write failure can be delayed until the flush/close. --jhi */
1361     if (len && (PerlIO_write(fp,tmps,len) == 0))
1362         return FALSE;
1363     return !PerlIO_error(fp);
1364 }
1365
1366 I32
1367 Perl_my_stat(pTHX)
1368 {
1369     dSP;
1370     IO *io;
1371     GV* gv;
1372
1373     if (PL_op->op_flags & OPf_REF) {
1374         EXTEND(SP,1);
1375         gv = cGVOP_gv;
1376       do_fstat:
1377         io = GvIO(gv);
1378         if (io && IoIFP(io)) {
1379             PL_statgv = gv;
1380             sv_setpv(PL_statname,"");
1381             PL_laststype = OP_STAT;
1382             return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache));
1383         }
1384         else {
1385             if (gv == PL_defgv)
1386                 return PL_laststatval;
1387             if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1388                 report_evil_fh(gv, io, PL_op->op_type);
1389             PL_statgv = Nullgv;
1390             sv_setpv(PL_statname,"");
1391             return (PL_laststatval = -1);
1392         }
1393     }
1394     else if (PL_op->op_private & OPpFT_STACKED) {
1395         return PL_laststatval;
1396     }
1397     else {
1398         SV* sv = POPs;
1399         char *s;
1400         STRLEN len;
1401         PUTBACK;
1402         if (SvTYPE(sv) == SVt_PVGV) {
1403             gv = (GV*)sv;
1404             goto do_fstat;
1405         }
1406         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
1407             gv = (GV*)SvRV(sv);
1408             goto do_fstat;
1409         }
1410
1411         s = SvPV(sv, len);
1412         PL_statgv = Nullgv;
1413         sv_setpvn(PL_statname, s, len);
1414         s = SvPVX(PL_statname);         /* s now NUL-terminated */
1415         PL_laststype = OP_STAT;
1416         PL_laststatval = PerlLIO_stat(s, &PL_statcache);
1417         if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(s, '\n'))
1418             Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
1419         return PL_laststatval;
1420     }
1421 }
1422
1423 static char no_prev_lstat[] = "The stat preceding -l _ wasn't an lstat";
1424
1425 I32
1426 Perl_my_lstat(pTHX)
1427 {
1428     dSP;
1429     SV *sv;
1430     STRLEN n_a;
1431     if (PL_op->op_flags & OPf_REF) {
1432         EXTEND(SP,1);
1433         if (cGVOP_gv == PL_defgv) {
1434             if (PL_laststype != OP_LSTAT)
1435                 Perl_croak(aTHX_ no_prev_lstat);
1436             return PL_laststatval;
1437         }
1438         if (ckWARN(WARN_IO)) {
1439             Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1440                     GvENAME(cGVOP_gv));
1441             return (PL_laststatval = -1);
1442         }
1443     }
1444     else if (ckWARN(WARN_IO) && PL_laststype != OP_LSTAT
1445             && (PL_op->op_private & OPpFT_STACKED))
1446         Perl_croak(aTHX_ no_prev_lstat);
1447
1448     PL_laststype = OP_LSTAT;
1449     PL_statgv = Nullgv;
1450     sv = POPs;
1451     PUTBACK;
1452     if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV && ckWARN(WARN_IO)) {
1453         Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1454                 GvENAME((GV*) SvRV(sv)));
1455         return (PL_laststatval = -1);
1456     }
1457     sv_setpv(PL_statname,SvPV(sv, n_a));
1458     PL_laststatval = PerlLIO_lstat(SvPV(sv, n_a),&PL_statcache);
1459     if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(SvPV(sv, n_a), '\n'))
1460         Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
1461     return PL_laststatval;
1462 }
1463
1464 #ifndef OS2
1465 bool
1466 Perl_do_aexec(pTHX_ SV *really, register SV **mark, register SV **sp)
1467 {
1468     return do_aexec5(really, mark, sp, 0, 0);
1469 }
1470 #endif
1471
1472 bool
1473 Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
1474                int fd, int do_report)
1475 {
1476 #ifdef MACOS_TRADITIONAL
1477     Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
1478 #else
1479     register char **a;
1480     const char *tmps = Nullch;
1481     STRLEN n_a;
1482
1483     if (sp > mark) {
1484         New(401,PL_Argv, sp - mark + 1, char*);
1485         a = PL_Argv;
1486         while (++mark <= sp) {
1487             if (*mark)
1488                 *a++ = SvPVx(*mark, n_a);
1489             else
1490                 *a++ = "";
1491         }
1492         *a = Nullch;
1493         if (really)
1494             tmps = SvPV(really, n_a);
1495         if ((!really && *PL_Argv[0] != '/') ||
1496             (really && *tmps != '/'))           /* will execvp use PATH? */
1497             TAINT_ENV();                /* testing IFS here is overkill, probably */
1498         PERL_FPU_PRE_EXEC
1499         if (really && *tmps)
1500             PerlProc_execvp(tmps,EXEC_ARGV_CAST(PL_Argv));
1501         else
1502             PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
1503         PERL_FPU_POST_EXEC
1504         if (ckWARN(WARN_EXEC))
1505             Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
1506                 (really ? tmps : PL_Argv[0]), Strerror(errno));
1507         if (do_report) {
1508             int e = errno;
1509
1510             PerlLIO_write(fd, (void*)&e, sizeof(int));
1511             PerlLIO_close(fd);
1512         }
1513     }
1514     do_execfree();
1515 #endif
1516     return FALSE;
1517 }
1518
1519 void
1520 Perl_do_execfree(pTHX)
1521 {
1522     if (PL_Argv) {
1523         Safefree(PL_Argv);
1524         PL_Argv = Null(char **);
1525     }
1526     if (PL_Cmd) {
1527         Safefree(PL_Cmd);
1528         PL_Cmd = Nullch;
1529     }
1530 }
1531
1532 #if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
1533
1534 bool
1535 Perl_do_exec(pTHX_ char *cmd)
1536 {
1537     return do_exec3(cmd,0,0);
1538 }
1539
1540 bool
1541 Perl_do_exec3(pTHX_ char *cmd, int fd, int do_report)
1542 {
1543     register char **a;
1544     register char *s;
1545
1546     while (*cmd && isSPACE(*cmd))
1547         cmd++;
1548
1549     /* save an extra exec if possible */
1550
1551 #ifdef CSH
1552     {
1553         char flags[PERL_FLAGS_MAX];
1554         if (strnEQ(cmd,PL_cshname,PL_cshlen) &&
1555             strnEQ(cmd+PL_cshlen," -c",3)) {
1556 #ifdef HAS_STRLCPY
1557           strlcpy(flags, "-c", PERL_FLAGS_MAX);
1558 #else
1559           strcpy(flags,"-c");
1560 #endif
1561           s = cmd+PL_cshlen+3;
1562           if (*s == 'f') {
1563               s++;
1564 #ifdef HAS_STRLCPY
1565               strlcat(flags, "f", PERL_FLAGS_MAX);
1566 #else
1567               strcat(flags,"f");
1568 #endif
1569           }
1570           if (*s == ' ')
1571               s++;
1572           if (*s++ == '\'') {
1573               char *ncmd = s;
1574
1575               while (*s)
1576                   s++;
1577               if (s[-1] == '\n')
1578                   *--s = '\0';
1579               if (s[-1] == '\'') {
1580                   *--s = '\0';
1581                   PERL_FPU_PRE_EXEC
1582                   PerlProc_execl(PL_cshname,"csh", flags, ncmd, (char*)0);
1583                   PERL_FPU_POST_EXEC
1584                   *s = '\'';
1585                   return FALSE;
1586               }
1587           }
1588         }
1589     }
1590 #endif /* CSH */
1591
1592     /* see if there are shell metacharacters in it */
1593
1594     if (*cmd == '.' && isSPACE(cmd[1]))
1595         goto doshell;
1596
1597     if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
1598         goto doshell;
1599
1600     for (s = cmd; *s && isALNUM(*s); s++) ;     /* catch VAR=val gizmo */
1601     if (*s == '=')
1602         goto doshell;
1603
1604     for (s = cmd; *s; s++) {
1605         if (*s != ' ' && !isALPHA(*s) &&
1606             strchr("$&*(){}[]'\";\\|?<>~`\n",*s)) {
1607             if (*s == '\n' && !s[1]) {
1608                 *s = '\0';
1609                 break;
1610             }
1611             /* handle the 2>&1 construct at the end */
1612             if (*s == '>' && s[1] == '&' && s[2] == '1'
1613                 && s > cmd + 1 && s[-1] == '2' && isSPACE(s[-2])
1614                 && (!s[3] || isSPACE(s[3])))
1615             {
1616                 char *t = s + 3;
1617
1618                 while (*t && isSPACE(*t))
1619                     ++t;
1620                 if (!*t && (PerlLIO_dup2(1,2) != -1)) {
1621                     s[-2] = '\0';
1622                     break;
1623                 }
1624             }
1625           doshell:
1626             PERL_FPU_PRE_EXEC
1627             PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char*)0);
1628             PERL_FPU_POST_EXEC
1629             return FALSE;
1630         }
1631     }
1632
1633     New(402,PL_Argv, (s - cmd) / 2 + 2, char*);
1634     PL_Cmd = savepvn(cmd, s-cmd);
1635     a = PL_Argv;
1636     for (s = PL_Cmd; *s;) {
1637         while (*s && isSPACE(*s)) s++;
1638         if (*s)
1639             *(a++) = s;
1640         while (*s && !isSPACE(*s)) s++;
1641         if (*s)
1642             *s++ = '\0';
1643     }
1644     *a = Nullch;
1645     if (PL_Argv[0]) {
1646         PERL_FPU_PRE_EXEC
1647         PerlProc_execvp(PL_Argv[0],PL_Argv);
1648         PERL_FPU_POST_EXEC
1649         if (errno == ENOEXEC) {         /* for system V NIH syndrome */
1650             do_execfree();
1651             goto doshell;
1652         }
1653         {
1654             int e = errno;
1655
1656             if (ckWARN(WARN_EXEC))
1657                 Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
1658                     PL_Argv[0], Strerror(errno));
1659             if (do_report) {
1660                 PerlLIO_write(fd, (void*)&e, sizeof(int));
1661                 PerlLIO_close(fd);
1662             }
1663         }
1664     }
1665     do_execfree();
1666     return FALSE;
1667 }
1668
1669 #endif /* OS2 || WIN32 */
1670
1671 I32
1672 Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
1673 {
1674     register I32 val;
1675     register I32 val2;
1676     register I32 tot = 0;
1677     const char *what;
1678     char *s;
1679     SV **oldmark = mark;
1680     STRLEN n_a;
1681
1682 #define APPLY_TAINT_PROPER() \
1683     STMT_START {                                                        \
1684         if (PL_tainted) { TAINT_PROPER(what); }                         \
1685     } STMT_END
1686
1687     /* This is a first heuristic; it doesn't catch tainting magic. */
1688     if (PL_tainting) {
1689         while (++mark <= sp) {
1690             if (SvTAINTED(*mark)) {
1691                 TAINT;
1692                 break;
1693             }
1694         }
1695         mark = oldmark;
1696     }
1697     switch (type) {
1698     case OP_CHMOD:
1699         what = "chmod";
1700         APPLY_TAINT_PROPER();
1701         if (++mark <= sp) {
1702             val = SvIVx(*mark);
1703             APPLY_TAINT_PROPER();
1704             tot = sp - mark;
1705             while (++mark <= sp) {
1706                 char *name = SvPVx(*mark, n_a);
1707                 APPLY_TAINT_PROPER();
1708                 if (PerlLIO_chmod(name, val))
1709                     tot--;
1710             }
1711         }
1712         break;
1713 #ifdef HAS_CHOWN
1714     case OP_CHOWN:
1715         what = "chown";
1716         APPLY_TAINT_PROPER();
1717         if (sp - mark > 2) {
1718             val = SvIVx(*++mark);
1719             val2 = SvIVx(*++mark);
1720             APPLY_TAINT_PROPER();
1721             tot = sp - mark;
1722             while (++mark <= sp) {
1723                 char *name = SvPVx(*mark, n_a);
1724                 APPLY_TAINT_PROPER();
1725                 if (PerlLIO_chown(name, val, val2))
1726                     tot--;
1727             }
1728         }
1729         break;
1730 #endif
1731 /*
1732 XXX Should we make lchown() directly available from perl?
1733 For now, we'll let Configure test for HAS_LCHOWN, but do
1734 nothing in the core.
1735     --AD  5/1998
1736 */
1737 #ifdef HAS_KILL
1738     case OP_KILL:
1739         what = "kill";
1740         APPLY_TAINT_PROPER();
1741         if (mark == sp)
1742             break;
1743         s = SvPVx(*++mark, n_a);
1744         if (isALPHA(*s)) {
1745             if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1746                 s += 3;
1747             if ((val = whichsig(s)) < 0)
1748                 Perl_croak(aTHX_ "Unrecognized signal name \"%s\"",s);
1749         }
1750         else
1751             val = SvIVx(*mark);
1752         APPLY_TAINT_PROPER();
1753         tot = sp - mark;
1754 #ifdef VMS
1755         /* kill() doesn't do process groups (job trees?) under VMS */
1756         if (val < 0) val = -val;
1757         if (val == SIGKILL) {
1758 #           include <starlet.h>
1759             /* Use native sys$delprc() to insure that target process is
1760              * deleted; supervisor-mode images don't pay attention to
1761              * CRTL's emulation of Unix-style signals and kill()
1762              */
1763             while (++mark <= sp) {
1764                 I32 proc = SvIVx(*mark);
1765                 register unsigned long int __vmssts;
1766                 APPLY_TAINT_PROPER();
1767                 if (!((__vmssts = sys$delprc(&proc,0)) & 1)) {
1768                     tot--;
1769                     switch (__vmssts) {
1770                         case SS$_NONEXPR:
1771                         case SS$_NOSUCHNODE:
1772                             SETERRNO(ESRCH,__vmssts);
1773                             break;
1774                         case SS$_NOPRIV:
1775                             SETERRNO(EPERM,__vmssts);
1776                             break;
1777                         default:
1778                             SETERRNO(EVMSERR,__vmssts);
1779                     }
1780                 }
1781             }
1782             break;
1783         }
1784 #endif
1785         if (val < 0) {
1786             val = -val;
1787             while (++mark <= sp) {
1788                 I32 proc = SvIVx(*mark);
1789                 APPLY_TAINT_PROPER();
1790 #ifdef HAS_KILLPG
1791                 if (PerlProc_killpg(proc,val))  /* BSD */
1792 #else
1793                 if (PerlProc_kill(-proc,val))   /* SYSV */
1794 #endif
1795                     tot--;
1796             }
1797         }
1798         else {
1799             while (++mark <= sp) {
1800                 I32 proc = SvIVx(*mark);
1801                 APPLY_TAINT_PROPER();
1802                 if (PerlProc_kill(proc, val))
1803                     tot--;
1804             }
1805         }
1806         break;
1807 #endif
1808     case OP_UNLINK:
1809         what = "unlink";
1810         APPLY_TAINT_PROPER();
1811         tot = sp - mark;
1812         while (++mark <= sp) {
1813             s = SvPVx(*mark, n_a);
1814             APPLY_TAINT_PROPER();
1815             if (PL_euid || PL_unsafe) {
1816                 if (UNLINK(s))
1817                     tot--;
1818             }
1819             else {      /* don't let root wipe out directories without -U */
1820                 if (PerlLIO_lstat(s,&PL_statbuf) < 0 || S_ISDIR(PL_statbuf.st_mode))
1821                     tot--;
1822                 else {
1823                     if (UNLINK(s))
1824                         tot--;
1825                 }
1826             }
1827         }
1828         break;
1829 #ifdef HAS_UTIME
1830     case OP_UTIME:
1831         what = "utime";
1832         APPLY_TAINT_PROPER();
1833         if (sp - mark > 2) {
1834 #if defined(I_UTIME) || defined(VMS)
1835             struct utimbuf utbuf;
1836 #else
1837             struct {
1838                 Time_t  actime;
1839                 Time_t  modtime;
1840             } utbuf;
1841 #endif
1842
1843            SV* accessed = *++mark;
1844            SV* modified = *++mark;
1845            void * utbufp = &utbuf;
1846
1847            /* Be like C, and if both times are undefined, let the C
1848             * library figure out what to do.  This usually means
1849             * "current time". */
1850
1851            if ( accessed == &PL_sv_undef && modified == &PL_sv_undef )
1852                 utbufp = NULL;
1853            else {
1854                 Zero(&utbuf, sizeof utbuf, char);
1855 #ifdef BIG_TIME
1856                 utbuf.actime = (Time_t)SvNVx(accessed);  /* time accessed */
1857                 utbuf.modtime = (Time_t)SvNVx(modified); /* time modified */
1858 #else
1859                 utbuf.actime = (Time_t)SvIVx(accessed);  /* time accessed */
1860                 utbuf.modtime = (Time_t)SvIVx(modified); /* time modified */
1861 #endif
1862             }
1863             APPLY_TAINT_PROPER();
1864             tot = sp - mark;
1865             while (++mark <= sp) {
1866                 char *name = SvPVx(*mark, n_a);
1867                 APPLY_TAINT_PROPER();
1868                if (PerlLIO_utime(name, utbufp))
1869                     tot--;
1870             }
1871         }
1872         else
1873             tot = 0;
1874         break;
1875 #endif
1876     }
1877     return tot;
1878
1879 #undef APPLY_TAINT_PROPER
1880 }
1881
1882 /* Do the permissions allow some operation?  Assumes statcache already set. */
1883 #ifndef VMS /* VMS' cando is in vms.c */
1884 bool
1885 Perl_cando(pTHX_ Mode_t mode, Uid_t effective, register Stat_t *statbufp)
1886 /* Note: we use `effective' both for uids and gids.
1887  * Here we are betting on Uid_t being equal or wider than Gid_t.  */
1888 {
1889 #ifdef DOSISH
1890     /* [Comments and code from Len Reed]
1891      * MS-DOS "user" is similar to UNIX's "superuser," but can't write
1892      * to write-protected files.  The execute permission bit is set
1893      * by the Miscrosoft C library stat() function for the following:
1894      *          .exe files
1895      *          .com files
1896      *          .bat files
1897      *          directories
1898      * All files and directories are readable.
1899      * Directories and special files, e.g. "CON", cannot be
1900      * write-protected.
1901      * [Comment by Tom Dinger -- a directory can have the write-protect
1902      *          bit set in the file system, but DOS permits changes to
1903      *          the directory anyway.  In addition, all bets are off
1904      *          here for networked software, such as Novell and
1905      *          Sun's PC-NFS.]
1906      */
1907
1908      /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
1909       * too so it will actually look into the files for magic numbers
1910       */
1911      return (mode & statbufp->st_mode) ? TRUE : FALSE;
1912
1913 #else /* ! DOSISH */
1914     if ((effective ? PL_euid : PL_uid) == 0) {  /* root is special */
1915         if (mode == S_IXUSR) {
1916             if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))
1917                 return TRUE;
1918         }
1919         else
1920             return TRUE;                /* root reads and writes anything */
1921         return FALSE;
1922     }
1923     if (statbufp->st_uid == (effective ? PL_euid : PL_uid) ) {
1924         if (statbufp->st_mode & mode)
1925             return TRUE;        /* ok as "user" */
1926     }
1927     else if (ingroup(statbufp->st_gid,effective)) {
1928         if (statbufp->st_mode & mode >> 3)
1929             return TRUE;        /* ok as "group" */
1930     }
1931     else if (statbufp->st_mode & mode >> 6)
1932         return TRUE;    /* ok as "other" */
1933     return FALSE;
1934 #endif /* ! DOSISH */
1935 }
1936 #endif /* ! VMS */
1937
1938 bool
1939 Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
1940 {
1941 #ifdef MACOS_TRADITIONAL
1942     /* This is simply not correct for AppleShare, but fix it yerself. */
1943     return TRUE;
1944 #else
1945     if (testgid == (effective ? PL_egid : PL_gid))
1946         return TRUE;
1947 #ifdef HAS_GETGROUPS
1948 #ifndef NGROUPS
1949 #define NGROUPS 32
1950 #endif
1951     {
1952         Groups_t gary[NGROUPS];
1953         I32 anum;
1954
1955         anum = getgroups(NGROUPS,gary);
1956         while (--anum >= 0)
1957             if (gary[anum] == testgid)
1958                 return TRUE;
1959     }
1960 #endif
1961     return FALSE;
1962 #endif
1963 }
1964
1965 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
1966
1967 I32
1968 Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
1969 {
1970     key_t key;
1971     I32 n, flags;
1972
1973     key = (key_t)SvNVx(*++mark);
1974     n = (optype == OP_MSGGET) ? 0 : SvIVx(*++mark);
1975     flags = SvIVx(*++mark);
1976     SETERRNO(0,0);
1977     switch (optype)
1978     {
1979 #ifdef HAS_MSG
1980     case OP_MSGGET:
1981         return msgget(key, flags);
1982 #endif
1983 #ifdef HAS_SEM
1984     case OP_SEMGET:
1985         return semget(key, n, flags);
1986 #endif
1987 #ifdef HAS_SHM
1988     case OP_SHMGET:
1989         return shmget(key, n, flags);
1990 #endif
1991 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
1992     default:
1993         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
1994 #endif
1995     }
1996     return -1;                  /* should never happen */
1997 }
1998
1999 I32
2000 Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
2001 {
2002     SV *astr;
2003     char *a;
2004     I32 id, n, cmd, infosize, getinfo;
2005     I32 ret = -1;
2006
2007     id = SvIVx(*++mark);
2008     n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
2009     cmd = SvIVx(*++mark);
2010     astr = *++mark;
2011     infosize = 0;
2012     getinfo = (cmd == IPC_STAT);
2013
2014     switch (optype)
2015     {
2016 #ifdef HAS_MSG
2017     case OP_MSGCTL:
2018         if (cmd == IPC_STAT || cmd == IPC_SET)
2019             infosize = sizeof(struct msqid_ds);
2020         break;
2021 #endif
2022 #ifdef HAS_SHM
2023     case OP_SHMCTL:
2024         if (cmd == IPC_STAT || cmd == IPC_SET)
2025             infosize = sizeof(struct shmid_ds);
2026         break;
2027 #endif
2028 #ifdef HAS_SEM
2029     case OP_SEMCTL:
2030 #ifdef Semctl
2031         if (cmd == IPC_STAT || cmd == IPC_SET)
2032             infosize = sizeof(struct semid_ds);
2033         else if (cmd == GETALL || cmd == SETALL)
2034         {
2035             struct semid_ds semds;
2036             union semun semun;
2037 #ifdef EXTRA_F_IN_SEMUN_BUF
2038             semun.buff = &semds;
2039 #else
2040             semun.buf = &semds;
2041 #endif
2042             getinfo = (cmd == GETALL);
2043             if (Semctl(id, 0, IPC_STAT, semun) == -1)
2044                 return -1;
2045             infosize = semds.sem_nsems * sizeof(short);
2046                 /* "short" is technically wrong but much more portable
2047                    than guessing about u_?short(_t)? */
2048         }
2049 #else
2050         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2051 #endif
2052         break;
2053 #endif
2054 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
2055     default:
2056         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2057 #endif
2058     }
2059
2060     if (infosize)
2061     {
2062         STRLEN len;
2063         if (getinfo)
2064         {
2065             SvPV_force(astr, len);
2066             a = SvGROW(astr, infosize+1);
2067         }
2068         else
2069         {
2070             a = SvPV(astr, len);
2071             if (len != infosize)
2072                 Perl_croak(aTHX_ "Bad arg length for %s, is %lu, should be %ld",
2073                       PL_op_desc[optype],
2074                       (unsigned long)len,
2075                       (long)infosize);
2076         }
2077     }
2078     else
2079     {
2080         IV i = SvIV(astr);
2081         a = INT2PTR(char *,i);          /* ouch */
2082     }
2083     SETERRNO(0,0);
2084     switch (optype)
2085     {
2086 #ifdef HAS_MSG
2087     case OP_MSGCTL:
2088         ret = msgctl(id, cmd, (struct msqid_ds *)a);
2089         break;
2090 #endif
2091 #ifdef HAS_SEM
2092     case OP_SEMCTL: {
2093 #ifdef Semctl
2094             union semun unsemds;
2095
2096 #ifdef EXTRA_F_IN_SEMUN_BUF
2097             unsemds.buff = (struct semid_ds *)a;
2098 #else
2099             unsemds.buf = (struct semid_ds *)a;
2100 #endif
2101             ret = Semctl(id, n, cmd, unsemds);
2102 #else
2103             Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2104 #endif
2105         }
2106         break;
2107 #endif
2108 #ifdef HAS_SHM
2109     case OP_SHMCTL:
2110         ret = shmctl(id, cmd, (struct shmid_ds *)a);
2111         break;
2112 #endif
2113     }
2114     if (getinfo && ret >= 0) {
2115         SvCUR_set(astr, infosize);
2116         *SvEND(astr) = '\0';
2117         SvSETMAGIC(astr);
2118     }
2119     return ret;
2120 }
2121
2122 I32
2123 Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
2124 {
2125 #ifdef HAS_MSG
2126     SV *mstr;
2127     char *mbuf;
2128     I32 id, msize, flags;
2129     STRLEN len;
2130
2131     id = SvIVx(*++mark);
2132     mstr = *++mark;
2133     flags = SvIVx(*++mark);
2134     mbuf = SvPV(mstr, len);
2135     if ((msize = len - sizeof(long)) < 0)
2136         Perl_croak(aTHX_ "Arg too short for msgsnd");
2137     SETERRNO(0,0);
2138     return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
2139 #else
2140     Perl_croak(aTHX_ "msgsnd not implemented");
2141 #endif
2142 }
2143
2144 I32
2145 Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
2146 {
2147 #ifdef HAS_MSG
2148     SV *mstr;
2149     char *mbuf;
2150     long mtype;
2151     I32 id, msize, flags, ret;
2152     STRLEN len;
2153
2154     id = SvIVx(*++mark);
2155     mstr = *++mark;
2156     /* suppress warning when reading into undef var --jhi */
2157     if (! SvOK(mstr))
2158         sv_setpvn(mstr, "", 0);
2159     msize = SvIVx(*++mark);
2160     mtype = (long)SvIVx(*++mark);
2161     flags = SvIVx(*++mark);
2162     SvPV_force(mstr, len);
2163     mbuf = SvGROW(mstr, sizeof(long)+msize+1);
2164
2165     SETERRNO(0,0);
2166     ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
2167     if (ret >= 0) {
2168         SvCUR_set(mstr, sizeof(long)+ret);
2169         *SvEND(mstr) = '\0';
2170 #ifndef INCOMPLETE_TAINTS
2171         /* who knows who has been playing with this message? */
2172         SvTAINTED_on(mstr);
2173 #endif
2174     }
2175     return ret;
2176 #else
2177     Perl_croak(aTHX_ "msgrcv not implemented");
2178 #endif
2179 }
2180
2181 I32
2182 Perl_do_semop(pTHX_ SV **mark, SV **sp)
2183 {
2184 #ifdef HAS_SEM
2185     SV *opstr;
2186     char *opbuf;
2187     I32 id;
2188     STRLEN opsize;
2189
2190     id = SvIVx(*++mark);
2191     opstr = *++mark;
2192     opbuf = SvPV(opstr, opsize);
2193     if (opsize < 3 * SHORTSIZE
2194         || (opsize % (3 * SHORTSIZE))) {
2195         SETERRNO(EINVAL,LIB_INVARG);
2196         return -1;
2197     }
2198     SETERRNO(0,0);
2199     /* We can't assume that sizeof(struct sembuf) == 3 * sizeof(short). */
2200     {
2201         int nsops  = opsize / (3 * sizeof (short));
2202         int i      = nsops;
2203         short *ops = (short *) opbuf;
2204         short *o   = ops;
2205         struct sembuf *temps, *t;
2206         I32 result;
2207
2208         New (0, temps, nsops, struct sembuf);
2209         t = temps;
2210         while (i--) {
2211             t->sem_num = *o++;
2212             t->sem_op  = *o++;
2213             t->sem_flg = *o++;
2214             t++;
2215         }
2216         result = semop(id, temps, nsops);
2217         t = temps;
2218         o = ops;
2219         i = nsops;
2220         while (i--) {
2221             *o++ = t->sem_num;
2222             *o++ = t->sem_op;
2223             *o++ = t->sem_flg;
2224             t++;
2225         }
2226         Safefree(temps);
2227         return result;
2228     }
2229 #else
2230     Perl_croak(aTHX_ "semop not implemented");
2231 #endif
2232 }
2233
2234 I32
2235 Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
2236 {
2237 #ifdef HAS_SHM
2238     SV *mstr;
2239     char *mbuf, *shm;
2240     I32 id, mpos, msize;
2241     STRLEN len;
2242     struct shmid_ds shmds;
2243
2244     id = SvIVx(*++mark);
2245     mstr = *++mark;
2246     mpos = SvIVx(*++mark);
2247     msize = SvIVx(*++mark);
2248     SETERRNO(0,0);
2249     if (shmctl(id, IPC_STAT, &shmds) == -1)
2250         return -1;
2251     if (mpos < 0 || msize < 0 || mpos + msize > shmds.shm_segsz) {
2252         SETERRNO(EFAULT,SS_ACCVIO);             /* can't do as caller requested */
2253         return -1;
2254     }
2255     shm = (char *)shmat(id, (char*)NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
2256     if (shm == (char *)-1)      /* I hate System V IPC, I really do */
2257         return -1;
2258     if (optype == OP_SHMREAD) {
2259         /* suppress warning when reading into undef var (tchrist 3/Mar/00) */
2260         if (! SvOK(mstr))
2261             sv_setpvn(mstr, "", 0);
2262         SvPV_force(mstr, len);
2263         mbuf = SvGROW(mstr, msize+1);
2264
2265         Copy(shm + mpos, mbuf, msize, char);
2266         SvCUR_set(mstr, msize);
2267         *SvEND(mstr) = '\0';
2268         SvSETMAGIC(mstr);
2269 #ifndef INCOMPLETE_TAINTS
2270         /* who knows who has been playing with this shared memory? */
2271         SvTAINTED_on(mstr);
2272 #endif
2273     }
2274     else {
2275         I32 n;
2276
2277         mbuf = SvPV(mstr, len);
2278         if ((n = len) > msize)
2279             n = msize;
2280         Copy(mbuf, shm + mpos, n, char);
2281         if (n < msize)
2282             memzero(shm + mpos + n, msize - n);
2283     }
2284     return shmdt(shm);
2285 #else
2286     Perl_croak(aTHX_ "shm I/O not implemented");
2287 #endif
2288 }
2289
2290 #endif /* SYSV IPC */
2291
2292 /*
2293 =head1 IO Functions
2294
2295 =for apidoc start_glob
2296
2297 Function called by C<do_readline> to spawn a glob (or do the glob inside
2298 perl on VMS). This code used to be inline, but now perl uses C<File::Glob>
2299 this glob starter is only used by miniperl during the build process.
2300 Moving it away shrinks pp_hot.c; shrinking pp_hot.c helps speed perl up.
2301
2302 =cut
2303 */
2304
2305 PerlIO *
2306 Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
2307 {
2308     SV *tmpcmd = NEWSV(55, 0);
2309     PerlIO *fp;
2310     ENTER;
2311     SAVEFREESV(tmpcmd);
2312 #ifdef VMS /* expand the wildcards right here, rather than opening a pipe, */
2313            /* since spawning off a process is a real performance hit */
2314     {
2315 #include <descrip.h>
2316 #include <lib$routines.h>
2317 #include <nam.h>
2318 #include <rmsdef.h>
2319         char rslt[NAM$C_MAXRSS+1+sizeof(unsigned short int)] = {'\0','\0'};
2320         char vmsspec[NAM$C_MAXRSS+1];
2321         char *rstr = rslt + sizeof(unsigned short int), *begin, *end, *cp;
2322         $DESCRIPTOR(dfltdsc,"SYS$DISK:[]*.*;");
2323         PerlIO *tmpfp;
2324         STRLEN i;
2325         struct dsc$descriptor_s wilddsc
2326             = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
2327         struct dsc$descriptor_vs rsdsc
2328             = {sizeof rslt, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, rslt};
2329         unsigned long int cxt = 0, sts = 0, ok = 1, hasdir = 0, hasver = 0, isunix = 0;
2330
2331         /* We could find out if there's an explicit dev/dir or version
2332            by peeking into lib$find_file's internal context at
2333            ((struct NAM *)((struct FAB *)cxt)->fab$l_nam)->nam$l_fnb
2334            but that's unsupported, so I don't want to do it now and
2335            have it bite someone in the future. */
2336         cp = SvPV(tmpglob,i);
2337         for (; i; i--) {
2338             if (cp[i] == ';') hasver = 1;
2339             if (cp[i] == '.') {
2340                 if (sts) hasver = 1;
2341                 else sts = 1;
2342             }
2343             if (cp[i] == '/') {
2344                 hasdir = isunix = 1;
2345                 break;
2346             }
2347             if (cp[i] == ']' || cp[i] == '>' || cp[i] == ':') {
2348                 hasdir = 1;
2349                 break;
2350             }
2351         }
2352        if ((tmpfp = PerlIO_tmpfile()) != NULL) {
2353             Stat_t st;
2354             if (!PerlLIO_stat(SvPVX(tmpglob),&st) && S_ISDIR(st.st_mode))
2355                 ok = ((wilddsc.dsc$a_pointer = tovmspath(SvPVX(tmpglob),vmsspec)) != NULL);
2356             else ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL);
2357             if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer);
2358             for (cp=wilddsc.dsc$a_pointer; ok && cp && *cp; cp++)
2359                 if (*cp == '?') *cp = '%';  /* VMS style single-char wildcard */
2360             while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt,
2361                                                &dfltdsc,NULL,NULL,NULL))&1)) {
2362                 /* with varying string, 1st word of buffer contains result length */
2363                 end = rstr + *((unsigned short int*)rslt);
2364                 if (!hasver) while (*end != ';' && end > rstr) end--;
2365                 *(end++) = '\n';  *end = '\0';
2366                 for (cp = rstr; *cp; cp++) *cp = _tolower(*cp);
2367                 if (hasdir) {
2368                     if (isunix) trim_unixpath(rstr,SvPVX(tmpglob),1);
2369                     begin = rstr;
2370                 }
2371                 else {
2372                     begin = end;
2373                     while (*(--begin) != ']' && *begin != '>') ;
2374                     ++begin;
2375                 }
2376                 ok = (PerlIO_puts(tmpfp,begin) != EOF);
2377             }
2378             if (cxt) (void)lib$find_file_end(&cxt);
2379             if (ok && sts != RMS$_NMF &&
2380                 sts != RMS$_DNF && sts != RMS_FNF) ok = 0;
2381             if (!ok) {
2382                 if (!(sts & 1)) {
2383                     SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts);
2384                 }
2385                 PerlIO_close(tmpfp);
2386                 fp = NULL;
2387             }
2388             else {
2389                 PerlIO_rewind(tmpfp);
2390                 IoTYPE(io) = IoTYPE_RDONLY;
2391                 IoIFP(io) = fp = tmpfp;
2392                 IoFLAGS(io) &= ~IOf_UNTAINT;  /* maybe redundant */
2393             }
2394         }
2395     }
2396 #else /* !VMS */
2397 #ifdef MACOS_TRADITIONAL
2398     sv_setpv(tmpcmd, "glob ");
2399     sv_catsv(tmpcmd, tmpglob);
2400     sv_catpv(tmpcmd, " |");
2401 #else
2402 #ifdef DOSISH
2403 #ifdef OS2
2404     sv_setpv(tmpcmd, "for a in ");
2405     sv_catsv(tmpcmd, tmpglob);
2406     sv_catpv(tmpcmd, "; do echo \"$a\\0\\c\"; done |");
2407 #else
2408 #ifdef DJGPP
2409     sv_setpv(tmpcmd, "/dev/dosglob/"); /* File System Extension */
2410     sv_catsv(tmpcmd, tmpglob);
2411 #else
2412     sv_setpv(tmpcmd, "perlglob ");
2413     sv_catsv(tmpcmd, tmpglob);
2414     sv_catpv(tmpcmd, " |");
2415 #endif /* !DJGPP */
2416 #endif /* !OS2 */
2417 #else /* !DOSISH */
2418 #if defined(CSH)
2419     sv_setpvn(tmpcmd, PL_cshname, PL_cshlen);
2420     sv_catpv(tmpcmd, " -cf 'set nonomatch; glob ");
2421     sv_catsv(tmpcmd, tmpglob);
2422     sv_catpv(tmpcmd, "' 2>/dev/null |");
2423 #else
2424     sv_setpv(tmpcmd, "echo ");
2425     sv_catsv(tmpcmd, tmpglob);
2426 #if 'z' - 'a' == 25
2427     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
2428 #else
2429     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|");
2430 #endif
2431 #endif /* !CSH */
2432 #endif /* !DOSISH */
2433 #endif /* MACOS_TRADITIONAL */
2434     (void)do_open(PL_last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd),
2435                   FALSE, O_RDONLY, 0, Nullfp);
2436     fp = IoIFP(io);
2437 #endif /* !VMS */
2438     LEAVE;
2439     return fp;
2440 }