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