This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
98e7204768c3a811655e1a9e1fdf41ca5cdde66f
[perl5.git] / doio.c
1 /*    doio.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4  *    2000, 2001, 2002, 2003, 2004, 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 #include <signal.h>
52
53 bool
54 Perl_do_open(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
55              int rawmode, int rawperm, PerlIO *supplied_fp)
56 {
57     return do_openn(gv, name, len, as_raw, rawmode, rawperm,
58                     supplied_fp, (SV **) NULL, 0);
59 }
60
61 bool
62 Perl_do_open9(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
63               int rawmode, int rawperm, PerlIO *supplied_fp, SV *svs,
64               I32 num_svs)
65 {
66     return do_openn(gv, name, len, as_raw, rawmode, rawperm,
67                     supplied_fp, &svs, 1);
68 }
69
70 bool
71 Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
72               int rawmode, int rawperm, PerlIO *supplied_fp, SV **svp,
73               I32 num_svs)
74 {
75     register IO *io = GvIOn(gv);
76     PerlIO *saveifp = Nullfp;
77     PerlIO *saveofp = Nullfp;
78     int savefd = -1;
79     char savetype = IoTYPE_CLOSED;
80     int writing = 0;
81     PerlIO *fp;
82     int fd;
83     int result;
84     bool was_fdopen = FALSE;
85     bool in_raw = 0, in_crlf = 0, out_raw = 0, out_crlf = 0;
86     char *type  = NULL;
87     char mode[8];               /* stdio file mode ("r\0", "rb\0", "r+b\0" etc.) */
88     SV *namesv;
89
90     Zero(mode,sizeof(mode),char);
91     PL_forkprocess = 1;         /* assume true if no fork */
92
93     /* Collect default raw/crlf info from the op */
94     if (PL_op && PL_op->op_type == OP_OPEN) {
95         /* set up IO layers */
96         U8 flags = PL_op->op_private;
97         in_raw = (flags & OPpOPEN_IN_RAW);
98         in_crlf = (flags & OPpOPEN_IN_CRLF);
99         out_raw = (flags & OPpOPEN_OUT_RAW);
100         out_crlf = (flags & OPpOPEN_OUT_CRLF);
101     }
102
103     /* If currently open - close before we re-open */
104     if (IoIFP(io)) {
105         fd = PerlIO_fileno(IoIFP(io));
106         if (IoTYPE(io) == IoTYPE_STD) {
107             /* This is a clone of one of STD* handles */
108             result = 0;
109         }
110         else if (fd >= 0 && fd <= PL_maxsysfd) {
111             /* This is one of the original STD* handles */
112             saveifp  = IoIFP(io);
113             saveofp  = IoOFP(io);
114             savetype = IoTYPE(io);
115             savefd   = fd;
116             result   = 0;
117         }
118         else if (IoTYPE(io) == IoTYPE_PIPE)
119             result = PerlProc_pclose(IoIFP(io));
120         else if (IoIFP(io) != IoOFP(io)) {
121             if (IoOFP(io)) {
122                 result = PerlIO_close(IoOFP(io));
123                 PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */
124             }
125             else
126                 result = PerlIO_close(IoIFP(io));
127         }
128         else
129             result = PerlIO_close(IoIFP(io));
130         if (result == EOF && fd > PL_maxsysfd) {
131             /* Why is this not Perl_warn*() call ? */
132             PerlIO_printf(Perl_error_log,
133                           "Warning: unable to close filehandle %s properly.\n",
134                           GvENAME(gv));
135         }
136         IoOFP(io) = IoIFP(io) = Nullfp;
137     }
138
139     if (as_raw) {
140         /* sysopen style args, i.e. integer mode and permissions */
141         STRLEN ix = 0;
142         int appendtrunc =
143              0
144 #ifdef O_APPEND /* Not fully portable. */
145              |O_APPEND
146 #endif
147 #ifdef O_TRUNC  /* Not fully portable. */
148              |O_TRUNC
149 #endif
150              ;
151         int modifyingmode =
152              O_WRONLY|O_RDWR|O_CREAT|appendtrunc;
153         int ismodifying;
154
155         if (num_svs != 0) {
156              Perl_croak(aTHX_ "panic: sysopen with multiple args");
157         }
158         /* It's not always
159
160            O_RDONLY 0
161            O_WRONLY 1
162            O_RDWR   2
163
164            It might be (in OS/390 and Mac OS Classic it is)
165
166            O_WRONLY 1
167            O_RDONLY 2
168            O_RDWR   3
169
170            This means that simple & with O_RDWR would look
171            like O_RDONLY is present.  Therefore we have to
172            be more careful.
173         */
174         if ((ismodifying = (rawmode & modifyingmode))) {
175              if ((ismodifying & O_WRONLY) == O_WRONLY ||
176                  (ismodifying & O_RDWR)   == O_RDWR   ||
177                  (ismodifying & (O_CREAT|appendtrunc)))
178                   TAINT_PROPER("sysopen");
179         }
180         mode[ix++] = IoTYPE_NUMERIC; /* Marker to openn to use numeric "sysopen" */
181
182 #if defined(USE_64_BIT_RAWIO) && defined(O_LARGEFILE)
183         rawmode |= O_LARGEFILE; /* Transparently largefiley. */
184 #endif
185
186         IoTYPE(io) = PerlIO_intmode2str(rawmode, &mode[ix], &writing);
187
188         namesv = sv_2mortal(newSVpvn(name,strlen(name)));
189         num_svs = 1;
190         svp = &namesv;
191         type = Nullch;
192         fp = PerlIO_openn(aTHX_ type, mode, -1, rawmode, rawperm, NULL, num_svs, svp);
193     }
194     else {
195         /* Regular (non-sys) open */
196         char *oname = name;
197         STRLEN olen = len;
198         char *tend;
199         int dodup = 0;
200         PerlIO *that_fp = NULL;
201
202         type = savepvn(name, len);
203         tend = type+len;
204         SAVEFREEPV(type);
205
206         /* Lose leading and trailing white space */
207         /*SUPPRESS 530*/
208         for (; isSPACE(*type); type++) ;
209         while (tend > type && isSPACE(tend[-1]))
210             *--tend = '\0';
211
212         if (num_svs) {
213             /* New style explicit name, type is just mode and layer info */
214             STRLEN l = 0;
215 #ifdef USE_STDIO
216             if (SvROK(*svp) && !strchr(name,'&')) {
217                 if (ckWARN(WARN_IO))
218                     Perl_warner(aTHX_ packWARN(WARN_IO),
219                             "Can't open a reference");
220                 SETERRNO(EINVAL, LIB_INVARG);
221                 goto say_false;
222             }
223 #endif /* USE_STDIO */
224             name = SvOK(*svp) ? SvPV(*svp, l) : "";
225             len = (I32)l;
226             name = savepvn(name, len);
227             SAVEFREEPV(name);
228         }
229         else {
230             name = type;
231             len  = tend-type;
232         }
233         IoTYPE(io) = *type;
234         if ((*type == IoTYPE_RDWR) && /* scary */
235            (*(type+1) == IoTYPE_RDONLY || *(type+1) == IoTYPE_WRONLY) &&
236             ((!num_svs || (tend > type+1 && tend[-1] != IoTYPE_PIPE)))) {
237             TAINT_PROPER("open");
238             mode[1] = *type++;
239             writing = 1;
240         }
241
242         if (*type == IoTYPE_PIPE) {
243             if (num_svs) {
244                 if (type[1] != IoTYPE_STD) {
245                   unknown_open_mode:
246                     Perl_croak(aTHX_ "Unknown open() mode '%.*s'", (int)olen, oname);
247                 }
248                 type++;
249             }
250             /*SUPPRESS 530*/
251             for (type++; isSPACE(*type); type++) ;
252             if (!num_svs) {
253                 name = type;
254                 len = tend-type;
255             }
256             if (*name == '\0') {
257                 /* command is missing 19990114 */
258                 if (ckWARN(WARN_PIPE))
259                     Perl_warner(aTHX_ packWARN(WARN_PIPE), "Missing command in piped open");
260                 errno = EPIPE;
261                 goto say_false;
262             }
263             if (strNE(name,"-") || num_svs)
264                 TAINT_ENV();
265             TAINT_PROPER("piped open");
266             if (!num_svs && name[len-1] == '|') {
267                 name[--len] = '\0' ;
268                 if (ckWARN(WARN_PIPE))
269                     Perl_warner(aTHX_ packWARN(WARN_PIPE), "Can't open bidirectional pipe");
270             }
271             mode[0] = 'w';
272             writing = 1;
273             if (out_raw)
274                 strcat(mode, "b");
275             else if (out_crlf)
276                 strcat(mode, "t");
277             if (num_svs > 1) {
278                 fp = PerlProc_popen_list(mode, num_svs, svp);
279             }
280             else {
281                 fp = PerlProc_popen(name,mode);
282             }
283             if (num_svs) {
284                 if (*type) {
285                     if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
286                         goto say_false;
287                     }
288                 }
289             }
290         } /* IoTYPE_PIPE */
291         else if (*type == IoTYPE_WRONLY) {
292             TAINT_PROPER("open");
293             type++;
294             if (*type == IoTYPE_WRONLY) {
295                 /* Two IoTYPE_WRONLYs in a row make for an IoTYPE_APPEND. */
296                 mode[0] = IoTYPE(io) = IoTYPE_APPEND;
297                 type++;
298             }
299             else {
300                 mode[0] = 'w';
301             }
302             writing = 1;
303
304             if (out_raw)
305                 strcat(mode, "b");
306             else if (out_crlf)
307                 strcat(mode, "t");
308
309             if (*type == '&') {
310               duplicity:
311                 dodup = PERLIO_DUP_FD;
312                 type++;
313                 if (*type == '=') {
314                     dodup = 0;
315                     type++;
316                 }
317                 if (!num_svs && !*type && supplied_fp) {
318                     /* "<+&" etc. is used by typemaps */
319                     fp = supplied_fp;
320                 }
321                 else {
322                     if (num_svs > 1) {
323                         Perl_croak(aTHX_ "More than one argument to '%c&' open",IoTYPE(io));
324                     }
325                     /*SUPPRESS 530*/
326                     for (; isSPACE(*type); type++) ;
327                     if (num_svs && (SvIOK(*svp) || (SvPOK(*svp) && looks_like_number(*svp)))) {
328                         fd = SvUV(*svp);
329                         num_svs = 0;
330                     }
331                     else if (isDIGIT(*type)) {
332                         fd = atoi(type);
333                     }
334                     else {
335                         IO* thatio;
336                         if (num_svs) {
337                             thatio = sv_2io(*svp);
338                         }
339                         else {
340                             GV *thatgv;
341                             thatgv = gv_fetchpv(type,FALSE,SVt_PVIO);
342                             thatio = GvIO(thatgv);
343                         }
344                         if (!thatio) {
345 #ifdef EINVAL
346                             SETERRNO(EINVAL,SS_IVCHAN);
347 #endif
348                             goto say_false;
349                         }
350                         if ((that_fp = IoIFP(thatio))) {
351                             /* Flush stdio buffer before dup. --mjd
352                              * Unfortunately SEEK_CURing 0 seems to
353                              * be optimized away on most platforms;
354                              * only Solaris and Linux seem to flush
355                              * on that. --jhi */
356 #ifdef USE_SFIO
357                             /* sfio fails to clear error on next
358                                sfwrite, contrary to documentation.
359                                -- Nick Clark */
360                             if (PerlIO_seek(that_fp, 0, SEEK_CUR) == -1)
361                                 PerlIO_clearerr(that_fp);
362 #endif
363                             /* On the other hand, do all platforms
364                              * take gracefully to flushing a read-only
365                              * filehandle?  Perhaps we should do
366                              * fsetpos(src)+fgetpos(dst)?  --nik */
367                             PerlIO_flush(that_fp);
368                             fd = PerlIO_fileno(that_fp);
369                             /* When dup()ing STDIN, STDOUT or STDERR
370                              * explicitly set appropriate access mode */
371                             if (that_fp == PerlIO_stdout()
372                                 || that_fp == PerlIO_stderr())
373                                 IoTYPE(io) = IoTYPE_WRONLY;
374                             else if (that_fp == PerlIO_stdin())
375                                 IoTYPE(io) = IoTYPE_RDONLY;
376                             /* When dup()ing a socket, say result is
377                              * one as well */
378                             else if (IoTYPE(thatio) == IoTYPE_SOCKET)
379                                 IoTYPE(io) = IoTYPE_SOCKET;
380                         }
381                         else
382                             fd = -1;
383                     }
384                     if (!num_svs)
385                         type = Nullch;
386                     if (that_fp) {
387                         fp = PerlIO_fdupopen(aTHX_ that_fp, NULL, dodup);
388                     }
389                     else {
390                         if (dodup)
391                             fd = PerlLIO_dup(fd);
392                         else
393                             was_fdopen = TRUE;
394                         if (!(fp = PerlIO_openn(aTHX_ type,mode,fd,0,0,NULL,num_svs,svp))) {
395                             if (dodup)
396                                 PerlLIO_close(fd);
397                         }
398                     }
399                 }
400             } /* & */
401             else {
402                 /*SUPPRESS 530*/
403                 for (; isSPACE(*type); type++) ;
404                 if (*type == IoTYPE_STD && (!type[1] || isSPACE(type[1]) || type[1] == ':')) {
405                     /*SUPPRESS 530*/
406                     type++;
407                     fp = PerlIO_stdout();
408                     IoTYPE(io) = IoTYPE_STD;
409                     if (num_svs > 1) {
410                         Perl_croak(aTHX_ "More than one argument to '>%c' open",IoTYPE_STD);
411                     }
412                 }
413                 else  {
414                     if (!num_svs) {
415                         namesv = sv_2mortal(newSVpvn(type,strlen(type)));
416                         num_svs = 1;
417                         svp = &namesv;
418                         type = Nullch;
419                     }
420                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
421                 }
422             } /* !& */
423             if (!fp && type && *type && *type != ':' && !isIDFIRST(*type))
424                goto unknown_open_mode;
425         } /* IoTYPE_WRONLY */
426         else if (*type == IoTYPE_RDONLY) {
427             /*SUPPRESS 530*/
428             for (type++; isSPACE(*type); type++) ;
429             mode[0] = 'r';
430             if (in_raw)
431                 strcat(mode, "b");
432             else if (in_crlf)
433                 strcat(mode, "t");
434
435             if (*type == '&') {
436                 goto duplicity;
437             }
438             if (*type == IoTYPE_STD && (!type[1] || isSPACE(type[1]) || type[1] == ':')) {
439                 /*SUPPRESS 530*/
440                 type++;
441                 fp = PerlIO_stdin();
442                 IoTYPE(io) = IoTYPE_STD;
443                 if (num_svs > 1) {
444                     Perl_croak(aTHX_ "More than one argument to '<%c' open",IoTYPE_STD);
445                 }
446             }
447             else {
448                 if (!num_svs) {
449                     namesv = sv_2mortal(newSVpvn(type,strlen(type)));
450                     num_svs = 1;
451                     svp = &namesv;
452                     type = Nullch;
453                 }
454                 fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
455             }
456             if (!fp && type && *type && *type != ':' && !isIDFIRST(*type))
457                goto unknown_open_mode;
458         } /* IoTYPE_RDONLY */
459         else if ((num_svs && /* '-|...' or '...|' */
460                   type[0] == IoTYPE_STD && type[1] == IoTYPE_PIPE) ||
461                  (!num_svs && tend > type+1 && tend[-1] == IoTYPE_PIPE)) {
462             if (num_svs) {
463                 type += 2;   /* skip over '-|' */
464             }
465             else {
466                 *--tend = '\0';
467                 while (tend > type && isSPACE(tend[-1]))
468                     *--tend = '\0';
469                 /*SUPPRESS 530*/
470                 for (; isSPACE(*type); type++) ;
471                 name = type;
472                 len  = tend-type;
473             }
474             if (*name == '\0') {
475                 /* command is missing 19990114 */
476                 if (ckWARN(WARN_PIPE))
477                     Perl_warner(aTHX_ packWARN(WARN_PIPE), "Missing command in piped open");
478                 errno = EPIPE;
479                 goto say_false;
480             }
481             if (strNE(name,"-") || num_svs)
482                 TAINT_ENV();
483             TAINT_PROPER("piped open");
484             mode[0] = 'r';
485             if (in_raw)
486                 strcat(mode, "b");
487             else if (in_crlf)
488                 strcat(mode, "t");
489             if (num_svs > 1) {
490                 fp = PerlProc_popen_list(mode,num_svs,svp);
491             }
492             else {
493                 fp = PerlProc_popen(name,mode);
494             }
495             IoTYPE(io) = IoTYPE_PIPE;
496             if (num_svs) {
497                 for (; isSPACE(*type); type++) ;
498                 if (*type) {
499                     if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
500                         goto say_false;
501                     }
502                 }
503             }
504         }
505         else { /* layer(Args) */
506             if (num_svs)
507                 goto unknown_open_mode;
508             name = type;
509             IoTYPE(io) = IoTYPE_RDONLY;
510             /*SUPPRESS 530*/
511             for (; isSPACE(*name); name++) ;
512             mode[0] = 'r';
513             if (in_raw)
514                 strcat(mode, "b");
515             else if (in_crlf)
516                 strcat(mode, "t");
517             if (strEQ(name,"-")) {
518                 fp = PerlIO_stdin();
519                 IoTYPE(io) = IoTYPE_STD;
520             }
521             else {
522                 if (!num_svs) {
523                     namesv = sv_2mortal(newSVpvn(type,strlen(type)));
524                     num_svs = 1;
525                     svp = &namesv;
526                     type = Nullch;
527                 }
528                 fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
529             }
530         }
531     }
532     if (!fp) {
533         if (ckWARN(WARN_NEWLINE) && IoTYPE(io) == IoTYPE_RDONLY && strchr(name, '\n'))
534             Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
535         goto say_false;
536     }
537
538     if (ckWARN(WARN_IO)) {
539         if ((IoTYPE(io) == IoTYPE_RDONLY) &&
540             (fp == PerlIO_stdout() || fp == PerlIO_stderr())) {
541                 Perl_warner(aTHX_ packWARN(WARN_IO),
542                             "Filehandle STD%s reopened as %s only for input",
543                             ((fp == PerlIO_stdout()) ? "OUT" : "ERR"),
544                             GvENAME(gv));
545         }
546         else if ((IoTYPE(io) == IoTYPE_WRONLY) && fp == PerlIO_stdin()) {
547                 Perl_warner(aTHX_ packWARN(WARN_IO),
548                             "Filehandle STDIN reopened as %s only for output",
549                             GvENAME(gv));
550         }
551     }
552
553     fd = PerlIO_fileno(fp);
554     /* If there is no fd (e.g. PerlIO::scalar) assume it isn't a
555      * socket - this covers PerlIO::scalar - otherwise unless we "know" the
556      * type probe for socket-ness.
557      */
558     if (IoTYPE(io) && IoTYPE(io) != IoTYPE_PIPE && IoTYPE(io) != IoTYPE_STD && fd >= 0) {
559         if (PerlLIO_fstat(fd,&PL_statbuf) < 0) {
560             /* If PerlIO claims to have fd we had better be able to fstat() it. */
561             (void) PerlIO_close(fp);
562             goto say_false;
563         }
564 #ifndef PERL_MICRO
565         if (S_ISSOCK(PL_statbuf.st_mode))
566             IoTYPE(io) = IoTYPE_SOCKET; /* in case a socket was passed in to us */
567 #ifdef HAS_SOCKET
568         else if (
569 #ifdef S_IFMT
570             !(PL_statbuf.st_mode & S_IFMT)
571 #else
572             !PL_statbuf.st_mode
573 #endif
574             && IoTYPE(io) != IoTYPE_WRONLY  /* Dups of STD* filehandles already have */
575             && IoTYPE(io) != IoTYPE_RDONLY  /* type so they aren't marked as sockets */
576         ) {                                 /* on OS's that return 0 on fstat()ed pipe */
577              char tmpbuf[256];
578              Sock_size_t buflen = sizeof tmpbuf;
579              if (PerlSock_getsockname(fd, (struct sockaddr *)tmpbuf, &buflen) >= 0
580                       || errno != ENOTSOCK)
581                     IoTYPE(io) = IoTYPE_SOCKET; /* some OS's return 0 on fstat()ed socket */
582                                                 /* but some return 0 for streams too, sigh */
583         }
584 #endif /* HAS_SOCKET */
585 #endif /* !PERL_MICRO */
586     }
587
588     /* Eeek - FIXME !!!
589      * If this is a standard handle we discard all the layer stuff
590      * and just dup the fd into whatever was on the handle before !
591      */
592
593     if (saveifp) {              /* must use old fp? */
594         /* If fd is less that PL_maxsysfd i.e. STDIN..STDERR
595            then dup the new fileno down
596          */
597         if (saveofp) {
598             PerlIO_flush(saveofp);      /* emulate PerlIO_close() */
599             if (saveofp != saveifp) {   /* was a socket? */
600                 PerlIO_close(saveofp);
601             }
602         }
603         if (savefd != fd) {
604             /* Still a small can-of-worms here if (say) PerlIO::scalar
605                is assigned to (say) STDOUT - for now let dup2() fail
606                and provide the error
607              */
608             if (PerlLIO_dup2(fd, savefd) < 0) {
609                 (void)PerlIO_close(fp);
610                 goto say_false;
611             }
612 #ifdef VMS
613             if (savefd != PerlIO_fileno(PerlIO_stdin())) {
614                 char newname[FILENAME_MAX+1];
615                 if (PerlIO_getname(fp, newname)) {
616                     if (fd == PerlIO_fileno(PerlIO_stdout()))
617                         Perl_vmssetuserlnm(aTHX_ "SYS$OUTPUT", newname);
618                     if (fd == PerlIO_fileno(PerlIO_stderr()))
619                         Perl_vmssetuserlnm(aTHX_ "SYS$ERROR",  newname);
620                 }
621             }
622 #endif
623
624 #if !defined(WIN32)
625            /* PL_fdpid isn't used on Windows, so avoid this useless work.
626             * XXX Probably the same for a lot of other places. */
627             {
628                 Pid_t pid;
629                 SV *sv;
630
631                 LOCK_FDPID_MUTEX;
632                 sv = *av_fetch(PL_fdpid,fd,TRUE);
633                 (void)SvUPGRADE(sv, SVt_IV);
634                 pid = SvIVX(sv);
635                 SvIVX(sv) = 0;
636                 sv = *av_fetch(PL_fdpid,savefd,TRUE);
637                 (void)SvUPGRADE(sv, SVt_IV);
638                 SvIVX(sv) = pid;
639                 UNLOCK_FDPID_MUTEX;
640             }
641 #endif
642
643             if (was_fdopen) {
644                 /* need to close fp without closing underlying fd */
645                 int ofd = PerlIO_fileno(fp);
646                 int dupfd = PerlLIO_dup(ofd);
647 #if defined(HAS_FCNTL) && defined(F_SETFD)
648                 /* Assume if we have F_SETFD we have F_GETFD */
649                 int coe = fcntl(ofd,F_GETFD);
650 #endif
651                 PerlIO_close(fp);
652                 PerlLIO_dup2(dupfd,ofd);
653 #if defined(HAS_FCNTL) && defined(F_SETFD)
654                 /* The dup trick has lost close-on-exec on ofd */
655                 fcntl(ofd,F_SETFD, coe);
656 #endif
657                 PerlLIO_close(dupfd);
658             }
659             else
660                 PerlIO_close(fp);
661         }
662         fp = saveifp;
663         PerlIO_clearerr(fp);
664         fd = PerlIO_fileno(fp);
665     }
666 #if defined(HAS_FCNTL) && defined(F_SETFD)
667     if (fd >= 0) {
668         int save_errno = errno;
669         fcntl(fd,F_SETFD,fd > PL_maxsysfd); /* can change errno */
670         errno = save_errno;
671     }
672 #endif
673     IoIFP(io) = fp;
674
675     IoFLAGS(io) &= ~IOf_NOLINE;
676     if (writing) {
677         if (IoTYPE(io) == IoTYPE_SOCKET
678             || (IoTYPE(io) == IoTYPE_WRONLY && fd >= 0 && S_ISCHR(PL_statbuf.st_mode)) ) {
679             char *s = mode;
680             if (*s == IoTYPE_IMPLICIT || *s == IoTYPE_NUMERIC)
681               s++;
682             *s = 'w';
683             if (!(IoOFP(io) = PerlIO_openn(aTHX_ type,s,fd,0,0,NULL,0,svp))) {
684                 PerlIO_close(fp);
685                 IoIFP(io) = Nullfp;
686                 goto say_false;
687             }
688         }
689         else
690             IoOFP(io) = fp;
691     }
692     return TRUE;
693
694 say_false:
695     IoIFP(io) = saveifp;
696     IoOFP(io) = saveofp;
697     IoTYPE(io) = savetype;
698     return FALSE;
699 }
700
701 PerlIO *
702 Perl_nextargv(pTHX_ register GV *gv)
703 {
704     register SV *sv;
705 #ifndef FLEXFILENAMES
706     int filedev;
707     int fileino;
708 #endif
709     Uid_t fileuid;
710     Gid_t filegid;
711     IO *io = GvIOp(gv);
712
713     if (!PL_argvoutgv)
714         PL_argvoutgv = gv_fetchpv("ARGVOUT",TRUE,SVt_PVIO);
715     if (io && (IoFLAGS(io) & IOf_ARGV) && (IoFLAGS(io) & IOf_START)) {
716         IoFLAGS(io) &= ~IOf_START;
717         if (PL_inplace) {
718             if (!PL_argvout_stack)
719                 PL_argvout_stack = newAV();
720             av_push(PL_argvout_stack, SvREFCNT_inc(PL_defoutgv));
721         }
722     }
723     if (PL_filemode & (S_ISUID|S_ISGID)) {
724         PerlIO_flush(IoIFP(GvIOn(PL_argvoutgv)));  /* chmod must follow last write */
725 #ifdef HAS_FCHMOD
726         if (PL_lastfd != -1)
727             (void)fchmod(PL_lastfd,PL_filemode);
728 #else
729         (void)PerlLIO_chmod(PL_oldname,PL_filemode);
730 #endif
731     }
732     PL_lastfd = -1;
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"PIPE_OPEN_MODE);
941     IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPE_OPEN_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(sv);
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 if (PL_op->op_private & OPpFT_STACKED) {
1342         return PL_laststatval;
1343     }
1344     else {
1345         SV* sv = POPs;
1346         char *s;
1347         STRLEN len;
1348         PUTBACK;
1349         if (SvTYPE(sv) == SVt_PVGV) {
1350             gv = (GV*)sv;
1351             goto do_fstat;
1352         }
1353         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
1354             gv = (GV*)SvRV(sv);
1355             goto do_fstat;
1356         }
1357
1358         s = SvPV(sv, len);
1359         PL_statgv = Nullgv;
1360         sv_setpvn(PL_statname, s, len);
1361         s = SvPVX(PL_statname);         /* s now NUL-terminated */
1362         PL_laststype = OP_STAT;
1363         PL_laststatval = PerlLIO_stat(s, &PL_statcache);
1364         if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(s, '\n'))
1365             Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
1366         return PL_laststatval;
1367     }
1368 }
1369
1370 static char no_prev_lstat[] = "The stat preceding -l _ wasn't an lstat";
1371
1372 I32
1373 Perl_my_lstat(pTHX)
1374 {
1375     dSP;
1376     SV *sv;
1377     STRLEN n_a;
1378     if (PL_op->op_flags & OPf_REF) {
1379         EXTEND(SP,1);
1380         if (cGVOP_gv == PL_defgv) {
1381             if (PL_laststype != OP_LSTAT)
1382                 Perl_croak(aTHX_ no_prev_lstat);
1383             return PL_laststatval;
1384         }
1385         if (ckWARN(WARN_IO)) {
1386             Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1387                     GvENAME(cGVOP_gv));
1388             return (PL_laststatval = -1);
1389         }
1390     }
1391     else if (ckWARN(WARN_IO) && PL_laststype != OP_LSTAT
1392             && (PL_op->op_private & OPpFT_STACKED))
1393         Perl_croak(aTHX_ no_prev_lstat);
1394
1395     PL_laststype = OP_LSTAT;
1396     PL_statgv = Nullgv;
1397     sv = POPs;
1398     PUTBACK;
1399     if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV && ckWARN(WARN_IO)) {
1400         Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
1401                 GvENAME((GV*) SvRV(sv)));
1402         return (PL_laststatval = -1);
1403     }
1404     sv_setpv(PL_statname,SvPV(sv, n_a));
1405     PL_laststatval = PerlLIO_lstat(SvPV(sv, n_a),&PL_statcache);
1406     if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(SvPV(sv, n_a), '\n'))
1407         Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
1408     return PL_laststatval;
1409 }
1410
1411 #ifndef OS2
1412 bool
1413 Perl_do_aexec(pTHX_ SV *really, register SV **mark, register SV **sp)
1414 {
1415     return do_aexec5(really, mark, sp, 0, 0);
1416 }
1417 #endif
1418
1419 bool
1420 Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
1421                int fd, int do_report)
1422 {
1423 #ifdef MACOS_TRADITIONAL
1424     Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
1425 #else
1426     register char **a;
1427     char *tmps = Nullch;
1428     STRLEN n_a;
1429
1430     if (sp > mark) {
1431         New(401,PL_Argv, sp - mark + 1, char*);
1432         a = PL_Argv;
1433         while (++mark <= sp) {
1434             if (*mark)
1435                 *a++ = SvPVx(*mark, n_a);
1436             else
1437                 *a++ = "";
1438         }
1439         *a = Nullch;
1440         if (really)
1441             tmps = SvPV(really, n_a);
1442         if ((!really && *PL_Argv[0] != '/') ||
1443             (really && *tmps != '/'))           /* will execvp use PATH? */
1444             TAINT_ENV();                /* testing IFS here is overkill, probably */
1445         PERL_FPU_PRE_EXEC
1446         if (really && *tmps)
1447             PerlProc_execvp(tmps,EXEC_ARGV_CAST(PL_Argv));
1448         else
1449             PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
1450         PERL_FPU_POST_EXEC
1451         if (ckWARN(WARN_EXEC))
1452             Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
1453                 (really ? tmps : PL_Argv[0]), Strerror(errno));
1454         if (do_report) {
1455             int e = errno;
1456
1457             PerlLIO_write(fd, (void*)&e, sizeof(int));
1458             PerlLIO_close(fd);
1459         }
1460     }
1461     do_execfree();
1462 #endif
1463     return FALSE;
1464 }
1465
1466 void
1467 Perl_do_execfree(pTHX)
1468 {
1469     if (PL_Argv) {
1470         Safefree(PL_Argv);
1471         PL_Argv = Null(char **);
1472     }
1473     if (PL_Cmd) {
1474         Safefree(PL_Cmd);
1475         PL_Cmd = Nullch;
1476     }
1477 }
1478
1479 #if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
1480
1481 bool
1482 Perl_do_exec(pTHX_ char *cmd)
1483 {
1484     return do_exec3(cmd,0,0);
1485 }
1486
1487 bool
1488 Perl_do_exec3(pTHX_ char *cmd, int fd, int do_report)
1489 {
1490     register char **a;
1491     register char *s;
1492
1493     while (*cmd && isSPACE(*cmd))
1494         cmd++;
1495
1496     /* save an extra exec if possible */
1497
1498 #ifdef CSH
1499     {
1500         char flags[10];
1501         if (strnEQ(cmd,PL_cshname,PL_cshlen) &&
1502             strnEQ(cmd+PL_cshlen," -c",3)) {
1503           strcpy(flags,"-c");
1504           s = cmd+PL_cshlen+3;
1505           if (*s == 'f') {
1506               s++;
1507               strcat(flags,"f");
1508           }
1509           if (*s == ' ')
1510               s++;
1511           if (*s++ == '\'') {
1512               char *ncmd = s;
1513
1514               while (*s)
1515                   s++;
1516               if (s[-1] == '\n')
1517                   *--s = '\0';
1518               if (s[-1] == '\'') {
1519                   *--s = '\0';
1520                   PERL_FPU_PRE_EXEC
1521                   PerlProc_execl(PL_cshname,"csh", flags, ncmd, (char*)0);
1522                   PERL_FPU_POST_EXEC
1523                   *s = '\'';
1524                   return FALSE;
1525               }
1526           }
1527         }
1528     }
1529 #endif /* CSH */
1530
1531     /* see if there are shell metacharacters in it */
1532
1533     if (*cmd == '.' && isSPACE(cmd[1]))
1534         goto doshell;
1535
1536     if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
1537         goto doshell;
1538
1539     for (s = cmd; *s && isALNUM(*s); s++) ;     /* catch VAR=val gizmo */
1540     if (*s == '=')
1541         goto doshell;
1542
1543     for (s = cmd; *s; s++) {
1544         if (*s != ' ' && !isALPHA(*s) &&
1545             strchr("$&*(){}[]'\";\\|?<>~`\n",*s)) {
1546             if (*s == '\n' && !s[1]) {
1547                 *s = '\0';
1548                 break;
1549             }
1550             /* handle the 2>&1 construct at the end */
1551             if (*s == '>' && s[1] == '&' && s[2] == '1'
1552                 && s > cmd + 1 && s[-1] == '2' && isSPACE(s[-2])
1553                 && (!s[3] || isSPACE(s[3])))
1554             {
1555                 char *t = s + 3;
1556
1557                 while (*t && isSPACE(*t))
1558                     ++t;
1559                 if (!*t && (PerlLIO_dup2(1,2) != -1)) {
1560                     s[-2] = '\0';
1561                     break;
1562                 }
1563             }
1564           doshell:
1565             PERL_FPU_PRE_EXEC
1566             PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char*)0);
1567             PERL_FPU_POST_EXEC
1568             return FALSE;
1569         }
1570     }
1571
1572     New(402,PL_Argv, (s - cmd) / 2 + 2, char*);
1573     PL_Cmd = savepvn(cmd, s-cmd);
1574     a = PL_Argv;
1575     for (s = PL_Cmd; *s;) {
1576         while (*s && isSPACE(*s)) s++;
1577         if (*s)
1578             *(a++) = s;
1579         while (*s && !isSPACE(*s)) s++;
1580         if (*s)
1581             *s++ = '\0';
1582     }
1583     *a = Nullch;
1584     if (PL_Argv[0]) {
1585         PERL_FPU_PRE_EXEC
1586         PerlProc_execvp(PL_Argv[0],PL_Argv);
1587         PERL_FPU_POST_EXEC
1588         if (errno == ENOEXEC) {         /* for system V NIH syndrome */
1589             do_execfree();
1590             goto doshell;
1591         }
1592         {
1593             int e = errno;
1594
1595             if (ckWARN(WARN_EXEC))
1596                 Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
1597                     PL_Argv[0], Strerror(errno));
1598             if (do_report) {
1599                 PerlLIO_write(fd, (void*)&e, sizeof(int));
1600                 PerlLIO_close(fd);
1601             }
1602         }
1603     }
1604     do_execfree();
1605     return FALSE;
1606 }
1607
1608 #endif /* OS2 || WIN32 */
1609
1610 I32
1611 Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
1612 {
1613     register I32 val;
1614     register I32 val2;
1615     register I32 tot = 0;
1616     char *what;
1617     char *s;
1618     SV **oldmark = mark;
1619     STRLEN n_a;
1620
1621 #define APPLY_TAINT_PROPER() \
1622     STMT_START {                                                        \
1623         if (PL_tainted) { TAINT_PROPER(what); }                         \
1624     } STMT_END
1625
1626     /* This is a first heuristic; it doesn't catch tainting magic. */
1627     if (PL_tainting) {
1628         while (++mark <= sp) {
1629             if (SvTAINTED(*mark)) {
1630                 TAINT;
1631                 break;
1632             }
1633         }
1634         mark = oldmark;
1635     }
1636     switch (type) {
1637     case OP_CHMOD:
1638         what = "chmod";
1639         APPLY_TAINT_PROPER();
1640         if (++mark <= sp) {
1641             val = SvIVx(*mark);
1642             APPLY_TAINT_PROPER();
1643             tot = sp - mark;
1644             while (++mark <= sp) {
1645                 char *name = SvPVx(*mark, n_a);
1646                 APPLY_TAINT_PROPER();
1647                 if (PerlLIO_chmod(name, val))
1648                     tot--;
1649             }
1650         }
1651         break;
1652 #ifdef HAS_CHOWN
1653     case OP_CHOWN:
1654         what = "chown";
1655         APPLY_TAINT_PROPER();
1656         if (sp - mark > 2) {
1657             val = SvIVx(*++mark);
1658             val2 = SvIVx(*++mark);
1659             APPLY_TAINT_PROPER();
1660             tot = sp - mark;
1661             while (++mark <= sp) {
1662                 char *name = SvPVx(*mark, n_a);
1663                 APPLY_TAINT_PROPER();
1664                 if (PerlLIO_chown(name, val, val2))
1665                     tot--;
1666             }
1667         }
1668         break;
1669 #endif
1670 /*
1671 XXX Should we make lchown() directly available from perl?
1672 For now, we'll let Configure test for HAS_LCHOWN, but do
1673 nothing in the core.
1674     --AD  5/1998
1675 */
1676 #ifdef HAS_KILL
1677     case OP_KILL:
1678         what = "kill";
1679         APPLY_TAINT_PROPER();
1680         if (mark == sp)
1681             break;
1682         s = SvPVx(*++mark, n_a);
1683         if (isALPHA(*s)) {
1684             if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1685                 s += 3;
1686             if ((val = whichsig(s)) < 0)
1687                 Perl_croak(aTHX_ "Unrecognized signal name \"%s\"",s);
1688         }
1689         else
1690             val = SvIVx(*mark);
1691         APPLY_TAINT_PROPER();
1692         tot = sp - mark;
1693 #ifdef VMS
1694         /* kill() doesn't do process groups (job trees?) under VMS */
1695         if (val < 0) val = -val;
1696         if (val == SIGKILL) {
1697 #           include <starlet.h>
1698             /* Use native sys$delprc() to insure that target process is
1699              * deleted; supervisor-mode images don't pay attention to
1700              * CRTL's emulation of Unix-style signals and kill()
1701              */
1702             while (++mark <= sp) {
1703                 I32 proc = SvIVx(*mark);
1704                 register unsigned long int __vmssts;
1705                 APPLY_TAINT_PROPER();
1706                 if (!((__vmssts = sys$delprc(&proc,0)) & 1)) {
1707                     tot--;
1708                     switch (__vmssts) {
1709                         case SS$_NONEXPR:
1710                         case SS$_NOSUCHNODE:
1711                             SETERRNO(ESRCH,__vmssts);
1712                             break;
1713                         case SS$_NOPRIV:
1714                             SETERRNO(EPERM,__vmssts);
1715                             break;
1716                         default:
1717                             SETERRNO(EVMSERR,__vmssts);
1718                     }
1719                 }
1720             }
1721             break;
1722         }
1723 #endif
1724         if (val < 0) {
1725             val = -val;
1726             while (++mark <= sp) {
1727                 I32 proc = SvIVx(*mark);
1728                 APPLY_TAINT_PROPER();
1729 #ifdef HAS_KILLPG
1730                 if (PerlProc_killpg(proc,val))  /* BSD */
1731 #else
1732                 if (PerlProc_kill(-proc,val))   /* SYSV */
1733 #endif
1734                     tot--;
1735             }
1736         }
1737         else {
1738             while (++mark <= sp) {
1739                 I32 proc = SvIVx(*mark);
1740                 APPLY_TAINT_PROPER();
1741                 if (PerlProc_kill(proc, val))
1742                     tot--;
1743             }
1744         }
1745         break;
1746 #endif
1747     case OP_UNLINK:
1748         what = "unlink";
1749         APPLY_TAINT_PROPER();
1750         tot = sp - mark;
1751         while (++mark <= sp) {
1752             s = SvPVx(*mark, n_a);
1753             APPLY_TAINT_PROPER();
1754             if (PL_euid || PL_unsafe) {
1755                 if (UNLINK(s))
1756                     tot--;
1757             }
1758             else {      /* don't let root wipe out directories without -U */
1759                 if (PerlLIO_lstat(s,&PL_statbuf) < 0 || S_ISDIR(PL_statbuf.st_mode))
1760                     tot--;
1761                 else {
1762                     if (UNLINK(s))
1763                         tot--;
1764                 }
1765             }
1766         }
1767         break;
1768 #ifdef HAS_UTIME
1769     case OP_UTIME:
1770         what = "utime";
1771         APPLY_TAINT_PROPER();
1772         if (sp - mark > 2) {
1773 #if defined(I_UTIME) || defined(VMS)
1774             struct utimbuf utbuf;
1775 #else
1776             struct {
1777                 Time_t  actime;
1778                 Time_t  modtime;
1779             } utbuf;
1780 #endif
1781
1782            SV* accessed = *++mark;
1783            SV* modified = *++mark;
1784            void * utbufp = &utbuf;
1785
1786            /* Be like C, and if both times are undefined, let the C
1787             * library figure out what to do.  This usually means
1788             * "current time". */
1789
1790            if ( accessed == &PL_sv_undef && modified == &PL_sv_undef )
1791                 utbufp = NULL;
1792            else {
1793                 Zero(&utbuf, sizeof utbuf, char);
1794 #ifdef BIG_TIME
1795                 utbuf.actime = (Time_t)SvNVx(accessed);  /* time accessed */
1796                 utbuf.modtime = (Time_t)SvNVx(modified); /* time modified */
1797 #else
1798                 utbuf.actime = (Time_t)SvIVx(accessed);  /* time accessed */
1799                 utbuf.modtime = (Time_t)SvIVx(modified); /* time modified */
1800 #endif
1801             }
1802             APPLY_TAINT_PROPER();
1803             tot = sp - mark;
1804             while (++mark <= sp) {
1805                 char *name = SvPVx(*mark, n_a);
1806                 APPLY_TAINT_PROPER();
1807                if (PerlLIO_utime(name, utbufp))
1808                     tot--;
1809             }
1810         }
1811         else
1812             tot = 0;
1813         break;
1814 #endif
1815     }
1816     return tot;
1817
1818 #undef APPLY_TAINT_PROPER
1819 }
1820
1821 /* Do the permissions allow some operation?  Assumes statcache already set. */
1822 #ifndef VMS /* VMS' cando is in vms.c */
1823 bool
1824 Perl_cando(pTHX_ Mode_t mode, Uid_t effective, register Stat_t *statbufp)
1825 /* Note: we use `effective' both for uids and gids.
1826  * Here we are betting on Uid_t being equal or wider than Gid_t.  */
1827 {
1828 #ifdef DOSISH
1829     /* [Comments and code from Len Reed]
1830      * MS-DOS "user" is similar to UNIX's "superuser," but can't write
1831      * to write-protected files.  The execute permission bit is set
1832      * by the Miscrosoft C library stat() function for the following:
1833      *          .exe files
1834      *          .com files
1835      *          .bat files
1836      *          directories
1837      * All files and directories are readable.
1838      * Directories and special files, e.g. "CON", cannot be
1839      * write-protected.
1840      * [Comment by Tom Dinger -- a directory can have the write-protect
1841      *          bit set in the file system, but DOS permits changes to
1842      *          the directory anyway.  In addition, all bets are off
1843      *          here for networked software, such as Novell and
1844      *          Sun's PC-NFS.]
1845      */
1846
1847      /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
1848       * too so it will actually look into the files for magic numbers
1849       */
1850      return (mode & statbufp->st_mode) ? TRUE : FALSE;
1851
1852 #else /* ! DOSISH */
1853     if ((effective ? PL_euid : PL_uid) == 0) {  /* root is special */
1854         if (mode == S_IXUSR) {
1855             if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))
1856                 return TRUE;
1857         }
1858         else
1859             return TRUE;                /* root reads and writes anything */
1860         return FALSE;
1861     }
1862     if (statbufp->st_uid == (effective ? PL_euid : PL_uid) ) {
1863         if (statbufp->st_mode & mode)
1864             return TRUE;        /* ok as "user" */
1865     }
1866     else if (ingroup(statbufp->st_gid,effective)) {
1867         if (statbufp->st_mode & mode >> 3)
1868             return TRUE;        /* ok as "group" */
1869     }
1870     else if (statbufp->st_mode & mode >> 6)
1871         return TRUE;    /* ok as "other" */
1872     return FALSE;
1873 #endif /* ! DOSISH */
1874 }
1875 #endif /* ! VMS */
1876
1877 bool
1878 Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
1879 {
1880 #ifdef MACOS_TRADITIONAL
1881     /* This is simply not correct for AppleShare, but fix it yerself. */
1882     return TRUE;
1883 #else
1884     if (testgid == (effective ? PL_egid : PL_gid))
1885         return TRUE;
1886 #ifdef HAS_GETGROUPS
1887 #ifndef NGROUPS
1888 #define NGROUPS 32
1889 #endif
1890     {
1891         Groups_t gary[NGROUPS];
1892         I32 anum;
1893
1894         anum = getgroups(NGROUPS,gary);
1895         while (--anum >= 0)
1896             if (gary[anum] == testgid)
1897                 return TRUE;
1898     }
1899 #endif
1900     return FALSE;
1901 #endif
1902 }
1903
1904 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
1905
1906 I32
1907 Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
1908 {
1909     key_t key;
1910     I32 n, flags;
1911
1912     key = (key_t)SvNVx(*++mark);
1913     n = (optype == OP_MSGGET) ? 0 : SvIVx(*++mark);
1914     flags = SvIVx(*++mark);
1915     SETERRNO(0,0);
1916     switch (optype)
1917     {
1918 #ifdef HAS_MSG
1919     case OP_MSGGET:
1920         return msgget(key, flags);
1921 #endif
1922 #ifdef HAS_SEM
1923     case OP_SEMGET:
1924         return semget(key, n, flags);
1925 #endif
1926 #ifdef HAS_SHM
1927     case OP_SHMGET:
1928         return shmget(key, n, flags);
1929 #endif
1930 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
1931     default:
1932         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
1933 #endif
1934     }
1935     return -1;                  /* should never happen */
1936 }
1937
1938 I32
1939 Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
1940 {
1941     SV *astr;
1942     char *a;
1943     I32 id, n, cmd, infosize, getinfo;
1944     I32 ret = -1;
1945
1946     id = SvIVx(*++mark);
1947     n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
1948     cmd = SvIVx(*++mark);
1949     astr = *++mark;
1950     infosize = 0;
1951     getinfo = (cmd == IPC_STAT);
1952
1953     switch (optype)
1954     {
1955 #ifdef HAS_MSG
1956     case OP_MSGCTL:
1957         if (cmd == IPC_STAT || cmd == IPC_SET)
1958             infosize = sizeof(struct msqid_ds);
1959         break;
1960 #endif
1961 #ifdef HAS_SHM
1962     case OP_SHMCTL:
1963         if (cmd == IPC_STAT || cmd == IPC_SET)
1964             infosize = sizeof(struct shmid_ds);
1965         break;
1966 #endif
1967 #ifdef HAS_SEM
1968     case OP_SEMCTL:
1969 #ifdef Semctl
1970         if (cmd == IPC_STAT || cmd == IPC_SET)
1971             infosize = sizeof(struct semid_ds);
1972         else if (cmd == GETALL || cmd == SETALL)
1973         {
1974             struct semid_ds semds;
1975             union semun semun;
1976 #ifdef EXTRA_F_IN_SEMUN_BUF
1977             semun.buff = &semds;
1978 #else
1979             semun.buf = &semds;
1980 #endif
1981             getinfo = (cmd == GETALL);
1982             if (Semctl(id, 0, IPC_STAT, semun) == -1)
1983                 return -1;
1984             infosize = semds.sem_nsems * sizeof(short);
1985                 /* "short" is technically wrong but much more portable
1986                    than guessing about u_?short(_t)? */
1987         }
1988 #else
1989         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
1990 #endif
1991         break;
1992 #endif
1993 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
1994     default:
1995         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
1996 #endif
1997     }
1998
1999     if (infosize)
2000     {
2001         STRLEN len;
2002         if (getinfo)
2003         {
2004             SvPV_force(astr, len);
2005             a = SvGROW(astr, infosize+1);
2006         }
2007         else
2008         {
2009             a = SvPV(astr, len);
2010             if (len != infosize)
2011                 Perl_croak(aTHX_ "Bad arg length for %s, is %lu, should be %ld",
2012                       PL_op_desc[optype],
2013                       (unsigned long)len,
2014                       (long)infosize);
2015         }
2016     }
2017     else
2018     {
2019         IV i = SvIV(astr);
2020         a = INT2PTR(char *,i);          /* ouch */
2021     }
2022     SETERRNO(0,0);
2023     switch (optype)
2024     {
2025 #ifdef HAS_MSG
2026     case OP_MSGCTL:
2027         ret = msgctl(id, cmd, (struct msqid_ds *)a);
2028         break;
2029 #endif
2030 #ifdef HAS_SEM
2031     case OP_SEMCTL: {
2032 #ifdef Semctl
2033             union semun unsemds;
2034
2035 #ifdef EXTRA_F_IN_SEMUN_BUF
2036             unsemds.buff = (struct semid_ds *)a;
2037 #else
2038             unsemds.buf = (struct semid_ds *)a;
2039 #endif
2040             ret = Semctl(id, n, cmd, unsemds);
2041 #else
2042             Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2043 #endif
2044         }
2045         break;
2046 #endif
2047 #ifdef HAS_SHM
2048     case OP_SHMCTL:
2049         ret = shmctl(id, cmd, (struct shmid_ds *)a);
2050         break;
2051 #endif
2052     }
2053     if (getinfo && ret >= 0) {
2054         SvCUR_set(astr, infosize);
2055         *SvEND(astr) = '\0';
2056         SvSETMAGIC(astr);
2057     }
2058     return ret;
2059 }
2060
2061 I32
2062 Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
2063 {
2064 #ifdef HAS_MSG
2065     SV *mstr;
2066     char *mbuf;
2067     I32 id, msize, flags;
2068     STRLEN len;
2069
2070     id = SvIVx(*++mark);
2071     mstr = *++mark;
2072     flags = SvIVx(*++mark);
2073     mbuf = SvPV(mstr, len);
2074     if ((msize = len - sizeof(long)) < 0)
2075         Perl_croak(aTHX_ "Arg too short for msgsnd");
2076     SETERRNO(0,0);
2077     return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
2078 #else
2079     Perl_croak(aTHX_ "msgsnd not implemented");
2080 #endif
2081 }
2082
2083 I32
2084 Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
2085 {
2086 #ifdef HAS_MSG
2087     SV *mstr;
2088     char *mbuf;
2089     long mtype;
2090     I32 id, msize, flags, ret;
2091     STRLEN len;
2092
2093     id = SvIVx(*++mark);
2094     mstr = *++mark;
2095     /* suppress warning when reading into undef var --jhi */
2096     if (! SvOK(mstr))
2097         sv_setpvn(mstr, "", 0);
2098     msize = SvIVx(*++mark);
2099     mtype = (long)SvIVx(*++mark);
2100     flags = SvIVx(*++mark);
2101     SvPV_force(mstr, len);
2102     mbuf = SvGROW(mstr, sizeof(long)+msize+1);
2103
2104     SETERRNO(0,0);
2105     ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
2106     if (ret >= 0) {
2107         SvCUR_set(mstr, sizeof(long)+ret);
2108         *SvEND(mstr) = '\0';
2109 #ifndef INCOMPLETE_TAINTS
2110         /* who knows who has been playing with this message? */
2111         SvTAINTED_on(mstr);
2112 #endif
2113     }
2114     return ret;
2115 #else
2116     Perl_croak(aTHX_ "msgrcv not implemented");
2117 #endif
2118 }
2119
2120 I32
2121 Perl_do_semop(pTHX_ SV **mark, SV **sp)
2122 {
2123 #ifdef HAS_SEM
2124     SV *opstr;
2125     char *opbuf;
2126     I32 id;
2127     STRLEN opsize;
2128
2129     id = SvIVx(*++mark);
2130     opstr = *++mark;
2131     opbuf = SvPV(opstr, opsize);
2132     if (opsize < 3 * SHORTSIZE
2133         || (opsize % (3 * SHORTSIZE))) {
2134         SETERRNO(EINVAL,LIB_INVARG);
2135         return -1;
2136     }
2137     SETERRNO(0,0);
2138     /* We can't assume that sizeof(struct sembuf) == 3 * sizeof(short). */
2139     {
2140         int nsops  = opsize / (3 * sizeof (short));
2141         int i      = nsops;
2142         short *ops = (short *) opbuf;
2143         short *o   = ops;
2144         struct sembuf *temps, *t;
2145         I32 result;
2146
2147         New (0, temps, nsops, struct sembuf);
2148         t = temps;
2149         while (i--) {
2150             t->sem_num = *o++;
2151             t->sem_op  = *o++;
2152             t->sem_flg = *o++;
2153             t++;
2154         }
2155         result = semop(id, temps, nsops);
2156         t = temps;
2157         o = ops;
2158         i = nsops;
2159         while (i--) {
2160             *o++ = t->sem_num;
2161             *o++ = t->sem_op;
2162             *o++ = t->sem_flg;
2163             t++;
2164         }
2165         Safefree(temps);
2166         return result;
2167     }
2168 #else
2169     Perl_croak(aTHX_ "semop not implemented");
2170 #endif
2171 }
2172
2173 I32
2174 Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
2175 {
2176 #ifdef HAS_SHM
2177     SV *mstr;
2178     char *mbuf, *shm;
2179     I32 id, mpos, msize;
2180     STRLEN len;
2181     struct shmid_ds shmds;
2182
2183     id = SvIVx(*++mark);
2184     mstr = *++mark;
2185     mpos = SvIVx(*++mark);
2186     msize = SvIVx(*++mark);
2187     SETERRNO(0,0);
2188     if (shmctl(id, IPC_STAT, &shmds) == -1)
2189         return -1;
2190     if (mpos < 0 || msize < 0 || mpos + msize > shmds.shm_segsz) {
2191         SETERRNO(EFAULT,SS_ACCVIO);             /* can't do as caller requested */
2192         return -1;
2193     }
2194     shm = (char *)shmat(id, (char*)NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
2195     if (shm == (char *)-1)      /* I hate System V IPC, I really do */
2196         return -1;
2197     if (optype == OP_SHMREAD) {
2198         /* suppress warning when reading into undef var (tchrist 3/Mar/00) */
2199         if (! SvOK(mstr))
2200             sv_setpvn(mstr, "", 0);
2201         SvPV_force(mstr, len);
2202         mbuf = SvGROW(mstr, msize+1);
2203
2204         Copy(shm + mpos, mbuf, msize, char);
2205         SvCUR_set(mstr, msize);
2206         *SvEND(mstr) = '\0';
2207         SvSETMAGIC(mstr);
2208 #ifndef INCOMPLETE_TAINTS
2209         /* who knows who has been playing with this shared memory? */
2210         SvTAINTED_on(mstr);
2211 #endif
2212     }
2213     else {
2214         I32 n;
2215
2216         mbuf = SvPV(mstr, len);
2217         if ((n = len) > msize)
2218             n = msize;
2219         Copy(mbuf, shm + mpos, n, char);
2220         if (n < msize)
2221             memzero(shm + mpos + n, msize - n);
2222     }
2223     return shmdt(shm);
2224 #else
2225     Perl_croak(aTHX_ "shm I/O not implemented");
2226 #endif
2227 }
2228
2229 #endif /* SYSV IPC */
2230
2231 /*
2232 =head1 IO Functions
2233
2234 =for apidoc start_glob
2235
2236 Function called by C<do_readline> to spawn a glob (or do the glob inside
2237 perl on VMS). This code used to be inline, but now perl uses C<File::Glob>
2238 this glob starter is only used by miniperl during the build process.
2239 Moving it away shrinks pp_hot.c; shrinking pp_hot.c helps speed perl up.
2240
2241 =cut
2242 */
2243
2244 PerlIO *
2245 Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
2246 {
2247     SV *tmpcmd = NEWSV(55, 0);
2248     PerlIO *fp;
2249     ENTER;
2250     SAVEFREESV(tmpcmd);
2251 #ifdef VMS /* expand the wildcards right here, rather than opening a pipe, */
2252            /* since spawning off a process is a real performance hit */
2253     {
2254 #include <descrip.h>
2255 #include <lib$routines.h>
2256 #include <nam.h>
2257 #include <rmsdef.h>
2258         char rslt[NAM$C_MAXRSS+1+sizeof(unsigned short int)] = {'\0','\0'};
2259         char vmsspec[NAM$C_MAXRSS+1];
2260         char *rstr = rslt + sizeof(unsigned short int), *begin, *end, *cp;
2261         $DESCRIPTOR(dfltdsc,"SYS$DISK:[]*.*;");
2262         PerlIO *tmpfp;
2263         STRLEN i;
2264         struct dsc$descriptor_s wilddsc
2265             = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
2266         struct dsc$descriptor_vs rsdsc
2267             = {sizeof rslt, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, rslt};
2268         unsigned long int cxt = 0, sts = 0, ok = 1, hasdir = 0, hasver = 0, isunix = 0;
2269
2270         /* We could find out if there's an explicit dev/dir or version
2271            by peeking into lib$find_file's internal context at
2272            ((struct NAM *)((struct FAB *)cxt)->fab$l_nam)->nam$l_fnb
2273            but that's unsupported, so I don't want to do it now and
2274            have it bite someone in the future. */
2275         cp = SvPV(tmpglob,i);
2276         for (; i; i--) {
2277             if (cp[i] == ';') hasver = 1;
2278             if (cp[i] == '.') {
2279                 if (sts) hasver = 1;
2280                 else sts = 1;
2281             }
2282             if (cp[i] == '/') {
2283                 hasdir = isunix = 1;
2284                 break;
2285             }
2286             if (cp[i] == ']' || cp[i] == '>' || cp[i] == ':') {
2287                 hasdir = 1;
2288                 break;
2289             }
2290         }
2291        if ((tmpfp = PerlIO_tmpfile()) != NULL) {
2292             Stat_t st;
2293             if (!PerlLIO_stat(SvPVX(tmpglob),&st) && S_ISDIR(st.st_mode))
2294                 ok = ((wilddsc.dsc$a_pointer = tovmspath(SvPVX(tmpglob),vmsspec)) != NULL);
2295             else ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL);
2296             if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer);
2297             for (cp=wilddsc.dsc$a_pointer; ok && cp && *cp; cp++)
2298                 if (*cp == '?') *cp = '%';  /* VMS style single-char wildcard */
2299             while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt,
2300                                                &dfltdsc,NULL,NULL,NULL))&1)) {
2301                 /* with varying string, 1st word of buffer contains result length */
2302                 end = rstr + *((unsigned short int*)rslt);
2303                 if (!hasver) while (*end != ';' && end > rstr) end--;
2304                 *(end++) = '\n';  *end = '\0';
2305                 for (cp = rstr; *cp; cp++) *cp = _tolower(*cp);
2306                 if (hasdir) {
2307                     if (isunix) trim_unixpath(rstr,SvPVX(tmpglob),1);
2308                     begin = rstr;
2309                 }
2310                 else {
2311                     begin = end;
2312                     while (*(--begin) != ']' && *begin != '>') ;
2313                     ++begin;
2314                 }
2315                 ok = (PerlIO_puts(tmpfp,begin) != EOF);
2316             }
2317             if (cxt) (void)lib$find_file_end(&cxt);
2318             if (ok && sts != RMS$_NMF &&
2319                 sts != RMS$_DNF && sts != RMS_FNF) ok = 0;
2320             if (!ok) {
2321                 if (!(sts & 1)) {
2322                     SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts);
2323                 }
2324                 PerlIO_close(tmpfp);
2325                 fp = NULL;
2326             }
2327             else {
2328                 PerlIO_rewind(tmpfp);
2329                 IoTYPE(io) = IoTYPE_RDONLY;
2330                 IoIFP(io) = fp = tmpfp;
2331                 IoFLAGS(io) &= ~IOf_UNTAINT;  /* maybe redundant */
2332             }
2333         }
2334     }
2335 #else /* !VMS */
2336 #ifdef MACOS_TRADITIONAL
2337     sv_setpv(tmpcmd, "glob ");
2338     sv_catsv(tmpcmd, tmpglob);
2339     sv_catpv(tmpcmd, " |");
2340 #else
2341 #ifdef DOSISH
2342 #ifdef OS2
2343     sv_setpv(tmpcmd, "for a in ");
2344     sv_catsv(tmpcmd, tmpglob);
2345     sv_catpv(tmpcmd, "; do echo \"$a\\0\\c\"; done |");
2346 #else
2347 #ifdef DJGPP
2348     sv_setpv(tmpcmd, "/dev/dosglob/"); /* File System Extension */
2349     sv_catsv(tmpcmd, tmpglob);
2350 #else
2351     sv_setpv(tmpcmd, "perlglob ");
2352     sv_catsv(tmpcmd, tmpglob);
2353     sv_catpv(tmpcmd, " |");
2354 #endif /* !DJGPP */
2355 #endif /* !OS2 */
2356 #else /* !DOSISH */
2357 #if defined(CSH)
2358     sv_setpvn(tmpcmd, PL_cshname, PL_cshlen);
2359     sv_catpv(tmpcmd, " -cf 'set nonomatch; glob ");
2360     sv_catsv(tmpcmd, tmpglob);
2361     sv_catpv(tmpcmd, "' 2>/dev/null |");
2362 #else
2363     sv_setpv(tmpcmd, "echo ");
2364     sv_catsv(tmpcmd, tmpglob);
2365 #if 'z' - 'a' == 25
2366     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
2367 #else
2368     sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|");
2369 #endif
2370 #endif /* !CSH */
2371 #endif /* !DOSISH */
2372 #endif /* MACOS_TRADITIONAL */
2373     (void)do_open(PL_last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd),
2374                   FALSE, O_RDONLY, 0, Nullfp);
2375     fp = IoIFP(io);
2376 #endif /* !VMS */
2377     LEAVE;
2378     return fp;
2379 }