Symbian port of Perl
[p5sagit/p5-mst-13.2.git] / doio.c
1 /*    doio.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4  *    2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  */
10
11 /*
12  * "Far below them they saw the white waters pour into a foaming bowl, and
13  * then swirl darkly about a deep oval basin in the rocks, until they found
14  * their way out again through a narrow gate, and flowed away, fuming and
15  * chattering, into calmer and more level reaches."
16  */
17
18 /* This file contains functions that do the actual I/O on behalf of ops.
19  * For example, pp_print() calls the do_print() function in this file for
20  * each argument needing printing.
21  */
22
23 #include "EXTERN.h"
24 #define PERL_IN_DOIO_C
25 #include "perl.h"
26
27 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
28 #ifndef HAS_SEM
29 #include <sys/ipc.h>
30 #endif
31 #ifdef HAS_MSG
32 #include <sys/msg.h>
33 #endif
34 #ifdef HAS_SHM
35 #include <sys/shm.h>
36 # ifndef HAS_SHMAT_PROTOTYPE
37     extern Shmat_t shmat (int, char *, int);
38 # endif
39 #endif
40 #endif
41
42 #ifdef I_UTIME
43 #  if defined(_MSC_VER) || defined(__MINGW32__)
44 #    include <sys/utime.h>
45 #  else
46 #    include <utime.h>
47 #  endif
48 #endif
49
50 #ifdef O_EXCL
51 #  define OPEN_EXCL O_EXCL
52 #else
53 #  define OPEN_EXCL 0
54 #endif
55
56 #define PERL_MODE_MAX 8
57 #define PERL_FLAGS_MAX 10
58
59 #include <signal.h>
60
61 bool
62 Perl_do_open(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
63              int rawmode, int rawperm, PerlIO *supplied_fp)
64 {
65     return do_openn(gv, name, len, as_raw, rawmode, rawperm,
66                     supplied_fp, (SV **) NULL, 0);
67 }
68
69 bool
70 Perl_do_open9(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
71               int rawmode, int rawperm, PerlIO *supplied_fp, SV *svs,
72               I32 num_svs)
73 {
74     (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         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(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(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(sv));
854                     (void)PerlLIO_rename(PL_oldname,SvPVX(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(sv));
859                     if (link(PL_oldname,SvPVX(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                 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     int status;
1044
1045     if (IoIFP(io)) {
1046         if (IoTYPE(io) == IoTYPE_PIPE) {
1047             status = PerlProc_pclose(IoIFP(io));
1048             if (not_implicit) {
1049                 STATUS_NATIVE_SET(status);
1050                 retval = (STATUS_POSIX == 0);
1051             }
1052             else {
1053                 retval = (status != -1);
1054             }
1055         }
1056         else if (IoTYPE(io) == IoTYPE_STD)
1057             retval = TRUE;
1058         else {
1059             if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {          /* a socket */
1060                 bool prev_err = PerlIO_error(IoOFP(io));
1061                 retval = (PerlIO_close(IoOFP(io)) != EOF && !prev_err);
1062                 PerlIO_close(IoIFP(io));        /* clear stdio, fd already closed */
1063             }
1064             else {
1065                 bool prev_err = PerlIO_error(IoIFP(io));
1066                 retval = (PerlIO_close(IoIFP(io)) != EOF && !prev_err);
1067             }
1068         }
1069         IoOFP(io) = IoIFP(io) = Nullfp;
1070     }
1071     else if (not_implicit) {
1072         SETERRNO(EBADF,SS_IVCHAN);
1073     }
1074
1075     return retval;
1076 }
1077
1078 bool
1079 Perl_do_eof(pTHX_ GV *gv)
1080 {
1081     register IO *io;
1082     int ch;
1083
1084     io = GvIO(gv);
1085
1086     if (!io)
1087         return TRUE;
1088     else if (ckWARN(WARN_IO) && (IoTYPE(io) == IoTYPE_WRONLY))
1089         report_evil_fh(gv, io, OP_phoney_OUTPUT_ONLY);
1090
1091     while (IoIFP(io)) {
1092         int saverrno;
1093
1094         if (PerlIO_has_cntptr(IoIFP(io))) {     /* (the code works without this) */
1095             if (PerlIO_get_cnt(IoIFP(io)) > 0)  /* cheat a little, since */
1096                 return FALSE;                   /* this is the most usual case */
1097         }
1098
1099         saverrno = errno; /* getc and ungetc can stomp on errno */
1100         ch = PerlIO_getc(IoIFP(io));
1101         if (ch != EOF) {
1102             (void)PerlIO_ungetc(IoIFP(io),ch);
1103             errno = saverrno;
1104             return FALSE;
1105         }
1106         errno = saverrno;
1107
1108         if (PerlIO_has_cntptr(IoIFP(io)) && PerlIO_canset_cnt(IoIFP(io))) {
1109             if (PerlIO_get_cnt(IoIFP(io)) < -1)
1110                 PerlIO_set_cnt(IoIFP(io),-1);
1111         }
1112         if (PL_op->op_flags & OPf_SPECIAL) { /* not necessarily a real EOF yet? */
1113             if (gv != PL_argvgv || !nextargv(gv))       /* get another fp handy */
1114                 return TRUE;
1115         }
1116         else
1117             return TRUE;                /* normal fp, definitely end of file */
1118     }
1119     return TRUE;
1120 }
1121
1122 Off_t
1123 Perl_do_tell(pTHX_ GV *gv)
1124 {
1125     register IO *io = 0;
1126     register PerlIO *fp;
1127
1128     if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) {
1129 #ifdef ULTRIX_STDIO_BOTCH
1130         if (PerlIO_eof(fp))
1131             (void)PerlIO_seek(fp, 0L, 2);       /* ultrix 1.2 workaround */
1132 #endif
1133         return PerlIO_tell(fp);
1134     }
1135     if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1136         report_evil_fh(gv, io, PL_op->op_type);
1137     SETERRNO(EBADF,RMS_IFI);
1138     return (Off_t)-1;
1139 }
1140
1141 bool
1142 Perl_do_seek(pTHX_ GV *gv, Off_t pos, int whence)
1143 {
1144     register IO *io = 0;
1145     register PerlIO *fp;
1146
1147     if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) {
1148 #ifdef ULTRIX_STDIO_BOTCH
1149         if (PerlIO_eof(fp))
1150             (void)PerlIO_seek(fp, 0L, 2);       /* ultrix 1.2 workaround */
1151 #endif
1152         return PerlIO_seek(fp, pos, whence) >= 0;
1153     }
1154     if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1155         report_evil_fh(gv, io, PL_op->op_type);
1156     SETERRNO(EBADF,RMS_IFI);
1157     return FALSE;
1158 }
1159
1160 Off_t
1161 Perl_do_sysseek(pTHX_ GV *gv, Off_t pos, int whence)
1162 {
1163     register IO *io = 0;
1164     register PerlIO *fp;
1165
1166     if (gv && (io = GvIO(gv)) && (fp = IoIFP(io)))
1167         return PerlLIO_lseek(PerlIO_fileno(fp), pos, whence);
1168     if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1169         report_evil_fh(gv, io, PL_op->op_type);
1170     SETERRNO(EBADF,RMS_IFI);
1171     return (Off_t)-1;
1172 }
1173
1174 int
1175 Perl_mode_from_discipline(pTHX_ SV *discp)
1176 {
1177     int mode = O_BINARY;
1178     if (discp) {
1179         STRLEN len;
1180         char *s = SvPV(discp,len);
1181         while (*s) {
1182             if (*s == ':') {
1183                 switch (s[1]) {
1184                 case 'r':
1185                     if (s[2] == 'a' && s[3] == 'w'
1186                         && (!s[4] || s[4] == ':' || isSPACE(s[4])))
1187                     {
1188                         mode = O_BINARY;
1189                         s += 4;
1190                         len -= 4;
1191                         break;
1192                     }
1193                     /* FALL THROUGH */
1194                 case 'c':
1195                     if (s[2] == 'r' && s[3] == 'l' && s[4] == 'f'
1196                         && (!s[5] || s[5] == ':' || isSPACE(s[5])))
1197                     {
1198                         mode = O_TEXT;
1199                         s += 5;
1200                         len -= 5;
1201                         break;
1202                     }
1203                     /* FALL THROUGH */
1204                 default:
1205                     goto fail_discipline;
1206                 }
1207             }
1208             else if (isSPACE(*s)) {
1209                 ++s;
1210                 --len;
1211             }
1212             else {
1213                 char *end;
1214 fail_discipline:
1215                 end = strchr(s+1, ':');
1216                 if (!end)
1217                     end = s+len;
1218 #ifndef PERLIO_LAYERS
1219                 Perl_croak(aTHX_ "IO layers (like '%.*s') unavailable", end-s, s);
1220 #else
1221                 len -= end-s;
1222                 s = end;
1223 #endif
1224             }
1225         }
1226     }
1227     return mode;
1228 }
1229
1230 int
1231 Perl_do_binmode(pTHX_ PerlIO *fp, int iotype, int mode)
1232 {
1233  /* The old body of this is now in non-LAYER part of perlio.c
1234   * This is a stub for any XS code which might have been calling it.
1235   */
1236  const char *name = ":raw";
1237 #ifdef PERLIO_USING_CRLF
1238  if (!(mode & O_BINARY))
1239      name = ":crlf";
1240 #endif
1241  return PerlIO_binmode(aTHX_ fp, iotype, mode, name);
1242 }
1243
1244 #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE)
1245 I32
1246 my_chsize(int fd, Off_t length)
1247 {
1248 #ifdef F_FREESP
1249         /* code courtesy of William Kucharski */
1250 #define HAS_CHSIZE
1251
1252     struct flock fl;
1253     Stat_t filebuf;
1254
1255     if (PerlLIO_fstat(fd, &filebuf) < 0)
1256         return -1;
1257
1258     if (filebuf.st_size < length) {
1259
1260         /* extend file length */
1261
1262         if ((PerlLIO_lseek(fd, (length - 1), 0)) < 0)
1263             return -1;
1264
1265         /* write a "0" byte */
1266
1267         if ((PerlLIO_write(fd, "", 1)) != 1)
1268             return -1;
1269     }
1270     else {
1271         /* truncate length */
1272
1273         fl.l_whence = 0;
1274         fl.l_len = 0;
1275         fl.l_start = length;
1276         fl.l_type = F_WRLCK;    /* write lock on file space */
1277
1278         /*
1279         * This relies on the UNDOCUMENTED F_FREESP argument to
1280         * fcntl(2), which truncates the file so that it ends at the
1281         * position indicated by fl.l_start.
1282         *
1283         * Will minor miracles never cease?
1284         */
1285
1286         if (fcntl(fd, F_FREESP, &fl) < 0)
1287             return -1;
1288
1289     }
1290     return 0;
1291 #else
1292     Perl_croak_nocontext("truncate not implemented");
1293 #endif /* F_FREESP */
1294     return -1;
1295 }
1296 #endif /* !HAS_TRUNCATE && !HAS_CHSIZE */
1297
1298 bool
1299 Perl_do_print(pTHX_ register SV *sv, PerlIO *fp)
1300 {
1301     register const char *tmps;
1302     STRLEN len;
1303
1304     /* assuming fp is checked earlier */
1305     if (!sv)
1306         return TRUE;
1307     if (PL_ofmt) {
1308         if (SvGMAGICAL(sv))
1309             mg_get(sv);
1310         if (SvIOK(sv) && SvIVX(sv) != 0) {
1311             PerlIO_printf(fp, PL_ofmt, (NV)SvIVX(sv));
1312             return !PerlIO_error(fp);
1313         }
1314         if (  (SvNOK(sv) && SvNVX(sv) != 0.0)
1315            || (looks_like_number(sv) && sv_2nv(sv) != 0.0) ) {
1316             PerlIO_printf(fp, PL_ofmt, SvNVX(sv));
1317             return !PerlIO_error(fp);
1318         }
1319     }
1320     switch (SvTYPE(sv)) {
1321     case SVt_NULL:
1322         if (ckWARN(WARN_UNINITIALIZED))
1323             report_uninit(sv);
1324         return TRUE;
1325     case SVt_IV:
1326         if (SvIOK(sv)) {
1327             if (SvGMAGICAL(sv))
1328                 mg_get(sv);
1329             if (SvIsUV(sv))
1330                 PerlIO_printf(fp, "%"UVuf, (UV)SvUVX(sv));
1331             else
1332                 PerlIO_printf(fp, "%"IVdf, (IV)SvIVX(sv));
1333             return !PerlIO_error(fp);
1334         }
1335         /* FALL THROUGH */
1336     default:
1337         if (PerlIO_isutf8(fp)) {
1338             if (!SvUTF8(sv))
1339                 sv_utf8_upgrade_flags(sv = sv_mortalcopy(sv),
1340                                       SV_GMAGIC|SV_UTF8_NO_ENCODING);
1341         }
1342         else if (DO_UTF8(sv)) {
1343             if (!sv_utf8_downgrade((sv = sv_mortalcopy(sv)), TRUE)
1344                 && ckWARN_d(WARN_UTF8))
1345             {
1346                 Perl_warner(aTHX_ packWARN(WARN_UTF8), "Wide character in print");
1347             }
1348         }
1349         tmps = SvPV(sv, len);
1350         break;
1351     }
1352     /* To detect whether the process is about to overstep its
1353      * filesize limit we would need getrlimit().  We could then
1354      * also transparently raise the limit with setrlimit() --
1355      * but only until the system hard limit/the filesystem limit,
1356      * at which we would get EPERM.  Note that when using buffered
1357      * io the write failure can be delayed until the flush/close. --jhi */
1358     if (len && (PerlIO_write(fp,tmps,len) == 0))
1359         return FALSE;
1360     return !PerlIO_error(fp);
1361 }
1362
1363 I32
1364 Perl_my_stat(pTHX)
1365 {
1366     dSP;
1367     IO *io;
1368     GV* gv;
1369
1370     if (PL_op->op_flags & OPf_REF) {
1371         EXTEND(SP,1);
1372         gv = cGVOP_gv;
1373       do_fstat:
1374         io = GvIO(gv);
1375         if (io && IoIFP(io)) {
1376             PL_statgv = gv;
1377             sv_setpv(PL_statname,"");
1378             PL_laststype = OP_STAT;
1379             return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache));
1380         }
1381         else {
1382             if (gv == PL_defgv)
1383                 return PL_laststatval;
1384             if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1385                 report_evil_fh(gv, io, PL_op->op_type);
1386             PL_statgv = Nullgv;
1387             sv_setpv(PL_statname,"");
1388             return (PL_laststatval = -1);
1389         }
1390     }
1391     else if (PL_op->op_private & OPpFT_STACKED) {
1392         return PL_laststatval;
1393     }
1394     else {
1395         SV* sv = POPs;
1396         char *s;
1397         STRLEN len;
1398         PUTBACK;
1399         if (SvTYPE(sv) == SVt_PVGV) {
1400             gv = (GV*)sv;
1401             goto do_fstat;
1402         }
1403         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
1404             gv = (GV*)SvRV(sv);
1405             goto do_fstat;
1406         }
1407
1408         s = SvPV(sv, len);
1409         PL_statgv = Nullgv;
1410         sv_setpvn(PL_statname, s, len);
1411         s = SvPVX(PL_statname);         /* s now NUL-terminated */
1412         PL_laststype = OP_STAT;
1413         PL_laststatval = PerlLIO_stat(s, &PL_statcache);
1414         if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(s, '\n'))
1415             Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
1416         return PL_laststatval;
1417     }
1418 }
1419
1420 static const char no_prev_lstat[] = "The stat preceding -l _ wasn't an lstat";
1421
1422 I32
1423 Perl_my_lstat(pTHX)
1424 {
1425     dSP;
1426     SV *sv;
1427     STRLEN n_a;
1428     if (PL_op->op_flags & OPf_REF) {
1429         EXTEND(SP,1);
1430         if (cGVOP_gv == PL_defgv) {
1431             if (PL_laststype != OP_LSTAT)
1432                 Perl_croak(aTHX_ no_prev_lstat);
1433             return PL_laststatval;
1434         }
1435         if (ckWARN(WARN_IO)) {
1436             Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1437                     GvENAME(cGVOP_gv));
1438             return (PL_laststatval = -1);
1439         }
1440     }
1441     else if (ckWARN(WARN_IO) && PL_laststype != OP_LSTAT
1442             && (PL_op->op_private & OPpFT_STACKED))
1443         Perl_croak(aTHX_ no_prev_lstat);
1444
1445     PL_laststype = OP_LSTAT;
1446     PL_statgv = Nullgv;
1447     sv = POPs;
1448     PUTBACK;
1449     if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV && ckWARN(WARN_IO)) {
1450         Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1451                 GvENAME((GV*) SvRV(sv)));
1452         return (PL_laststatval = -1);
1453     }
1454     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                 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                 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                 char *name = SvPVx(*mark, n_a);
1866                 APPLY_TAINT_PROPER();
1867                if (PerlLIO_utime(name, utbufp))
1868                     tot--;
1869             }
1870         }
1871         else
1872             tot = 0;
1873         break;
1874 #endif
1875     }
1876     return tot;
1877
1878 #undef APPLY_TAINT_PROPER
1879 }
1880
1881 /* Do the permissions allow some operation?  Assumes statcache already set. */
1882 #ifndef VMS /* VMS' cando is in vms.c */
1883 bool
1884 Perl_cando(pTHX_ Mode_t mode, Uid_t effective, register Stat_t *statbufp)
1885 /* Note: we use `effective' both for uids and gids.
1886  * Here we are betting on Uid_t being equal or wider than Gid_t.  */
1887 {
1888 #ifdef DOSISH
1889     /* [Comments and code from Len Reed]
1890      * MS-DOS "user" is similar to UNIX's "superuser," but can't write
1891      * to write-protected files.  The execute permission bit is set
1892      * by the Miscrosoft C library stat() function for the following:
1893      *          .exe files
1894      *          .com files
1895      *          .bat files
1896      *          directories
1897      * All files and directories are readable.
1898      * Directories and special files, e.g. "CON", cannot be
1899      * write-protected.
1900      * [Comment by Tom Dinger -- a directory can have the write-protect
1901      *          bit set in the file system, but DOS permits changes to
1902      *          the directory anyway.  In addition, all bets are off
1903      *          here for networked software, such as Novell and
1904      *          Sun's PC-NFS.]
1905      */
1906
1907      /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
1908       * too so it will actually look into the files for magic numbers
1909       */
1910      return (mode & statbufp->st_mode) ? TRUE : FALSE;
1911
1912 #else /* ! DOSISH */
1913     if ((effective ? PL_euid : PL_uid) == 0) {  /* root is special */
1914         if (mode == S_IXUSR) {
1915             if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))
1916                 return TRUE;
1917         }
1918         else
1919             return TRUE;                /* root reads and writes anything */
1920         return FALSE;
1921     }
1922     if (statbufp->st_uid == (effective ? PL_euid : PL_uid) ) {
1923         if (statbufp->st_mode & mode)
1924             return TRUE;        /* ok as "user" */
1925     }
1926     else if (ingroup(statbufp->st_gid,effective)) {
1927         if (statbufp->st_mode & mode >> 3)
1928             return TRUE;        /* ok as "group" */
1929     }
1930     else if (statbufp->st_mode & mode >> 6)
1931         return TRUE;    /* ok as "other" */
1932     return FALSE;
1933 #endif /* ! DOSISH */
1934 }
1935 #endif /* ! VMS */
1936
1937 bool
1938 Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
1939 {
1940 #ifdef MACOS_TRADITIONAL
1941     /* This is simply not correct for AppleShare, but fix it yerself. */
1942     return TRUE;
1943 #else
1944     if (testgid == (effective ? PL_egid : PL_gid))
1945         return TRUE;
1946 #ifdef HAS_GETGROUPS
1947 #ifndef NGROUPS
1948 #define NGROUPS 32
1949 #endif
1950     {
1951         Groups_t gary[NGROUPS];
1952         I32 anum;
1953
1954         anum = getgroups(NGROUPS,gary);
1955         while (--anum >= 0)
1956             if (gary[anum] == testgid)
1957                 return TRUE;
1958     }
1959 #endif
1960     return FALSE;
1961 #endif
1962 }
1963
1964 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
1965
1966 I32
1967 Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
1968 {
1969     key_t key = (key_t)SvNVx(*++mark);
1970     const I32 n = (optype == OP_MSGGET) ? 0 : SvIVx(*++mark);
1971     const I32 flags = SvIVx(*++mark);
1972     (void)sp;
1973
1974     SETERRNO(0,0);
1975     switch (optype)
1976     {
1977 #ifdef HAS_MSG
1978     case OP_MSGGET:
1979         return msgget(key, flags);
1980 #endif
1981 #ifdef HAS_SEM
1982     case OP_SEMGET:
1983         return semget(key, n, flags);
1984 #endif
1985 #ifdef HAS_SHM
1986     case OP_SHMGET:
1987         return shmget(key, n, flags);
1988 #endif
1989 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
1990     default:
1991         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
1992 #endif
1993     }
1994     return -1;                  /* should never happen */
1995 }
1996
1997 I32
1998 Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
1999 {
2000     SV *astr;
2001     char *a;
2002     I32 infosize, getinfo;
2003     I32 ret = -1;
2004     const I32 id  = SvIVx(*++mark);
2005     const I32 n   = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
2006     const I32 cmd = SvIVx(*++mark);
2007     (void)sp;
2008
2009     astr = *++mark;
2010     infosize = 0;
2011     getinfo = (cmd == IPC_STAT);
2012
2013     switch (optype)
2014     {
2015 #ifdef HAS_MSG
2016     case OP_MSGCTL:
2017         if (cmd == IPC_STAT || cmd == IPC_SET)
2018             infosize = sizeof(struct msqid_ds);
2019         break;
2020 #endif
2021 #ifdef HAS_SHM
2022     case OP_SHMCTL:
2023         if (cmd == IPC_STAT || cmd == IPC_SET)
2024             infosize = sizeof(struct shmid_ds);
2025         break;
2026 #endif
2027 #ifdef HAS_SEM
2028     case OP_SEMCTL:
2029 #ifdef Semctl
2030         if (cmd == IPC_STAT || cmd == IPC_SET)
2031             infosize = sizeof(struct semid_ds);
2032         else if (cmd == GETALL || cmd == SETALL)
2033         {
2034             struct semid_ds semds;
2035             union semun semun;
2036 #ifdef EXTRA_F_IN_SEMUN_BUF
2037             semun.buff = &semds;
2038 #else
2039             semun.buf = &semds;
2040 #endif
2041             getinfo = (cmd == GETALL);
2042             if (Semctl(id, 0, IPC_STAT, semun) == -1)
2043                 return -1;
2044             infosize = semds.sem_nsems * sizeof(short);
2045                 /* "short" is technically wrong but much more portable
2046                    than guessing about u_?short(_t)? */
2047         }
2048 #else
2049         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2050 #endif
2051         break;
2052 #endif
2053 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
2054     default:
2055         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2056 #endif
2057     }
2058
2059     if (infosize)
2060     {
2061         STRLEN len;
2062         if (getinfo)
2063         {
2064             SvPV_force(astr, len);
2065             a = SvGROW(astr, infosize+1);
2066         }
2067         else
2068         {
2069             a = SvPV(astr, len);
2070             if (len != infosize)
2071                 Perl_croak(aTHX_ "Bad arg length for %s, is %lu, should be %ld",
2072                       PL_op_desc[optype],
2073                       (unsigned long)len,
2074                       (long)infosize);
2075         }
2076     }
2077     else
2078     {
2079         IV i = SvIV(astr);
2080         a = INT2PTR(char *,i);          /* ouch */
2081     }
2082     SETERRNO(0,0);
2083     switch (optype)
2084     {
2085 #ifdef HAS_MSG
2086     case OP_MSGCTL:
2087         ret = msgctl(id, cmd, (struct msqid_ds *)a);
2088         break;
2089 #endif
2090 #ifdef HAS_SEM
2091     case OP_SEMCTL: {
2092 #ifdef Semctl
2093             union semun unsemds;
2094
2095 #ifdef EXTRA_F_IN_SEMUN_BUF
2096             unsemds.buff = (struct semid_ds *)a;
2097 #else
2098             unsemds.buf = (struct semid_ds *)a;
2099 #endif
2100             ret = Semctl(id, n, cmd, unsemds);
2101 #else
2102             Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2103 #endif
2104         }
2105         break;
2106 #endif
2107 #ifdef HAS_SHM
2108     case OP_SHMCTL:
2109         ret = shmctl(id, cmd, (struct shmid_ds *)a);
2110         break;
2111 #endif
2112     }
2113     if (getinfo && ret >= 0) {
2114         SvCUR_set(astr, infosize);
2115         *SvEND(astr) = '\0';
2116         SvSETMAGIC(astr);
2117     }
2118     return ret;
2119 }
2120
2121 I32
2122 Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
2123 {
2124 #ifdef HAS_MSG
2125     SV *mstr;
2126     char *mbuf;
2127     I32 msize, flags;
2128     STRLEN len;
2129     const I32 id = SvIVx(*++mark);
2130     (void)sp;
2131
2132     mstr = *++mark;
2133     flags = SvIVx(*++mark);
2134     mbuf = SvPV(mstr, len);
2135     if ((msize = len - sizeof(long)) < 0)
2136         Perl_croak(aTHX_ "Arg too short for msgsnd");
2137     SETERRNO(0,0);
2138     return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
2139 #else
2140     Perl_croak(aTHX_ "msgsnd not implemented");
2141 #endif
2142 }
2143
2144 I32
2145 Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
2146 {
2147 #ifdef HAS_MSG
2148     SV *mstr;
2149     char *mbuf;
2150     long mtype;
2151     I32 msize, flags, ret;
2152     STRLEN len;
2153     const I32 id = SvIVx(*++mark);
2154     (void)sp;
2155
2156     mstr = *++mark;
2157     /* suppress warning when reading into undef var --jhi */
2158     if (! SvOK(mstr))
2159         sv_setpvn(mstr, "", 0);
2160     msize = SvIVx(*++mark);
2161     mtype = (long)SvIVx(*++mark);
2162     flags = SvIVx(*++mark);
2163     SvPV_force(mstr, len);
2164     mbuf = SvGROW(mstr, sizeof(long)+msize+1);
2165
2166     SETERRNO(0,0);
2167     ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
2168     if (ret >= 0) {
2169         SvCUR_set(mstr, sizeof(long)+ret);
2170         *SvEND(mstr) = '\0';
2171 #ifndef INCOMPLETE_TAINTS
2172         /* who knows who has been playing with this message? */
2173         SvTAINTED_on(mstr);
2174 #endif
2175     }
2176     return ret;
2177 #else
2178     Perl_croak(aTHX_ "msgrcv not implemented");
2179 #endif
2180 }
2181
2182 I32
2183 Perl_do_semop(pTHX_ SV **mark, SV **sp)
2184 {
2185 #ifdef HAS_SEM
2186     SV *opstr;
2187     char *opbuf;
2188     STRLEN opsize;
2189     const I32 id = SvIVx(*++mark);
2190     (void)sp;
2191
2192     opstr = *++mark;
2193     opbuf = SvPV(opstr, opsize);
2194     if (opsize < 3 * SHORTSIZE
2195         || (opsize % (3 * SHORTSIZE))) {
2196         SETERRNO(EINVAL,LIB_INVARG);
2197         return -1;
2198     }
2199     SETERRNO(0,0);
2200     /* We can't assume that sizeof(struct sembuf) == 3 * sizeof(short). */
2201     {
2202         const int nsops  = opsize / (3 * sizeof (short));
2203         int i      = nsops;
2204         short *ops = (short *) opbuf;
2205         short *o   = ops;
2206         struct sembuf *temps, *t;
2207         I32 result;
2208
2209         New (0, temps, nsops, struct sembuf);
2210         t = temps;
2211         while (i--) {
2212             t->sem_num = *o++;
2213             t->sem_op  = *o++;
2214             t->sem_flg = *o++;
2215             t++;
2216         }
2217         result = semop(id, temps, nsops);
2218         t = temps;
2219         o = ops;
2220         i = nsops;
2221         while (i--) {
2222             *o++ = t->sem_num;
2223             *o++ = t->sem_op;
2224             *o++ = t->sem_flg;
2225             t++;
2226         }
2227         Safefree(temps);
2228         return result;
2229     }
2230 #else
2231     Perl_croak(aTHX_ "semop not implemented");
2232 #endif
2233 }
2234
2235 I32
2236 Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
2237 {
2238 #ifdef HAS_SHM
2239     SV *mstr;
2240     char *mbuf, *shm;
2241     I32 mpos, msize;
2242     STRLEN len;
2243     struct shmid_ds shmds;
2244     const I32 id = SvIVx(*++mark);
2245     (void)sp;
2246
2247     mstr = *++mark;
2248     mpos = SvIVx(*++mark);
2249     msize = SvIVx(*++mark);
2250     SETERRNO(0,0);
2251     if (shmctl(id, IPC_STAT, &shmds) == -1)
2252         return -1;
2253     if (mpos < 0 || msize < 0 || mpos + msize > shmds.shm_segsz) {
2254         SETERRNO(EFAULT,SS_ACCVIO);             /* can't do as caller requested */
2255         return -1;
2256     }
2257     shm = (char *)shmat(id, (char*)NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
2258     if (shm == (char *)-1)      /* I hate System V IPC, I really do */
2259         return -1;
2260     if (optype == OP_SHMREAD) {
2261         /* suppress warning when reading into undef var (tchrist 3/Mar/00) */
2262         if (! SvOK(mstr))
2263             sv_setpvn(mstr, "", 0);
2264         SvPV_force(mstr, len);
2265         mbuf = SvGROW(mstr, msize+1);
2266
2267         Copy(shm + mpos, mbuf, msize, char);
2268         SvCUR_set(mstr, msize);
2269         *SvEND(mstr) = '\0';
2270         SvSETMAGIC(mstr);
2271 #ifndef INCOMPLETE_TAINTS
2272         /* who knows who has been playing with this shared memory? */
2273         SvTAINTED_on(mstr);
2274 #endif
2275     }
2276     else {
2277         I32 n;
2278
2279         mbuf = SvPV(mstr, len);
2280         if ((n = len) > msize)
2281             n = msize;
2282         Copy(mbuf, shm + mpos, n, char);
2283         if (n < msize)
2284             memzero(shm + mpos + n, msize - n);
2285     }
2286     return shmdt(shm);
2287 #else
2288     Perl_croak(aTHX_ "shm I/O not implemented");
2289 #endif
2290 }
2291
2292 #endif /* SYSV IPC */
2293
2294 /*
2295 =head1 IO Functions
2296
2297 =for apidoc start_glob
2298
2299 Function called by C<do_readline> to spawn a glob (or do the glob inside
2300 perl on VMS). This code used to be inline, but now perl uses C<File::Glob>
2301 this glob starter is only used by miniperl during the build process.
2302 Moving it away shrinks pp_hot.c; shrinking pp_hot.c helps speed perl up.
2303
2304 =cut
2305 */
2306
2307 PerlIO *
2308 Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
2309 {
2310     dVAR;
2311     SV *tmpcmd = NEWSV(55, 0);
2312     PerlIO *fp;
2313     ENTER;
2314     SAVEFREESV(tmpcmd);
2315 #ifdef VMS /* expand the wildcards right here, rather than opening a pipe, */
2316            /* since spawning off a process is a real performance hit */
2317     {
2318 #include <descrip.h>
2319 #include <lib$routines.h>
2320 #include <nam.h>
2321 #include <rmsdef.h>
2322         char rslt[NAM$C_MAXRSS+1+sizeof(unsigned short int)] = {'\0','\0'};
2323         char vmsspec[NAM$C_MAXRSS+1];
2324         char *rstr = rslt + sizeof(unsigned short int), *begin, *end, *cp;
2325         $DESCRIPTOR(dfltdsc,"SYS$DISK:[]*.*;");
2326         PerlIO *tmpfp;
2327         STRLEN i;
2328         struct dsc$descriptor_s wilddsc
2329             = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
2330         struct dsc$descriptor_vs rsdsc
2331             = {sizeof rslt, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, rslt};
2332         unsigned long int cxt = 0, sts = 0, ok = 1, hasdir = 0, hasver = 0, isunix = 0;
2333
2334         /* We could find out if there's an explicit dev/dir or version
2335            by peeking into lib$find_file's internal context at
2336            ((struct NAM *)((struct FAB *)cxt)->fab$l_nam)->nam$l_fnb
2337            but that's unsupported, so I don't want to do it now and
2338            have it bite someone in the future. */
2339         cp = SvPV(tmpglob,i);
2340         for (; i; i--) {
2341             if (cp[i] == ';') hasver = 1;
2342             if (cp[i] == '.') {
2343                 if (sts) hasver = 1;
2344                 else sts = 1;
2345             }
2346             if (cp[i] == '/') {
2347                 hasdir = isunix = 1;
2348                 break;
2349             }
2350             if (cp[i] == ']' || cp[i] == '>' || cp[i] == ':') {
2351                 hasdir = 1;
2352                 break;
2353             }
2354         }
2355        if ((tmpfp = PerlIO_tmpfile()) != NULL) {
2356             Stat_t st;
2357             if (!PerlLIO_stat(SvPVX(tmpglob),&st) && S_ISDIR(st.st_mode))
2358                 ok = ((wilddsc.dsc$a_pointer = tovmspath(SvPVX(tmpglob),vmsspec)) != NULL);
2359             else ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL);
2360             if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer);
2361             for (cp=wilddsc.dsc$a_pointer; ok && cp && *cp; cp++)
2362                 if (*cp == '?') *cp = '%';  /* VMS style single-char wildcard */
2363             while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt,
2364                                                &dfltdsc,NULL,NULL,NULL))&1)) {
2365                 /* with varying string, 1st word of buffer contains result length */
2366                 end = rstr + *((unsigned short int*)rslt);
2367                 if (!hasver) while (*end != ';' && end > rstr) end--;
2368                 *(end++) = '\n';  *end = '\0';
2369                 for (cp = rstr; *cp; cp++) *cp = _tolower(*cp);
2370                 if (hasdir) {
2371                     if (isunix) trim_unixpath(rstr,SvPVX(tmpglob),1);
2372                     begin = rstr;
2373                 }
2374                 else {
2375                     begin = end;
2376                     while (*(--begin) != ']' && *begin != '>') ;
2377                     ++begin;
2378                 }
2379                 ok = (PerlIO_puts(tmpfp,begin) != EOF);
2380             }
2381             if (cxt) (void)lib$find_file_end(&cxt);
2382             if (ok && sts != RMS$_NMF &&
2383                 sts != RMS$_DNF && sts != RMS_FNF) ok = 0;
2384             if (!ok) {
2385                 if (!(sts & 1)) {
2386                     SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts);
2387                 }
2388                 PerlIO_close(tmpfp);
2389                 fp = NULL;
2390             }
2391             else {
2392                 PerlIO_rewind(tmpfp);
2393                 IoTYPE(io) = IoTYPE_RDONLY;
2394                 IoIFP(io) = fp = tmpfp;
2395                 IoFLAGS(io) &= ~IOf_UNTAINT;  /* maybe redundant */
2396             }
2397         }
2398     }
2399 #else /* !VMS */
2400 #ifdef MACOS_TRADITIONAL
2401     sv_setpv(tmpcmd, "glob ");
2402     sv_catsv(tmpcmd, tmpglob);
2403     sv_catpv(tmpcmd, " |");
2404 #else
2405 #ifdef DOSISH
2406 #ifdef OS2
2407     sv_setpv(tmpcmd, "for a in ");
2408     sv_catsv(tmpcmd, tmpglob);
2409     sv_catpv(tmpcmd, "; do echo \"$a\\0\\c\"; done |");
2410 #else
2411 #ifdef DJGPP
2412     sv_setpv(tmpcmd, "/dev/dosglob/"); /* File System Extension */
2413     sv_catsv(tmpcmd, tmpglob);
2414 #else
2415     sv_setpv(tmpcmd, "perlglob ");
2416     sv_catsv(tmpcmd, tmpglob);
2417     sv_catpv(tmpcmd, " |");
2418 #endif /* !DJGPP */
2419 #endif /* !OS2 */
2420 #else /* !DOSISH */
2421 #if defined(CSH)
2422     sv_setpvn(tmpcmd, PL_cshname, PL_cshlen);
2423     sv_catpv(tmpcmd, " -cf 'set nonomatch; glob ");
2424     sv_catsv(tmpcmd, tmpglob);
2425     sv_catpv(tmpcmd, "' 2>/dev/null |");
2426 #else
2427     sv_setpv(tmpcmd, "echo ");
2428     sv_catsv(tmpcmd, tmpglob);
2429 #if 'z' - 'a' == 25
2430     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
2431 #else
2432     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|");
2433 #endif
2434 #endif /* !CSH */
2435 #endif /* !DOSISH */
2436 #endif /* MACOS_TRADITIONAL */
2437     (void)do_open(PL_last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd),
2438                   FALSE, O_RDONLY, 0, Nullfp);
2439     fp = IoIFP(io);
2440 #endif /* !VMS */
2441     LEAVE;
2442     return fp;
2443 }