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