regcomp.c: Rmv unnecessary else
[perl.git] / doio.c
1 /*    doio.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4  *    2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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  *     [p.684 of _The Lord of the Rings_, IV/vi: "The Forbidden Pool"]
18  */
19
20 /* This file contains functions that do the actual I/O on behalf of ops.
21  * For example, pp_print() calls the do_print() function in this file for
22  * each argument needing printing.
23  */
24
25 #include "EXTERN.h"
26 #define PERL_IN_DOIO_C
27 #include "perl.h"
28
29 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
30 #ifndef HAS_SEM
31 #include <sys/ipc.h>
32 #endif
33 #ifdef HAS_MSG
34 #include <sys/msg.h>
35 #endif
36 #ifdef HAS_SHM
37 #include <sys/shm.h>
38 # ifndef HAS_SHMAT_PROTOTYPE
39     extern Shmat_t shmat (int, char *, int);
40 # endif
41 #endif
42 #endif
43
44 #ifdef I_UTIME
45 #  if defined(_MSC_VER) || defined(__MINGW32__)
46 #    include <sys/utime.h>
47 #  else
48 #    include <utime.h>
49 #  endif
50 #endif
51
52 #ifdef O_EXCL
53 #  define OPEN_EXCL O_EXCL
54 #else
55 #  define OPEN_EXCL 0
56 #endif
57
58 #define PERL_MODE_MAX 8
59 #define PERL_FLAGS_MAX 10
60
61 #include <signal.h>
62
63 void
64 Perl_setfd_cloexec(int fd)
65 {
66     assert(fd >= 0);
67 #if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
68     (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
69 #endif
70 }
71
72 void
73 Perl_setfd_inhexec(int fd)
74 {
75     assert(fd >= 0);
76 #if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
77     (void) fcntl(fd, F_SETFD, 0);
78 #endif
79 }
80
81 void
82 Perl_setfd_cloexec_for_nonsysfd(pTHX_ int fd)
83 {
84     assert(fd >= 0);
85     if(fd > PL_maxsysfd)
86         setfd_cloexec(fd);
87 }
88
89 void
90 Perl_setfd_inhexec_for_sysfd(pTHX_ int fd)
91 {
92     assert(fd >= 0);
93     if(fd <= PL_maxsysfd)
94         setfd_inhexec(fd);
95 }
96 void
97 Perl_setfd_cloexec_or_inhexec_by_sysfdness(pTHX_ int fd)
98 {
99     assert(fd >= 0);
100     if(fd <= PL_maxsysfd)
101         setfd_inhexec(fd);
102     else
103         setfd_cloexec(fd);
104 }
105
106
107 #define DO_GENOPEN_THEN_CLOEXEC(GENOPEN_NORMAL, GENSETFD_CLOEXEC) \
108         do { \
109             int res = (GENOPEN_NORMAL); \
110             if(LIKELY(res != -1)) GENSETFD_CLOEXEC; \
111             return res; \
112         } while(0)
113 #if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) && \
114                         defined(F_GETFD)
115 enum { CLOEXEC_EXPERIMENT, CLOEXEC_AT_OPEN, CLOEXEC_AFTER_OPEN };
116 #  define DO_GENOPEN_EXPERIMENTING_CLOEXEC(TESTFD, GENOPEN_CLOEXEC, \
117                         GENOPEN_NORMAL, GENSETFD_CLOEXEC) \
118         do { \
119             static int strategy = CLOEXEC_EXPERIMENT; \
120             switch (strategy) { \
121                 case CLOEXEC_EXPERIMENT: default: { \
122                     int res = (GENOPEN_CLOEXEC), eno; \
123                     if (LIKELY(res != -1)) { \
124                         int fdflags = fcntl((TESTFD), F_GETFD); \
125                         if (LIKELY(fdflags != -1) && \
126                                 LIKELY(fdflags & FD_CLOEXEC)) { \
127                             strategy = CLOEXEC_AT_OPEN; \
128                         } else { \
129                             strategy = CLOEXEC_AFTER_OPEN; \
130                             GENSETFD_CLOEXEC; \
131                         } \
132                     } else if (UNLIKELY((eno = errno) == EINVAL || \
133                                                 eno == ENOSYS)) { \
134                         res = (GENOPEN_NORMAL); \
135                         if (LIKELY(res != -1)) { \
136                             strategy = CLOEXEC_AFTER_OPEN; \
137                             GENSETFD_CLOEXEC; \
138                         } else if (!LIKELY((eno = errno) == EINVAL || \
139                                                 eno == ENOSYS)) { \
140                             strategy = CLOEXEC_AFTER_OPEN; \
141                         } \
142                     } \
143                     return res; \
144                 } \
145                 case CLOEXEC_AT_OPEN: \
146                     return (GENOPEN_CLOEXEC); \
147                 case CLOEXEC_AFTER_OPEN: \
148                     DO_GENOPEN_THEN_CLOEXEC(GENOPEN_NORMAL, GENSETFD_CLOEXEC); \
149             } \
150         } while(0)
151 #else
152 #  define DO_GENOPEN_EXPERIMENTING_CLOEXEC(TESTFD, GENOPEN_CLOEXEC, \
153                         GENOPEN_NORMAL, GENSETFD_CLOEXEC) \
154         DO_GENOPEN_THEN_CLOEXEC(GENOPEN_NORMAL, GENSETFD_CLOEXEC)
155 #endif
156
157 #define DO_ONEOPEN_THEN_CLOEXEC(ONEOPEN_NORMAL) \
158         do { \
159             int fd; \
160             DO_GENOPEN_THEN_CLOEXEC(fd = (ONEOPEN_NORMAL), \
161                 setfd_cloexec(fd)); \
162         } while(0)
163 #define DO_ONEOPEN_EXPERIMENTING_CLOEXEC(ONEOPEN_CLOEXEC, ONEOPEN_NORMAL) \
164         do { \
165             int fd; \
166             DO_GENOPEN_EXPERIMENTING_CLOEXEC(fd, fd = (ONEOPEN_CLOEXEC), \
167                 fd = (ONEOPEN_NORMAL), setfd_cloexec(fd)); \
168         } while(0)
169
170 #define DO_PIPESETFD_CLOEXEC(PIPEFD) \
171         do { \
172             setfd_cloexec((PIPEFD)[0]); \
173             setfd_cloexec((PIPEFD)[1]); \
174         } while(0)
175 #define DO_PIPEOPEN_THEN_CLOEXEC(PIPEFD, PIPEOPEN_NORMAL) \
176         DO_GENOPEN_THEN_CLOEXEC(PIPEOPEN_NORMAL, DO_PIPESETFD_CLOEXEC(PIPEFD))
177 #define DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(PIPEFD, PIPEOPEN_CLOEXEC, \
178                         PIPEOPEN_NORMAL) \
179         DO_GENOPEN_EXPERIMENTING_CLOEXEC((PIPEFD)[0], PIPEOPEN_CLOEXEC, \
180             PIPEOPEN_NORMAL, DO_PIPESETFD_CLOEXEC(PIPEFD))
181
182 int
183 Perl_PerlLIO_dup_cloexec(pTHX_ int oldfd)
184 {
185 #if !defined(PERL_IMPLICIT_SYS) && defined(F_DUPFD_CLOEXEC)
186     /*
187      * struct IPerlLIO doesn't cover fcntl(), and there's no clear way
188      * to extend it, so for the time being this just isn't available on
189      * PERL_IMPLICIT_SYS builds.
190      */
191     DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
192         fcntl(oldfd, F_DUPFD_CLOEXEC, 0),
193         PerlLIO_dup(oldfd));
194 #else
195     DO_ONEOPEN_THEN_CLOEXEC(PerlLIO_dup(oldfd));
196 #endif
197 }
198
199 int
200 Perl_PerlLIO_dup2_cloexec(pTHX_ int oldfd, int newfd)
201 {
202 #if !defined(PERL_IMPLICIT_SYS) && defined(HAS_DUP3) && defined(O_CLOEXEC)
203     /*
204      * struct IPerlLIO doesn't cover dup3(), and there's no clear way
205      * to extend it, so for the time being this just isn't available on
206      * PERL_IMPLICIT_SYS builds.
207      */
208     DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
209         dup3(oldfd, newfd, O_CLOEXEC),
210         PerlLIO_dup2(oldfd, newfd));
211 #else
212     DO_ONEOPEN_THEN_CLOEXEC(PerlLIO_dup2(oldfd, newfd));
213 #endif
214 }
215
216 int
217 Perl_PerlLIO_open_cloexec(pTHX_ const char *file, int flag)
218 {
219     PERL_ARGS_ASSERT_PERLLIO_OPEN_CLOEXEC;
220 #if defined(O_CLOEXEC)
221     DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
222         PerlLIO_open(file, flag | O_CLOEXEC),
223         PerlLIO_open(file, flag));
224 #else
225     DO_ONEOPEN_THEN_CLOEXEC(PerlLIO_open(file, flag));
226 #endif
227 }
228
229 int
230 Perl_PerlLIO_open3_cloexec(pTHX_ const char *file, int flag, int perm)
231 {
232     PERL_ARGS_ASSERT_PERLLIO_OPEN3_CLOEXEC;
233 #if defined(O_CLOEXEC)
234     DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
235         PerlLIO_open3(file, flag | O_CLOEXEC, perm),
236         PerlLIO_open3(file, flag, perm));
237 #else
238     DO_ONEOPEN_THEN_CLOEXEC(PerlLIO_open3(file, flag, perm));
239 #endif
240 }
241
242 int
243 Perl_my_mkstemp_cloexec(char *templte)
244 {
245     PERL_ARGS_ASSERT_MY_MKSTEMP_CLOEXEC;
246 #if defined(O_CLOEXEC)
247     DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
248         Perl_my_mkostemp(templte, O_CLOEXEC),
249         Perl_my_mkstemp(templte));
250 #else
251     DO_ONEOPEN_THEN_CLOEXEC(Perl_my_mkstemp(templte));
252 #endif
253 }
254
255 #ifdef HAS_PIPE
256 int
257 Perl_PerlProc_pipe_cloexec(pTHX_ int *pipefd)
258 {
259     PERL_ARGS_ASSERT_PERLPROC_PIPE_CLOEXEC;
260     /*
261      * struct IPerlProc doesn't cover pipe2(), and there's no clear way
262      * to extend it, so for the time being this just isn't available on
263      * PERL_IMPLICIT_SYS builds.
264      */
265 #  if !defined(PERL_IMPLICIT_SYS) && defined(HAS_PIPE2) && defined(O_CLOEXEC)
266     DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(pipefd,
267         pipe2(pipefd, O_CLOEXEC),
268         PerlProc_pipe(pipefd));
269 #  else
270     DO_PIPEOPEN_THEN_CLOEXEC(pipefd, PerlProc_pipe(pipefd));
271 #  endif
272 }
273 #endif
274
275 #ifdef HAS_SOCKET
276
277 int
278 Perl_PerlSock_socket_cloexec(pTHX_ int domain, int type, int protocol)
279 {
280 #  if defined(SOCK_CLOEXEC)
281     DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
282         PerlSock_socket(domain, type | SOCK_CLOEXEC, protocol),
283         PerlSock_socket(domain, type, protocol));
284 #  else
285     DO_ONEOPEN_THEN_CLOEXEC(PerlSock_socket(domain, type, protocol));
286 #  endif
287 }
288
289 int
290 Perl_PerlSock_accept_cloexec(pTHX_ int listenfd, struct sockaddr *addr,
291     Sock_size_t *addrlen)
292 {
293 #  if !defined(PERL_IMPLICIT_SYS) && \
294         defined(HAS_ACCEPT4) && defined(SOCK_CLOEXEC)
295     /*
296      * struct IPerlSock doesn't cover accept4(), and there's no clear
297      * way to extend it, so for the time being this just isn't available
298      * on PERL_IMPLICIT_SYS builds.
299      */
300     DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
301         accept4(listenfd, addr, addrlen, SOCK_CLOEXEC),
302         PerlSock_accept(listenfd, addr, addrlen));
303 #  else
304     DO_ONEOPEN_THEN_CLOEXEC(PerlSock_accept(listenfd, addr, addrlen));
305 #  endif
306 }
307
308 #endif
309
310 #if defined (HAS_SOCKETPAIR) || \
311     (defined (HAS_SOCKET) && defined(SOCK_DGRAM) && \
312         defined(AF_INET) && defined(PF_INET))
313 int
314 Perl_PerlSock_socketpair_cloexec(pTHX_ int domain, int type, int protocol,
315     int *pairfd)
316 {
317     PERL_ARGS_ASSERT_PERLSOCK_SOCKETPAIR_CLOEXEC;
318 #  ifdef SOCK_CLOEXEC
319     DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(pairfd,
320         PerlSock_socketpair(domain, type | SOCK_CLOEXEC, protocol, pairfd),
321         PerlSock_socketpair(domain, type, protocol, pairfd));
322 #  else
323     DO_PIPEOPEN_THEN_CLOEXEC(pairfd,
324         PerlSock_socketpair(domain, type, protocol, pairfd));
325 #  endif
326 }
327 #endif
328
329 static IO *
330 S_openn_setup(pTHX_ GV *gv, char *mode, PerlIO **saveifp, PerlIO **saveofp,
331               int *savefd,  char *savetype)
332 {
333     IO * const io = GvIOn(gv);
334
335     PERL_ARGS_ASSERT_OPENN_SETUP;
336
337     *saveifp = NULL;
338     *saveofp = NULL;
339     *savefd = -1;
340     *savetype = IoTYPE_CLOSED;
341
342     Zero(mode,sizeof(mode),char);
343     PL_forkprocess = 1;         /* assume true if no fork */
344
345     /* If currently open - close before we re-open */
346     if (IoIFP(io)) {
347         if (IoTYPE(io) == IoTYPE_STD) {
348             /* This is a clone of one of STD* handles */
349         }
350         else {
351             const int old_fd = PerlIO_fileno(IoIFP(io));
352
353             if (old_fd >= 0 && old_fd <= PL_maxsysfd) {
354                 /* This is one of the original STD* handles */
355                 *saveifp  = IoIFP(io);
356                 *saveofp  = IoOFP(io);
357                 *savetype = IoTYPE(io);
358                 *savefd   = old_fd;
359             }
360             else {
361                 int result;
362
363                 if (IoTYPE(io) == IoTYPE_PIPE)
364                     result = PerlProc_pclose(IoIFP(io));
365                 else if (IoIFP(io) != IoOFP(io)) {
366                     if (IoOFP(io)) {
367                         result = PerlIO_close(IoOFP(io));
368                         PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */
369                     }
370                     else
371                         result = PerlIO_close(IoIFP(io));
372                 }
373                 else
374                     result = PerlIO_close(IoIFP(io));
375
376                 if (result == EOF && old_fd > PL_maxsysfd) {
377                     /* Why is this not Perl_warn*() call ? */
378                     PerlIO_printf(Perl_error_log,
379                                   "Warning: unable to close filehandle %" HEKf
380                                   " properly.\n",
381                                   HEKfARG(GvENAME_HEK(gv))
382                         );
383                 }
384             }
385         }
386         IoOFP(io) = IoIFP(io) = NULL;
387     }
388     return io;
389 }
390
391 bool
392 Perl_do_openn(pTHX_ GV *gv, const char *oname, I32 len, int as_raw,
393               int rawmode, int rawperm, PerlIO *supplied_fp, SV **svp,
394               I32 num_svs)
395 {
396     PERL_ARGS_ASSERT_DO_OPENN;
397
398     if (as_raw) {
399         /* sysopen style args, i.e. integer mode and permissions */
400
401         if (num_svs != 0) {
402             Perl_croak(aTHX_ "panic: sysopen with multiple args, num_svs=%ld",
403                        (long) num_svs);
404         }
405         return do_open_raw(gv, oname, len, rawmode, rawperm, NULL);
406     }
407     return do_open6(gv, oname, len, supplied_fp, svp, num_svs);
408 }
409
410 bool
411 Perl_do_open_raw(pTHX_ GV *gv, const char *oname, STRLEN len,
412                  int rawmode, int rawperm, Stat_t *statbufp)
413 {
414     PerlIO *saveifp;
415     PerlIO *saveofp;
416     int savefd;
417     char savetype;
418     char mode[PERL_MODE_MAX];   /* file mode ("r\0", "rb\0", "ab\0" etc.) */
419     IO * const io = openn_setup(gv, mode, &saveifp, &saveofp, &savefd, &savetype);
420     int writing = 0;
421     PerlIO *fp;
422
423     PERL_ARGS_ASSERT_DO_OPEN_RAW;
424
425     /* For ease of blame back to 5.000, keep the existing indenting. */
426     {
427         /* sysopen style args, i.e. integer mode and permissions */
428         STRLEN ix = 0;
429         const int appendtrunc =
430              0
431 #ifdef O_APPEND /* Not fully portable. */
432              |O_APPEND
433 #endif
434 #ifdef O_TRUNC  /* Not fully portable. */
435              |O_TRUNC
436 #endif
437              ;
438         const int modifyingmode = O_WRONLY|O_RDWR|O_CREAT|appendtrunc;
439         int ismodifying;
440         SV *namesv;
441
442         /* It's not always
443
444            O_RDONLY 0
445            O_WRONLY 1
446            O_RDWR   2
447
448            It might be (in OS/390 and Mac OS Classic it is)
449
450            O_WRONLY 1
451            O_RDONLY 2
452            O_RDWR   3
453
454            This means that simple & with O_RDWR would look
455            like O_RDONLY is present.  Therefore we have to
456            be more careful.
457         */
458         if ((ismodifying = (rawmode & modifyingmode))) {
459              if ((ismodifying & O_WRONLY) == O_WRONLY ||
460                  (ismodifying & O_RDWR)   == O_RDWR   ||
461                  (ismodifying & (O_CREAT|appendtrunc)))
462                   TAINT_PROPER("sysopen");
463         }
464         mode[ix++] = IoTYPE_NUMERIC; /* Marker to openn to use numeric "sysopen" */
465
466 #if defined(USE_64_BIT_RAWIO) && defined(O_LARGEFILE)
467         rawmode |= O_LARGEFILE; /* Transparently largefiley. */
468 #endif
469
470         IoTYPE(io) = PerlIO_intmode2str(rawmode, &mode[ix], &writing);
471
472         namesv = newSVpvn_flags(oname, len, SVs_TEMP);
473         fp = PerlIO_openn(aTHX_ NULL, mode, -1, rawmode, rawperm, NULL, 1, &namesv);
474     }
475     return openn_cleanup(gv, io, fp, mode, oname, saveifp, saveofp, savefd,
476                          savetype, writing, 0, NULL, statbufp);
477 }
478
479 bool
480 Perl_do_open6(pTHX_ GV *gv, const char *oname, STRLEN len,
481               PerlIO *supplied_fp, SV **svp, U32 num_svs)
482 {
483     PerlIO *saveifp;
484     PerlIO *saveofp;
485     int savefd;
486     char savetype;
487     char mode[PERL_MODE_MAX];   /* file mode ("r\0", "rb\0", "ab\0" etc.) */
488     IO * const io = openn_setup(gv, mode, &saveifp, &saveofp, &savefd, &savetype);
489     int writing = 0;
490     PerlIO *fp;
491     bool was_fdopen = FALSE;
492     char *type  = NULL;
493
494     PERL_ARGS_ASSERT_DO_OPEN6;
495
496     /* For ease of blame back to 5.000, keep the existing indenting. */
497     {
498         /* Regular (non-sys) open */
499         char *name;
500         STRLEN olen = len;
501         char *tend;
502         int dodup = 0;
503         bool in_raw = 0, in_crlf = 0, out_raw = 0, out_crlf = 0;
504
505         /* Collect default raw/crlf info from the op */
506         if (PL_op && PL_op->op_type == OP_OPEN) {
507             /* set up IO layers */
508             const U8 flags = PL_op->op_private;
509             in_raw = (flags & OPpOPEN_IN_RAW);
510             in_crlf = (flags & OPpOPEN_IN_CRLF);
511             out_raw = (flags & OPpOPEN_OUT_RAW);
512             out_crlf = (flags & OPpOPEN_OUT_CRLF);
513         }
514
515         type = savepvn(oname, len);
516         tend = type+len;
517         SAVEFREEPV(type);
518
519         /* Lose leading and trailing white space */
520         while (isSPACE(*type))
521             type++;
522         while (tend > type && isSPACE(tend[-1]))
523             *--tend = '\0';
524
525         if (num_svs) {
526             const char *p;
527             STRLEN nlen = 0;
528             /* New style explicit name, type is just mode and layer info */
529 #ifdef USE_STDIO
530             if (SvROK(*svp) && !memchr(oname, '&', len)) {
531                 if (ckWARN(WARN_IO))
532                     Perl_warner(aTHX_ packWARN(WARN_IO),
533                             "Can't open a reference");
534                 SETERRNO(EINVAL, LIB_INVARG);
535                 fp = NULL;
536                 goto say_false;
537             }
538 #endif /* USE_STDIO */
539             p = (SvOK(*svp) || SvGMAGICAL(*svp)) ? SvPV(*svp, nlen) : NULL;
540
541             if (p && !IS_SAFE_PATHNAME(p, nlen, "open")) {
542                 fp = NULL;
543                 goto say_false;
544             }
545
546             name = p ? savepvn(p, nlen) : savepvs("");
547
548             SAVEFREEPV(name);
549         }
550         else {
551             name = type;
552             len  = tend-type;
553         }
554         IoTYPE(io) = *type;
555         if ((*type == IoTYPE_RDWR) && /* scary */
556            (*(type+1) == IoTYPE_RDONLY || *(type+1) == IoTYPE_WRONLY) &&
557             ((!num_svs || (tend > type+1 && tend[-1] != IoTYPE_PIPE)))) {
558             TAINT_PROPER("open");
559             mode[1] = *type++;
560             writing = 1;
561         }
562
563         if (*type == IoTYPE_PIPE) {
564             if (num_svs) {
565                 if (type[1] != IoTYPE_STD) {
566                   unknown_open_mode:
567                     Perl_croak(aTHX_ "Unknown open() mode '%.*s'", (int)olen, oname);
568                 }
569                 type++;
570             }
571             do {
572                 type++;
573             } while (isSPACE(*type));
574             if (!num_svs) {
575                 name = type;
576                 len = tend-type;
577             }
578             if (*name == '\0') {
579                 /* command is missing 19990114 */
580                 if (ckWARN(WARN_PIPE))
581                     Perl_warner(aTHX_ packWARN(WARN_PIPE), "Missing command in piped open");
582                 errno = EPIPE;
583                 fp = NULL;
584                 goto say_false;
585             }
586             if (!(*name == '-' && name[1] == '\0') || num_svs)
587                 TAINT_ENV();
588             TAINT_PROPER("piped open");
589             if (!num_svs && name[len-1] == '|') {
590                 name[--len] = '\0' ;
591                 if (ckWARN(WARN_PIPE))
592                     Perl_warner(aTHX_ packWARN(WARN_PIPE), "Can't open bidirectional pipe");
593             }
594             mode[0] = 'w';
595             writing = 1;
596             if (out_raw)
597                 mode[1] = 'b';
598             else if (out_crlf)
599                 mode[1] = 't';
600             if (num_svs > 1) {
601                 fp = PerlProc_popen_list(mode, num_svs, svp);
602             }
603             else {
604                 fp = PerlProc_popen(name,mode);
605             }
606             if (num_svs) {
607                 if (*type) {
608                     if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
609                         fp = NULL;
610                         goto say_false;
611                     }
612                 }
613             }
614         } /* IoTYPE_PIPE */
615         else if (*type == IoTYPE_WRONLY) {
616             TAINT_PROPER("open");
617             type++;
618             if (*type == IoTYPE_WRONLY) {
619                 /* Two IoTYPE_WRONLYs in a row make for an IoTYPE_APPEND. */
620                 mode[0] = IoTYPE(io) = IoTYPE_APPEND;
621                 type++;
622             }
623             else {
624                 mode[0] = 'w';
625             }
626             writing = 1;
627
628             if (out_raw)
629                 mode[1] = 'b';
630             else if (out_crlf)
631                 mode[1] = 't';
632             if (*type == '&') {
633               duplicity:
634                 dodup = PERLIO_DUP_FD;
635                 type++;
636                 if (*type == '=') {
637                     dodup = 0;
638                     type++;
639                 }
640                 if (!num_svs && !*type && supplied_fp) {
641                     /* "<+&" etc. is used by typemaps */
642                     fp = supplied_fp;
643                 }
644                 else {
645                     PerlIO *that_fp = NULL;
646                     int wanted_fd;
647                     UV uv;
648                     if (num_svs > 1) {
649                         /* diag_listed_as: More than one argument to '%s' open */
650                         Perl_croak(aTHX_ "More than one argument to '%c&' open",IoTYPE(io));
651                     }
652                     while (isSPACE(*type))
653                         type++;
654                     if (num_svs && (
655                              SvIOK(*svp)
656                           || (SvPOKp(*svp) && looks_like_number(*svp))
657                        )) {
658                         wanted_fd = SvUV(*svp);
659                         num_svs = 0;
660                     }
661                     else if (isDIGIT(*type)
662                         && grok_atoUV(type, &uv, NULL)
663                         && uv <= INT_MAX
664                     ) {
665                         wanted_fd = (int)uv;
666                     }
667                     else {
668                         const IO* thatio;
669                         if (num_svs) {
670                             thatio = sv_2io(*svp);
671                         }
672                         else {
673                             GV * const thatgv = gv_fetchpvn_flags(type, tend - type,
674                                                        0, SVt_PVIO);
675                             thatio = GvIO(thatgv);
676                         }
677                         if (!thatio) {
678 #ifdef EINVAL
679                             SETERRNO(EINVAL,SS_IVCHAN);
680 #endif
681                             fp = NULL;
682                             goto say_false;
683                         }
684                         if ((that_fp = IoIFP(thatio))) {
685                             /* Flush stdio buffer before dup. --mjd
686                              * Unfortunately SEEK_CURing 0 seems to
687                              * be optimized away on most platforms;
688                              * only Solaris and Linux seem to flush
689                              * on that. --jhi */
690                             /* On the other hand, do all platforms
691                              * take gracefully to flushing a read-only
692                              * filehandle?  Perhaps we should do
693                              * fsetpos(src)+fgetpos(dst)?  --nik */
694                             PerlIO_flush(that_fp);
695                             wanted_fd = PerlIO_fileno(that_fp);
696                             /* When dup()ing STDIN, STDOUT or STDERR
697                              * explicitly set appropriate access mode */
698                             if (that_fp == PerlIO_stdout()
699                                 || that_fp == PerlIO_stderr())
700                                 IoTYPE(io) = IoTYPE_WRONLY;
701                             else if (that_fp == PerlIO_stdin())
702                                 IoTYPE(io) = IoTYPE_RDONLY;
703                             /* When dup()ing a socket, say result is
704                              * one as well */
705                             else if (IoTYPE(thatio) == IoTYPE_SOCKET)
706                                 IoTYPE(io) = IoTYPE_SOCKET;
707                         }
708                         else {
709                             SETERRNO(EBADF, RMS_IFI);
710                             fp = NULL;
711                             goto say_false;
712                         }
713                     }
714                     if (!num_svs)
715                         type = NULL;
716                     if (that_fp) {
717                         fp = PerlIO_fdupopen(aTHX_ that_fp, NULL, dodup);
718                     }
719                     else {
720                         if (dodup)
721                             wanted_fd = PerlLIO_dup_cloexec(wanted_fd);
722                         else
723                             was_fdopen = TRUE;
724                         if (!(fp = PerlIO_openn(aTHX_ type,mode,wanted_fd,0,0,NULL,num_svs,svp))) {
725                             if (dodup && wanted_fd >= 0)
726                                 PerlLIO_close(wanted_fd);
727                         }
728                     }
729                 }
730             } /* & */
731             else {
732                 while (isSPACE(*type))
733                     type++;
734                 if (*type == IoTYPE_STD && (!type[1] || isSPACE(type[1]) || type[1] == ':')) {
735                     type++;
736                     fp = PerlIO_stdout();
737                     IoTYPE(io) = IoTYPE_STD;
738                     if (num_svs > 1) {
739                         /* diag_listed_as: More than one argument to '%s' open */
740                         Perl_croak(aTHX_ "More than one argument to '>%c' open",IoTYPE_STD);
741                     }
742                 }
743                 else  {
744                     if (num_svs) {
745                         fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
746                     }
747                     else {
748                         SV *namesv = newSVpvn_flags(type, tend - type, SVs_TEMP);
749                         type = NULL;
750                         fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,1,&namesv);
751                     }
752                 }
753             } /* !& */
754             if (!fp && type && *type && *type != ':' && !isIDFIRST(*type))
755                goto unknown_open_mode;
756         } /* IoTYPE_WRONLY */
757         else if (*type == IoTYPE_RDONLY) {
758             do {
759                 type++;
760             } while (isSPACE(*type));
761             mode[0] = 'r';
762             if (in_raw)
763                 mode[1] = 'b';
764             else if (in_crlf)
765                 mode[1] = 't';
766             if (*type == '&') {
767                 goto duplicity;
768             }
769             if (*type == IoTYPE_STD && (!type[1] || isSPACE(type[1]) || type[1] == ':')) {
770                 type++;
771                 fp = PerlIO_stdin();
772                 IoTYPE(io) = IoTYPE_STD;
773                 if (num_svs > 1) {
774                     /* diag_listed_as: More than one argument to '%s' open */
775                     Perl_croak(aTHX_ "More than one argument to '<%c' open",IoTYPE_STD);
776                 }
777             }
778             else {
779                 if (num_svs) {
780                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
781                 }
782                 else {
783                     SV *namesv  = newSVpvn_flags(type, tend - type, SVs_TEMP);
784                     type = NULL;
785                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,1,&namesv);
786                 }
787             }
788             if (!fp && type && *type && *type != ':' && !isIDFIRST(*type))
789                goto unknown_open_mode;
790         } /* IoTYPE_RDONLY */
791         else if ((num_svs && /* '-|...' or '...|' */
792                   type[0] == IoTYPE_STD && type[1] == IoTYPE_PIPE) ||
793                  (!num_svs && tend > type+1 && tend[-1] == IoTYPE_PIPE)) {
794             if (num_svs) {
795                 type += 2;   /* skip over '-|' */
796             }
797             else {
798                 *--tend = '\0';
799                 while (tend > type && isSPACE(tend[-1]))
800                     *--tend = '\0';
801                 for (; isSPACE(*type); type++)
802                     ;
803                 name = type;
804                 len  = tend-type;
805             }
806             if (*name == '\0') {
807                 /* command is missing 19990114 */
808                 if (ckWARN(WARN_PIPE))
809                     Perl_warner(aTHX_ packWARN(WARN_PIPE), "Missing command in piped open");
810                 errno = EPIPE;
811                 fp = NULL;
812                 goto say_false;
813             }
814             if (!(*name == '-' && name[1] == '\0') || num_svs)
815                 TAINT_ENV();
816             TAINT_PROPER("piped open");
817             mode[0] = 'r';
818
819             if (in_raw)
820                 mode[1] = 'b';
821             else if (in_crlf)
822                 mode[1] = 't';
823
824             if (num_svs > 1) {
825                 fp = PerlProc_popen_list(mode,num_svs,svp);
826             }
827             else {
828                 fp = PerlProc_popen(name,mode);
829             }
830             IoTYPE(io) = IoTYPE_PIPE;
831             if (num_svs) {
832                 while (isSPACE(*type))
833                     type++;
834                 if (*type) {
835                     if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
836                         fp = NULL;
837                         goto say_false;
838                     }
839                 }
840             }
841         }
842         else { /* layer(Args) */
843             if (num_svs)
844                 goto unknown_open_mode;
845             name = type;
846             IoTYPE(io) = IoTYPE_RDONLY;
847             for (; isSPACE(*name); name++)
848                 ;
849             mode[0] = 'r';
850
851             if (in_raw)
852                 mode[1] = 'b';
853             else if (in_crlf)
854                 mode[1] = 't';
855
856             if (*name == '-' && name[1] == '\0') {
857                 fp = PerlIO_stdin();
858                 IoTYPE(io) = IoTYPE_STD;
859             }
860             else {
861                 if (num_svs) {
862                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
863                 }
864                 else {
865                     SV *namesv = newSVpvn_flags(type, tend - type, SVs_TEMP);
866                     type = NULL;
867                     fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,1,&namesv);
868                 }
869             }
870         }
871     }
872
873   say_false:
874     return openn_cleanup(gv, io, fp, mode, oname, saveifp, saveofp, savefd,
875                          savetype, writing, was_fdopen, type, NULL);
876 }
877
878 /* Yes, this is ugly, but it's private, and I don't see a cleaner way to
879    simplify the two-headed public interface of do_openn. */
880 static bool
881 S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname,
882                 PerlIO *saveifp, PerlIO *saveofp, int savefd, char savetype,
883                 int writing, bool was_fdopen, const char *type, Stat_t *statbufp)
884 {
885     int fd;
886     Stat_t statbuf;
887
888     PERL_ARGS_ASSERT_OPENN_CLEANUP;
889
890     Zero(&statbuf, 1, Stat_t);
891
892     if (!fp) {
893         if (IoTYPE(io) == IoTYPE_RDONLY && ckWARN(WARN_NEWLINE)
894             && should_warn_nl(oname)
895             
896         )
897         {
898             GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral); /* PL_warn_nl is constant */
899             Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
900             GCC_DIAG_RESTORE_STMT;
901         }
902         goto say_false;
903     }
904
905     if (ckWARN(WARN_IO)) {
906         if ((IoTYPE(io) == IoTYPE_RDONLY) &&
907             (fp == PerlIO_stdout() || fp == PerlIO_stderr())) {
908                 Perl_warner(aTHX_ packWARN(WARN_IO),
909                             "Filehandle STD%s reopened as %" HEKf
910                             " only for input",
911                             ((fp == PerlIO_stdout()) ? "OUT" : "ERR"),
912                             HEKfARG(GvENAME_HEK(gv)));
913         }
914         else if ((IoTYPE(io) == IoTYPE_WRONLY) && fp == PerlIO_stdin()) {
915                 Perl_warner(aTHX_ packWARN(WARN_IO),
916                     "Filehandle STDIN reopened as %" HEKf " only for output",
917                      HEKfARG(GvENAME_HEK(gv))
918                 );
919         }
920     }
921
922     fd = PerlIO_fileno(fp);
923     /* Do NOT do: "if (fd < 0) goto say_false;" here.  If there is no
924      * fd assume it isn't a socket - this covers PerlIO::scalar -
925      * otherwise unless we "know" the type probe for socket-ness.
926      */
927     if (IoTYPE(io) && IoTYPE(io) != IoTYPE_PIPE && IoTYPE(io) != IoTYPE_STD && fd >= 0) {
928         if (PerlLIO_fstat(fd,&statbuf) < 0) {
929             /* If PerlIO claims to have fd we had better be able to fstat() it. */
930             (void) PerlIO_close(fp);
931             goto say_false;
932         }
933 #ifndef PERL_MICRO
934         if (S_ISSOCK(statbuf.st_mode))
935             IoTYPE(io) = IoTYPE_SOCKET; /* in case a socket was passed in to us */
936 #ifdef HAS_SOCKET
937         else if (
938             !(statbuf.st_mode & S_IFMT)
939             && IoTYPE(io) != IoTYPE_WRONLY  /* Dups of STD* filehandles already have */
940             && IoTYPE(io) != IoTYPE_RDONLY  /* type so they aren't marked as sockets */
941         ) {                                 /* on OS's that return 0 on fstat()ed pipe */
942              char tmpbuf[256];
943              Sock_size_t buflen = sizeof tmpbuf;
944              if (PerlSock_getsockname(fd, (struct sockaddr *)tmpbuf, &buflen) >= 0
945                       || errno != ENOTSOCK)
946                     IoTYPE(io) = IoTYPE_SOCKET; /* some OS's return 0 on fstat()ed socket */
947                                                 /* but some return 0 for streams too, sigh */
948         }
949 #endif /* HAS_SOCKET */
950 #endif /* !PERL_MICRO */
951     }
952
953     /* Eeek - FIXME !!!
954      * If this is a standard handle we discard all the layer stuff
955      * and just dup the fd into whatever was on the handle before !
956      */
957
958     if (saveifp) {              /* must use old fp? */
959         /* If fd is less that PL_maxsysfd i.e. STDIN..STDERR
960            then dup the new fileno down
961          */
962         if (saveofp) {
963             PerlIO_flush(saveofp);      /* emulate PerlIO_close() */
964             if (saveofp != saveifp) {   /* was a socket? */
965                 PerlIO_close(saveofp);
966             }
967         }
968         if (savefd != fd) {
969             /* Still a small can-of-worms here if (say) PerlIO::scalar
970                is assigned to (say) STDOUT - for now let dup2() fail
971                and provide the error
972              */
973             if (fd < 0) {
974                 SETERRNO(EBADF,RMS_IFI);
975                 goto say_false;
976             } else if (PerlLIO_dup2(fd, savefd) < 0) {
977                 (void)PerlIO_close(fp);
978                 goto say_false;
979             }
980 #ifdef VMS
981             if (savefd != PerlIO_fileno(PerlIO_stdin())) {
982                 char newname[FILENAME_MAX+1];
983                 if (PerlIO_getname(fp, newname)) {
984                     if (fd == PerlIO_fileno(PerlIO_stdout()))
985                         vmssetuserlnm("SYS$OUTPUT", newname);
986                     if (fd == PerlIO_fileno(PerlIO_stderr()))
987                         vmssetuserlnm("SYS$ERROR", newname);
988                 }
989             }
990 #endif
991
992 #if !defined(WIN32)
993            /* PL_fdpid isn't used on Windows, so avoid this useless work.
994             * XXX Probably the same for a lot of other places. */
995             {
996                 Pid_t pid;
997                 SV *sv;
998
999                 sv = *av_fetch(PL_fdpid,fd,TRUE);
1000                 SvUPGRADE(sv, SVt_IV);
1001                 pid = SvIVX(sv);
1002                 SvIV_set(sv, 0);
1003                 sv = *av_fetch(PL_fdpid,savefd,TRUE);
1004                 SvUPGRADE(sv, SVt_IV);
1005                 SvIV_set(sv, pid);
1006             }
1007 #endif
1008
1009             if (was_fdopen) {
1010                 /* need to close fp without closing underlying fd */
1011                 int ofd = PerlIO_fileno(fp);
1012                 int dupfd = ofd >= 0 ? PerlLIO_dup_cloexec(ofd) : -1;
1013                 if (ofd < 0 || dupfd < 0) {
1014                     if (dupfd >= 0)
1015                         PerlLIO_close(dupfd);
1016                     goto say_false;
1017                 }
1018                 PerlIO_close(fp);
1019                 PerlLIO_dup2_cloexec(dupfd, ofd);
1020                 setfd_inhexec_for_sysfd(ofd);
1021                 PerlLIO_close(dupfd);
1022             }
1023             else
1024                 PerlIO_close(fp);
1025         }
1026         fp = saveifp;
1027         PerlIO_clearerr(fp);
1028         fd = PerlIO_fileno(fp);
1029     }
1030     IoIFP(io) = fp;
1031
1032     IoFLAGS(io) &= ~IOf_NOLINE;
1033     if (writing) {
1034         if (IoTYPE(io) == IoTYPE_SOCKET
1035             || (IoTYPE(io) == IoTYPE_WRONLY && fd >= 0 && S_ISCHR(statbuf.st_mode)) ) {
1036             char *s = mode;
1037             if (*s == IoTYPE_IMPLICIT || *s == IoTYPE_NUMERIC)
1038               s++;
1039             *s = 'w';
1040             if (!(IoOFP(io) = PerlIO_openn(aTHX_ type,s,fd,0,0,NULL,0,NULL))) {
1041                 PerlIO_close(fp);
1042                 goto say_false;
1043             }
1044         }
1045         else
1046             IoOFP(io) = fp;
1047     }
1048     if (statbufp)
1049         *statbufp = statbuf;
1050
1051     return TRUE;
1052
1053   say_false:
1054     IoIFP(io) = saveifp;
1055     IoOFP(io) = saveofp;
1056     IoTYPE(io) = savetype;
1057     return FALSE;
1058 }
1059
1060 /* Open a temp file in the same directory as an original name.
1061 */
1062
1063 static bool
1064 S_openindirtemp(pTHX_ GV *gv, SV *orig_name, SV *temp_out_name) {
1065     int fd;
1066     PerlIO *fp;
1067     const char *p = SvPV_nolen(orig_name);
1068     const char *sep;
1069
1070     /* look for the last directory separator */
1071     sep = strrchr(p, '/');
1072
1073 #ifdef DOSISH
1074     {
1075         const char *sep2;
1076         if ((sep2 = strrchr(sep ? sep : p, '\\')))
1077             sep = sep2;
1078     }
1079 #endif
1080 #ifdef VMS
1081     if (!sep) {
1082         const char *openp = strchr(p, '[');
1083         if (openp)
1084             sep = strchr(openp, ']');
1085         else {
1086             sep = strchr(p, ':');
1087         }
1088     }
1089 #endif
1090     if (sep) {
1091         sv_setpvn(temp_out_name, p, sep - p + 1);
1092         sv_catpvs(temp_out_name, "XXXXXXXX");
1093     }
1094     else
1095         sv_setpvs(temp_out_name, "XXXXXXXX");
1096
1097     {
1098       int old_umask = umask(0177);
1099       fd = Perl_my_mkstemp_cloexec(SvPVX(temp_out_name));
1100       umask(old_umask);
1101     }
1102
1103     if (fd < 0)
1104         return FALSE;
1105
1106     fp = PerlIO_fdopen(fd, "w+");
1107     if (!fp)
1108         return FALSE;
1109
1110     return do_openn(gv, "+>&", 3, 0, 0, 0, fp, NULL, 0);
1111 }
1112
1113 #if defined(HAS_UNLINKAT) && defined(HAS_RENAMEAT) && defined(HAS_FCHMODAT) && \
1114     (defined(HAS_DIRFD) || defined(HAS_DIR_DD_FD)) && !defined(NO_USE_ATFUNCTIONS) && \
1115     defined(HAS_LINKAT)
1116 #  define ARGV_USE_ATFUNCTIONS
1117 #endif
1118
1119 /* Win32 doesn't necessarily return useful information
1120  * in st_dev, st_ino.
1121  */
1122 #ifndef DOSISH
1123 #  define ARGV_USE_STAT_INO
1124 #endif
1125
1126 #define ARGVMG_BACKUP_NAME 0
1127 #define ARGVMG_TEMP_NAME 1
1128 #define ARGVMG_ORIG_NAME 2
1129 #define ARGVMG_ORIG_MODE 3
1130 #define ARGVMG_ORIG_PID 4
1131
1132 /* we store the entire stat_t since the ino_t and dev_t values might
1133    not fit in an IV.  I could have created a new structure and
1134    transferred them across, but this seemed too much effort for very
1135    little win.
1136
1137    We store it even when the *at() functions are available, since
1138    while the C runtime might have definitions for these functions, the
1139    operating system or a specific filesystem might not implement them.
1140    eg. NetBSD 6 implements linkat() but only where the fds are AT_FDCWD.
1141  */
1142 #ifdef ARGV_USE_STAT_INO
1143 #  define ARGVMG_ORIG_CWD_STAT 5
1144 #endif
1145
1146 #ifdef ARGV_USE_ATFUNCTIONS
1147 #  define ARGVMG_ORIG_DIRP 6
1148 #endif
1149
1150 #ifdef ENOTSUP
1151 #define NotSupported(e) ((e) == ENOSYS || (e) == ENOTSUP)
1152 #else
1153 #define NotSupported(e) ((e) == ENOSYS)
1154 #endif
1155
1156 static int
1157 S_argvout_free(pTHX_ SV *io, MAGIC *mg) {
1158     PERL_UNUSED_ARG(io);
1159
1160     /* note this can be entered once the file has been
1161        successfully deleted too */
1162     assert(IoTYPE(io) != IoTYPE_PIPE);
1163
1164     /* mg_obj can be NULL if a thread is created with the handle open, in which
1165      case we leave any clean up to the parent thread */
1166     if (mg->mg_obj) {
1167 #ifdef ARGV_USE_ATFUNCTIONS
1168         SV **dir_psv;
1169         DIR *dir;
1170
1171         dir_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_DIRP, FALSE);
1172         assert(dir_psv && *dir_psv && SvIOK(*dir_psv));
1173         dir = INT2PTR(DIR *, SvIV(*dir_psv));
1174 #endif
1175         if (IoIFP(io)) {
1176             SV **pid_psv;
1177             PerlIO *iop = IoIFP(io);
1178
1179             assert(SvTYPE(mg->mg_obj) == SVt_PVAV);
1180
1181             pid_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_PID, FALSE);
1182
1183             assert(pid_psv && *pid_psv);
1184
1185             if (SvIV(*pid_psv) == (IV)PerlProc_getpid()) {
1186                 /* if we get here the file hasn't been closed explicitly by the
1187                    user and hadn't been closed implicitly by nextargv(), so
1188                    abandon the edit */
1189                 SV **temp_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_TEMP_NAME, FALSE);
1190                 const char *temp_pv = SvPVX(*temp_psv);
1191
1192                 assert(temp_psv && *temp_psv && SvPOK(*temp_psv));
1193                 (void)PerlIO_close(iop);
1194                 IoIFP(io) = IoOFP(io) = NULL;
1195 #ifdef ARGV_USE_ATFUNCTIONS
1196                 if (dir) {
1197                     if (unlinkat(my_dirfd(dir), temp_pv, 0) < 0 &&
1198                         NotSupported(errno))
1199                         (void)UNLINK(temp_pv);
1200                 }
1201 #else
1202                 (void)UNLINK(temp_pv);
1203 #endif
1204             }
1205         }
1206 #ifdef ARGV_USE_ATFUNCTIONS
1207         if (dir)
1208             closedir(dir);
1209 #endif
1210     }
1211
1212     return 0;
1213 }
1214
1215 static int
1216 S_argvout_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param) {
1217     PERL_UNUSED_ARG(param);
1218
1219     /* ideally we could just remove the magic from the SV but we don't get the SV here */
1220     SvREFCNT_dec(mg->mg_obj);
1221     mg->mg_obj = NULL;
1222
1223     return 0;
1224 }
1225
1226 /* Magic of this type has an AV containing the following:
1227    0: name of the backup file (if any)
1228    1: name of the temp output file
1229    2: name of the original file
1230    3: file mode of the original file
1231    4: pid of the process we opened at, to prevent doing the renaming
1232       etc in both the child and the parent after a fork
1233
1234 If we have useful inode/device ids in stat_t we also keep:
1235    5: a stat of the original current working directory
1236
1237 If we have unlinkat(), renameat(), fchmodat(), dirfd() we also keep:
1238    6: the DIR * for the current directory when we open the file, stored as an IV
1239  */
1240
1241 static const MGVTBL argvout_vtbl =
1242     {
1243         NULL, /* svt_get */
1244         NULL, /* svt_set */
1245         NULL, /* svt_len */
1246         NULL, /* svt_clear */
1247         S_argvout_free, /* svt_free */
1248         NULL, /* svt_copy */
1249         S_argvout_dup,  /* svt_dup */
1250         NULL /* svt_local */
1251     };
1252
1253 PerlIO *
1254 Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
1255 {
1256     IO * const io = GvIOp(gv);
1257     SV *const old_out_name = PL_inplace ? newSVsv(GvSV(gv)) : NULL;
1258
1259     PERL_ARGS_ASSERT_NEXTARGV;
1260
1261     if (old_out_name)
1262         SAVEFREESV(old_out_name);
1263
1264     if (!PL_argvoutgv)
1265         PL_argvoutgv = gv_fetchpvs("ARGVOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
1266     if (io && (IoFLAGS(io) & (IOf_ARGV|IOf_START)) == (IOf_ARGV|IOf_START)) {
1267         IoFLAGS(io) &= ~IOf_START;
1268         if (PL_inplace) {
1269             assert(PL_defoutgv);
1270             Perl_av_create_and_push(aTHX_ &PL_argvout_stack,
1271                                     SvREFCNT_inc_simple_NN(PL_defoutgv));
1272         }
1273     }
1274
1275     {
1276         IO * const io = GvIOp(PL_argvoutgv);
1277         if (io && IoIFP(io) && old_out_name) {
1278             do_close(PL_argvoutgv, FALSE);
1279         }
1280     }
1281
1282     PL_lastfd = -1;
1283     PL_filemode = 0;
1284     if (!GvAV(gv))
1285         return NULL;
1286     while (av_tindex(GvAV(gv)) >= 0) {
1287         STRLEN oldlen;
1288         SV *const sv = av_shift(GvAV(gv));
1289         SAVEFREESV(sv);
1290         SvTAINTED_off(GvSVn(gv)); /* previous tainting irrelevant */
1291         sv_setsv(GvSVn(gv),sv);
1292         SvSETMAGIC(GvSV(gv));
1293         PL_oldname = SvPVx(GvSV(gv), oldlen);
1294         if (LIKELY(!PL_inplace)) {
1295             if (nomagicopen
1296                     ? do_open6(gv, "<", 1, NULL, &GvSV(gv), 1)
1297                     : do_open6(gv, PL_oldname, oldlen, NULL, NULL, 0)
1298                ) {
1299                 return IoIFP(GvIOp(gv));
1300             }
1301         }
1302         else {
1303             Stat_t statbuf;
1304             /* This very long block ends with return IoIFP(GvIOp(gv));
1305                Both this block and the block above fall through on open
1306                failure to the warning code, and then the while loop above tries
1307                the next entry. */
1308             if (do_open_raw(gv, PL_oldname, oldlen, O_RDONLY, 0, &statbuf)) {
1309 #ifndef FLEXFILENAMES
1310                 int filedev;
1311                 int fileino;
1312 #endif
1313 #ifdef ARGV_USE_ATFUNCTIONS
1314                 DIR *curdir;
1315 #endif
1316                 Uid_t fileuid;
1317                 Gid_t filegid;
1318                 AV *magic_av = NULL;
1319                 SV *temp_name_sv = NULL;
1320                 MAGIC *mg;
1321
1322                 TAINT_PROPER("inplace open");
1323                 if (oldlen == 1 && *PL_oldname == '-') {
1324                     setdefout(gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL,
1325                                           SVt_PVIO));
1326                     return IoIFP(GvIOp(gv));
1327                 }
1328 #ifndef FLEXFILENAMES
1329                 filedev = statbuf.st_dev;
1330                 fileino = statbuf.st_ino;
1331 #endif
1332                 PL_filemode = statbuf.st_mode;
1333                 fileuid = statbuf.st_uid;
1334                 filegid = statbuf.st_gid;
1335                 if (!S_ISREG(PL_filemode)) {
1336                     Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE),
1337                                      "Can't do inplace edit: %s is not a regular file",
1338                                      PL_oldname );
1339                     do_close(gv,FALSE);
1340                     continue;
1341                 }
1342                 magic_av = newAV();
1343                 if (*PL_inplace && strNE(PL_inplace, "*")) {
1344                     const char *star = strchr(PL_inplace, '*');
1345                     if (star) {
1346                         const char *begin = PL_inplace;
1347                         SvPVCLEAR(sv);
1348                         do {
1349                             sv_catpvn(sv, begin, star - begin);
1350                             sv_catpvn(sv, PL_oldname, oldlen);
1351                             begin = ++star;
1352                         } while ((star = strchr(begin, '*')));
1353                         if (*begin)
1354                             sv_catpv(sv,begin);
1355                     }
1356                     else {
1357                         sv_catpv(sv,PL_inplace);
1358                     }
1359 #ifndef FLEXFILENAMES
1360                     if ((PerlLIO_stat(SvPVX_const(sv),&statbuf) >= 0
1361                          && statbuf.st_dev == filedev
1362                          && statbuf.st_ino == fileino)
1363 #ifdef DJGPP
1364                         || ((_djstat_fail_bits & _STFAIL_TRUENAME)!=0)
1365 #endif
1366                       )
1367                     {
1368                         Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE),
1369                                          "Can't do inplace edit: %"
1370                                          SVf " would not be unique",
1371                                          SVfARG(sv));
1372                         goto cleanup_argv;
1373                     }
1374 #endif
1375                     av_store(magic_av, ARGVMG_BACKUP_NAME, newSVsv(sv));
1376                 }
1377
1378                 sv_setpvn(sv,PL_oldname,oldlen);
1379                 SETERRNO(0,0);          /* in case sprintf set errno */
1380                 temp_name_sv = newSV(0);
1381                 if (!S_openindirtemp(aTHX_ PL_argvoutgv, GvSV(gv), temp_name_sv)) {
1382                     SvREFCNT_dec(temp_name_sv);
1383                     /* diag_listed_as: Can't do inplace edit on %s: %s */
1384                     Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE), "Can't do inplace edit on %s: Cannot make temp name: %s",
1385                                      PL_oldname, Strerror(errno) );
1386 #ifndef FLEXFILENAMES
1387                 cleanup_argv:
1388 #endif
1389                     do_close(gv,FALSE);
1390                     SvREFCNT_dec(magic_av);
1391                     continue;
1392                 }
1393                 av_store(magic_av, ARGVMG_TEMP_NAME, temp_name_sv);
1394                 av_store(magic_av, ARGVMG_ORIG_NAME, newSVsv(sv));
1395                 av_store(magic_av, ARGVMG_ORIG_MODE, newSVuv(PL_filemode));
1396                 av_store(magic_av, ARGVMG_ORIG_PID, newSViv((IV)PerlProc_getpid()));
1397 #if defined(ARGV_USE_ATFUNCTIONS)
1398                 curdir = opendir(".");
1399                 av_store(magic_av, ARGVMG_ORIG_DIRP, newSViv(PTR2IV(curdir)));
1400 #elif defined(ARGV_USE_STAT_INO)
1401                 if (PerlLIO_stat(".", &statbuf) >= 0) {
1402                     av_store(magic_av, ARGVMG_ORIG_CWD_STAT,
1403                              newSVpvn((char *)&statbuf, sizeof(statbuf)));
1404                 }
1405 #endif
1406                 setdefout(PL_argvoutgv);
1407                 sv_setsv(GvSVn(PL_argvoutgv), temp_name_sv);
1408                 mg = sv_magicext((SV*)GvIOp(PL_argvoutgv), (SV*)magic_av, PERL_MAGIC_uvar, &argvout_vtbl, NULL, 0);
1409                 mg->mg_flags |= MGf_DUP;
1410                 SvREFCNT_dec(magic_av);
1411                 PL_lastfd = PerlIO_fileno(IoIFP(GvIOp(PL_argvoutgv)));
1412                 if (PL_lastfd >= 0) {
1413                     (void)PerlLIO_fstat(PL_lastfd,&statbuf);
1414 #ifdef HAS_FCHMOD
1415                     (void)fchmod(PL_lastfd,PL_filemode);
1416 #else
1417                     (void)PerlLIO_chmod(PL_oldname,PL_filemode);
1418 #endif
1419                     if (fileuid != statbuf.st_uid || filegid != statbuf.st_gid) {
1420                         /* XXX silently ignore failures */
1421 #ifdef HAS_FCHOWN
1422                         PERL_UNUSED_RESULT(fchown(PL_lastfd,fileuid,filegid));
1423 #elif defined(HAS_CHOWN)
1424                         PERL_UNUSED_RESULT(PerlLIO_chown(PL_oldname,fileuid,filegid));
1425 #endif
1426                     }
1427                 }
1428                 return IoIFP(GvIOp(gv));
1429             }
1430         } /* successful do_open_raw(), PL_inplace non-NULL */
1431
1432         if (ckWARN_d(WARN_INPLACE)) {
1433             const int eno = errno;
1434             Stat_t statbuf;
1435             if (PerlLIO_stat(PL_oldname, &statbuf) >= 0
1436                 && !S_ISREG(statbuf.st_mode)) {
1437                 Perl_warner(aTHX_ packWARN(WARN_INPLACE),
1438                             "Can't do inplace edit: %s is not a regular file",
1439                             PL_oldname);
1440             }
1441             else {
1442                 Perl_warner(aTHX_ packWARN(WARN_INPLACE), "Can't open %s: %s",
1443                             PL_oldname, Strerror(eno));
1444             }
1445         }
1446     }
1447     if (io && (IoFLAGS(io) & IOf_ARGV))
1448         IoFLAGS(io) |= IOf_START;
1449     if (PL_inplace) {
1450         if (io && (IoFLAGS(io) & IOf_ARGV)
1451             && PL_argvout_stack && AvFILLp(PL_argvout_stack) >= 0)
1452         {
1453             GV * const oldout = MUTABLE_GV(av_pop(PL_argvout_stack));
1454             setdefout(oldout);
1455             SvREFCNT_dec_NN(oldout);
1456             return NULL;
1457         }
1458         setdefout(gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO));
1459     }
1460     return NULL;
1461 }
1462
1463 #ifdef ARGV_USE_ATFUNCTIONS
1464 #  if defined(__FreeBSD__)
1465
1466 /* FreeBSD 11 renameat() mis-behaves strangely with absolute paths in cases where the
1467  * equivalent rename() succeeds
1468  */
1469 static int
1470 S_my_renameat(int olddfd, const char *oldpath, int newdfd, const char *newpath) {
1471     /* this is intended only for use in Perl_do_close() */
1472     assert(olddfd == newdfd);
1473     assert(PERL_FILE_IS_ABSOLUTE(oldpath) == PERL_FILE_IS_ABSOLUTE(newpath));
1474     if (PERL_FILE_IS_ABSOLUTE(oldpath)) {
1475         return PerlLIO_rename(oldpath, newpath);
1476     }
1477     else {
1478         return renameat(olddfd, oldpath, newdfd, newpath);
1479     }
1480 }
1481
1482 #  else
1483 #    define S_my_renameat(dh1, pv1, dh2, pv2) renameat((dh1), (pv1), (dh2), (pv2))
1484 #  endif /* if defined(__FreeBSD__) */
1485 #endif
1486
1487 static bool
1488 S_dir_unchanged(pTHX_ const char *orig_pv, MAGIC *mg) {
1489     Stat_t statbuf;
1490
1491 #ifdef ARGV_USE_STAT_INO
1492     SV **stat_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_CWD_STAT, FALSE);
1493     Stat_t *orig_cwd_stat = stat_psv && *stat_psv ? (Stat_t *)SvPVX(*stat_psv) : NULL;
1494
1495     /* if the path is absolute the possible moving of cwd (which the file
1496        might be in) isn't our problem.
1497        This code tries to be reasonably balanced about detecting a changed
1498        CWD, if we have the information needed to check that curdir has changed, we
1499        check it
1500     */
1501     if (!PERL_FILE_IS_ABSOLUTE(orig_pv)
1502         && orig_cwd_stat
1503         && PerlLIO_stat(".", &statbuf) >= 0
1504         && ( statbuf.st_dev != orig_cwd_stat->st_dev
1505                      || statbuf.st_ino != orig_cwd_stat->st_ino)) {
1506         Perl_croak(aTHX_ "Cannot complete in-place edit of %s: %s",
1507                    orig_pv, "Current directory has changed");
1508     }
1509 #else
1510     SV **temp_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_TEMP_NAME, FALSE);
1511
1512     /* Some platforms don't have useful st_ino etc, so just
1513        check we can see the work file.
1514     */
1515     if (!PERL_FILE_IS_ABSOLUTE(orig_pv)
1516         && PerlLIO_stat(SvPVX(*temp_psv), &statbuf) < 0) {
1517         Perl_croak(aTHX_ "Cannot complete in-place edit of %s: %s",
1518                    orig_pv,
1519                    "Work file is missing - did you change directory?");
1520     }
1521 #endif
1522
1523     return TRUE;
1524 }
1525
1526 #define dir_unchanged(orig_psv, mg) \
1527     S_dir_unchanged(aTHX_ (orig_psv), (mg))
1528
1529 /* explicit renamed to avoid C++ conflict    -- kja */
1530 bool
1531 Perl_do_close(pTHX_ GV *gv, bool not_implicit)
1532 {
1533     bool retval;
1534     IO *io;
1535     MAGIC *mg;
1536
1537     if (!gv)
1538         gv = PL_argvgv;
1539     if (!gv || !isGV_with_GP(gv)) {
1540         if (not_implicit)
1541             SETERRNO(EBADF,SS_IVCHAN);
1542         return FALSE;
1543     }
1544     io = GvIO(gv);
1545     if (!io) {          /* never opened */
1546         if (not_implicit) {
1547             report_evil_fh(gv);
1548             SETERRNO(EBADF,SS_IVCHAN);
1549         }
1550         return FALSE;
1551     }
1552     if ((mg = mg_findext((SV*)io, PERL_MAGIC_uvar, &argvout_vtbl))
1553         && mg->mg_obj) {
1554         /* handle to an in-place edit work file */
1555         SV **back_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_BACKUP_NAME, FALSE);
1556         SV **temp_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_TEMP_NAME, FALSE);
1557         /* PL_oldname may have been modified by a nested ARGV use at this point */
1558         SV **orig_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_NAME, FALSE);
1559         SV **mode_psv = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_MODE, FALSE);
1560         SV **pid_psv  = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_PID, FALSE);
1561 #if defined(ARGV_USE_ATFUNCTIONS)
1562         SV **dir_psv  = av_fetch((AV*)mg->mg_obj, ARGVMG_ORIG_DIRP, FALSE);
1563         DIR *dir;
1564         int dfd;
1565 #endif
1566         UV mode;
1567         int fd;
1568
1569         const char *orig_pv;
1570
1571         assert(temp_psv && *temp_psv);
1572         assert(orig_psv && *orig_psv);
1573         assert(mode_psv && *mode_psv);
1574         assert(pid_psv && *pid_psv);
1575 #ifdef ARGV_USE_ATFUNCTIONS
1576         assert(dir_psv && *dir_psv);
1577         dir = INT2PTR(DIR *, SvIVX(*dir_psv));
1578         dfd = my_dirfd(dir);
1579 #endif
1580
1581         orig_pv = SvPVX(*orig_psv);
1582         mode = SvUV(*mode_psv);
1583
1584         if ((mode & (S_ISUID|S_ISGID)) != 0
1585             && (fd = PerlIO_fileno(IoIFP(io))) >= 0) {
1586             (void)PerlIO_flush(IoIFP(io));
1587 #ifdef HAS_FCHMOD
1588             (void)fchmod(fd, mode);
1589 #else
1590             (void)PerlLIO_chmod(orig_pv, mode);
1591 #endif
1592         }
1593
1594         retval = io_close(io, NULL, not_implicit, FALSE);
1595
1596         if (SvIV(*pid_psv) != (IV)PerlProc_getpid()) {
1597             /* this is a child process, don't duplicate our rename() etc
1598                processing below */
1599             goto freext;
1600         }
1601
1602         if (retval) {
1603 #if defined(DOSISH) || defined(__CYGWIN__)
1604             if (PL_argvgv && GvIOp(PL_argvgv)
1605                 && IoIFP(GvIOp(PL_argvgv))
1606                 && (IoFLAGS(GvIOp(PL_argvgv)) & (IOf_ARGV|IOf_START)) == IOf_ARGV) {
1607                 do_close(PL_argvgv, FALSE);
1608             }
1609 #endif
1610 #ifndef ARGV_USE_ATFUNCTIONS
1611             if (!dir_unchanged(orig_pv, mg))
1612                 goto abort_inplace;
1613 #endif
1614             if (back_psv && *back_psv) {
1615 #if defined(HAS_LINK) && !defined(DOSISH) && !defined(__CYGWIN__) && defined(HAS_RENAME)
1616                 if (
1617 #  ifdef ARGV_USE_ATFUNCTIONS
1618                     linkat(dfd, orig_pv, dfd, SvPVX(*back_psv), 0) < 0 &&
1619                     !(UNLIKELY(NotSupported(errno)) &&
1620                       dir_unchanged(orig_pv, mg) &&
1621                                link(orig_pv, SvPVX(*back_psv)) == 0)
1622 #  else
1623                     link(orig_pv, SvPVX(*back_psv)) < 0
1624 #  endif
1625                     )
1626 #endif
1627                 {
1628 #ifdef HAS_RENAME
1629                     if (
1630 #  ifdef ARGV_USE_ATFUNCTIONS
1631                         S_my_renameat(dfd, orig_pv, dfd, SvPVX(*back_psv)) < 0 &&
1632                         !(UNLIKELY(NotSupported(errno)) &&
1633                           dir_unchanged(orig_pv, mg) &&
1634                           PerlLIO_rename(orig_pv, SvPVX(*back_psv)) == 0)
1635 #  else
1636                         PerlLIO_rename(orig_pv, SvPVX(*back_psv)) < 0
1637 #  endif
1638                         ) {
1639                         if (!not_implicit) {
1640 #  ifdef ARGV_USE_ATFUNCTIONS
1641                             if (unlinkat(dfd, SvPVX_const(*temp_psv), 0) < 0 &&
1642                                 UNLIKELY(NotSupported(errno)) &&
1643                                 dir_unchanged(orig_pv, mg))
1644                                 (void)UNLINK(SvPVX_const(*temp_psv));
1645 #  else
1646                             UNLINK(SvPVX(*temp_psv));
1647 #  endif
1648                             Perl_croak(aTHX_ "Can't rename %s to %s: %s, skipping file",
1649                                        SvPVX(*orig_psv), SvPVX(*back_psv), Strerror(errno));
1650                         }
1651                         /* should we warn here? */
1652                         goto abort_inplace;
1653                     }
1654 #else
1655                     (void)UNLINK(SvPVX(*back_psv));
1656                     if (link(orig_pv, SvPVX(*back_psv))) {
1657                         if (!not_implicit) {
1658                             Perl_croak(aTHX_ "Can't rename %s to %s: %s, skipping file",
1659                                        SvPVX(*orig_psv), SvPVX(*back_psv), Strerror(errno));
1660                         }
1661                         goto abort_inplace;
1662                     }
1663                     /* we need to use link() to get the temp into place too, and linK()
1664                        fails if the new link name exists */
1665                     (void)UNLINK(orig_pv);
1666 #endif
1667                 }
1668             }
1669 #if defined(DOSISH) || defined(__CYGWIN__) || !defined(HAS_RENAME)
1670             else {
1671                 UNLINK(orig_pv);
1672             }
1673 #endif
1674             if (
1675 #if !defined(HAS_RENAME)
1676                 link(SvPVX(*temp_psv), orig_pv) < 0
1677 #elif defined(ARGV_USE_ATFUNCTIONS)
1678                 S_my_renameat(dfd, SvPVX(*temp_psv), dfd, orig_pv) < 0 &&
1679                 !(UNLIKELY(NotSupported(errno)) &&
1680                   dir_unchanged(orig_pv, mg) &&
1681                   PerlLIO_rename(SvPVX(*temp_psv), orig_pv) == 0)
1682 #else
1683                 PerlLIO_rename(SvPVX(*temp_psv), orig_pv) < 0
1684 #endif
1685                 ) {
1686                 if (!not_implicit) {
1687 #ifdef ARGV_USE_ATFUNCTIONS
1688                     if (unlinkat(dfd, SvPVX_const(*temp_psv), 0) < 0 &&
1689                         NotSupported(errno))
1690                         UNLINK(SvPVX(*temp_psv));
1691 #else
1692                     UNLINK(SvPVX(*temp_psv));
1693 #endif
1694                     /* diag_listed_as: Cannot complete in-place edit of %s: %s */
1695                     Perl_croak(aTHX_ "Cannot complete in-place edit of %s: failed to rename work file '%s' to '%s': %s",
1696                                orig_pv, SvPVX(*temp_psv), orig_pv, Strerror(errno));
1697                 }
1698             abort_inplace:
1699                 UNLINK(SvPVX_const(*temp_psv));
1700                 retval = FALSE;
1701             }
1702 #ifndef HAS_RENAME
1703             UNLINK(SvPVX(*temp_psv));
1704 #endif
1705         }
1706         else {
1707 #ifdef ARGV_USE_ATFUNCTIONS
1708             if (unlinkat(dfd, SvPVX_const(*temp_psv), 0) &&
1709                 NotSupported(errno))
1710                 UNLINK(SvPVX_const(*temp_psv));
1711                 
1712 #else
1713             UNLINK(SvPVX_const(*temp_psv));
1714 #endif
1715             if (!not_implicit) {
1716                 Perl_croak(aTHX_ "Failed to close in-place work file %s: %s",
1717                            SvPVX(*temp_psv), Strerror(errno));
1718             }
1719         }
1720     freext:
1721         mg_freeext((SV*)io, PERL_MAGIC_uvar, &argvout_vtbl);
1722     }
1723     else {
1724         retval = io_close(io, NULL, not_implicit, FALSE);
1725     }
1726     if (not_implicit) {
1727         IoLINES(io) = 0;
1728         IoPAGE(io) = 0;
1729         IoLINES_LEFT(io) = IoPAGE_LEN(io);
1730     }
1731     IoTYPE(io) = IoTYPE_CLOSED;
1732     return retval;
1733 }
1734
1735 bool
1736 Perl_io_close(pTHX_ IO *io, GV *gv, bool not_implicit, bool warn_on_fail)
1737 {
1738     bool retval = FALSE;
1739
1740     PERL_ARGS_ASSERT_IO_CLOSE;
1741
1742     if (IoIFP(io)) {
1743         if (IoTYPE(io) == IoTYPE_PIPE) {
1744             const int status = PerlProc_pclose(IoIFP(io));
1745             if (not_implicit) {
1746                 STATUS_NATIVE_CHILD_SET(status);
1747                 retval = (STATUS_UNIX == 0);
1748             }
1749             else {
1750                 retval = (status != -1);
1751             }
1752         }
1753         else if (IoTYPE(io) == IoTYPE_STD)
1754             retval = TRUE;
1755         else {
1756             if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {          /* a socket */
1757                 const bool prev_err = PerlIO_error(IoOFP(io));
1758 #ifdef USE_PERLIO
1759                 if (prev_err)
1760                     PerlIO_restore_errno(IoOFP(io));
1761 #endif
1762                 retval = (PerlIO_close(IoOFP(io)) != EOF && !prev_err);
1763                 PerlIO_close(IoIFP(io));        /* clear stdio, fd already closed */
1764             }
1765             else {
1766                 const bool prev_err = PerlIO_error(IoIFP(io));
1767 #ifdef USE_PERLIO
1768                 if (prev_err)
1769                     PerlIO_restore_errno(IoIFP(io));
1770 #endif
1771                 retval = (PerlIO_close(IoIFP(io)) != EOF && !prev_err);
1772             }
1773         }
1774         IoOFP(io) = IoIFP(io) = NULL;
1775
1776         if (warn_on_fail && !retval) {
1777             if (gv)
1778                 Perl_ck_warner_d(aTHX_ packWARN(WARN_IO),
1779                                 "Warning: unable to close filehandle %"
1780                                  HEKf " properly: %" SVf,
1781                                  HEKfARG(GvNAME_HEK(gv)),
1782                                  SVfARG(get_sv("!",GV_ADD)));
1783             else
1784                 Perl_ck_warner_d(aTHX_ packWARN(WARN_IO),
1785                                 "Warning: unable to close filehandle "
1786                                 "properly: %" SVf,
1787                                  SVfARG(get_sv("!",GV_ADD)));
1788         }
1789     }
1790     else if (not_implicit) {
1791         SETERRNO(EBADF,SS_IVCHAN);
1792     }
1793
1794     return retval;
1795 }
1796
1797 bool
1798 Perl_do_eof(pTHX_ GV *gv)
1799 {
1800     IO * const io = GvIO(gv);
1801
1802     PERL_ARGS_ASSERT_DO_EOF;
1803
1804     if (!io)
1805         return TRUE;
1806     else if (IoTYPE(io) == IoTYPE_WRONLY)
1807         report_wrongway_fh(gv, '>');
1808
1809     while (IoIFP(io)) {
1810         if (PerlIO_has_cntptr(IoIFP(io))) {     /* (the code works without this) */
1811             if (PerlIO_get_cnt(IoIFP(io)) > 0)  /* cheat a little, since */
1812                 return FALSE;                   /* this is the most usual case */
1813         }
1814
1815         {
1816              /* getc and ungetc can stomp on errno */
1817             dSAVE_ERRNO;
1818             const int ch = PerlIO_getc(IoIFP(io));
1819             if (ch != EOF) {
1820                 (void)PerlIO_ungetc(IoIFP(io),ch);
1821                 RESTORE_ERRNO;
1822                 return FALSE;
1823             }
1824             RESTORE_ERRNO;
1825         }
1826
1827         if (PerlIO_has_cntptr(IoIFP(io)) && PerlIO_canset_cnt(IoIFP(io))) {
1828             if (PerlIO_get_cnt(IoIFP(io)) < -1)
1829                 PerlIO_set_cnt(IoIFP(io),-1);
1830         }
1831         if (PL_op->op_flags & OPf_SPECIAL) { /* not necessarily a real EOF yet? */
1832             if (gv != PL_argvgv || !nextargv(gv, FALSE))        /* get another fp handy */
1833                 return TRUE;
1834         }
1835         else
1836             return TRUE;                /* normal fp, definitely end of file */
1837     }
1838     return TRUE;
1839 }
1840
1841 Off_t
1842 Perl_do_tell(pTHX_ GV *gv)
1843 {
1844     IO *const io = GvIO(gv);
1845     PerlIO *fp;
1846
1847     PERL_ARGS_ASSERT_DO_TELL;
1848
1849     if (io && (fp = IoIFP(io))) {
1850         return PerlIO_tell(fp);
1851     }
1852     report_evil_fh(gv);
1853     SETERRNO(EBADF,RMS_IFI);
1854     return (Off_t)-1;
1855 }
1856
1857 bool
1858 Perl_do_seek(pTHX_ GV *gv, Off_t pos, int whence)
1859 {
1860     IO *const io = GvIO(gv);
1861     PerlIO *fp;
1862
1863     if (io && (fp = IoIFP(io))) {
1864         return PerlIO_seek(fp, pos, whence) >= 0;
1865     }
1866     report_evil_fh(gv);
1867     SETERRNO(EBADF,RMS_IFI);
1868     return FALSE;
1869 }
1870
1871 Off_t
1872 Perl_do_sysseek(pTHX_ GV *gv, Off_t pos, int whence)
1873 {
1874     IO *const io = GvIO(gv);
1875     PerlIO *fp;
1876
1877     PERL_ARGS_ASSERT_DO_SYSSEEK;
1878
1879     if (io && (fp = IoIFP(io))) {
1880         int fd = PerlIO_fileno(fp);
1881         if (fd < 0 || (whence == SEEK_SET && pos < 0)) {
1882             SETERRNO(EINVAL,LIB_INVARG);
1883             return -1;
1884         } else {
1885             return PerlLIO_lseek(fd, pos, whence);
1886         }
1887     }
1888     report_evil_fh(gv);
1889     SETERRNO(EBADF,RMS_IFI);
1890     return (Off_t)-1;
1891 }
1892
1893 int
1894 Perl_mode_from_discipline(pTHX_ const char *s, STRLEN len)
1895 {
1896     int mode = O_BINARY;
1897     PERL_UNUSED_CONTEXT;
1898     if (s) {
1899         while (*s) {
1900             if (*s == ':') {
1901                 switch (s[1]) {
1902                 case 'r':
1903                     if (s[2] == 'a' && s[3] == 'w'
1904                         && (!s[4] || s[4] == ':' || isSPACE(s[4])))
1905                     {
1906                         mode = O_BINARY;
1907                         s += 4;
1908                         len -= 4;
1909                         break;
1910                     }
1911                     /* FALLTHROUGH */
1912                 case 'c':
1913                     if (s[2] == 'r' && s[3] == 'l' && s[4] == 'f'
1914                         && (!s[5] || s[5] == ':' || isSPACE(s[5])))
1915                     {
1916                         mode = O_TEXT;
1917                         s += 5;
1918                         len -= 5;
1919                         break;
1920                     }
1921                     /* FALLTHROUGH */
1922                 default:
1923                     goto fail_discipline;
1924                 }
1925             }
1926             else if (isSPACE(*s)) {
1927                 ++s;
1928                 --len;
1929             }
1930             else {
1931                 const char *end;
1932   fail_discipline:
1933                 end = (char *) memchr(s+1, ':', len);
1934                 if (!end)
1935                     end = s+len;
1936 #ifndef PERLIO_LAYERS
1937                 Perl_croak(aTHX_ "IO layers (like '%.*s') unavailable", end-s, s);
1938 #else
1939                 len -= end-s;
1940                 s = end;
1941 #endif
1942             }
1943         }
1944     }
1945     return mode;
1946 }
1947
1948 #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE)
1949 I32
1950 my_chsize(int fd, Off_t length)
1951 {
1952 #ifdef F_FREESP
1953         /* code courtesy of William Kucharski */
1954 #define HAS_CHSIZE
1955
1956     Stat_t filebuf;
1957
1958     if (PerlLIO_fstat(fd, &filebuf) < 0)
1959         return -1;
1960
1961     if (filebuf.st_size < length) {
1962
1963         /* extend file length */
1964
1965         if ((PerlLIO_lseek(fd, (length - 1), 0)) < 0)
1966             return -1;
1967
1968         /* write a "0" byte */
1969
1970         if ((PerlLIO_write(fd, "", 1)) != 1)
1971             return -1;
1972     }
1973     else {
1974         /* truncate length */
1975         struct flock fl;
1976         fl.l_whence = 0;
1977         fl.l_len = 0;
1978         fl.l_start = length;
1979         fl.l_type = F_WRLCK;    /* write lock on file space */
1980
1981         /*
1982         * This relies on the UNDOCUMENTED F_FREESP argument to
1983         * fcntl(2), which truncates the file so that it ends at the
1984         * position indicated by fl.l_start.
1985         *
1986         * Will minor miracles never cease?
1987         */
1988
1989         if (fcntl(fd, F_FREESP, &fl) < 0)
1990             return -1;
1991
1992     }
1993     return 0;
1994 #else
1995     Perl_croak_nocontext("truncate not implemented");
1996 #endif /* F_FREESP */
1997     return -1;
1998 }
1999 #endif /* !HAS_TRUNCATE && !HAS_CHSIZE */
2000
2001 bool
2002 Perl_do_print(pTHX_ SV *sv, PerlIO *fp)
2003 {
2004     PERL_ARGS_ASSERT_DO_PRINT;
2005
2006     /* assuming fp is checked earlier */
2007     if (!sv)
2008         return TRUE;
2009     if (SvTYPE(sv) == SVt_IV && SvIOK(sv)) {
2010         assert(!SvGMAGICAL(sv));
2011         if (SvIsUV(sv))
2012             PerlIO_printf(fp, "%" UVuf, (UV)SvUVX(sv));
2013         else
2014             PerlIO_printf(fp, "%" IVdf, (IV)SvIVX(sv));
2015         return !PerlIO_error(fp);
2016     }
2017     else {
2018         STRLEN len;
2019         /* Do this first to trigger any overloading.  */
2020         const char *tmps = SvPV_const(sv, len);
2021         U8 *tmpbuf = NULL;
2022         bool happy = TRUE;
2023
2024         if (PerlIO_isutf8(fp)) { /* If the stream is utf8 ... */
2025             if (!SvUTF8(sv)) {  /* Convert to utf8 if necessary */
2026                 /* We don't modify the original scalar.  */
2027                 tmpbuf = bytes_to_utf8((const U8*) tmps, &len);
2028                 tmps = (char *) tmpbuf;
2029             }
2030             else if (ckWARN4_d(WARN_UTF8, WARN_SURROGATE, WARN_NON_UNICODE, WARN_NONCHAR)) {
2031                 (void) check_utf8_print((const U8*) tmps, len);
2032             }
2033         } /* else stream isn't utf8 */
2034         else if (DO_UTF8(sv)) { /* But if is utf8 internally, attempt to
2035                                    convert to bytes */
2036             STRLEN tmplen = len;
2037             bool utf8 = TRUE;
2038             U8 * const result = bytes_from_utf8((const U8*) tmps, &tmplen, &utf8);
2039             if (!utf8) {
2040
2041                 /* Here, succeeded in downgrading from utf8.  Set up to below
2042                  * output the converted value */
2043                 tmpbuf = result;
2044                 tmps = (char *) tmpbuf;
2045                 len = tmplen;
2046             }
2047             else {  /* Non-utf8 output stream, but string only representable in
2048                        utf8 */
2049                 assert((char *)result == tmps);
2050                 Perl_ck_warner_d(aTHX_ packWARN(WARN_UTF8),
2051                                  "Wide character in %s",
2052                                    PL_op ? OP_DESC(PL_op) : "print"
2053                                 );
2054                     /* Could also check that isn't one of the things to avoid
2055                      * in utf8 by using check_utf8_print(), but not doing so,
2056                      * since the stream isn't a UTF8 stream */
2057             }
2058         }
2059         /* To detect whether the process is about to overstep its
2060          * filesize limit we would need getrlimit().  We could then
2061          * also transparently raise the limit with setrlimit() --
2062          * but only until the system hard limit/the filesystem limit,
2063          * at which we would get EPERM.  Note that when using buffered
2064          * io the write failure can be delayed until the flush/close. --jhi */
2065         if (len && (PerlIO_write(fp,tmps,len) == 0))
2066             happy = FALSE;
2067         Safefree(tmpbuf);
2068         return happy ? !PerlIO_error(fp) : FALSE;
2069     }
2070 }
2071
2072 I32
2073 Perl_my_stat_flags(pTHX_ const U32 flags)
2074 {
2075     dSP;
2076     IO *io;
2077     GV* gv;
2078
2079     if (PL_op->op_flags & OPf_REF) {
2080         gv = cGVOP_gv;
2081       do_fstat:
2082         if (gv == PL_defgv) {
2083             if (PL_laststatval < 0)
2084                 SETERRNO(EBADF,RMS_IFI);
2085             return PL_laststatval;
2086         }
2087         io = GvIO(gv);
2088         do_fstat_have_io:
2089         PL_laststype = OP_STAT;
2090         PL_statgv = gv ? gv : (GV *)io;
2091         SvPVCLEAR(PL_statname);
2092         if (io) {
2093             if (IoIFP(io)) {
2094                 int fd = PerlIO_fileno(IoIFP(io));
2095                 if (fd < 0) {
2096                     /* E.g. PerlIO::scalar has no real fd. */
2097                     SETERRNO(EBADF,RMS_IFI);
2098                     return (PL_laststatval = -1);
2099                 } else {
2100                     return (PL_laststatval = PerlLIO_fstat(fd, &PL_statcache));
2101                 }
2102             } else if (IoDIRP(io)) {
2103                 return (PL_laststatval = PerlLIO_fstat(my_dirfd(IoDIRP(io)), &PL_statcache));
2104             }
2105         }
2106         PL_laststatval = -1;
2107         report_evil_fh(gv);
2108         SETERRNO(EBADF,RMS_IFI);
2109         return -1;
2110     }
2111     else if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t))
2112              == OPpFT_STACKED)
2113         return PL_laststatval;
2114     else {
2115         SV* const sv = TOPs;
2116         const char *s, *d;
2117         STRLEN len;
2118         if ((gv = MAYBE_DEREF_GV_flags(sv,flags))) {
2119             goto do_fstat;
2120         }
2121         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) {
2122             io = MUTABLE_IO(SvRV(sv));
2123             gv = NULL;
2124             goto do_fstat_have_io;
2125         }
2126
2127         s = SvPV_flags_const(sv, len, flags);
2128         PL_statgv = NULL;
2129         sv_setpvn(PL_statname, s, len);
2130         d = SvPVX_const(PL_statname);           /* s now NUL-terminated */
2131         PL_laststype = OP_STAT;
2132         if (!IS_SAFE_PATHNAME(s, len, OP_NAME(PL_op))) {
2133             PL_laststatval = -1;
2134         }
2135         else {
2136             PL_laststatval = PerlLIO_stat(d, &PL_statcache);
2137         }
2138         if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && should_warn_nl(s)) {
2139             GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral); /* PL_warn_nl is constant */
2140             Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
2141             GCC_DIAG_RESTORE_STMT;
2142         }
2143         return PL_laststatval;
2144     }
2145 }
2146
2147
2148 I32
2149 Perl_my_lstat_flags(pTHX_ const U32 flags)
2150 {
2151     static const char* const no_prev_lstat = "The stat preceding -l _ wasn't an lstat";
2152     dSP;
2153     const char *file;
2154     STRLEN len;
2155     SV* const sv = TOPs;
2156     bool isio = FALSE;
2157     if (PL_op->op_flags & OPf_REF) {
2158         if (cGVOP_gv == PL_defgv) {
2159             if (PL_laststype != OP_LSTAT)
2160                 Perl_croak(aTHX_ "%s", no_prev_lstat);
2161             if (PL_laststatval < 0)
2162                 SETERRNO(EBADF,RMS_IFI);
2163             return PL_laststatval;
2164         }
2165         PL_laststatval = -1;
2166         if (ckWARN(WARN_IO)) {
2167             /* diag_listed_as: Use of -l on filehandle%s */
2168             Perl_warner(aTHX_ packWARN(WARN_IO),
2169                               "Use of -l on filehandle %" HEKf,
2170                               HEKfARG(GvENAME_HEK(cGVOP_gv)));
2171         }
2172         SETERRNO(EBADF,RMS_IFI);
2173         return -1;
2174     }
2175     if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t))
2176              == OPpFT_STACKED) {
2177       if (PL_laststype != OP_LSTAT)
2178         Perl_croak(aTHX_ "%s", no_prev_lstat);
2179       return PL_laststatval;
2180     }
2181
2182     PL_laststype = OP_LSTAT;
2183     PL_statgv = NULL;
2184     if ( (  (SvROK(sv) && (  isGV_with_GP(SvRV(sv))
2185                           || (isio = SvTYPE(SvRV(sv)) == SVt_PVIO)  )
2186             )
2187          || isGV_with_GP(sv)
2188          )
2189       && ckWARN(WARN_IO)) {
2190         if (isio)
2191             /* diag_listed_as: Use of -l on filehandle%s */
2192             Perl_warner(aTHX_ packWARN(WARN_IO),
2193                              "Use of -l on filehandle");
2194         else
2195             /* diag_listed_as: Use of -l on filehandle%s */
2196             Perl_warner(aTHX_ packWARN(WARN_IO),
2197                              "Use of -l on filehandle %" HEKf,
2198                               HEKfARG(GvENAME_HEK((const GV *)
2199                                           (SvROK(sv) ? SvRV(sv) : sv))));
2200     }
2201     file = SvPV_flags_const(sv, len, flags);
2202     sv_setpv(PL_statname,file);
2203     if (!IS_SAFE_PATHNAME(file, len, OP_NAME(PL_op))) {
2204         PL_laststatval = -1;
2205     }
2206     else {
2207         PL_laststatval = PerlLIO_lstat(file,&PL_statcache);
2208     }
2209     if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && should_warn_nl(file)) {
2210         GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral); /* PL_warn_nl is constant */
2211         Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
2212         GCC_DIAG_RESTORE_STMT;
2213     }
2214     return PL_laststatval;
2215 }
2216
2217 static void
2218 S_exec_failed(pTHX_ const char *cmd, int fd, int do_report)
2219 {
2220     const int e = errno;
2221     PERL_ARGS_ASSERT_EXEC_FAILED;
2222
2223     if (ckWARN(WARN_EXEC))
2224         Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
2225                     cmd, Strerror(e));
2226     if (do_report) {
2227         /* XXX silently ignore failures */
2228         PERL_UNUSED_RESULT(PerlLIO_write(fd, (void*)&e, sizeof(int)));
2229         PerlLIO_close(fd);
2230     }
2231 }
2232
2233 bool
2234 Perl_do_aexec5(pTHX_ SV *really, SV **mark, SV **sp,
2235                int fd, int do_report)
2236 {
2237     dVAR;
2238     PERL_ARGS_ASSERT_DO_AEXEC5;
2239 #if defined(__SYMBIAN32__) || defined(__LIBCATAMOUNT__)
2240     Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
2241 #else
2242     assert(sp >= mark);
2243     ENTER;
2244     {
2245         const char **argv, **a;
2246         const char *tmps = NULL;
2247         Newx(argv, sp - mark + 1, const char*);
2248         SAVEFREEPV(argv);
2249         a = argv;
2250
2251         while (++mark <= sp) {
2252             if (*mark) {
2253                 char *arg = savepv(SvPV_nolen_const(*mark));
2254                 SAVEFREEPV(arg);
2255                 *a++ = arg;
2256             } else
2257                 *a++ = "";
2258         }
2259         *a = NULL;
2260         if (really) {
2261             tmps = savepv(SvPV_nolen_const(really));
2262             SAVEFREEPV(tmps);
2263         }
2264         if ((!really && argv[0] && *argv[0] != '/') ||
2265             (really && *tmps != '/'))           /* will execvp use PATH? */
2266             TAINT_ENV();                /* testing IFS here is overkill, probably */
2267         PERL_FPU_PRE_EXEC
2268         if (really && *tmps) {
2269             PerlProc_execvp(tmps,EXEC_ARGV_CAST(argv));
2270         } else if (argv[0]) {
2271             PerlProc_execvp(argv[0],EXEC_ARGV_CAST(argv));
2272         } else {
2273             SETERRNO(ENOENT,RMS_FNF);
2274         }
2275         PERL_FPU_POST_EXEC
2276         S_exec_failed(aTHX_ (really ? tmps : argv[0] ? argv[0] : ""), fd, do_report);
2277     }
2278     LEAVE;
2279 #endif
2280     return FALSE;
2281 }
2282
2283 #ifdef PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
2284
2285 bool
2286 Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
2287 {
2288     dVAR;
2289     const char **argv, **a;
2290     char *s;
2291     char *buf;
2292     char *cmd;
2293     /* Make a copy so we can change it */
2294     const Size_t cmdlen = strlen(incmd) + 1;
2295
2296     PERL_ARGS_ASSERT_DO_EXEC3;
2297
2298     ENTER;
2299     Newx(buf, cmdlen, char);
2300     SAVEFREEPV(buf);
2301     cmd = buf;
2302     memcpy(cmd, incmd, cmdlen);
2303
2304     while (*cmd && isSPACE(*cmd))
2305         cmd++;
2306
2307     /* save an extra exec if possible */
2308
2309 #ifdef CSH
2310     {
2311         char flags[PERL_FLAGS_MAX];
2312         if (strnEQ(cmd,PL_cshname,PL_cshlen) &&
2313             strBEGINs(cmd+PL_cshlen," -c")) {
2314           my_strlcpy(flags, "-c", PERL_FLAGS_MAX);
2315           s = cmd+PL_cshlen+3;
2316           if (*s == 'f') {
2317               s++;
2318               my_strlcat(flags, "f", PERL_FLAGS_MAX - 2);
2319           }
2320           if (*s == ' ')
2321               s++;
2322           if (*s++ == '\'') {
2323               char * const ncmd = s;
2324
2325               while (*s)
2326                   s++;
2327               if (s[-1] == '\n')
2328                   *--s = '\0';
2329               if (s[-1] == '\'') {
2330                   *--s = '\0';
2331                   PERL_FPU_PRE_EXEC
2332                   PerlProc_execl(PL_cshname, "csh", flags, ncmd, (char*)NULL);
2333                   PERL_FPU_POST_EXEC
2334                   *s = '\'';
2335                   S_exec_failed(aTHX_ PL_cshname, fd, do_report);
2336                   goto leave;
2337               }
2338           }
2339         }
2340     }
2341 #endif /* CSH */
2342
2343     /* see if there are shell metacharacters in it */
2344
2345     if (*cmd == '.' && isSPACE(cmd[1]))
2346         goto doshell;
2347
2348     if (strBEGINs(cmd,"exec") && isSPACE(cmd[4]))
2349         goto doshell;
2350
2351     s = cmd;
2352     while (isWORDCHAR(*s))
2353         s++;    /* catch VAR=val gizmo */
2354     if (*s == '=')
2355         goto doshell;
2356
2357     for (s = cmd; *s; s++) {
2358         if (*s != ' ' && !isALPHA(*s) &&
2359             strchr("$&*(){}[]'\";\\|?<>~`\n",*s)) {
2360             if (*s == '\n' && !s[1]) {
2361                 *s = '\0';
2362                 break;
2363             }
2364             /* handle the 2>&1 construct at the end */
2365             if (*s == '>' && s[1] == '&' && s[2] == '1'
2366                 && s > cmd + 1 && s[-1] == '2' && isSPACE(s[-2])
2367                 && (!s[3] || isSPACE(s[3])))
2368             {
2369                 const char *t = s + 3;
2370
2371                 while (*t && isSPACE(*t))
2372                     ++t;
2373                 if (!*t && (PerlLIO_dup2(1,2) != -1)) {
2374                     s[-2] = '\0';
2375                     break;
2376                 }
2377             }
2378           doshell:
2379             PERL_FPU_PRE_EXEC
2380             PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char *)NULL);
2381             PERL_FPU_POST_EXEC
2382             S_exec_failed(aTHX_ PL_sh_path, fd, do_report);
2383             goto leave;
2384         }
2385     }
2386
2387     Newx(argv, (s - cmd) / 2 + 2, const char*);
2388     SAVEFREEPV(argv);
2389     cmd = savepvn(cmd, s-cmd);
2390     SAVEFREEPV(cmd);
2391     a = argv;
2392     for (s = cmd; *s;) {
2393         while (isSPACE(*s))
2394             s++;
2395         if (*s)
2396             *(a++) = s;
2397         while (*s && !isSPACE(*s))
2398             s++;
2399         if (*s)
2400             *s++ = '\0';
2401     }
2402     *a = NULL;
2403     if (argv[0]) {
2404         PERL_FPU_PRE_EXEC
2405         PerlProc_execvp(argv[0],EXEC_ARGV_CAST(argv));
2406         PERL_FPU_POST_EXEC
2407         if (errno == ENOEXEC)           /* for system V NIH syndrome */
2408             goto doshell;
2409         S_exec_failed(aTHX_ argv[0], fd, do_report);
2410     }
2411 leave:
2412     LEAVE;
2413     return FALSE;
2414 }
2415
2416 #endif /* OS2 || WIN32 */
2417
2418 I32
2419 Perl_apply(pTHX_ I32 type, SV **mark, SV **sp)
2420 {
2421     I32 val;
2422     I32 tot = 0;
2423     const char *const what = PL_op_name[type];
2424     const char *s;
2425     STRLEN len;
2426     SV ** const oldmark = mark;
2427     bool killgp = FALSE;
2428
2429     PERL_ARGS_ASSERT_APPLY;
2430
2431     PERL_UNUSED_VAR(what); /* may not be used depending on compile options */
2432
2433     /* Doing this ahead of the switch statement preserves the old behaviour,
2434        where attempting to use kill as a taint test test would fail on
2435        platforms where kill was not defined.  */
2436 #ifndef HAS_KILL
2437     if (type == OP_KILL)
2438         Perl_die(aTHX_ PL_no_func, what);
2439 #endif
2440 #ifndef HAS_CHOWN
2441     if (type == OP_CHOWN)
2442         Perl_die(aTHX_ PL_no_func, what);
2443 #endif
2444
2445
2446 #define APPLY_TAINT_PROPER() \
2447     STMT_START {                                                        \
2448         if (TAINT_get) { TAINT_PROPER(what); }                          \
2449     } STMT_END
2450
2451     /* This is a first heuristic; it doesn't catch tainting magic. */
2452     if (TAINTING_get) {
2453         while (++mark <= sp) {
2454             if (SvTAINTED(*mark)) {
2455                 TAINT;
2456                 break;
2457             }
2458         }
2459         mark = oldmark;
2460     }
2461     switch (type) {
2462     case OP_CHMOD:
2463         APPLY_TAINT_PROPER();
2464         if (++mark <= sp) {
2465             val = SvIV(*mark);
2466             APPLY_TAINT_PROPER();
2467             tot = sp - mark;
2468             while (++mark <= sp) {
2469                 GV* gv;
2470                 if ((gv = MAYBE_DEREF_GV(*mark))) {
2471                     if (GvIO(gv) && IoIFP(GvIOp(gv))) {
2472 #ifdef HAS_FCHMOD
2473                         int fd = PerlIO_fileno(IoIFP(GvIOn(gv)));
2474                         APPLY_TAINT_PROPER();
2475                         if (fd < 0) {
2476                             SETERRNO(EBADF,RMS_IFI);
2477                             tot--;
2478                         } else if (fchmod(fd, val))
2479                             tot--;
2480 #else
2481                         Perl_die(aTHX_ PL_no_func, "fchmod");
2482 #endif
2483                     }
2484                     else {
2485                         SETERRNO(EBADF,RMS_IFI);
2486                         tot--;
2487                     }
2488                 }
2489                 else {
2490                     const char *name = SvPV_nomg_const(*mark, len);
2491                     APPLY_TAINT_PROPER();
2492                     if (!IS_SAFE_PATHNAME(name, len, "chmod") ||
2493                         PerlLIO_chmod(name, val)) {
2494                         tot--;
2495                     }
2496                 }
2497             }
2498         }
2499         break;
2500 #ifdef HAS_CHOWN
2501     case OP_CHOWN:
2502         APPLY_TAINT_PROPER();
2503         if (sp - mark > 2) {
2504             I32 val2;
2505             val = SvIVx(*++mark);
2506             val2 = SvIVx(*++mark);
2507             APPLY_TAINT_PROPER();
2508             tot = sp - mark;
2509             while (++mark <= sp) {
2510                 GV* gv;
2511                 if ((gv = MAYBE_DEREF_GV(*mark))) {
2512                     if (GvIO(gv) && IoIFP(GvIOp(gv))) {
2513 #ifdef HAS_FCHOWN
2514                         int fd = PerlIO_fileno(IoIFP(GvIOn(gv)));
2515                         APPLY_TAINT_PROPER();
2516                         if (fd < 0) {
2517                             SETERRNO(EBADF,RMS_IFI);
2518                             tot--;
2519                         } else if (fchown(fd, val, val2))
2520                             tot--;
2521 #else
2522                         Perl_die(aTHX_ PL_no_func, "fchown");
2523 #endif
2524                     }
2525                     else {
2526                         SETERRNO(EBADF,RMS_IFI);
2527                         tot--;
2528                     }
2529                 }
2530                 else {
2531                     const char *name = SvPV_nomg_const(*mark, len);
2532                     APPLY_TAINT_PROPER();
2533                     if (!IS_SAFE_PATHNAME(name, len, "chown") ||
2534                         PerlLIO_chown(name, val, val2)) {
2535                         tot--;
2536                     }
2537                 }
2538             }
2539         }
2540         break;
2541 #endif
2542 /*
2543 XXX Should we make lchown() directly available from perl?
2544 For now, we'll let Configure test for HAS_LCHOWN, but do
2545 nothing in the core.
2546     --AD  5/1998
2547 */
2548 #ifdef HAS_KILL
2549     case OP_KILL:
2550         APPLY_TAINT_PROPER();
2551         if (mark == sp)
2552             break;
2553         s = SvPVx_const(*++mark, len);
2554         if (*s == '-' && isALPHA(s[1]))
2555         {
2556             s++;
2557             len--;
2558             killgp = TRUE;
2559         }
2560         if (isALPHA(*s)) {
2561             if (*s == 'S' && s[1] == 'I' && s[2] == 'G') {
2562                 s += 3;
2563                 len -= 3;
2564             }
2565            if ((val = whichsig_pvn(s, len)) < 0)
2566                Perl_croak(aTHX_ "Unrecognized signal name \"%" SVf "\"",
2567                                 SVfARG(*mark));
2568         }
2569         else
2570         {
2571             val = SvIV(*mark);
2572             if (val < 0)
2573             {
2574                 killgp = TRUE;
2575                 val = -val;
2576             }
2577         }
2578         APPLY_TAINT_PROPER();
2579         tot = sp - mark;
2580
2581         while (++mark <= sp) {
2582             Pid_t proc;
2583             SvGETMAGIC(*mark);
2584             if (!(SvNIOK(*mark) || looks_like_number(*mark)))
2585                 Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
2586             proc = SvIV_nomg(*mark);
2587             APPLY_TAINT_PROPER();
2588 #ifdef HAS_KILLPG
2589             /* use killpg in preference, as the killpg() wrapper for Win32
2590              * understands process groups, but the kill() wrapper doesn't */
2591             if (killgp ? PerlProc_killpg(proc, val)
2592                        : PerlProc_kill(proc, val))
2593 #else
2594             if (PerlProc_kill(killgp ? -proc: proc, val))
2595 #endif
2596                 tot--;
2597         }
2598         PERL_ASYNC_CHECK();
2599         break;
2600 #endif
2601     case OP_UNLINK:
2602         APPLY_TAINT_PROPER();
2603         tot = sp - mark;
2604         while (++mark <= sp) {
2605             s = SvPV_const(*mark, len);
2606             APPLY_TAINT_PROPER();
2607             if (!IS_SAFE_PATHNAME(s, len, "unlink")) {
2608                 tot--;
2609             }
2610             else if (PL_unsafe) {
2611                 if (UNLINK(s))
2612                 {
2613                     tot--;
2614                 }
2615 #if defined(__amigaos4__) && defined(NEWLIB)
2616                 else
2617                 {
2618                   /* Under AmigaOS4 unlink only 'fails' if the
2619                    * filename is invalid.  It may not remove the file
2620                    * if it's locked, so check if it's still around. */
2621                   if ((access(s,F_OK) != -1))
2622                   {
2623                     tot--;
2624                   }
2625                 }
2626 #endif
2627             }
2628             else {      /* don't let root wipe out directories without -U */
2629                 Stat_t statbuf;
2630                 if (PerlLIO_lstat(s, &statbuf) < 0)
2631                     tot--;
2632                 else if (S_ISDIR(statbuf.st_mode)) {
2633                     SETERRNO(EISDIR, SS_NOPRIV);
2634                     tot--;
2635                 }
2636                 else {
2637                     if (UNLINK(s))
2638                     {
2639                                 tot--;
2640                         }
2641 #if defined(__amigaos4__) && defined(NEWLIB)
2642                         else
2643                         {
2644                                 /* Under AmigaOS4 unlink only 'fails' if the filename is invalid */
2645                                 /* It may not remove the file if it's Locked, so check if it's still */
2646                                 /* arround */
2647                                 if((access(s,F_OK) != -1))
2648                                 {
2649                                         tot--;
2650                                 }
2651                         }       
2652 #endif
2653                 }
2654             }
2655         }
2656         break;
2657 #if defined(HAS_UTIME) || defined(HAS_FUTIMES)
2658     case OP_UTIME:
2659         APPLY_TAINT_PROPER();
2660         if (sp - mark > 2) {
2661 #if defined(HAS_FUTIMES)
2662             struct timeval utbuf[2];
2663             void *utbufp = utbuf;
2664 #elif defined(I_UTIME) || defined(VMS)
2665             struct utimbuf utbuf;
2666             struct utimbuf *utbufp = &utbuf;
2667 #else
2668             struct {
2669                 Time_t  actime;
2670                 Time_t  modtime;
2671             } utbuf;
2672             void *utbufp = &utbuf;
2673 #endif
2674
2675            SV* const accessed = *++mark;
2676            SV* const modified = *++mark;
2677
2678            /* Be like C, and if both times are undefined, let the C
2679             * library figure out what to do.  This usually means
2680             * "current time". */
2681
2682            if ( accessed == &PL_sv_undef && modified == &PL_sv_undef )
2683                 utbufp = NULL;
2684            else {
2685                 Zero(&utbuf, sizeof utbuf, char);
2686 #ifdef HAS_FUTIMES
2687                 utbuf[0].tv_sec = (long)SvIV(accessed);  /* time accessed */
2688                 utbuf[0].tv_usec = 0;
2689                 utbuf[1].tv_sec = (long)SvIV(modified);  /* time modified */
2690                 utbuf[1].tv_usec = 0;
2691 #elif defined(BIG_TIME)
2692                 utbuf.actime = (Time_t)SvNV(accessed);  /* time accessed */
2693                 utbuf.modtime = (Time_t)SvNV(modified); /* time modified */
2694 #else
2695                 utbuf.actime = (Time_t)SvIV(accessed);  /* time accessed */
2696                 utbuf.modtime = (Time_t)SvIV(modified); /* time modified */
2697 #endif
2698             }
2699             APPLY_TAINT_PROPER();
2700             tot = sp - mark;
2701             while (++mark <= sp) {
2702                 GV* gv;
2703                 if ((gv = MAYBE_DEREF_GV(*mark))) {
2704                     if (GvIO(gv) && IoIFP(GvIOp(gv))) {
2705 #ifdef HAS_FUTIMES
2706                         int fd =  PerlIO_fileno(IoIFP(GvIOn(gv)));
2707                         APPLY_TAINT_PROPER();
2708                         if (fd < 0) {
2709                             SETERRNO(EBADF,RMS_IFI);
2710                             tot--;
2711                         } else if (futimes(fd, (struct timeval *) utbufp))
2712                             tot--;
2713 #else
2714                         Perl_die(aTHX_ PL_no_func, "futimes");
2715 #endif
2716                     }
2717                     else {
2718                         tot--;
2719                     }
2720                 }
2721                 else {
2722                     const char * const name = SvPV_nomg_const(*mark, len);
2723                     APPLY_TAINT_PROPER();
2724                     if (!IS_SAFE_PATHNAME(name, len, "utime")) {
2725                         tot--;
2726                     }
2727                     else
2728 #ifdef HAS_FUTIMES
2729                     if (utimes(name, (struct timeval *)utbufp))
2730 #else
2731                     if (PerlLIO_utime(name, utbufp))
2732 #endif
2733                         tot--;
2734                 }
2735
2736             }
2737         }
2738         else
2739             tot = 0;
2740         break;
2741 #endif
2742     }
2743     return tot;
2744
2745 #undef APPLY_TAINT_PROPER
2746 }
2747
2748 /* Do the permissions in *statbufp allow some operation? */
2749 #ifndef VMS /* VMS' cando is in vms.c */
2750 bool
2751 Perl_cando(pTHX_ Mode_t mode, bool effective, const Stat_t *statbufp)
2752 /* effective is a flag, true for EUID, or for checking if the effective gid
2753  *  is in the list of groups returned from getgroups().
2754  */
2755 {
2756     PERL_ARGS_ASSERT_CANDO;
2757     PERL_UNUSED_CONTEXT;
2758
2759 #ifdef DOSISH
2760     /* [Comments and code from Len Reed]
2761      * MS-DOS "user" is similar to UNIX's "superuser," but can't write
2762      * to write-protected files.  The execute permission bit is set
2763      * by the Microsoft C library stat() function for the following:
2764      *          .exe files
2765      *          .com files
2766      *          .bat files
2767      *          directories
2768      * All files and directories are readable.
2769      * Directories and special files, e.g. "CON", cannot be
2770      * write-protected.
2771      * [Comment by Tom Dinger -- a directory can have the write-protect
2772      *          bit set in the file system, but DOS permits changes to
2773      *          the directory anyway.  In addition, all bets are off
2774      *          here for networked software, such as Novell and
2775      *          Sun's PC-NFS.]
2776      */
2777
2778      /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
2779       * too so it will actually look into the files for magic numbers
2780       */
2781     return cBOOL(mode & statbufp->st_mode);
2782
2783 #else /* ! DOSISH */
2784 # ifdef __CYGWIN__
2785     if (ingroup(544,effective)) {     /* member of Administrators */
2786 # else
2787     if ((effective ? PerlProc_geteuid() : PerlProc_getuid()) == 0) {    /* root is special */
2788 # endif
2789         if (mode == S_IXUSR) {
2790             if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))
2791                 return TRUE;
2792         }
2793         else
2794             return TRUE;                /* root reads and writes anything */
2795         return FALSE;
2796     }
2797     if (statbufp->st_uid == (effective ? PerlProc_geteuid() : PerlProc_getuid()) ) {
2798         if (statbufp->st_mode & mode)
2799             return TRUE;        /* ok as "user" */
2800     }
2801     else if (ingroup(statbufp->st_gid,effective)) {
2802         if (statbufp->st_mode & mode >> 3)
2803             return TRUE;        /* ok as "group" */
2804     }
2805     else if (statbufp->st_mode & mode >> 6)
2806         return TRUE;    /* ok as "other" */
2807     return FALSE;
2808 #endif /* ! DOSISH */
2809 }
2810 #endif /* ! VMS */
2811
2812 static bool
2813 S_ingroup(pTHX_ Gid_t testgid, bool effective)
2814 {
2815 #ifndef PERL_IMPLICIT_SYS
2816     /* PERL_IMPLICIT_SYS like Win32: getegid() etc. require the context. */
2817     PERL_UNUSED_CONTEXT;
2818 #endif
2819     if (testgid == (effective ? PerlProc_getegid() : PerlProc_getgid()))
2820         return TRUE;
2821 #ifdef HAS_GETGROUPS
2822     {
2823         Groups_t *gary = NULL;
2824         I32 anum;
2825         bool rc = FALSE;
2826
2827         anum = getgroups(0, gary);
2828         if (anum > 0) {
2829             Newx(gary, anum, Groups_t);
2830             anum = getgroups(anum, gary);
2831             while (--anum >= 0)
2832                 if (gary[anum] == testgid) {
2833                     rc = TRUE;
2834                     break;
2835                 }
2836
2837             Safefree(gary);
2838         }
2839         return rc;
2840     }
2841 #else
2842     return FALSE;
2843 #endif
2844 }
2845
2846 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
2847
2848 I32
2849 Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
2850 {
2851     const key_t key = (key_t)SvNVx(*++mark);
2852     SV *nsv = optype == OP_MSGGET ? NULL : *++mark;
2853     const I32 flags = SvIVx(*++mark);
2854
2855     PERL_ARGS_ASSERT_DO_IPCGET;
2856     PERL_UNUSED_ARG(sp);
2857
2858     SETERRNO(0,0);
2859     switch (optype)
2860     {
2861 #ifdef HAS_MSG
2862     case OP_MSGGET:
2863         return msgget(key, flags);
2864 #endif
2865 #ifdef HAS_SEM
2866     case OP_SEMGET:
2867         return semget(key, (int) SvIV(nsv), flags);
2868 #endif
2869 #ifdef HAS_SHM
2870     case OP_SHMGET:
2871         return shmget(key, (size_t) SvUV(nsv), flags);
2872 #endif
2873 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
2874     default:
2875         /* diag_listed_as: msg%s not implemented */
2876         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2877 #endif
2878     }
2879     return -1;                  /* should never happen */
2880 }
2881
2882 I32
2883 Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
2884 {
2885     char *a;
2886     I32 ret = -1;
2887     const I32 id  = SvIVx(*++mark);
2888 #ifdef Semctl
2889     const I32 n   = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
2890 #endif
2891     const I32 cmd = SvIVx(*++mark);
2892     SV * const astr = *++mark;
2893     STRLEN infosize = 0;
2894     I32 getinfo = (cmd == IPC_STAT);
2895
2896     PERL_ARGS_ASSERT_DO_IPCCTL;
2897     PERL_UNUSED_ARG(sp);
2898
2899     switch (optype)
2900     {
2901 #ifdef HAS_MSG
2902     case OP_MSGCTL:
2903         if (cmd == IPC_STAT || cmd == IPC_SET)
2904             infosize = sizeof(struct msqid_ds);
2905         break;
2906 #endif
2907 #ifdef HAS_SHM
2908     case OP_SHMCTL:
2909         if (cmd == IPC_STAT || cmd == IPC_SET)
2910             infosize = sizeof(struct shmid_ds);
2911         break;
2912 #endif
2913 #ifdef HAS_SEM
2914     case OP_SEMCTL:
2915 #ifdef Semctl
2916         if (cmd == IPC_STAT || cmd == IPC_SET)
2917             infosize = sizeof(struct semid_ds);
2918         else if (cmd == GETALL || cmd == SETALL)
2919         {
2920             struct semid_ds semds;
2921             union semun semun;
2922 #ifdef EXTRA_F_IN_SEMUN_BUF
2923             semun.buff = &semds;
2924 #else
2925             semun.buf = &semds;
2926 #endif
2927             getinfo = (cmd == GETALL);
2928             if (Semctl(id, 0, IPC_STAT, semun) == -1)
2929                 return -1;
2930             infosize = semds.sem_nsems * sizeof(short);
2931                 /* "short" is technically wrong but much more portable
2932                    than guessing about u_?short(_t)? */
2933         }
2934 #else
2935         /* diag_listed_as: sem%s not implemented */
2936         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2937 #endif
2938         break;
2939 #endif
2940 #if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
2941     default:
2942         /* diag_listed_as: shm%s not implemented */
2943         Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2944 #endif
2945     }
2946
2947     if (infosize)
2948     {
2949         if (getinfo)
2950         {
2951             SvPV_force_nolen(astr);
2952             a = SvGROW(astr, infosize+1);
2953         }
2954         else
2955         {
2956             STRLEN len;
2957             a = SvPV(astr, len);
2958             if (len != infosize)
2959                 Perl_croak(aTHX_ "Bad arg length for %s, is %lu, should be %ld",
2960                       PL_op_desc[optype],
2961                       (unsigned long)len,
2962                       (long)infosize);
2963         }
2964     }
2965     else
2966     {
2967         const IV i = SvIV(astr);
2968         a = INT2PTR(char *,i);          /* ouch */
2969     }
2970     SETERRNO(0,0);
2971     switch (optype)
2972     {
2973 #ifdef HAS_MSG
2974     case OP_MSGCTL:
2975         ret = msgctl(id, cmd, (struct msqid_ds *)a);
2976         break;
2977 #endif
2978 #ifdef HAS_SEM
2979     case OP_SEMCTL: {
2980 #ifdef Semctl
2981             union semun unsemds;
2982
2983             if(cmd == SETVAL) {
2984                 unsemds.val = PTR2nat(a);
2985             }
2986             else {
2987 #ifdef EXTRA_F_IN_SEMUN_BUF
2988                 unsemds.buff = (struct semid_ds *)a;
2989 #else
2990                 unsemds.buf = (struct semid_ds *)a;
2991 #endif
2992             }
2993             ret = Semctl(id, n, cmd, unsemds);
2994 #else
2995             /* diag_listed_as: sem%s not implemented */
2996             Perl_croak(aTHX_ "%s not implemented", PL_op_desc[optype]);
2997 #endif
2998         }
2999         break;
3000 #endif
3001 #ifdef HAS_SHM
3002     case OP_SHMCTL:
3003         ret = shmctl(id, cmd, (struct shmid_ds *)a);
3004         break;
3005 #endif
3006     }
3007     if (getinfo && ret >= 0) {
3008         SvCUR_set(astr, infosize);
3009         *SvEND(astr) = '\0';
3010         SvSETMAGIC(astr);
3011     }
3012     return ret;
3013 }
3014
3015 I32
3016 Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
3017 {
3018 #ifdef HAS_MSG
3019     STRLEN len;
3020     const I32 id = SvIVx(*++mark);
3021     SV * const mstr = *++mark;
3022     const I32 flags = SvIVx(*++mark);
3023     const char * const mbuf = SvPV_const(mstr, len);
3024     const I32 msize = len - sizeof(long);
3025
3026     PERL_ARGS_ASSERT_DO_MSGSND;
3027     PERL_UNUSED_ARG(sp);
3028
3029     if (msize < 0)
3030         Perl_croak(aTHX_ "Arg too short for msgsnd");
3031     SETERRNO(0,0);
3032     if (id >= 0 && flags >= 0) {
3033       return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
3034     } else {
3035       SETERRNO(EINVAL,LIB_INVARG);
3036       return -1;
3037     }
3038 #else
3039     PERL_UNUSED_ARG(sp);
3040     PERL_UNUSED_ARG(mark);
3041     /* diag_listed_as: msg%s not implemented */
3042     Perl_croak(aTHX_ "msgsnd not implemented");
3043     return -1;
3044 #endif
3045 }
3046
3047 I32
3048 Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
3049 {
3050 #ifdef HAS_MSG
3051     char *mbuf;
3052     long mtype;
3053     I32 msize, flags, ret;
3054     const I32 id = SvIVx(*++mark);
3055     SV * const mstr = *++mark;
3056
3057     PERL_ARGS_ASSERT_DO_MSGRCV;
3058     PERL_UNUSED_ARG(sp);
3059
3060     /* suppress warning when reading into undef var --jhi */
3061     if (! SvOK(mstr))
3062         SvPVCLEAR(mstr);
3063     msize = SvIVx(*++mark);
3064     mtype = (long)SvIVx(*++mark);
3065     flags = SvIVx(*++mark);
3066     SvPV_force_nolen(mstr);
3067     mbuf = SvGROW(mstr, sizeof(long)+msize+1);
3068
3069     SETERRNO(0,0);
3070     if (id >= 0 && msize >= 0 && flags >= 0) {
3071         ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
3072     } else {
3073         SETERRNO(EINVAL,LIB_INVARG);
3074         ret = -1;
3075     }
3076     if (ret >= 0) {
3077         SvCUR_set(mstr, sizeof(long)+ret);
3078         *SvEND(mstr) = '\0';
3079         /* who knows who has been playing with this message? */
3080         SvTAINTED_on(mstr);
3081     }
3082     return ret;
3083 #else
3084     PERL_UNUSED_ARG(sp);
3085     PERL_UNUSED_ARG(mark);
3086     /* diag_listed_as: msg%s not implemented */
3087     Perl_croak(aTHX_ "msgrcv not implemented");
3088     return -1;
3089 #endif
3090 }
3091
3092 I32
3093 Perl_do_semop(pTHX_ SV **mark, SV **sp)
3094 {
3095 #ifdef HAS_SEM
3096     STRLEN opsize;
3097     const I32 id = SvIVx(*++mark);
3098     SV * const opstr = *++mark;
3099     const char * const opbuf = SvPV_const(opstr, opsize);
3100
3101     PERL_ARGS_ASSERT_DO_SEMOP;
3102     PERL_UNUSED_ARG(sp);
3103
3104     if (opsize < 3 * SHORTSIZE
3105         || (opsize % (3 * SHORTSIZE))) {
3106         SETERRNO(EINVAL,LIB_INVARG);
3107         return -1;
3108     }
3109     SETERRNO(0,0);
3110     /* We can't assume that sizeof(struct sembuf) == 3 * sizeof(short). */
3111     {
3112         const int nsops  = opsize / (3 * sizeof (short));
3113         int i      = nsops;
3114         short * const ops = (short *) opbuf;
3115         short *o   = ops;
3116         struct sembuf *temps, *t;
3117         I32 result;
3118
3119         Newx (temps, nsops, struct sembuf);
3120         t = temps;
3121         while (i--) {
3122             t->sem_num = *o++;
3123             t->sem_op  = *o++;
3124             t->sem_flg = *o++;
3125             t++;
3126         }
3127         result = semop(id, temps, nsops);
3128         Safefree(temps);
3129         return result;
3130     }
3131 #else
3132     /* diag_listed_as: sem%s not implemented */
3133     Perl_croak(aTHX_ "semop not implemented");
3134 #endif
3135 }
3136
3137 I32
3138 Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
3139 {
3140 #ifdef HAS_SHM
3141     char *shm;
3142     struct shmid_ds shmds;
3143     const I32 id = SvIVx(*++mark);
3144     SV * const mstr = *++mark;
3145     const I32 mpos = SvIVx(*++mark);
3146     const I32 msize = SvIVx(*++mark);
3147
3148     PERL_ARGS_ASSERT_DO_SHMIO;
3149     PERL_UNUSED_ARG(sp);
3150
3151     SETERRNO(0,0);
3152     if (shmctl(id, IPC_STAT, &shmds) == -1)
3153         return -1;
3154     if (mpos < 0 || msize < 0
3155         || (size_t)mpos + msize > (size_t)shmds.shm_segsz) {
3156         SETERRNO(EFAULT,SS_ACCVIO);             /* can't do as caller requested */
3157         return -1;
3158     }
3159     if (id >= 0) {
3160         shm = (char *)shmat(id, NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
3161     } else {
3162         SETERRNO(EINVAL,LIB_INVARG);
3163         return -1;
3164     }
3165     if (shm == (char *)-1)      /* I hate System V IPC, I really do */
3166         return -1;
3167     if (optype == OP_SHMREAD) {
3168         char *mbuf;
3169         /* suppress warning when reading into undef var (tchrist 3/Mar/00) */
3170         SvGETMAGIC(mstr);
3171         SvUPGRADE(mstr, SVt_PV);
3172         if (! SvOK(mstr))
3173             SvPVCLEAR(mstr);
3174         SvPOK_only(mstr);
3175         mbuf = SvGROW(mstr, (STRLEN)msize+1);
3176
3177         Copy(shm + mpos, mbuf, msize, char);
3178         SvCUR_set(mstr, msize);
3179         *SvEND(mstr) = '\0';
3180         SvSETMAGIC(mstr);
3181         /* who knows who has been playing with this shared memory? */
3182         SvTAINTED_on(mstr);
3183     }
3184     else {
3185         STRLEN len;
3186
3187         const char *mbuf = SvPV_const(mstr, len);
3188         const I32 n = ((I32)len > msize) ? msize : (I32)len;
3189         Copy(mbuf, shm + mpos, n, char);
3190         if (n < msize)
3191             memzero(shm + mpos + n, msize - n);
3192     }
3193     return shmdt(shm);
3194 #else
3195     /* diag_listed_as: shm%s not implemented */
3196     Perl_croak(aTHX_ "shm I/O not implemented");
3197     return -1;
3198 #endif
3199 }
3200
3201 #endif /* SYSV IPC */
3202
3203 /*
3204 =head1 IO Functions
3205
3206 =for apidoc start_glob
3207
3208 Function called by C<do_readline> to spawn a glob (or do the glob inside
3209 perl on VMS).  This code used to be inline, but now perl uses C<File::Glob>
3210 this glob starter is only used by miniperl during the build process,
3211 or when PERL_EXTERNAL_GLOB is defined.
3212 Moving it away shrinks F<pp_hot.c>; shrinking F<pp_hot.c> helps speed perl up.
3213
3214 =cut
3215 */
3216
3217 PerlIO *
3218 Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
3219 {
3220     SV * const tmpcmd = newSV(0);
3221     PerlIO *fp;
3222     STRLEN len;
3223     const char *s = SvPV(tmpglob, len);
3224
3225     PERL_ARGS_ASSERT_START_GLOB;
3226
3227     if (!IS_SAFE_SYSCALL(s, len, "pattern", "glob"))
3228         return NULL;
3229
3230     ENTER;
3231     SAVEFREESV(tmpcmd);
3232 #ifdef VMS /* expand the wildcards right here, rather than opening a pipe, */
3233            /* since spawning off a process is a real performance hit */
3234
3235 PerlIO * 
3236 Perl_vms_start_glob
3237    (pTHX_ SV *tmpglob,
3238     IO *io);
3239
3240     fp = Perl_vms_start_glob(aTHX_ tmpglob, io);
3241
3242 #else /* !VMS */
3243 # ifdef DOSISH
3244 #  if defined(OS2)
3245     sv_setpv(tmpcmd, "for a in ");
3246     sv_catsv(tmpcmd, tmpglob);
3247     sv_catpvs(tmpcmd, "; do echo \"$a\\0\\c\"; done |");
3248 #  elif defined(DJGPP)
3249     sv_setpv(tmpcmd, "/dev/dosglob/"); /* File System Extension */
3250     sv_catsv(tmpcmd, tmpglob);
3251 #  else
3252     sv_setpv(tmpcmd, "perlglob ");
3253     sv_catsv(tmpcmd, tmpglob);
3254     sv_catpvs(tmpcmd, " |");
3255 #  endif
3256 # elif defined(CSH)
3257     sv_setpvn(tmpcmd, PL_cshname, PL_cshlen);
3258     sv_catpvs(tmpcmd, " -cf 'set nonomatch; glob ");
3259     sv_catsv(tmpcmd, tmpglob);
3260     sv_catpvs(tmpcmd, "' 2>/dev/null |");
3261 # else
3262     sv_setpv(tmpcmd, "echo ");
3263     sv_catsv(tmpcmd, tmpglob);
3264     sv_catpvs(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|");
3265 # endif /* !DOSISH && !CSH */
3266     {
3267         SV ** const svp = hv_fetchs(GvHVn(PL_envgv), "LS_COLORS", 0);
3268         if (svp && *svp)
3269             save_helem_flags(GvHV(PL_envgv),
3270                              newSVpvs_flags("LS_COLORS", SVs_TEMP), svp,
3271                              SAVEf_SETMAGIC);
3272     }
3273     (void)do_open6(PL_last_in_gv, SvPVX_const(tmpcmd), SvCUR(tmpcmd),
3274                    NULL, NULL, 0);
3275     fp = IoIFP(io);
3276 #endif /* !VMS */
3277     LEAVE;
3278
3279     if (!fp && ckWARN(WARN_GLOB)) {
3280         Perl_warner(aTHX_ packWARN(WARN_GLOB), "glob failed (can't start child: %s)",
3281                     Strerror(errno));
3282     }
3283
3284     return fp;
3285 }
3286
3287 /*
3288  * ex: set ts=8 sts=4 sw=4 et:
3289  */