This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add SvGROW_mutable
[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,SvPVX(sv),SvCUR(sv),PL_inplace!=0,O_RDONLY,0,Nullfp);
856 #endif /* DOSISH */
857 #else
858                     (void)UNLINK(SvPVX_const(sv));
859                     if (link(PL_oldname,SvPVX_const(sv)) < 0) {
860                         if (ckWARN_d(WARN_INPLACE))     
861                             Perl_warner(aTHX_ packWARN(WARN_INPLACE),
862                               "Can't rename %s to %"SVf": %s, skipping file",
863                               PL_oldname, sv, Strerror(errno) );
864                         do_close(gv,FALSE);
865                         continue;
866                     }
867                     (void)UNLINK(PL_oldname);
868 #endif
869                 }
870                 else {
871 #if !defined(DOSISH) && !defined(AMIGAOS)
872 #  ifndef VMS  /* Don't delete; use automatic file versioning */
873                     if (UNLINK(PL_oldname) < 0) {
874                         if (ckWARN_d(WARN_INPLACE))     
875                             Perl_warner(aTHX_ packWARN(WARN_INPLACE),
876                               "Can't remove %s: %s, skipping file",
877                               PL_oldname, Strerror(errno) );
878                         do_close(gv,FALSE);
879                         continue;
880                     }
881 #  endif
882 #else
883                     Perl_croak(aTHX_ "Can't do inplace edit without backup");
884 #endif
885                 }
886
887                 sv_setpvn(sv,">",!PL_inplace);
888                 sv_catpvn(sv,PL_oldname,oldlen);
889                 SETERRNO(0,0);          /* in case sprintf set errno */
890 #ifdef VMS
891                 if (!do_open(PL_argvoutgv,SvPVX(sv),SvCUR(sv),PL_inplace!=0,
892                  O_WRONLY|O_CREAT|O_TRUNC,0,Nullfp))
893 #else
894                 if (!do_open(PL_argvoutgv,SvPVX(sv),SvCUR(sv),PL_inplace!=0,
895                              O_WRONLY|O_CREAT|OPEN_EXCL,0666,Nullfp))
896 #endif
897                 {
898                     if (ckWARN_d(WARN_INPLACE)) 
899                         Perl_warner(aTHX_ packWARN(WARN_INPLACE), "Can't do inplace edit on %s: %s",
900                           PL_oldname, Strerror(errno) );
901                     do_close(gv,FALSE);
902                     continue;
903                 }
904                 setdefout(PL_argvoutgv);
905                 PL_lastfd = PerlIO_fileno(IoIFP(GvIOp(PL_argvoutgv)));
906                 (void)PerlLIO_fstat(PL_lastfd,&PL_statbuf);
907 #ifdef HAS_FCHMOD
908                 (void)fchmod(PL_lastfd,PL_filemode);
909 #else
910 #  if !(defined(WIN32) && defined(__BORLANDC__))
911                 /* Borland runtime creates a readonly file! */
912                 (void)PerlLIO_chmod(PL_oldname,PL_filemode);
913 #  endif
914 #endif
915                 if (fileuid != PL_statbuf.st_uid || filegid != PL_statbuf.st_gid) {
916 #ifdef HAS_FCHOWN
917                     (void)fchown(PL_lastfd,fileuid,filegid);
918 #else
919 #ifdef HAS_CHOWN
920                     (void)PerlLIO_chown(PL_oldname,fileuid,filegid);
921 #endif
922 #endif
923                 }
924             }
925             return IoIFP(GvIOp(gv));
926         }
927         else {
928             if (ckWARN_d(WARN_INPLACE)) {
929                 const int eno = errno;
930                 if (PerlLIO_stat(PL_oldname, &PL_statbuf) >= 0
931                     && !S_ISREG(PL_statbuf.st_mode))    
932                 {
933                     Perl_warner(aTHX_ packWARN(WARN_INPLACE),
934                                 "Can't do inplace edit: %s is not a regular file",
935                                 PL_oldname);
936                 }
937                 else
938                     Perl_warner(aTHX_ packWARN(WARN_INPLACE), "Can't open %s: %s",
939                                 PL_oldname, Strerror(eno));
940             }
941         }
942     }
943     if (io && (IoFLAGS(io) & IOf_ARGV))
944         IoFLAGS(io) |= IOf_START;
945     if (PL_inplace) {
946         (void)do_close(PL_argvoutgv,FALSE);
947         if (io && (IoFLAGS(io) & IOf_ARGV)
948             && PL_argvout_stack && AvFILLp(PL_argvout_stack) >= 0)
949         {
950             GV *oldout = (GV*)av_pop(PL_argvout_stack);
951             setdefout(oldout);
952             SvREFCNT_dec(oldout);
953             return Nullfp;
954         }
955         setdefout(gv_fetchpv("STDOUT",TRUE,SVt_PVIO));
956     }
957     return Nullfp;
958 }
959
960 #ifdef HAS_PIPE
961 void
962 Perl_do_pipe(pTHX_ SV *sv, GV *rgv, GV *wgv)
963 {
964     register IO *rstio;
965     register IO *wstio;
966     int fd[2];
967
968     if (!rgv)
969         goto badexit;
970     if (!wgv)
971         goto badexit;
972
973     rstio = GvIOn(rgv);
974     wstio = GvIOn(wgv);
975
976     if (IoIFP(rstio))
977         do_close(rgv,FALSE);
978     if (IoIFP(wstio))
979         do_close(wgv,FALSE);
980
981     if (PerlProc_pipe(fd) < 0)
982         goto badexit;
983     IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPE_OPEN_MODE);
984     IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPE_OPEN_MODE);
985     IoOFP(rstio) = IoIFP(rstio);
986     IoIFP(wstio) = IoOFP(wstio);
987     IoTYPE(rstio) = IoTYPE_RDONLY;
988     IoTYPE(wstio) = IoTYPE_WRONLY;
989     if (!IoIFP(rstio) || !IoOFP(wstio)) {
990         if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio));
991         else PerlLIO_close(fd[0]);
992         if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio));
993         else PerlLIO_close(fd[1]);
994         goto badexit;
995     }
996
997     sv_setsv(sv,&PL_sv_yes);
998     return;
999
1000 badexit:
1001     sv_setsv(sv,&PL_sv_undef);
1002     return;
1003 }
1004 #endif
1005
1006 /* explicit renamed to avoid C++ conflict    -- kja */
1007 bool
1008 Perl_do_close(pTHX_ GV *gv, bool not_implicit)
1009 {
1010     bool retval;
1011     IO *io;
1012
1013     if (!gv)
1014         gv = PL_argvgv;
1015     if (!gv || SvTYPE(gv) != SVt_PVGV) {
1016         if (not_implicit)
1017             SETERRNO(EBADF,SS_IVCHAN);
1018         return FALSE;
1019     }
1020     io = GvIO(gv);
1021     if (!io) {          /* never opened */
1022         if (not_implicit) {
1023             if (ckWARN(WARN_UNOPENED)) /* no check for closed here */
1024                 report_evil_fh(gv, io, PL_op->op_type);
1025             SETERRNO(EBADF,SS_IVCHAN);
1026         }
1027         return FALSE;
1028     }
1029     retval = io_close(io, not_implicit);
1030     if (not_implicit) {
1031         IoLINES(io) = 0;
1032         IoPAGE(io) = 0;
1033         IoLINES_LEFT(io) = IoPAGE_LEN(io);
1034     }
1035     IoTYPE(io) = IoTYPE_CLOSED;
1036     return retval;
1037 }
1038
1039 bool
1040 Perl_io_close(pTHX_ IO *io, bool not_implicit)
1041 {
1042     bool retval = FALSE;
1043
1044     if (IoIFP(io)) {
1045         if (IoTYPE(io) == IoTYPE_PIPE) {
1046             const int status = PerlProc_pclose(IoIFP(io));
1047             if (not_implicit) {
1048                 STATUS_NATIVE_SET(status);
1049                 retval = (STATUS_UNIX == 0);
1050             }
1051             else {
1052                 retval = (status != -1);
1053             }
1054         }
1055         else if (IoTYPE(io) == IoTYPE_STD)
1056             retval = TRUE;
1057         else {
1058             if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {          /* a socket */
1059                 bool prev_err = PerlIO_error(IoOFP(io));
1060                 retval = (PerlIO_close(IoOFP(io)) != EOF && !prev_err);
1061                 PerlIO_close(IoIFP(io));        /* clear stdio, fd already closed */
1062             }
1063             else {
1064                 bool prev_err = PerlIO_error(IoIFP(io));
1065                 retval = (PerlIO_close(IoIFP(io)) != EOF && !prev_err);
1066             }
1067         }
1068         IoOFP(io) = IoIFP(io) = Nullfp;
1069     }
1070     else if (not_implicit) {
1071         SETERRNO(EBADF,SS_IVCHAN);
1072     }
1073
1074     return retval;
1075 }
1076
1077 bool
1078 Perl_do_eof(pTHX_ GV *gv)
1079 {
1080     register IO *io;
1081     int ch;
1082
1083     io = GvIO(gv);
1084
1085     if (!io)
1086         return TRUE;
1087     else if (ckWARN(WARN_IO) && (IoTYPE(io) == IoTYPE_WRONLY))
1088         report_evil_fh(gv, io, OP_phoney_OUTPUT_ONLY);
1089
1090     while (IoIFP(io)) {
1091         int saverrno;
1092
1093         if (PerlIO_has_cntptr(IoIFP(io))) {     /* (the code works without this) */
1094             if (PerlIO_get_cnt(IoIFP(io)) > 0)  /* cheat a little, since */
1095                 return FALSE;                   /* this is the most usual case */
1096         }
1097
1098         saverrno = errno; /* getc and ungetc can stomp on errno */
1099         ch = PerlIO_getc(IoIFP(io));
1100         if (ch != EOF) {
1101             (void)PerlIO_ungetc(IoIFP(io),ch);
1102             errno = saverrno;
1103             return FALSE;
1104         }
1105         errno = saverrno;
1106
1107         if (PerlIO_has_cntptr(IoIFP(io)) && PerlIO_canset_cnt(IoIFP(io))) {
1108             if (PerlIO_get_cnt(IoIFP(io)) < -1)
1109                 PerlIO_set_cnt(IoIFP(io),-1);
1110         }
1111         if (PL_op->op_flags & OPf_SPECIAL) { /* not necessarily a real EOF yet? */
1112             if (gv != PL_argvgv || !nextargv(gv))       /* get another fp handy */
1113                 return TRUE;
1114         }
1115         else
1116             return TRUE;                /* normal fp, definitely end of file */
1117     }
1118     return TRUE;
1119 }
1120
1121 Off_t
1122 Perl_do_tell(pTHX_ GV *gv)
1123 {
1124     register IO *io = 0;
1125     register PerlIO *fp;
1126
1127     if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) {
1128 #ifdef ULTRIX_STDIO_BOTCH
1129         if (PerlIO_eof(fp))
1130             (void)PerlIO_seek(fp, 0L, 2);       /* ultrix 1.2 workaround */
1131 #endif
1132         return PerlIO_tell(fp);
1133     }
1134     if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1135         report_evil_fh(gv, io, PL_op->op_type);
1136     SETERRNO(EBADF,RMS_IFI);
1137     return (Off_t)-1;
1138 }
1139
1140 bool
1141 Perl_do_seek(pTHX_ GV *gv, Off_t pos, int whence)
1142 {
1143     register IO *io = 0;
1144     register PerlIO *fp;
1145
1146     if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) {
1147 #ifdef ULTRIX_STDIO_BOTCH
1148         if (PerlIO_eof(fp))
1149             (void)PerlIO_seek(fp, 0L, 2);       /* ultrix 1.2 workaround */
1150 #endif
1151         return PerlIO_seek(fp, pos, whence) >= 0;
1152     }
1153     if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1154         report_evil_fh(gv, io, PL_op->op_type);
1155     SETERRNO(EBADF,RMS_IFI);
1156     return FALSE;
1157 }
1158
1159 Off_t
1160 Perl_do_sysseek(pTHX_ GV *gv, Off_t pos, int whence)
1161 {
1162     register IO *io = 0;
1163     register PerlIO *fp;
1164
1165     if (gv && (io = GvIO(gv)) && (fp = IoIFP(io)))
1166         return PerlLIO_lseek(PerlIO_fileno(fp), pos, whence);
1167     if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1168         report_evil_fh(gv, io, PL_op->op_type);
1169     SETERRNO(EBADF,RMS_IFI);
1170     return (Off_t)-1;
1171 }
1172
1173 int
1174 Perl_mode_from_discipline(pTHX_ SV *discp)
1175 {
1176     int mode = O_BINARY;
1177     if (discp) {
1178         STRLEN len;
1179         const char *s = SvPV_const(discp,len);
1180         while (*s) {
1181             if (*s == ':') {
1182                 switch (s[1]) {
1183                 case 'r':
1184                     if (s[2] == 'a' && s[3] == 'w'
1185                         && (!s[4] || s[4] == ':' || isSPACE(s[4])))
1186                     {
1187                         mode = O_BINARY;
1188                         s += 4;
1189                         len -= 4;
1190                         break;
1191                     }
1192                     /* FALL THROUGH */
1193                 case 'c':
1194                     if (s[2] == 'r' && s[3] == 'l' && s[4] == 'f'
1195                         && (!s[5] || s[5] == ':' || isSPACE(s[5])))
1196                     {
1197                         mode = O_TEXT;
1198                         s += 5;
1199                         len -= 5;
1200                         break;
1201                     }
1202                     /* FALL THROUGH */
1203                 default:
1204                     goto fail_discipline;
1205                 }
1206             }
1207             else if (isSPACE(*s)) {
1208                 ++s;
1209                 --len;
1210             }
1211             else {
1212                 const char *end;
1213 fail_discipline:
1214                 end = strchr(s+1, ':');
1215                 if (!end)
1216                     end = s+len;
1217 #ifndef PERLIO_LAYERS
1218                 Perl_croak(aTHX_ "IO layers (like '%.*s') unavailable", end-s, s);
1219 #else
1220                 len -= end-s;
1221                 s = end;
1222 #endif
1223             }
1224         }
1225     }
1226     return mode;
1227 }
1228
1229 int
1230 Perl_do_binmode(pTHX_ PerlIO *fp, int iotype, int mode)
1231 {
1232  /* The old body of this is now in non-LAYER part of perlio.c
1233   * This is a stub for any XS code which might have been calling it.
1234   */
1235  const char *name = ":raw";
1236 #ifdef PERLIO_USING_CRLF
1237  if (!(mode & O_BINARY))
1238      name = ":crlf";
1239 #endif
1240  return PerlIO_binmode(aTHX_ fp, iotype, mode, name);
1241 }
1242
1243 #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE)
1244 I32
1245 my_chsize(int fd, Off_t length)
1246 {
1247 #ifdef F_FREESP
1248         /* code courtesy of William Kucharski */
1249 #define HAS_CHSIZE
1250
1251     struct flock fl;
1252     Stat_t filebuf;
1253
1254     if (PerlLIO_fstat(fd, &filebuf) < 0)
1255         return -1;
1256
1257     if (filebuf.st_size < length) {
1258
1259         /* extend file length */
1260
1261         if ((PerlLIO_lseek(fd, (length - 1), 0)) < 0)
1262             return -1;
1263
1264         /* write a "0" byte */
1265
1266         if ((PerlLIO_write(fd, "", 1)) != 1)
1267             return -1;
1268     }
1269     else {
1270         /* truncate length */
1271
1272         fl.l_whence = 0;
1273         fl.l_len = 0;
1274         fl.l_start = length;
1275         fl.l_type = F_WRLCK;    /* write lock on file space */
1276
1277         /*
1278         * This relies on the UNDOCUMENTED F_FREESP argument to
1279         * fcntl(2), which truncates the file so that it ends at the
1280         * position indicated by fl.l_start.
1281         *
1282         * Will minor miracles never cease?
1283         */
1284
1285         if (fcntl(fd, F_FREESP, &fl) < 0)
1286             return -1;
1287
1288     }
1289     return 0;
1290 #else
1291     Perl_croak_nocontext("truncate not implemented");
1292 #endif /* F_FREESP */
1293     return -1;
1294 }
1295 #endif /* !HAS_TRUNCATE && !HAS_CHSIZE */
1296
1297 bool
1298 Perl_do_print(pTHX_ register SV *sv, PerlIO *fp)
1299 {
1300     register const char *tmps;
1301     STRLEN len;
1302
1303     /* assuming fp is checked earlier */
1304     if (!sv)
1305         return TRUE;
1306     if (PL_ofmt) {
1307         if (SvGMAGICAL(sv))
1308             mg_get(sv);
1309         if (SvIOK(sv) && SvIVX(sv) != 0) {
1310             PerlIO_printf(fp, PL_ofmt, (NV)SvIVX(sv));
1311             return !PerlIO_error(fp);
1312         }
1313         if (  (SvNOK(sv) && SvNVX(sv) != 0.0)
1314            || (looks_like_number(sv) && sv_2nv(sv) != 0.0) ) {
1315             PerlIO_printf(fp, PL_ofmt, SvNVX(sv));
1316             return !PerlIO_error(fp);
1317         }
1318     }
1319     switch (SvTYPE(sv)) {
1320     case SVt_NULL:
1321         if (ckWARN(WARN_UNINITIALIZED))
1322             report_uninit(sv);
1323         return TRUE;
1324     case SVt_IV:
1325         if (SvIOK(sv)) {
1326             if (SvGMAGICAL(sv))
1327                 mg_get(sv);
1328             if (SvIsUV(sv))
1329                 PerlIO_printf(fp, "%"UVuf, (UV)SvUVX(sv));
1330             else
1331                 PerlIO_printf(fp, "%"IVdf, (IV)SvIVX(sv));
1332             return !PerlIO_error(fp);
1333         }
1334         /* FALL THROUGH */
1335     default:
1336         if (PerlIO_isutf8(fp)) {
1337             if (!SvUTF8(sv))
1338                 sv_utf8_upgrade_flags(sv = sv_mortalcopy(sv),
1339                                       SV_GMAGIC|SV_UTF8_NO_ENCODING);
1340         }
1341         else if (DO_UTF8(sv)) {
1342             if (!sv_utf8_downgrade((sv = sv_mortalcopy(sv)), TRUE)
1343                 && ckWARN_d(WARN_UTF8))
1344             {
1345                 Perl_warner(aTHX_ packWARN(WARN_UTF8), "Wide character in print");
1346             }
1347         }
1348         tmps = SvPV_const(sv, len);
1349         break;
1350     }
1351     /* To detect whether the process is about to overstep its
1352      * filesize limit we would need getrlimit().  We could then
1353      * also transparently raise the limit with setrlimit() --
1354      * but only until the system hard limit/the filesystem limit,
1355      * at which we would get EPERM.  Note that when using buffered
1356      * io the write failure can be delayed until the flush/close. --jhi */
1357     if (len && (PerlIO_write(fp,tmps,len) == 0))
1358         return FALSE;
1359     return !PerlIO_error(fp);
1360 }
1361
1362 I32
1363 Perl_my_stat(pTHX)
1364 {
1365     dSP;
1366     IO *io;
1367     GV* gv;
1368
1369     if (PL_op->op_flags & OPf_REF) {
1370         EXTEND(SP,1);
1371         gv = cGVOP_gv;
1372       do_fstat:
1373         io = GvIO(gv);
1374         if (io && IoIFP(io)) {
1375             PL_statgv = gv;
1376             sv_setpvn(PL_statname,"", 0);
1377             PL_laststype = OP_STAT;
1378             return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache));
1379         }
1380         else {
1381             if (gv == PL_defgv)
1382                 return PL_laststatval;
1383             if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1384                 report_evil_fh(gv, io, PL_op->op_type);
1385             PL_statgv = Nullgv;
1386             sv_setpvn(PL_statname,"", 0);
1387             return (PL_laststatval = -1);
1388         }
1389     }
1390     else if (PL_op->op_private & OPpFT_STACKED) {
1391         return PL_laststatval;
1392     }
1393     else {
1394         SV* sv = POPs;
1395         const char *s;
1396         STRLEN len;
1397         PUTBACK;
1398         if (SvTYPE(sv) == SVt_PVGV) {
1399             gv = (GV*)sv;
1400             goto do_fstat;
1401         }
1402         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
1403             gv = (GV*)SvRV(sv);
1404             goto do_fstat;
1405         }
1406
1407         s = SvPV_const(sv, len);
1408         PL_statgv = Nullgv;
1409         sv_setpvn(PL_statname, s, len);
1410         s = SvPVX_const(PL_statname);           /* s now NUL-terminated */
1411         PL_laststype = OP_STAT;
1412         PL_laststatval = PerlLIO_stat(s, &PL_statcache);
1413         if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(s, '\n'))
1414             Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
1415         return PL_laststatval;
1416     }
1417 }
1418
1419 static const char no_prev_lstat[] = "The stat preceding -l _ wasn't an lstat";
1420
1421 I32
1422 Perl_my_lstat(pTHX)
1423 {
1424     dSP;
1425     SV *sv;
1426     if (PL_op->op_flags & OPf_REF) {
1427         EXTEND(SP,1);
1428         if (cGVOP_gv == PL_defgv) {
1429             if (PL_laststype != OP_LSTAT)
1430                 Perl_croak(aTHX_ no_prev_lstat);
1431             return PL_laststatval;
1432         }
1433         if (ckWARN(WARN_IO)) {
1434             Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1435                     GvENAME(cGVOP_gv));
1436             return (PL_laststatval = -1);
1437         }
1438     }
1439     else if (ckWARN(WARN_IO) && PL_laststype != OP_LSTAT
1440             && (PL_op->op_private & OPpFT_STACKED))
1441         Perl_croak(aTHX_ no_prev_lstat);
1442
1443     PL_laststype = OP_LSTAT;
1444     PL_statgv = Nullgv;
1445     sv = POPs;
1446     PUTBACK;
1447     if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV && ckWARN(WARN_IO)) {
1448         Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1449                 GvENAME((GV*) SvRV(sv)));
1450         return (PL_laststatval = -1);
1451     }
1452     /* XXX Do really need to be calling SvPV() all these times? */
1453     sv_setpv(PL_statname,SvPV_nolen_const(sv));
1454     PL_laststatval = PerlLIO_lstat(SvPV_nolen_const(sv),&PL_statcache);
1455     if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(SvPV_nolen_const(sv), '\n'))
1456         Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
1457     return PL_laststatval;
1458 }
1459
1460 #ifndef OS2
1461 bool
1462 Perl_do_aexec(pTHX_ SV *really, register SV **mark, register SV **sp)
1463 {
1464     return do_aexec5(really, mark, sp, 0, 0);
1465 }
1466 #endif
1467
1468 bool
1469 Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
1470                int fd, int do_report)
1471 {
1472     dVAR;
1473 #if defined(MACOS_TRADITIONAL) || defined(SYMBIAN)
1474     Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
1475 #else
1476     register char **a;
1477     const char *tmps = Nullch;
1478
1479     if (sp > mark) {
1480         New(401,PL_Argv, sp - mark + 1, char*);
1481         a = PL_Argv;
1482         while (++mark <= sp) {
1483             if (*mark)
1484                 *a++ = (char*)SvPV_nolen_const(*mark);
1485             else
1486                 *a++ = "";
1487         }
1488         *a = Nullch;
1489         if (really)
1490             tmps = SvPV_nolen_const(really);
1491         if ((!really && *PL_Argv[0] != '/') ||
1492             (really && *tmps != '/'))           /* will execvp use PATH? */
1493             TAINT_ENV();                /* testing IFS here is overkill, probably */
1494         PERL_FPU_PRE_EXEC
1495         if (really && *tmps)
1496             PerlProc_execvp(tmps,EXEC_ARGV_CAST(PL_Argv));
1497         else
1498             PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
1499         PERL_FPU_POST_EXEC
1500         if (ckWARN(WARN_EXEC))
1501             Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
1502                 (really ? tmps : PL_Argv[0]), Strerror(errno));
1503         if (do_report) {
1504             int e = errno;
1505
1506             PerlLIO_write(fd, (void*)&e, sizeof(int));
1507             PerlLIO_close(fd);
1508         }
1509     }
1510     do_execfree();
1511 #endif
1512     return FALSE;
1513 }
1514
1515 void
1516 Perl_do_execfree(pTHX)
1517 {
1518     if (PL_Argv) {
1519         Safefree(PL_Argv);
1520         PL_Argv = Null(char **);
1521     }
1522     if (PL_Cmd) {
1523         Safefree(PL_Cmd);
1524         PL_Cmd = Nullch;
1525     }
1526 }
1527
1528 #if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(EPOC) && !defined(SYMBIAN) && !defined(MACOS_TRADITIONAL)
1529
1530 bool
1531 Perl_do_exec(pTHX_ char *cmd)
1532 {
1533     return do_exec3(cmd,0,0);
1534 }
1535
1536 bool
1537 Perl_do_exec3(pTHX_ char *cmd, int fd, int do_report)
1538 {
1539     dVAR;
1540     register char **a;
1541     register char *s;
1542
1543     while (*cmd && isSPACE(*cmd))
1544         cmd++;
1545
1546     /* save an extra exec if possible */
1547
1548 #ifdef CSH
1549     {
1550         char flags[PERL_FLAGS_MAX];
1551         if (strnEQ(cmd,PL_cshname,PL_cshlen) &&
1552             strnEQ(cmd+PL_cshlen," -c",3)) {
1553 #ifdef HAS_STRLCPY
1554           strlcpy(flags, "-c", PERL_FLAGS_MAX);
1555 #else
1556           strcpy(flags,"-c");
1557 #endif
1558           s = cmd+PL_cshlen+3;
1559           if (*s == 'f') {
1560               s++;
1561 #ifdef HAS_STRLCPY
1562               strlcat(flags, "f", PERL_FLAGS_MAX);
1563 #else
1564               strcat(flags,"f");
1565 #endif
1566           }
1567           if (*s == ' ')
1568               s++;
1569           if (*s++ == '\'') {
1570               char *ncmd = s;
1571
1572               while (*s)
1573                   s++;
1574               if (s[-1] == '\n')
1575                   *--s = '\0';
1576               if (s[-1] == '\'') {
1577                   *--s = '\0';
1578                   PERL_FPU_PRE_EXEC
1579                   PerlProc_execl(PL_cshname,"csh", flags, ncmd, (char*)0);
1580                   PERL_FPU_POST_EXEC
1581                   *s = '\'';
1582                   return FALSE;
1583               }
1584           }
1585         }
1586     }
1587 #endif /* CSH */
1588
1589     /* see if there are shell metacharacters in it */
1590
1591     if (*cmd == '.' && isSPACE(cmd[1]))
1592         goto doshell;
1593
1594     if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
1595         goto doshell;
1596
1597     for (s = cmd; *s && isALNUM(*s); s++) ;     /* catch VAR=val gizmo */
1598     if (*s == '=')
1599         goto doshell;
1600
1601     for (s = cmd; *s; s++) {
1602         if (*s != ' ' && !isALPHA(*s) &&
1603             strchr("$&*(){}[]'\";\\|?<>~`\n",*s)) {
1604             if (*s == '\n' && !s[1]) {
1605                 *s = '\0';
1606                 break;
1607             }
1608             /* handle the 2>&1 construct at the end */
1609             if (*s == '>' && s[1] == '&' && s[2] == '1'
1610                 && s > cmd + 1 && s[-1] == '2' && isSPACE(s[-2])
1611                 && (!s[3] || isSPACE(s[3])))
1612             {
1613                 const char *t = s + 3;
1614
1615                 while (*t && isSPACE(*t))
1616                     ++t;
1617                 if (!*t && (PerlLIO_dup2(1,2) != -1)) {
1618                     s[-2] = '\0';
1619                     break;
1620                 }
1621             }
1622           doshell:
1623             PERL_FPU_PRE_EXEC
1624             PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char*)0);
1625             PERL_FPU_POST_EXEC
1626             return FALSE;
1627         }
1628     }
1629
1630     New(402,PL_Argv, (s - cmd) / 2 + 2, char*);
1631     PL_Cmd = savepvn(cmd, s-cmd);
1632     a = PL_Argv;
1633     for (s = PL_Cmd; *s;) {
1634         while (*s && isSPACE(*s)) s++;
1635         if (*s)
1636             *(a++) = s;
1637         while (*s && !isSPACE(*s)) s++;
1638         if (*s)
1639             *s++ = '\0';
1640     }
1641     *a = Nullch;
1642     if (PL_Argv[0]) {
1643         PERL_FPU_PRE_EXEC
1644         PerlProc_execvp(PL_Argv[0],PL_Argv);
1645         PERL_FPU_POST_EXEC
1646         if (errno == ENOEXEC) {         /* for system V NIH syndrome */
1647             do_execfree();
1648             goto doshell;
1649         }
1650         {
1651             if (ckWARN(WARN_EXEC))
1652                 Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
1653                     PL_Argv[0], Strerror(errno));
1654             if (do_report) {
1655                 int e = errno;
1656                 PerlLIO_write(fd, (void*)&e, sizeof(int));
1657                 PerlLIO_close(fd);
1658             }
1659         }
1660     }
1661     do_execfree();
1662     return FALSE;
1663 }
1664
1665 #endif /* OS2 || WIN32 */
1666
1667 I32
1668 Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
1669 {
1670     register I32 val;
1671     register I32 tot = 0;
1672     const char *what;
1673     const char *s;
1674     SV **oldmark = mark;
1675
1676 #define APPLY_TAINT_PROPER() \
1677     STMT_START {                                                        \
1678         if (PL_tainted) { TAINT_PROPER(what); }                         \
1679     } STMT_END
1680
1681     /* This is a first heuristic; it doesn't catch tainting magic. */
1682     if (PL_tainting) {
1683         while (++mark <= sp) {
1684             if (SvTAINTED(*mark)) {
1685                 TAINT;
1686                 break;
1687             }
1688         }
1689         mark = oldmark;
1690     }
1691     switch (type) {
1692     case OP_CHMOD:
1693         what = "chmod";
1694         APPLY_TAINT_PROPER();
1695         if (++mark <= sp) {
1696             val = SvIVx(*mark);
1697             APPLY_TAINT_PROPER();
1698             tot = sp - mark;
1699             while (++mark <= sp) {
1700                 const char *name = SvPV_nolen_const(*mark);
1701                 APPLY_TAINT_PROPER();
1702                 if (PerlLIO_chmod(name, val))
1703                     tot--;
1704             }
1705         }
1706         break;
1707 #ifdef HAS_CHOWN
1708     case OP_CHOWN:
1709         what = "chown";
1710         APPLY_TAINT_PROPER();
1711         if (sp - mark > 2) {
1712             register I32 val2;
1713             val = SvIVx(*++mark);
1714             val2 = SvIVx(*++mark);
1715             APPLY_TAINT_PROPER();
1716             tot = sp - mark;
1717             while (++mark <= sp) {
1718                 const char *name = SvPV_nolen_const(*mark);
1719                 APPLY_TAINT_PROPER();
1720                 if (PerlLIO_chown(name, val, val2))
1721                     tot--;
1722             }
1723         }
1724         break;
1725 #endif
1726 /*
1727 XXX Should we make lchown() directly available from perl?
1728 For now, we'll let Configure test for HAS_LCHOWN, but do
1729 nothing in the core.
1730     --AD  5/1998
1731 */
1732 #ifdef HAS_KILL
1733     case OP_KILL:
1734         what = "kill";
1735         APPLY_TAINT_PROPER();
1736         if (mark == sp)
1737             break;
1738         s = SvPVx_nolen_const(*++mark);
1739         if (isALPHA(*s)) {
1740             if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1741                 s += 3;
1742             if ((val = whichsig(s)) < 0)
1743                 Perl_croak(aTHX_ "Unrecognized signal name \"%s\"",s);
1744         }
1745         else
1746             val = SvIVx(*mark);
1747         APPLY_TAINT_PROPER();
1748         tot = sp - mark;
1749 #ifdef VMS
1750         /* kill() doesn't do process groups (job trees?) under VMS */
1751         if (val < 0) val = -val;
1752         if (val == SIGKILL) {
1753 #           include <starlet.h>
1754             /* Use native sys$delprc() to insure that target process is
1755              * deleted; supervisor-mode images don't pay attention to
1756              * CRTL's emulation of Unix-style signals and kill()
1757              */
1758             while (++mark <= sp) {
1759                 I32 proc = SvIVx(*mark);
1760                 register unsigned long int __vmssts;
1761                 APPLY_TAINT_PROPER();
1762                 if (!((__vmssts = sys$delprc(&proc,0)) & 1)) {
1763                     tot--;
1764                     switch (__vmssts) {
1765                         case SS$_NONEXPR:
1766                         case SS$_NOSUCHNODE:
1767                             SETERRNO(ESRCH,__vmssts);
1768                             break;
1769                         case SS$_NOPRIV:
1770                             SETERRNO(EPERM,__vmssts);
1771                             break;
1772                         default:
1773                             SETERRNO(EVMSERR,__vmssts);
1774                     }
1775                 }
1776             }
1777             break;
1778         }
1779 #endif
1780         if (val < 0) {
1781             val = -val;
1782             while (++mark <= sp) {
1783                 I32 proc = SvIVx(*mark);
1784                 APPLY_TAINT_PROPER();
1785 #ifdef HAS_KILLPG
1786                 if (PerlProc_killpg(proc,val))  /* BSD */
1787 #else
1788                 if (PerlProc_kill(-proc,val))   /* SYSV */
1789 #endif
1790                     tot--;
1791             }
1792         }
1793         else {
1794             while (++mark <= sp) {
1795                 I32 proc = SvIVx(*mark);
1796                 APPLY_TAINT_PROPER();
1797                 if (PerlProc_kill(proc, val))
1798                     tot--;
1799             }
1800         }
1801         break;
1802 #endif
1803     case OP_UNLINK:
1804         what = "unlink";
1805         APPLY_TAINT_PROPER();
1806         tot = sp - mark;
1807         while (++mark <= sp) {
1808             s = SvPV_nolen_const(*mark);
1809             APPLY_TAINT_PROPER();
1810             if (PL_euid || PL_unsafe) {
1811                 if (UNLINK(s))
1812                     tot--;
1813             }
1814             else {      /* don't let root wipe out directories without -U */
1815                 if (PerlLIO_lstat(s,&PL_statbuf) < 0 || S_ISDIR(PL_statbuf.st_mode))
1816                     tot--;
1817                 else {
1818                     if (UNLINK(s))
1819                         tot--;
1820                 }
1821             }
1822         }
1823         break;
1824 #ifdef HAS_UTIME
1825     case OP_UTIME:
1826         what = "utime";
1827         APPLY_TAINT_PROPER();
1828         if (sp - mark > 2) {
1829 #if defined(I_UTIME) || defined(VMS)
1830             struct utimbuf utbuf;
1831             struct utimbuf *utbufp = &utbuf;
1832 #else
1833             struct {
1834                 Time_t  actime;
1835                 Time_t  modtime;
1836             } utbuf;
1837             void *utbufp = &utbuf;
1838 #endif
1839
1840            SV* accessed = *++mark;
1841            SV* modified = *++mark;
1842
1843            /* Be like C, and if both times are undefined, let the C
1844             * library figure out what to do.  This usually means
1845             * "current time". */
1846
1847            if ( accessed == &PL_sv_undef && modified == &PL_sv_undef )
1848                 utbufp = NULL;
1849            else {
1850                 Zero(&utbuf, sizeof utbuf, char);
1851 #ifdef BIG_TIME
1852                 utbuf.actime = (Time_t)SvNVx(accessed);  /* time accessed */
1853                 utbuf.modtime = (Time_t)SvNVx(modified); /* time modified */
1854 #else
1855                 utbuf.actime = (Time_t)SvIVx(accessed);  /* time accessed */
1856                 utbuf.modtime = (Time_t)SvIVx(modified); /* time modified */
1857 #endif
1858             }
1859             APPLY_TAINT_PROPER();
1860             tot = sp - mark;
1861             while (++mark <= sp) {
1862                 const char *name = SvPV_nolen_const(*mark);
1863                 APPLY_TAINT_PROPER();
1864                 if (PerlLIO_utime(name, utbufp))
1865                     tot--;
1866             }
1867         }
1868         else
1869             tot = 0;
1870         break;
1871 #endif
1872     }
1873     return tot;
1874
1875 #undef APPLY_TAINT_PROPER
1876 }
1877
1878 /* Do the permissions allow some operation?  Assumes statcache already set. */
1879 #ifndef VMS /* VMS' cando is in vms.c */
1880 bool
1881 Perl_cando(pTHX_ Mode_t mode, Uid_t effective, register const Stat_t *statbufp)
1882 /* Note: we use "effective" both for uids and gids.
1883  * Here we are betting on Uid_t being equal or wider than Gid_t.  */
1884 {
1885 #ifdef DOSISH
1886     /* [Comments and code from Len Reed]
1887      * MS-DOS "user" is similar to UNIX's "superuser," but can't write
1888      * to write-protected files.  The execute permission bit is set
1889      * by the Miscrosoft C library stat() function for the following:
1890      *          .exe files
1891      *          .com files
1892      *          .bat files
1893      *          directories
1894      * All files and directories are readable.
1895      * Directories and special files, e.g. "CON", cannot be
1896      * write-protected.
1897      * [Comment by Tom Dinger -- a directory can have the write-protect
1898      *          bit set in the file system, but DOS permits changes to
1899      *          the directory anyway.  In addition, all bets are off
1900      *          here for networked software, such as Novell and
1901      *          Sun's PC-NFS.]
1902      */
1903
1904      /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
1905       * too so it will actually look into the files for magic numbers
1906       */
1907      return (mode & statbufp->st_mode) ? TRUE : FALSE;
1908
1909 #else /* ! DOSISH */
1910     if ((effective ? PL_euid : PL_uid) == 0) {  /* root is special */
1911         if (mode == S_IXUSR) {
1912             if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))
1913                 return TRUE;
1914         }
1915         else
1916             return TRUE;                /* root reads and writes anything */
1917         return FALSE;
1918     }
1919     if (statbufp->st_uid == (effective ? PL_euid : PL_uid) ) {
1920         if (statbufp->st_mode & mode)
1921             return TRUE;        /* ok as "user" */
1922     }
1923     else if (ingroup(statbufp->st_gid,effective)) {
1924         if (statbufp->st_mode & mode >> 3)
1925             return TRUE;        /* ok as "group" */
1926     }
1927     else if (statbufp->st_mode & mode >> 6)
1928         return TRUE;    /* ok as "other" */
1929     return FALSE;
1930 #endif /* ! DOSISH */
1931 }
1932 #endif /* ! VMS */
1933
1934 bool
1935 Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
1936 {
1937 #ifdef MACOS_TRADITIONAL
1938     /* This is simply not correct for AppleShare, but fix it yerself. */
1939     return TRUE;
1940 #else
1941     if (testgid == (effective ? PL_egid : PL_gid))
1942         return TRUE;
1943 #ifdef HAS_GETGROUPS
1944 #ifndef NGROUPS
1945 #define NGROUPS 32
1946 #endif
1947     {
1948         Groups_t gary[NGROUPS];
1949         I32 anum;
1950
1951         anum = getgroups(NGROUPS,gary);
1952         while (--anum >= 0)
1953             if (gary[anum] == testgid)
1954                 return TRUE;
1955     }
1956 #endif
1957     return FALSE;
1958 #endif
1959 }
1960
1961 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
1962
1963 I32
1964 Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
1965 {
1966     key_t key = (key_t)SvNVx(*++mark);
1967     const I32 n = (optype == OP_MSGGET) ? 0 : SvIVx(*++mark);
1968     const I32 flags = SvIVx(*++mark);
1969     (void)sp;
1970
1971     SETERRNO(0,0);
1972     switch (optype)
1973     {
1974 #ifdef HAS_MSG
1975     case OP_MSGGET:
1976         return msgget(key, flags);
1977 #endif
1978 #ifdef HAS_SEM
1979     case OP_SEMGET:
1980         return semget(key, n, flags);
1981 #endif
1982 #ifdef HAS_SHM
1983     case OP_SHMGET:
1984         return shmget(key, n, flags);
1985 #endif
1986 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
1987     default:
1988         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
1989 #endif
1990     }
1991     return -1;                  /* should never happen */
1992 }
1993
1994 I32
1995 Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
1996 {
1997     SV *astr;
1998     char *a;
1999     STRLEN infosize;
2000     I32 getinfo;
2001     I32 ret = -1;
2002     const I32 id  = SvIVx(*++mark);
2003     const I32 n   = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
2004     const I32 cmd = SvIVx(*++mark);
2005     (void)sp;
2006
2007     astr = *++mark;
2008     infosize = 0;
2009     getinfo = (cmd == IPC_STAT);
2010
2011     switch (optype)
2012     {
2013 #ifdef HAS_MSG
2014     case OP_MSGCTL:
2015         if (cmd == IPC_STAT || cmd == IPC_SET)
2016             infosize = sizeof(struct msqid_ds);
2017         break;
2018 #endif
2019 #ifdef HAS_SHM
2020     case OP_SHMCTL:
2021         if (cmd == IPC_STAT || cmd == IPC_SET)
2022             infosize = sizeof(struct shmid_ds);
2023         break;
2024 #endif
2025 #ifdef HAS_SEM
2026     case OP_SEMCTL:
2027 #ifdef Semctl
2028         if (cmd == IPC_STAT || cmd == IPC_SET)
2029             infosize = sizeof(struct semid_ds);
2030         else if (cmd == GETALL || cmd == SETALL)
2031         {
2032             struct semid_ds semds;
2033             union semun semun;
2034 #ifdef EXTRA_F_IN_SEMUN_BUF
2035             semun.buff = &semds;
2036 #else
2037             semun.buf = &semds;
2038 #endif
2039             getinfo = (cmd == GETALL);
2040             if (Semctl(id, 0, IPC_STAT, semun) == -1)
2041                 return -1;
2042             infosize = semds.sem_nsems * sizeof(short);
2043                 /* "short" is technically wrong but much more portable
2044                    than guessing about u_?short(_t)? */
2045         }
2046 #else
2047         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2048 #endif
2049         break;
2050 #endif
2051 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
2052     default:
2053         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2054 #endif
2055     }
2056
2057     if (infosize)
2058     {
2059         STRLEN len;
2060         if (getinfo)
2061         {
2062             SvPV_force(astr, len);
2063             a = SvGROW(astr, infosize+1);
2064         }
2065         else
2066         {
2067             a = SvPV(astr, len);
2068             if (len != infosize)
2069                 Perl_croak(aTHX_ "Bad arg length for %s, is %lu, should be %ld",
2070                       PL_op_desc[optype],
2071                       (unsigned long)len,
2072                       (long)infosize);
2073         }
2074     }
2075     else
2076     {
2077         IV i = SvIV(astr);
2078         a = INT2PTR(char *,i);          /* ouch */
2079     }
2080     SETERRNO(0,0);
2081     switch (optype)
2082     {
2083 #ifdef HAS_MSG
2084     case OP_MSGCTL:
2085         ret = msgctl(id, cmd, (struct msqid_ds *)a);
2086         break;
2087 #endif
2088 #ifdef HAS_SEM
2089     case OP_SEMCTL: {
2090 #ifdef Semctl
2091             union semun unsemds;
2092
2093 #ifdef EXTRA_F_IN_SEMUN_BUF
2094             unsemds.buff = (struct semid_ds *)a;
2095 #else
2096             unsemds.buf = (struct semid_ds *)a;
2097 #endif
2098             ret = Semctl(id, n, cmd, unsemds);
2099 #else
2100             Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2101 #endif
2102         }
2103         break;
2104 #endif
2105 #ifdef HAS_SHM
2106     case OP_SHMCTL:
2107         ret = shmctl(id, cmd, (struct shmid_ds *)a);
2108         break;
2109 #endif
2110     }
2111     if (getinfo && ret >= 0) {
2112         SvCUR_set(astr, infosize);
2113         *SvEND(astr) = '\0';
2114         SvSETMAGIC(astr);
2115     }
2116     return ret;
2117 }
2118
2119 I32
2120 Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
2121 {
2122 #ifdef HAS_MSG
2123     SV *mstr;
2124     char *mbuf;
2125     I32 msize, flags;
2126     STRLEN len;
2127     const I32 id = SvIVx(*++mark);
2128     (void)sp;
2129
2130     mstr = *++mark;
2131     flags = SvIVx(*++mark);
2132     mbuf = SvPV(mstr, len);
2133     if ((msize = len - sizeof(long)) < 0)
2134         Perl_croak(aTHX_ "Arg too short for msgsnd");
2135     SETERRNO(0,0);
2136     return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
2137 #else
2138     Perl_croak(aTHX_ "msgsnd not implemented");
2139 #endif
2140 }
2141
2142 I32
2143 Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
2144 {
2145 #ifdef HAS_MSG
2146     SV *mstr;
2147     char *mbuf;
2148     long mtype;
2149     I32 msize, flags, ret;
2150     STRLEN len;
2151     const I32 id = SvIVx(*++mark);
2152     (void)sp;
2153
2154     mstr = *++mark;
2155     /* suppress warning when reading into undef var --jhi */
2156     if (! SvOK(mstr))
2157         sv_setpvn(mstr, "", 0);
2158     msize = SvIVx(*++mark);
2159     mtype = (long)SvIVx(*++mark);
2160     flags = SvIVx(*++mark);
2161     SvPV_force(mstr, len);
2162     mbuf = SvGROW(mstr, sizeof(long)+msize+1);
2163
2164     SETERRNO(0,0);
2165     ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
2166     if (ret >= 0) {
2167         SvCUR_set(mstr, sizeof(long)+ret);
2168         *SvEND(mstr) = '\0';
2169 #ifndef INCOMPLETE_TAINTS
2170         /* who knows who has been playing with this message? */
2171         SvTAINTED_on(mstr);
2172 #endif
2173     }
2174     return ret;
2175 #else
2176     Perl_croak(aTHX_ "msgrcv not implemented");
2177 #endif
2178 }
2179
2180 I32
2181 Perl_do_semop(pTHX_ SV **mark, SV **sp)
2182 {
2183 #ifdef HAS_SEM
2184     SV *opstr;
2185     char *opbuf;
2186     STRLEN opsize;
2187     const I32 id = SvIVx(*++mark);
2188     (void)sp;
2189
2190     opstr = *++mark;
2191     opbuf = SvPV(opstr, opsize);
2192     if (opsize < 3 * SHORTSIZE
2193         || (opsize % (3 * SHORTSIZE))) {
2194         SETERRNO(EINVAL,LIB_INVARG);
2195         return -1;
2196     }
2197     SETERRNO(0,0);
2198     /* We can't assume that sizeof(struct sembuf) == 3 * sizeof(short). */
2199     {
2200         const int nsops  = opsize / (3 * sizeof (short));
2201         int i      = nsops;
2202         short *ops = (short *) opbuf;
2203         short *o   = ops;
2204         struct sembuf *temps, *t;
2205         I32 result;
2206
2207         New (0, temps, nsops, struct sembuf);
2208         t = temps;
2209         while (i--) {
2210             t->sem_num = *o++;
2211             t->sem_op  = *o++;
2212             t->sem_flg = *o++;
2213             t++;
2214         }
2215         result = semop(id, temps, nsops);
2216         t = temps;
2217         o = ops;
2218         i = nsops;
2219         while (i--) {
2220             *o++ = t->sem_num;
2221             *o++ = t->sem_op;
2222             *o++ = t->sem_flg;
2223             t++;
2224         }
2225         Safefree(temps);
2226         return result;
2227     }
2228 #else
2229     Perl_croak(aTHX_ "semop not implemented");
2230 #endif
2231 }
2232
2233 I32
2234 Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
2235 {
2236 #ifdef HAS_SHM
2237     SV *mstr;
2238     char *shm;
2239     I32 mpos, msize;
2240     STRLEN len;
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(mstr, len);
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
2278         const char *mbuf = SvPV(mstr, len);
2279         if ((n = len) > msize)
2280             n = msize;
2281         Copy(mbuf, shm + mpos, n, char);
2282         if (n < msize)
2283             memzero(shm + mpos + n, msize - n);
2284     }
2285     return shmdt(shm);
2286 #else
2287     Perl_croak(aTHX_ "shm I/O not implemented");
2288 #endif
2289 }
2290
2291 #endif /* SYSV IPC */
2292
2293 /*
2294 =head1 IO Functions
2295
2296 =for apidoc start_glob
2297
2298 Function called by C<do_readline> to spawn a glob (or do the glob inside
2299 perl on VMS). This code used to be inline, but now perl uses C<File::Glob>
2300 this glob starter is only used by miniperl during the build process.
2301 Moving it away shrinks pp_hot.c; shrinking pp_hot.c helps speed perl up.
2302
2303 =cut
2304 */
2305
2306 PerlIO *
2307 Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
2308 {
2309     dVAR;
2310     SV *tmpcmd = NEWSV(55, 0);
2311     PerlIO *fp;
2312     ENTER;
2313     SAVEFREESV(tmpcmd);
2314 #ifdef VMS /* expand the wildcards right here, rather than opening a pipe, */
2315            /* since spawning off a process is a real performance hit */
2316     {
2317 #include <descrip.h>
2318 #include <lib$routines.h>
2319 #include <nam.h>
2320 #include <rmsdef.h>
2321         char rslt[NAM$C_MAXRSS+1+sizeof(unsigned short int)] = {'\0','\0'};
2322         char vmsspec[NAM$C_MAXRSS+1];
2323         char *rstr = rslt + sizeof(unsigned short int), *begin, *end, *cp;
2324         $DESCRIPTOR(dfltdsc,"SYS$DISK:[]*.*;");
2325         PerlIO *tmpfp;
2326         STRLEN i;
2327         struct dsc$descriptor_s wilddsc
2328             = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
2329         struct dsc$descriptor_vs rsdsc
2330             = {sizeof rslt, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, rslt};
2331         unsigned long int cxt = 0, sts = 0, ok = 1, hasdir = 0, hasver = 0, isunix = 0;
2332
2333         /* We could find out if there's an explicit dev/dir or version
2334            by peeking into lib$find_file's internal context at
2335            ((struct NAM *)((struct FAB *)cxt)->fab$l_nam)->nam$l_fnb
2336            but that's unsupported, so I don't want to do it now and
2337            have it bite someone in the future. */
2338         cp = SvPV(tmpglob,i);
2339         for (; i; i--) {
2340             if (cp[i] == ';') hasver = 1;
2341             if (cp[i] == '.') {
2342                 if (sts) hasver = 1;
2343                 else sts = 1;
2344             }
2345             if (cp[i] == '/') {
2346                 hasdir = isunix = 1;
2347                 break;
2348             }
2349             if (cp[i] == ']' || cp[i] == '>' || cp[i] == ':') {
2350                 hasdir = 1;
2351                 break;
2352             }
2353         }
2354        if ((tmpfp = PerlIO_tmpfile()) != NULL) {
2355             Stat_t st;
2356             if (!PerlLIO_stat(SvPVX_const(tmpglob),&st) && S_ISDIR(st.st_mode))
2357                 ok = ((wilddsc.dsc$a_pointer = tovmspath(SvPVX(tmpglob),vmsspec)) != NULL);
2358             else ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL);
2359             if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer);
2360             for (cp=wilddsc.dsc$a_pointer; ok && cp && *cp; cp++)
2361                 if (*cp == '?') *cp = '%';  /* VMS style single-char wildcard */
2362             while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt,
2363                                                &dfltdsc,NULL,NULL,NULL))&1)) {
2364                 /* with varying string, 1st word of buffer contains result length */
2365                 end = rstr + *((unsigned short int*)rslt);
2366                 if (!hasver) while (*end != ';' && end > rstr) end--;
2367                 *(end++) = '\n';  *end = '\0';
2368                 for (cp = rstr; *cp; cp++) *cp = _tolower(*cp);
2369                 if (hasdir) {
2370                     if (isunix) trim_unixpath(rstr,SvPVX(tmpglob),1);
2371                     begin = rstr;
2372                 }
2373                 else {
2374                     begin = end;
2375                     while (*(--begin) != ']' && *begin != '>') ;
2376                     ++begin;
2377                 }
2378                 ok = (PerlIO_puts(tmpfp,begin) != EOF);
2379             }
2380             if (cxt) (void)lib$find_file_end(&cxt);
2381             if (ok && sts != RMS$_NMF &&
2382                 sts != RMS$_DNF && sts != RMS_FNF) ok = 0;
2383             if (!ok) {
2384                 if (!(sts & 1)) {
2385                     SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts);
2386                 }
2387                 PerlIO_close(tmpfp);
2388                 fp = NULL;
2389             }
2390             else {
2391                 PerlIO_rewind(tmpfp);
2392                 IoTYPE(io) = IoTYPE_RDONLY;
2393                 IoIFP(io) = fp = tmpfp;
2394                 IoFLAGS(io) &= ~IOf_UNTAINT;  /* maybe redundant */
2395             }
2396         }
2397     }
2398 #else /* !VMS */
2399 #ifdef MACOS_TRADITIONAL
2400     sv_setpv(tmpcmd, "glob ");
2401     sv_catsv(tmpcmd, tmpglob);
2402     sv_catpv(tmpcmd, " |");
2403 #else
2404 #ifdef DOSISH
2405 #ifdef OS2
2406     sv_setpv(tmpcmd, "for a in ");
2407     sv_catsv(tmpcmd, tmpglob);
2408     sv_catpv(tmpcmd, "; do echo \"$a\\0\\c\"; done |");
2409 #else
2410 #ifdef DJGPP
2411     sv_setpv(tmpcmd, "/dev/dosglob/"); /* File System Extension */
2412     sv_catsv(tmpcmd, tmpglob);
2413 #else
2414     sv_setpv(tmpcmd, "perlglob ");
2415     sv_catsv(tmpcmd, tmpglob);
2416     sv_catpv(tmpcmd, " |");
2417 #endif /* !DJGPP */
2418 #endif /* !OS2 */
2419 #else /* !DOSISH */
2420 #if defined(CSH)
2421     sv_setpvn(tmpcmd, PL_cshname, PL_cshlen);
2422     sv_catpv(tmpcmd, " -cf 'set nonomatch; glob ");
2423     sv_catsv(tmpcmd, tmpglob);
2424     sv_catpv(tmpcmd, "' 2>/dev/null |");
2425 #else
2426     sv_setpv(tmpcmd, "echo ");
2427     sv_catsv(tmpcmd, tmpglob);
2428 #if 'z' - 'a' == 25
2429     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
2430 #else
2431     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|");
2432 #endif
2433 #endif /* !CSH */
2434 #endif /* !DOSISH */
2435 #endif /* MACOS_TRADITIONAL */
2436     (void)do_open(PL_last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd),
2437                   FALSE, O_RDONLY, 0, Nullfp);
2438     fp = IoIFP(io);
2439 #endif /* !VMS */
2440     LEAVE;
2441     return fp;
2442 }
2443
2444 /*
2445  * Local variables:
2446  * c-indentation-style: bsd
2447  * c-basic-offset: 4
2448  * indent-tabs-mode: t
2449  * End:
2450  *
2451  * ex: set ts=8 sts=4 sw=4 noet:
2452  */