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