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