This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: blead attribute warnings, cygwin + gcc 3.4.1
[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                 (void)SvUPGRADE(sv, SVt_IV);
677                 pid = SvIVX(sv);
678                 SvIV_set(sv, 0);
679                 sv = *av_fetch(PL_fdpid,savefd,TRUE);
680                 (void)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(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(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(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     STRLEN n_a;
1427     if (PL_op->op_flags & OPf_REF) {
1428         EXTEND(SP,1);
1429         if (cGVOP_gv == PL_defgv) {
1430             if (PL_laststype != OP_LSTAT)
1431                 Perl_croak(aTHX_ no_prev_lstat);
1432             return PL_laststatval;
1433         }
1434         if (ckWARN(WARN_IO)) {
1435             Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1436                     GvENAME(cGVOP_gv));
1437             return (PL_laststatval = -1);
1438         }
1439     }
1440     else if (ckWARN(WARN_IO) && PL_laststype != OP_LSTAT
1441             && (PL_op->op_private & OPpFT_STACKED))
1442         Perl_croak(aTHX_ no_prev_lstat);
1443
1444     PL_laststype = OP_LSTAT;
1445     PL_statgv = Nullgv;
1446     sv = POPs;
1447     PUTBACK;
1448     if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV && ckWARN(WARN_IO)) {
1449         Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1450                 GvENAME((GV*) SvRV(sv)));
1451         return (PL_laststatval = -1);
1452     }
1453     /* XXX Do really need to be calling SvPV() all these times? */
1454     sv_setpv(PL_statname,SvPV(sv, n_a));
1455     PL_laststatval = PerlLIO_lstat(SvPV(sv, n_a),&PL_statcache);
1456     if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(SvPV(sv, n_a), '\n'))
1457         Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
1458     return PL_laststatval;
1459 }
1460
1461 #ifndef OS2
1462 bool
1463 Perl_do_aexec(pTHX_ SV *really, register SV **mark, register SV **sp)
1464 {
1465     return do_aexec5(really, mark, sp, 0, 0);
1466 }
1467 #endif
1468
1469 bool
1470 Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
1471                int fd, int do_report)
1472 {
1473     dVAR;
1474 #if defined(MACOS_TRADITIONAL) || defined(SYMBIAN)
1475     Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
1476 #else
1477     register char **a;
1478     const char *tmps = Nullch;
1479     STRLEN n_a;
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++ = SvPVx(*mark, n_a);
1487             else
1488                 *a++ = "";
1489         }
1490         *a = Nullch;
1491         if (really)
1492             tmps = SvPV(really, n_a);
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     char *s;
1676     SV **oldmark = mark;
1677     STRLEN n_a;
1678
1679 #define APPLY_TAINT_PROPER() \
1680     STMT_START {                                                        \
1681         if (PL_tainted) { TAINT_PROPER(what); }                         \
1682     } STMT_END
1683
1684     /* This is a first heuristic; it doesn't catch tainting magic. */
1685     if (PL_tainting) {
1686         while (++mark <= sp) {
1687             if (SvTAINTED(*mark)) {
1688                 TAINT;
1689                 break;
1690             }
1691         }
1692         mark = oldmark;
1693     }
1694     switch (type) {
1695     case OP_CHMOD:
1696         what = "chmod";
1697         APPLY_TAINT_PROPER();
1698         if (++mark <= sp) {
1699             val = SvIVx(*mark);
1700             APPLY_TAINT_PROPER();
1701             tot = sp - mark;
1702             while (++mark <= sp) {
1703                 const char *name = SvPVx(*mark, n_a);
1704                 APPLY_TAINT_PROPER();
1705                 if (PerlLIO_chmod(name, val))
1706                     tot--;
1707             }
1708         }
1709         break;
1710 #ifdef HAS_CHOWN
1711     case OP_CHOWN:
1712         what = "chown";
1713         APPLY_TAINT_PROPER();
1714         if (sp - mark > 2) {
1715             register I32 val2;
1716             val = SvIVx(*++mark);
1717             val2 = SvIVx(*++mark);
1718             APPLY_TAINT_PROPER();
1719             tot = sp - mark;
1720             while (++mark <= sp) {
1721                 const char *name = SvPVx(*mark, n_a);
1722                 APPLY_TAINT_PROPER();
1723                 if (PerlLIO_chown(name, val, val2))
1724                     tot--;
1725             }
1726         }
1727         break;
1728 #endif
1729 /*
1730 XXX Should we make lchown() directly available from perl?
1731 For now, we'll let Configure test for HAS_LCHOWN, but do
1732 nothing in the core.
1733     --AD  5/1998
1734 */
1735 #ifdef HAS_KILL
1736     case OP_KILL:
1737         what = "kill";
1738         APPLY_TAINT_PROPER();
1739         if (mark == sp)
1740             break;
1741         s = SvPVx(*++mark, n_a);
1742         if (isALPHA(*s)) {
1743             if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1744                 s += 3;
1745             if ((val = whichsig(s)) < 0)
1746                 Perl_croak(aTHX_ "Unrecognized signal name \"%s\"",s);
1747         }
1748         else
1749             val = SvIVx(*mark);
1750         APPLY_TAINT_PROPER();
1751         tot = sp - mark;
1752 #ifdef VMS
1753         /* kill() doesn't do process groups (job trees?) under VMS */
1754         if (val < 0) val = -val;
1755         if (val == SIGKILL) {
1756 #           include <starlet.h>
1757             /* Use native sys$delprc() to insure that target process is
1758              * deleted; supervisor-mode images don't pay attention to
1759              * CRTL's emulation of Unix-style signals and kill()
1760              */
1761             while (++mark <= sp) {
1762                 I32 proc = SvIVx(*mark);
1763                 register unsigned long int __vmssts;
1764                 APPLY_TAINT_PROPER();
1765                 if (!((__vmssts = sys$delprc(&proc,0)) & 1)) {
1766                     tot--;
1767                     switch (__vmssts) {
1768                         case SS$_NONEXPR:
1769                         case SS$_NOSUCHNODE:
1770                             SETERRNO(ESRCH,__vmssts);
1771                             break;
1772                         case SS$_NOPRIV:
1773                             SETERRNO(EPERM,__vmssts);
1774                             break;
1775                         default:
1776                             SETERRNO(EVMSERR,__vmssts);
1777                     }
1778                 }
1779             }
1780             break;
1781         }
1782 #endif
1783         if (val < 0) {
1784             val = -val;
1785             while (++mark <= sp) {
1786                 I32 proc = SvIVx(*mark);
1787                 APPLY_TAINT_PROPER();
1788 #ifdef HAS_KILLPG
1789                 if (PerlProc_killpg(proc,val))  /* BSD */
1790 #else
1791                 if (PerlProc_kill(-proc,val))   /* SYSV */
1792 #endif
1793                     tot--;
1794             }
1795         }
1796         else {
1797             while (++mark <= sp) {
1798                 I32 proc = SvIVx(*mark);
1799                 APPLY_TAINT_PROPER();
1800                 if (PerlProc_kill(proc, val))
1801                     tot--;
1802             }
1803         }
1804         break;
1805 #endif
1806     case OP_UNLINK:
1807         what = "unlink";
1808         APPLY_TAINT_PROPER();
1809         tot = sp - mark;
1810         while (++mark <= sp) {
1811             s = SvPVx(*mark, n_a);
1812             APPLY_TAINT_PROPER();
1813             if (PL_euid || PL_unsafe) {
1814                 if (UNLINK(s))
1815                     tot--;
1816             }
1817             else {      /* don't let root wipe out directories without -U */
1818                 if (PerlLIO_lstat(s,&PL_statbuf) < 0 || S_ISDIR(PL_statbuf.st_mode))
1819                     tot--;
1820                 else {
1821                     if (UNLINK(s))
1822                         tot--;
1823                 }
1824             }
1825         }
1826         break;
1827 #ifdef HAS_UTIME
1828     case OP_UTIME:
1829         what = "utime";
1830         APPLY_TAINT_PROPER();
1831         if (sp - mark > 2) {
1832 #if defined(I_UTIME) || defined(VMS)
1833             struct utimbuf utbuf;
1834             struct utimbuf *utbufp = &utbuf;
1835 #else
1836             struct {
1837                 Time_t  actime;
1838                 Time_t  modtime;
1839             } utbuf;
1840             void *utbufp = &utbuf;
1841 #endif
1842
1843            SV* accessed = *++mark;
1844            SV* modified = *++mark;
1845
1846            /* Be like C, and if both times are undefined, let the C
1847             * library figure out what to do.  This usually means
1848             * "current time". */
1849
1850            if ( accessed == &PL_sv_undef && modified == &PL_sv_undef )
1851                 utbufp = NULL;
1852            else {
1853                 Zero(&utbuf, sizeof utbuf, char);
1854 #ifdef BIG_TIME
1855                 utbuf.actime = (Time_t)SvNVx(accessed);  /* time accessed */
1856                 utbuf.modtime = (Time_t)SvNVx(modified); /* time modified */
1857 #else
1858                 utbuf.actime = (Time_t)SvIVx(accessed);  /* time accessed */
1859                 utbuf.modtime = (Time_t)SvIVx(modified); /* time modified */
1860 #endif
1861             }
1862             APPLY_TAINT_PROPER();
1863             tot = sp - mark;
1864             while (++mark <= sp) {
1865                 STRLEN n_a;
1866                 const char *name = SvPVx(*mark, n_a);
1867                 APPLY_TAINT_PROPER();
1868                 if (PerlLIO_utime(name, utbufp))
1869                     tot--;
1870             }
1871         }
1872         else
1873             tot = 0;
1874         break;
1875 #endif
1876     }
1877     return tot;
1878
1879 #undef APPLY_TAINT_PROPER
1880 }
1881
1882 /* Do the permissions allow some operation?  Assumes statcache already set. */
1883 #ifndef VMS /* VMS' cando is in vms.c */
1884 bool
1885 Perl_cando(pTHX_ Mode_t mode, Uid_t effective, register const Stat_t *statbufp)
1886 /* Note: we use "effective" both for uids and gids.
1887  * Here we are betting on Uid_t being equal or wider than Gid_t.  */
1888 {
1889 #ifdef DOSISH
1890     /* [Comments and code from Len Reed]
1891      * MS-DOS "user" is similar to UNIX's "superuser," but can't write
1892      * to write-protected files.  The execute permission bit is set
1893      * by the Miscrosoft C library stat() function for the following:
1894      *          .exe files
1895      *          .com files
1896      *          .bat files
1897      *          directories
1898      * All files and directories are readable.
1899      * Directories and special files, e.g. "CON", cannot be
1900      * write-protected.
1901      * [Comment by Tom Dinger -- a directory can have the write-protect
1902      *          bit set in the file system, but DOS permits changes to
1903      *          the directory anyway.  In addition, all bets are off
1904      *          here for networked software, such as Novell and
1905      *          Sun's PC-NFS.]
1906      */
1907
1908      /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
1909       * too so it will actually look into the files for magic numbers
1910       */
1911      return (mode & statbufp->st_mode) ? TRUE : FALSE;
1912
1913 #else /* ! DOSISH */
1914     if ((effective ? PL_euid : PL_uid) == 0) {  /* root is special */
1915         if (mode == S_IXUSR) {
1916             if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))
1917                 return TRUE;
1918         }
1919         else
1920             return TRUE;                /* root reads and writes anything */
1921         return FALSE;
1922     }
1923     if (statbufp->st_uid == (effective ? PL_euid : PL_uid) ) {
1924         if (statbufp->st_mode & mode)
1925             return TRUE;        /* ok as "user" */
1926     }
1927     else if (ingroup(statbufp->st_gid,effective)) {
1928         if (statbufp->st_mode & mode >> 3)
1929             return TRUE;        /* ok as "group" */
1930     }
1931     else if (statbufp->st_mode & mode >> 6)
1932         return TRUE;    /* ok as "other" */
1933     return FALSE;
1934 #endif /* ! DOSISH */
1935 }
1936 #endif /* ! VMS */
1937
1938 bool
1939 Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
1940 {
1941 #ifdef MACOS_TRADITIONAL
1942     /* This is simply not correct for AppleShare, but fix it yerself. */
1943     return TRUE;
1944 #else
1945     if (testgid == (effective ? PL_egid : PL_gid))
1946         return TRUE;
1947 #ifdef HAS_GETGROUPS
1948 #ifndef NGROUPS
1949 #define NGROUPS 32
1950 #endif
1951     {
1952         Groups_t gary[NGROUPS];
1953         I32 anum;
1954
1955         anum = getgroups(NGROUPS,gary);
1956         while (--anum >= 0)
1957             if (gary[anum] == testgid)
1958                 return TRUE;
1959     }
1960 #endif
1961     return FALSE;
1962 #endif
1963 }
1964
1965 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
1966
1967 I32
1968 Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
1969 {
1970     key_t key = (key_t)SvNVx(*++mark);
1971     const I32 n = (optype == OP_MSGGET) ? 0 : SvIVx(*++mark);
1972     const I32 flags = SvIVx(*++mark);
1973     (void)sp;
1974
1975     SETERRNO(0,0);
1976     switch (optype)
1977     {
1978 #ifdef HAS_MSG
1979     case OP_MSGGET:
1980         return msgget(key, flags);
1981 #endif
1982 #ifdef HAS_SEM
1983     case OP_SEMGET:
1984         return semget(key, n, flags);
1985 #endif
1986 #ifdef HAS_SHM
1987     case OP_SHMGET:
1988         return shmget(key, n, flags);
1989 #endif
1990 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
1991     default:
1992         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
1993 #endif
1994     }
1995     return -1;                  /* should never happen */
1996 }
1997
1998 I32
1999 Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
2000 {
2001     SV *astr;
2002     char *a;
2003     STRLEN infosize;
2004     I32 getinfo;
2005     I32 ret = -1;
2006     const I32 id  = SvIVx(*++mark);
2007     const I32 n   = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
2008     const I32 cmd = SvIVx(*++mark);
2009     (void)sp;
2010
2011     astr = *++mark;
2012     infosize = 0;
2013     getinfo = (cmd == IPC_STAT);
2014
2015     switch (optype)
2016     {
2017 #ifdef HAS_MSG
2018     case OP_MSGCTL:
2019         if (cmd == IPC_STAT || cmd == IPC_SET)
2020             infosize = sizeof(struct msqid_ds);
2021         break;
2022 #endif
2023 #ifdef HAS_SHM
2024     case OP_SHMCTL:
2025         if (cmd == IPC_STAT || cmd == IPC_SET)
2026             infosize = sizeof(struct shmid_ds);
2027         break;
2028 #endif
2029 #ifdef HAS_SEM
2030     case OP_SEMCTL:
2031 #ifdef Semctl
2032         if (cmd == IPC_STAT || cmd == IPC_SET)
2033             infosize = sizeof(struct semid_ds);
2034         else if (cmd == GETALL || cmd == SETALL)
2035         {
2036             struct semid_ds semds;
2037             union semun semun;
2038 #ifdef EXTRA_F_IN_SEMUN_BUF
2039             semun.buff = &semds;
2040 #else
2041             semun.buf = &semds;
2042 #endif
2043             getinfo = (cmd == GETALL);
2044             if (Semctl(id, 0, IPC_STAT, semun) == -1)
2045                 return -1;
2046             infosize = semds.sem_nsems * sizeof(short);
2047                 /* "short" is technically wrong but much more portable
2048                    than guessing about u_?short(_t)? */
2049         }
2050 #else
2051         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2052 #endif
2053         break;
2054 #endif
2055 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
2056     default:
2057         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2058 #endif
2059     }
2060
2061     if (infosize)
2062     {
2063         STRLEN len;
2064         if (getinfo)
2065         {
2066             SvPV_force(astr, len);
2067             a = SvGROW(astr, infosize+1);
2068         }
2069         else
2070         {
2071             a = SvPV(astr, len);
2072             if (len != infosize)
2073                 Perl_croak(aTHX_ "Bad arg length for %s, is %lu, should be %ld",
2074                       PL_op_desc[optype],
2075                       (unsigned long)len,
2076                       (long)infosize);
2077         }
2078     }
2079     else
2080     {
2081         IV i = SvIV(astr);
2082         a = INT2PTR(char *,i);          /* ouch */
2083     }
2084     SETERRNO(0,0);
2085     switch (optype)
2086     {
2087 #ifdef HAS_MSG
2088     case OP_MSGCTL:
2089         ret = msgctl(id, cmd, (struct msqid_ds *)a);
2090         break;
2091 #endif
2092 #ifdef HAS_SEM
2093     case OP_SEMCTL: {
2094 #ifdef Semctl
2095             union semun unsemds;
2096
2097 #ifdef EXTRA_F_IN_SEMUN_BUF
2098             unsemds.buff = (struct semid_ds *)a;
2099 #else
2100             unsemds.buf = (struct semid_ds *)a;
2101 #endif
2102             ret = Semctl(id, n, cmd, unsemds);
2103 #else
2104             Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2105 #endif
2106         }
2107         break;
2108 #endif
2109 #ifdef HAS_SHM
2110     case OP_SHMCTL:
2111         ret = shmctl(id, cmd, (struct shmid_ds *)a);
2112         break;
2113 #endif
2114     }
2115     if (getinfo && ret >= 0) {
2116         SvCUR_set(astr, infosize);
2117         *SvEND(astr) = '\0';
2118         SvSETMAGIC(astr);
2119     }
2120     return ret;
2121 }
2122
2123 I32
2124 Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
2125 {
2126 #ifdef HAS_MSG
2127     SV *mstr;
2128     char *mbuf;
2129     I32 msize, flags;
2130     STRLEN len;
2131     const I32 id = SvIVx(*++mark);
2132     (void)sp;
2133
2134     mstr = *++mark;
2135     flags = SvIVx(*++mark);
2136     mbuf = SvPV(mstr, len);
2137     if ((msize = len - sizeof(long)) < 0)
2138         Perl_croak(aTHX_ "Arg too short for msgsnd");
2139     SETERRNO(0,0);
2140     return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
2141 #else
2142     Perl_croak(aTHX_ "msgsnd not implemented");
2143 #endif
2144 }
2145
2146 I32
2147 Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
2148 {
2149 #ifdef HAS_MSG
2150     SV *mstr;
2151     char *mbuf;
2152     long mtype;
2153     I32 msize, flags, ret;
2154     STRLEN len;
2155     const I32 id = SvIVx(*++mark);
2156     (void)sp;
2157
2158     mstr = *++mark;
2159     /* suppress warning when reading into undef var --jhi */
2160     if (! SvOK(mstr))
2161         sv_setpvn(mstr, "", 0);
2162     msize = SvIVx(*++mark);
2163     mtype = (long)SvIVx(*++mark);
2164     flags = SvIVx(*++mark);
2165     SvPV_force(mstr, len);
2166     mbuf = SvGROW(mstr, sizeof(long)+msize+1);
2167
2168     SETERRNO(0,0);
2169     ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
2170     if (ret >= 0) {
2171         SvCUR_set(mstr, sizeof(long)+ret);
2172         *SvEND(mstr) = '\0';
2173 #ifndef INCOMPLETE_TAINTS
2174         /* who knows who has been playing with this message? */
2175         SvTAINTED_on(mstr);
2176 #endif
2177     }
2178     return ret;
2179 #else
2180     Perl_croak(aTHX_ "msgrcv not implemented");
2181 #endif
2182 }
2183
2184 I32
2185 Perl_do_semop(pTHX_ SV **mark, SV **sp)
2186 {
2187 #ifdef HAS_SEM
2188     SV *opstr;
2189     char *opbuf;
2190     STRLEN opsize;
2191     const I32 id = SvIVx(*++mark);
2192     (void)sp;
2193
2194     opstr = *++mark;
2195     opbuf = SvPV(opstr, opsize);
2196     if (opsize < 3 * SHORTSIZE
2197         || (opsize % (3 * SHORTSIZE))) {
2198         SETERRNO(EINVAL,LIB_INVARG);
2199         return -1;
2200     }
2201     SETERRNO(0,0);
2202     /* We can't assume that sizeof(struct sembuf) == 3 * sizeof(short). */
2203     {
2204         const int nsops  = opsize / (3 * sizeof (short));
2205         int i      = nsops;
2206         short *ops = (short *) opbuf;
2207         short *o   = ops;
2208         struct sembuf *temps, *t;
2209         I32 result;
2210
2211         New (0, temps, nsops, struct sembuf);
2212         t = temps;
2213         while (i--) {
2214             t->sem_num = *o++;
2215             t->sem_op  = *o++;
2216             t->sem_flg = *o++;
2217             t++;
2218         }
2219         result = semop(id, temps, nsops);
2220         t = temps;
2221         o = ops;
2222         i = nsops;
2223         while (i--) {
2224             *o++ = t->sem_num;
2225             *o++ = t->sem_op;
2226             *o++ = t->sem_flg;
2227             t++;
2228         }
2229         Safefree(temps);
2230         return result;
2231     }
2232 #else
2233     Perl_croak(aTHX_ "semop not implemented");
2234 #endif
2235 }
2236
2237 I32
2238 Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
2239 {
2240 #ifdef HAS_SHM
2241     SV *mstr;
2242     char *shm;
2243     I32 mpos, msize;
2244     STRLEN len;
2245     struct shmid_ds shmds;
2246     const I32 id = SvIVx(*++mark);
2247     (void)sp;
2248
2249     mstr = *++mark;
2250     mpos = SvIVx(*++mark);
2251     msize = SvIVx(*++mark);
2252     SETERRNO(0,0);
2253     if (shmctl(id, IPC_STAT, &shmds) == -1)
2254         return -1;
2255     if (mpos < 0 || msize < 0 || mpos + msize > shmds.shm_segsz) {
2256         SETERRNO(EFAULT,SS_ACCVIO);             /* can't do as caller requested */
2257         return -1;
2258     }
2259     shm = (char *)shmat(id, (char*)NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
2260     if (shm == (char *)-1)      /* I hate System V IPC, I really do */
2261         return -1;
2262     if (optype == OP_SHMREAD) {
2263         const char *mbuf;
2264         /* suppress warning when reading into undef var (tchrist 3/Mar/00) */
2265         if (! SvOK(mstr))
2266             sv_setpvn(mstr, "", 0);
2267         SvPV_force(mstr, len);
2268         mbuf = SvGROW(mstr, msize+1);
2269
2270         Copy(shm + mpos, mbuf, msize, char);
2271         SvCUR_set(mstr, msize);
2272         *SvEND(mstr) = '\0';
2273         SvSETMAGIC(mstr);
2274 #ifndef INCOMPLETE_TAINTS
2275         /* who knows who has been playing with this shared memory? */
2276         SvTAINTED_on(mstr);
2277 #endif
2278     }
2279     else {
2280         I32 n;
2281
2282         const char *mbuf = SvPV(mstr, len);
2283         if ((n = len) > msize)
2284             n = msize;
2285         Copy(mbuf, shm + mpos, n, char);
2286         if (n < msize)
2287             memzero(shm + mpos + n, msize - n);
2288     }
2289     return shmdt(shm);
2290 #else
2291     Perl_croak(aTHX_ "shm I/O not implemented");
2292 #endif
2293 }
2294
2295 #endif /* SYSV IPC */
2296
2297 /*
2298 =head1 IO Functions
2299
2300 =for apidoc start_glob
2301
2302 Function called by C<do_readline> to spawn a glob (or do the glob inside
2303 perl on VMS). This code used to be inline, but now perl uses C<File::Glob>
2304 this glob starter is only used by miniperl during the build process.
2305 Moving it away shrinks pp_hot.c; shrinking pp_hot.c helps speed perl up.
2306
2307 =cut
2308 */
2309
2310 PerlIO *
2311 Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
2312 {
2313     dVAR;
2314     SV *tmpcmd = NEWSV(55, 0);
2315     PerlIO *fp;
2316     ENTER;
2317     SAVEFREESV(tmpcmd);
2318 #ifdef VMS /* expand the wildcards right here, rather than opening a pipe, */
2319            /* since spawning off a process is a real performance hit */
2320     {
2321 #include <descrip.h>
2322 #include <lib$routines.h>
2323 #include <nam.h>
2324 #include <rmsdef.h>
2325         char rslt[NAM$C_MAXRSS+1+sizeof(unsigned short int)] = {'\0','\0'};
2326         char vmsspec[NAM$C_MAXRSS+1];
2327         char *rstr = rslt + sizeof(unsigned short int), *begin, *end, *cp;
2328         $DESCRIPTOR(dfltdsc,"SYS$DISK:[]*.*;");
2329         PerlIO *tmpfp;
2330         STRLEN i;
2331         struct dsc$descriptor_s wilddsc
2332             = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
2333         struct dsc$descriptor_vs rsdsc
2334             = {sizeof rslt, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, rslt};
2335         unsigned long int cxt = 0, sts = 0, ok = 1, hasdir = 0, hasver = 0, isunix = 0;
2336
2337         /* We could find out if there's an explicit dev/dir or version
2338            by peeking into lib$find_file's internal context at
2339            ((struct NAM *)((struct FAB *)cxt)->fab$l_nam)->nam$l_fnb
2340            but that's unsupported, so I don't want to do it now and
2341            have it bite someone in the future. */
2342         cp = SvPV(tmpglob,i);
2343         for (; i; i--) {
2344             if (cp[i] == ';') hasver = 1;
2345             if (cp[i] == '.') {
2346                 if (sts) hasver = 1;
2347                 else sts = 1;
2348             }
2349             if (cp[i] == '/') {
2350                 hasdir = isunix = 1;
2351                 break;
2352             }
2353             if (cp[i] == ']' || cp[i] == '>' || cp[i] == ':') {
2354                 hasdir = 1;
2355                 break;
2356             }
2357         }
2358        if ((tmpfp = PerlIO_tmpfile()) != NULL) {
2359             Stat_t st;
2360             if (!PerlLIO_stat(SvPVX_const(tmpglob),&st) && S_ISDIR(st.st_mode))
2361                 ok = ((wilddsc.dsc$a_pointer = tovmspath(SvPVX(tmpglob),vmsspec)) != NULL);
2362             else ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL);
2363             if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer);
2364             for (cp=wilddsc.dsc$a_pointer; ok && cp && *cp; cp++)
2365                 if (*cp == '?') *cp = '%';  /* VMS style single-char wildcard */
2366             while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt,
2367                                                &dfltdsc,NULL,NULL,NULL))&1)) {
2368                 /* with varying string, 1st word of buffer contains result length */
2369                 end = rstr + *((unsigned short int*)rslt);
2370                 if (!hasver) while (*end != ';' && end > rstr) end--;
2371                 *(end++) = '\n';  *end = '\0';
2372                 for (cp = rstr; *cp; cp++) *cp = _tolower(*cp);
2373                 if (hasdir) {
2374                     if (isunix) trim_unixpath(rstr,SvPVX(tmpglob),1);
2375                     begin = rstr;
2376                 }
2377                 else {
2378                     begin = end;
2379                     while (*(--begin) != ']' && *begin != '>') ;
2380                     ++begin;
2381                 }
2382                 ok = (PerlIO_puts(tmpfp,begin) != EOF);
2383             }
2384             if (cxt) (void)lib$find_file_end(&cxt);
2385             if (ok && sts != RMS$_NMF &&
2386                 sts != RMS$_DNF && sts != RMS_FNF) ok = 0;
2387             if (!ok) {
2388                 if (!(sts & 1)) {
2389                     SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts);
2390                 }
2391                 PerlIO_close(tmpfp);
2392                 fp = NULL;
2393             }
2394             else {
2395                 PerlIO_rewind(tmpfp);
2396                 IoTYPE(io) = IoTYPE_RDONLY;
2397                 IoIFP(io) = fp = tmpfp;
2398                 IoFLAGS(io) &= ~IOf_UNTAINT;  /* maybe redundant */
2399             }
2400         }
2401     }
2402 #else /* !VMS */
2403 #ifdef MACOS_TRADITIONAL
2404     sv_setpv(tmpcmd, "glob ");
2405     sv_catsv(tmpcmd, tmpglob);
2406     sv_catpv(tmpcmd, " |");
2407 #else
2408 #ifdef DOSISH
2409 #ifdef OS2
2410     sv_setpv(tmpcmd, "for a in ");
2411     sv_catsv(tmpcmd, tmpglob);
2412     sv_catpv(tmpcmd, "; do echo \"$a\\0\\c\"; done |");
2413 #else
2414 #ifdef DJGPP
2415     sv_setpv(tmpcmd, "/dev/dosglob/"); /* File System Extension */
2416     sv_catsv(tmpcmd, tmpglob);
2417 #else
2418     sv_setpv(tmpcmd, "perlglob ");
2419     sv_catsv(tmpcmd, tmpglob);
2420     sv_catpv(tmpcmd, " |");
2421 #endif /* !DJGPP */
2422 #endif /* !OS2 */
2423 #else /* !DOSISH */
2424 #if defined(CSH)
2425     sv_setpvn(tmpcmd, PL_cshname, PL_cshlen);
2426     sv_catpv(tmpcmd, " -cf 'set nonomatch; glob ");
2427     sv_catsv(tmpcmd, tmpglob);
2428     sv_catpv(tmpcmd, "' 2>/dev/null |");
2429 #else
2430     sv_setpv(tmpcmd, "echo ");
2431     sv_catsv(tmpcmd, tmpglob);
2432 #if 'z' - 'a' == 25
2433     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
2434 #else
2435     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|");
2436 #endif
2437 #endif /* !CSH */
2438 #endif /* !DOSISH */
2439 #endif /* MACOS_TRADITIONAL */
2440     (void)do_open(PL_last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd),
2441                   FALSE, O_RDONLY, 0, Nullfp);
2442     fp = IoIFP(io);
2443 #endif /* !VMS */
2444     LEAVE;
2445     return fp;
2446 }
2447
2448 /*
2449  * Local variables:
2450  * c-indentation-style: bsd
2451  * c-basic-offset: 4
2452  * indent-tabs-mode: t
2453  * End:
2454  *
2455  * ex: set ts=8 sts=4 sw=4 noet:
2456  */