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