This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
integrate changes#2978,2979 from mainline
[perl5.git] / doio.c
CommitLineData
a0d0e21e 1/* doio.c
a687059c 2 *
9607fc9c 3 * Copyright (c) 1991-1997, Larry Wall
a687059c 4 *
6e21c824
LW
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
LW
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
LW
15 */
16
17#include "EXTERN.h"
18#include "perl.h"
19
fe14fcc3 20#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
b47ccd61 21#ifndef HAS_SEM
c2ab57d4 22#include <sys/ipc.h>
b47ccd61 23#endif
fe14fcc3 24#ifdef HAS_MSG
c2ab57d4 25#include <sys/msg.h>
e5d73d77 26#endif
fe14fcc3 27#ifdef HAS_SHM
c2ab57d4 28#include <sys/shm.h>
a0d0e21e
LW
29# ifndef HAS_SHMAT_PROTOTYPE
30 extern Shmat_t shmat _((int, char *, int));
31# endif
c2ab57d4 32#endif
e5d73d77 33#endif
c2ab57d4 34
663a0e37 35#ifdef I_UTIME
3730b96e 36# if defined(_MSC_VER) || defined(__MINGW32__)
3fe9a6f1 37# include <sys/utime.h>
38# else
39# include <utime.h>
40# endif
663a0e37 41#endif
85aff577 42
ff8e2863
LW
43#ifdef I_FCNTL
44#include <fcntl.h>
45#endif
fe14fcc3
LW
46#ifdef I_SYS_FILE
47#include <sys/file.h>
48#endif
85aff577
CS
49#ifdef O_EXCL
50# define OPEN_EXCL O_EXCL
51#else
52# define OPEN_EXCL 0
53#endif
a687059c 54
76121258 55#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
56#include <signal.h>
57#endif
58
59/* XXX If this causes problems, set i_unistd=undef in the hint file. */
60#ifdef I_UNISTD
61# include <unistd.h>
62#endif
63
232e078e
AD
64#if defined(HAS_SOCKET) && !defined(VMS) /* VMS handles sockets via vmsish.h */
65# include <sys/socket.h>
66# include <netdb.h>
67# ifndef ENOTSOCK
68# ifdef I_NET_ERRNO
69# include <net/errno.h>
70# endif
71# endif
72#endif
73
d574b85e
CS
74/* Put this after #includes because <unistd.h> defines _XOPEN_*. */
75#ifndef Sock_size_t
137443ea 76# if _XOPEN_VERSION >= 5 || defined(_XOPEN_SOURCE_EXTENDED) || defined(__GLIBC__)
d574b85e
CS
77# define Sock_size_t Size_t
78# else
79# define Sock_size_t int
80# endif
81#endif
82
a687059c 83bool
6acef3b7 84do_open(GV *gv, register char *name, I32 len, int as_raw, int rawmode, int rawperm, PerlIO *supplied_fp)
a687059c 85{
a0d0e21e 86 register IO *io = GvIOn(gv);
760ac839
LW
87 PerlIO *saveifp = Nullfp;
88 PerlIO *saveofp = Nullfp;
6e21c824 89 char savetype = ' ';
c07a80fd 90 int writing = 0;
760ac839 91 PerlIO *fp;
c07a80fd 92 int fd;
93 int result;
3500f679 94 bool was_fdopen = FALSE;
a687059c 95
3280af22 96 PL_forkprocess = 1; /* assume true if no fork */
c07a80fd 97
a0d0e21e 98 if (IoIFP(io)) {
760ac839 99 fd = PerlIO_fileno(IoIFP(io));
8990e307 100 if (IoTYPE(io) == '-')
c2ab57d4 101 result = 0;
3280af22 102 else if (fd <= PL_maxsysfd) {
8990e307
LW
103 saveifp = IoIFP(io);
104 saveofp = IoOFP(io);
105 savetype = IoTYPE(io);
6e21c824
LW
106 result = 0;
107 }
8990e307 108 else if (IoTYPE(io) == '|')
3028581b 109 result = PerlProc_pclose(IoIFP(io));
8990e307
LW
110 else if (IoIFP(io) != IoOFP(io)) {
111 if (IoOFP(io)) {
760ac839
LW
112 result = PerlIO_close(IoOFP(io));
113 PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */
c2ab57d4
LW
114 }
115 else
760ac839 116 result = PerlIO_close(IoIFP(io));
a687059c 117 }
a687059c 118 else
760ac839 119 result = PerlIO_close(IoIFP(io));
3280af22 120 if (result == EOF && fd > PL_maxsysfd)
760ac839 121 PerlIO_printf(PerlIO_stderr(), "Warning: unable to close filehandle %s properly.\n",
79072805 122 GvENAME(gv));
8990e307 123 IoOFP(io) = IoIFP(io) = Nullfp;
a687059c 124 }
c07a80fd 125
126 if (as_raw) {
9d116dd7
JH
127#ifndef O_ACCMODE
128#define O_ACCMODE 3 /* Assume traditional implementation */
129#endif
130 switch (result = rawmode & O_ACCMODE) {
131 case O_RDONLY:
132 IoTYPE(io) = '<';
133 break;
134 case O_WRONLY:
135 IoTYPE(io) = '>';
136 break;
137 case O_RDWR:
138 default:
139 IoTYPE(io) = '+';
140 break;
141 }
142
c07a80fd 143 writing = (result > 0);
3028581b 144 fd = PerlLIO_open3(name, rawmode, rawperm);
9d116dd7 145
c07a80fd 146 if (fd == -1)
147 fp = NULL;
148 else {
360e5741 149 char *fpmode;
9d116dd7 150 if (result == O_RDONLY)
360e5741
CS
151 fpmode = "r";
152#ifdef O_APPEND
153 else if (rawmode & O_APPEND)
9d116dd7 154 fpmode = (result == O_WRONLY) ? "a" : "a+";
360e5741
CS
155#endif
156 else
9d116dd7 157 fpmode = (result == O_WRONLY) ? "w" : "r+";
360e5741 158 fp = PerlIO_fdopen(fd, fpmode);
c07a80fd 159 if (!fp)
3028581b 160 PerlLIO_close(fd);
c07a80fd 161 }
a687059c 162 }
c07a80fd 163 else {
164 char *myname;
165 char mode[3]; /* stdio file mode ("r\0" or "r+\0") */
166 int dodup;
167
168 myname = savepvn(name, len);
169 SAVEFREEPV(myname);
170 name = myname;
171 while (len && isSPACE(name[len-1]))
172 name[--len] = '\0';
173
174 mode[0] = mode[1] = mode[2] = '\0';
175 IoTYPE(io) = *name;
176 if (*name == '+' && len > 1 && name[len-1] != '|') { /* scary */
177 mode[1] = *name++;
178 --len;
179 writing = 1;
a687059c 180 }
c07a80fd 181
182 if (*name == '|') {
183 /*SUPPRESS 530*/
184 for (name++; isSPACE(*name); name++) ;
185 if (strNE(name,"-"))
186 TAINT_ENV();
187 TAINT_PROPER("piped open");
7b8d334a
GS
188 if (name[strlen(name)-1] == '|') {
189 name[strlen(name)-1] = '\0' ;
3280af22 190 if (PL_dowarn)
7b8d334a
GS
191 warn("Can't do bidirectional pipe");
192 }
3028581b 193 fp = PerlProc_popen(name,"w");
c07a80fd 194 writing = 1;
195 }
196 else if (*name == '>') {
197 TAINT_PROPER("open");
bf38876a 198 name++;
c07a80fd 199 if (*name == '>') {
200 mode[0] = IoTYPE(io) = 'a';
bf38876a 201 name++;
a0d0e21e 202 }
c07a80fd 203 else
204 mode[0] = 'w';
205 writing = 1;
206
207 if (*name == '&') {
208 duplicity:
209 dodup = 1;
210 name++;
211 if (*name == '=') {
212 dodup = 0;
a0d0e21e 213 name++;
c07a80fd 214 }
215 if (!*name && supplied_fp)
216 fp = supplied_fp;
a0d0e21e 217 else {
c07a80fd 218 /*SUPPRESS 530*/
219 for (; isSPACE(*name); name++) ;
220 if (isDIGIT(*name))
221 fd = atoi(name);
222 else {
223 IO* thatio;
224 gv = gv_fetchpv(name,FALSE,SVt_PVIO);
225 thatio = GvIO(gv);
226 if (!thatio) {
6e21c824 227#ifdef EINVAL
c07a80fd 228 SETERRNO(EINVAL,SS$_IVCHAN);
6e21c824 229#endif
c07a80fd 230 goto say_false;
231 }
232 if (IoIFP(thatio)) {
760ac839 233 fd = PerlIO_fileno(IoIFP(thatio));
c07a80fd 234 if (IoTYPE(thatio) == 's')
235 IoTYPE(io) = 's';
236 }
237 else
238 fd = -1;
a0d0e21e 239 }
fec02dd3 240 if (dodup)
3028581b 241 fd = PerlLIO_dup(fd);
3500f679
RS
242 else
243 was_fdopen = TRUE;
760ac839 244 if (!(fp = PerlIO_fdopen(fd,mode))) {
c07a80fd 245 if (dodup)
3028581b 246 PerlLIO_close(fd);
517844ec 247 }
c07a80fd 248 }
bf38876a 249 }
c07a80fd 250 else {
251 /*SUPPRESS 530*/
252 for (; isSPACE(*name); name++) ;
253 if (strEQ(name,"-")) {
760ac839 254 fp = PerlIO_stdout();
c07a80fd 255 IoTYPE(io) = '-';
256 }
257 else {
760ac839 258 fp = PerlIO_open(name,mode);
c07a80fd 259 }
bf38876a
LW
260 }
261 }
c07a80fd 262 else if (*name == '<') {
263 /*SUPPRESS 530*/
264 for (name++; isSPACE(*name); name++) ;
bf38876a 265 mode[0] = 'r';
bf38876a
LW
266 if (*name == '&')
267 goto duplicity;
a687059c 268 if (strEQ(name,"-")) {
760ac839 269 fp = PerlIO_stdin();
8990e307 270 IoTYPE(io) = '-';
a687059c 271 }
bf38876a 272 else
760ac839 273 fp = PerlIO_open(name,mode);
a687059c 274 }
00db4c45 275 else if (len > 1 && name[len-1] == '|') {
a687059c 276 name[--len] = '\0';
99b89507 277 while (len && isSPACE(name[len-1]))
a687059c 278 name[--len] = '\0';
99b89507
LW
279 /*SUPPRESS 530*/
280 for (; isSPACE(*name); name++) ;
79072805
LW
281 if (strNE(name,"-"))
282 TAINT_ENV();
283 TAINT_PROPER("piped open");
3028581b 284 fp = PerlProc_popen(name,"r");
8990e307 285 IoTYPE(io) = '|';
a687059c
LW
286 }
287 else {
8990e307 288 IoTYPE(io) = '<';
99b89507
LW
289 /*SUPPRESS 530*/
290 for (; isSPACE(*name); name++) ;
a687059c 291 if (strEQ(name,"-")) {
760ac839 292 fp = PerlIO_stdin();
8990e307 293 IoTYPE(io) = '-';
a687059c
LW
294 }
295 else
760ac839 296 fp = PerlIO_open(name,"r");
a687059c
LW
297 }
298 }
bee1dbe2 299 if (!fp) {
3280af22 300 if (PL_dowarn && IoTYPE(io) == '<' && strchr(name, '\n'))
bee1dbe2 301 warn(warn_nl, "open");
6e21c824 302 goto say_false;
bee1dbe2 303 }
8990e307
LW
304 if (IoTYPE(io) &&
305 IoTYPE(io) != '|' && IoTYPE(io) != '-') {
96827780 306 dTHR;
3280af22 307 if (PerlLIO_fstat(PerlIO_fileno(fp),&PL_statbuf) < 0) {
760ac839 308 (void)PerlIO_close(fp);
6e21c824 309 goto say_false;
a687059c 310 }
3280af22 311 if (S_ISSOCK(PL_statbuf.st_mode))
8990e307 312 IoTYPE(io) = 's'; /* in case a socket was passed in to us */
99b89507
LW
313#ifdef HAS_SOCKET
314 else if (
c623bd54 315#ifdef S_IFMT
3280af22 316 !(PL_statbuf.st_mode & S_IFMT)
99b89507 317#else
b28d0864 318 !PL_statbuf.st_mode
99b89507
LW
319#endif
320 ) {
96827780
MB
321 char tmpbuf[256];
322 Sock_size_t buflen = sizeof tmpbuf;
3028581b 323 if (PerlSock_getsockname(PerlIO_fileno(fp), (struct sockaddr *)tmpbuf,
d574b85e
CS
324 &buflen) >= 0
325 || errno != ENOTSOCK)
8990e307 326 IoTYPE(io) = 's'; /* some OS's return 0 on fstat()ed socket */
99b89507
LW
327 /* but some return 0 for streams too, sigh */
328 }
bf38876a 329#endif
a687059c 330 }
6e21c824 331 if (saveifp) { /* must use old fp? */
760ac839 332 fd = PerlIO_fileno(saveifp);
6e21c824 333 if (saveofp) {
760ac839 334 PerlIO_flush(saveofp); /* emulate PerlIO_close() */
6e21c824 335 if (saveofp != saveifp) { /* was a socket? */
760ac839 336 PerlIO_close(saveofp);
99b89507
LW
337 if (fd > 2)
338 Safefree(saveofp);
6e21c824
LW
339 }
340 }
760ac839 341 if (fd != PerlIO_fileno(fp)) {
bee1dbe2 342 int pid;
79072805 343 SV *sv;
bee1dbe2 344
3028581b 345 PerlLIO_dup2(PerlIO_fileno(fp), fd);
3280af22 346 sv = *av_fetch(PL_fdpid,PerlIO_fileno(fp),TRUE);
a0d0e21e 347 (void)SvUPGRADE(sv, SVt_IV);
463ee0b2
LW
348 pid = SvIVX(sv);
349 SvIVX(sv) = 0;
3280af22 350 sv = *av_fetch(PL_fdpid,fd,TRUE);
a0d0e21e 351 (void)SvUPGRADE(sv, SVt_IV);
463ee0b2 352 SvIVX(sv) = pid;
3500f679
RS
353 if (!was_fdopen)
354 PerlIO_close(fp);
bee1dbe2 355
6e21c824
LW
356 }
357 fp = saveifp;
760ac839 358 PerlIO_clearerr(fp);
6e21c824 359 }
a0d0e21e 360#if defined(HAS_FCNTL) && defined(F_SETFD)
ae39e9e8
GB
361 {
362 int save_errno = errno;
363 fd = PerlIO_fileno(fp);
364 fcntl(fd,F_SETFD,fd > PL_maxsysfd); /* can change errno */
365 errno = save_errno;
366 }
1462b684 367#endif
8990e307 368 IoIFP(io) = fp;
bf38876a 369 if (writing) {
96827780 370 dTHR;
8990e307 371 if (IoTYPE(io) == 's'
3280af22 372 || (IoTYPE(io) == '>' && S_ISCHR(PL_statbuf.st_mode)) ) {
760ac839
LW
373 if (!(IoOFP(io) = PerlIO_fdopen(PerlIO_fileno(fp),"w"))) {
374 PerlIO_close(fp);
8990e307 375 IoIFP(io) = Nullfp;
6e21c824 376 goto say_false;
fe14fcc3 377 }
1462b684
LW
378 }
379 else
8990e307 380 IoOFP(io) = fp;
bf38876a 381 }
a687059c 382 return TRUE;
6e21c824
LW
383
384say_false:
8990e307
LW
385 IoIFP(io) = saveifp;
386 IoOFP(io) = saveofp;
387 IoTYPE(io) = savetype;
6e21c824 388 return FALSE;
a687059c
LW
389}
390
760ac839 391PerlIO *
8ac85365 392nextargv(register GV *gv)
a687059c 393{
79072805 394 register SV *sv;
99b89507 395#ifndef FLEXFILENAMES
c623bd54
LW
396 int filedev;
397 int fileino;
99b89507 398#endif
c623bd54
LW
399 int fileuid;
400 int filegid;
fe14fcc3 401
3280af22
NIS
402 if (!PL_argvoutgv)
403 PL_argvoutgv = gv_fetchpv("ARGVOUT",TRUE,SVt_PVIO);
404 if (PL_filemode & (S_ISUID|S_ISGID)) {
405 PerlIO_flush(IoIFP(GvIOn(PL_argvoutgv))); /* chmod must follow last write */
fe14fcc3 406#ifdef HAS_FCHMOD
3280af22 407 (void)fchmod(PL_lastfd,PL_filemode);
fe14fcc3 408#else
b28d0864 409 (void)PerlLIO_chmod(PL_oldname,PL_filemode);
fe14fcc3
LW
410#endif
411 }
3280af22 412 PL_filemode = 0;
79072805 413 while (av_len(GvAV(gv)) >= 0) {
11343788 414 dTHR;
85aff577 415 STRLEN oldlen;
79072805 416 sv = av_shift(GvAV(gv));
8990e307 417 SAVEFREESV(sv);
79072805
LW
418 sv_setsv(GvSV(gv),sv);
419 SvSETMAGIC(GvSV(gv));
3280af22 420 PL_oldname = SvPVx(GvSV(gv), oldlen);
9d116dd7 421 if (do_open(gv,PL_oldname,oldlen,PL_inplace!=0,O_RDONLY,0,Nullfp)) {
3280af22 422 if (PL_inplace) {
79072805 423 TAINT_PROPER("inplace open");
3280af22 424 if (oldlen == 1 && *PL_oldname == '-') {
4633a7c4 425 setdefout(gv_fetchpv("STDOUT",TRUE,SVt_PVIO));
a0d0e21e 426 return IoIFP(GvIOp(gv));
c623bd54 427 }
99b89507 428#ifndef FLEXFILENAMES
b28d0864
NIS
429 filedev = PL_statbuf.st_dev;
430 fileino = PL_statbuf.st_ino;
99b89507 431#endif
3280af22
NIS
432 PL_filemode = PL_statbuf.st_mode;
433 fileuid = PL_statbuf.st_uid;
434 filegid = PL_statbuf.st_gid;
435 if (!S_ISREG(PL_filemode)) {
c623bd54 436 warn("Can't do inplace edit: %s is not a regular file",
3280af22 437 PL_oldname );
79072805 438 do_close(gv,FALSE);
c623bd54
LW
439 continue;
440 }
3280af22
NIS
441 if (*PL_inplace) {
442 char *star = strchr(PL_inplace, '*');
2d259d92 443 if (star) {
3280af22 444 char *begin = PL_inplace;
2d259d92
CK
445 sv_setpvn(sv, "", 0);
446 do {
447 sv_catpvn(sv, begin, star - begin);
3280af22 448 sv_catpvn(sv, PL_oldname, oldlen);
2d259d92
CK
449 begin = ++star;
450 } while ((star = strchr(begin, '*')));
3d66d7bb
GS
451 if (*begin)
452 sv_catpv(sv,begin);
2d259d92
CK
453 }
454 else {
3280af22 455 sv_catpv(sv,PL_inplace);
2d259d92 456 }
c623bd54 457#ifndef FLEXFILENAMES
b28d0864
NIS
458 if (PerlLIO_stat(SvPVX(sv),&PL_statbuf) >= 0
459 && PL_statbuf.st_dev == filedev
460 && PL_statbuf.st_ino == fileino
39e571d4
LM
461#ifdef DJGPP
462 || (_djstat_fail_bits & _STFAIL_TRUENAME)!=0
463#endif
464 ) {
465 warn("Can't do inplace edit: %s would not be uniq",
463ee0b2 466 SvPVX(sv) );
79072805 467 do_close(gv,FALSE);
c623bd54
LW
468 continue;
469 }
470#endif
fe14fcc3 471#ifdef HAS_RENAME
bee1dbe2 472#ifndef DOSISH
3280af22 473 if (PerlLIO_rename(PL_oldname,SvPVX(sv)) < 0) {
c623bd54 474 warn("Can't rename %s to %s: %s, skipping file",
3280af22 475 PL_oldname, SvPVX(sv), Strerror(errno) );
79072805 476 do_close(gv,FALSE);
c623bd54
LW
477 continue;
478 }
a687059c 479#else
79072805 480 do_close(gv,FALSE);
3028581b 481 (void)PerlLIO_unlink(SvPVX(sv));
b28d0864 482 (void)PerlLIO_rename(PL_oldname,SvPVX(sv));
9d116dd7 483 do_open(gv,SvPVX(sv),SvCUR(sv),PL_inplace!=0,O_RDONLY,0,Nullfp);
55497cff 484#endif /* DOSISH */
ff8e2863 485#else
463ee0b2 486 (void)UNLINK(SvPVX(sv));
b28d0864 487 if (link(PL_oldname,SvPVX(sv)) < 0) {
c623bd54 488 warn("Can't rename %s to %s: %s, skipping file",
b28d0864 489 PL_oldname, SvPVX(sv), Strerror(errno) );
79072805 490 do_close(gv,FALSE);
c623bd54
LW
491 continue;
492 }
b28d0864 493 (void)UNLINK(PL_oldname);
a687059c
LW
494#endif
495 }
496 else {
a8c18271 497#if !defined(DOSISH) && !defined(AMIGAOS)
edc7bc49 498# ifndef VMS /* Don't delete; use automatic file versioning */
3280af22 499 if (UNLINK(PL_oldname) < 0) {
85aff577 500 warn("Can't remove %s: %s, skipping file",
3280af22 501 PL_oldname, Strerror(errno) );
79072805 502 do_close(gv,FALSE);
fe14fcc3
LW
503 continue;
504 }
edc7bc49 505# endif
ff8e2863 506#else
463ee0b2 507 croak("Can't do inplace edit without backup");
ff8e2863 508#endif
a687059c
LW
509 }
510
3280af22
NIS
511 sv_setpvn(sv,">",!PL_inplace);
512 sv_catpvn(sv,PL_oldname,oldlen);
748a9306 513 SETERRNO(0,0); /* in case sprintf set errno */
4119ab01
HM
514#ifdef VMS
515 if (!do_open(PL_argvoutgv,SvPVX(sv),SvCUR(sv),PL_inplace!=0,
516 O_WRONLY|O_CREAT|O_TRUNC,0,Nullfp)) {
517#else
3280af22 518 if (!do_open(PL_argvoutgv,SvPVX(sv),SvCUR(sv),PL_inplace!=0,
85aff577 519 O_WRONLY|O_CREAT|OPEN_EXCL,0666,Nullfp)) {
4119ab01 520#endif
c623bd54 521 warn("Can't do inplace edit on %s: %s",
3280af22 522 PL_oldname, Strerror(errno) );
79072805 523 do_close(gv,FALSE);
fe14fcc3
LW
524 continue;
525 }
3280af22
NIS
526 setdefout(PL_argvoutgv);
527 PL_lastfd = PerlIO_fileno(IoIFP(GvIOp(PL_argvoutgv)));
528 (void)PerlLIO_fstat(PL_lastfd,&PL_statbuf);
fe14fcc3 529#ifdef HAS_FCHMOD
3280af22 530 (void)fchmod(PL_lastfd,PL_filemode);
a687059c 531#else
3e3baf6d
TB
532# if !(defined(WIN32) && defined(__BORLANDC__))
533 /* Borland runtime creates a readonly file! */
b28d0864 534 (void)PerlLIO_chmod(PL_oldname,PL_filemode);
3e3baf6d 535# endif
a687059c 536#endif
3280af22 537 if (fileuid != PL_statbuf.st_uid || filegid != PL_statbuf.st_gid) {
fe14fcc3 538#ifdef HAS_FCHOWN
3280af22 539 (void)fchown(PL_lastfd,fileuid,filegid);
a687059c 540#else
fe14fcc3 541#ifdef HAS_CHOWN
b28d0864 542 (void)PerlLIO_chown(PL_oldname,fileuid,filegid);
a687059c 543#endif
b1248f16 544#endif
fe14fcc3 545 }
a687059c 546 }
a0d0e21e 547 return IoIFP(GvIOp(gv));
a687059c
LW
548 }
549 else
22fae026 550 PerlIO_printf(PerlIO_stderr(), "Can't open %s: %s\n",
36596149 551 SvPV(sv, oldlen), Strerror(errno));
a687059c 552 }
3280af22
NIS
553 if (PL_inplace) {
554 (void)do_close(PL_argvoutgv,FALSE);
4633a7c4 555 setdefout(gv_fetchpv("STDOUT",TRUE,SVt_PVIO));
a687059c
LW
556 }
557 return Nullfp;
558}
559
fe14fcc3 560#ifdef HAS_PIPE
afd9f252 561void
8ac85365 562do_pipe(SV *sv, GV *rgv, GV *wgv)
afd9f252 563{
79072805
LW
564 register IO *rstio;
565 register IO *wstio;
afd9f252
LW
566 int fd[2];
567
79072805 568 if (!rgv)
afd9f252 569 goto badexit;
79072805 570 if (!wgv)
afd9f252
LW
571 goto badexit;
572
a0d0e21e
LW
573 rstio = GvIOn(rgv);
574 wstio = GvIOn(wgv);
afd9f252 575
a0d0e21e 576 if (IoIFP(rstio))
79072805 577 do_close(rgv,FALSE);
a0d0e21e 578 if (IoIFP(wstio))
79072805 579 do_close(wgv,FALSE);
afd9f252 580
3028581b 581 if (PerlProc_pipe(fd) < 0)
afd9f252 582 goto badexit;
760ac839
LW
583 IoIFP(rstio) = PerlIO_fdopen(fd[0], "r");
584 IoOFP(wstio) = PerlIO_fdopen(fd[1], "w");
8990e307
LW
585 IoIFP(wstio) = IoOFP(wstio);
586 IoTYPE(rstio) = '<';
587 IoTYPE(wstio) = '>';
588 if (!IoIFP(rstio) || !IoOFP(wstio)) {
760ac839 589 if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio));
3028581b 590 else PerlLIO_close(fd[0]);
760ac839 591 if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio));
3028581b 592 else PerlLIO_close(fd[1]);
fe14fcc3
LW
593 goto badexit;
594 }
afd9f252 595
3280af22 596 sv_setsv(sv,&PL_sv_yes);
afd9f252
LW
597 return;
598
599badexit:
3280af22 600 sv_setsv(sv,&PL_sv_undef);
afd9f252
LW
601 return;
602}
b1248f16 603#endif
afd9f252 604
517844ec 605/* explicit renamed to avoid C++ conflict -- kja */
a687059c 606bool
517844ec 607do_close(GV *gv, bool not_implicit)
a687059c 608{
1193dd27
IZ
609 bool retval;
610 IO *io;
a687059c 611
79072805 612 if (!gv)
3280af22 613 gv = PL_argvgv;
a0d0e21e 614 if (!gv || SvTYPE(gv) != SVt_PVGV) {
1d2dff63
GS
615 if (not_implicit)
616 SETERRNO(EBADF,SS$_IVCHAN);
c2ab57d4 617 return FALSE;
99b89507 618 }
79072805
LW
619 io = GvIO(gv);
620 if (!io) { /* never opened */
1d2dff63 621 if (not_implicit) {
3280af22 622 if (PL_dowarn)
1d2dff63
GS
623 warn("Close on unopened file <%s>",GvENAME(gv));
624 SETERRNO(EBADF,SS$_IVCHAN);
625 }
a687059c
LW
626 return FALSE;
627 }
1193dd27 628 retval = io_close(io);
517844ec 629 if (not_implicit) {
1193dd27
IZ
630 IoLINES(io) = 0;
631 IoPAGE(io) = 0;
632 IoLINES_LEFT(io) = IoPAGE_LEN(io);
633 }
634 IoTYPE(io) = ' ';
635 return retval;
636}
637
638bool
8ac85365 639io_close(IO *io)
1193dd27
IZ
640{
641 bool retval = FALSE;
642 int status;
643
8990e307
LW
644 if (IoIFP(io)) {
645 if (IoTYPE(io) == '|') {
3028581b 646 status = PerlProc_pclose(IoIFP(io));
f86702cc 647 STATUS_NATIVE_SET(status);
1e422769 648 retval = (STATUS_POSIX == 0);
a687059c 649 }
8990e307 650 else if (IoTYPE(io) == '-')
a687059c
LW
651 retval = TRUE;
652 else {
8990e307 653 if (IoOFP(io) && IoOFP(io) != IoIFP(io)) { /* a socket */
760ac839
LW
654 retval = (PerlIO_close(IoOFP(io)) != EOF);
655 PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */
c2ab57d4
LW
656 }
657 else
760ac839 658 retval = (PerlIO_close(IoIFP(io)) != EOF);
a687059c 659 }
8990e307 660 IoOFP(io) = IoIFP(io) = Nullfp;
79072805 661 }
20408e3c
GS
662 else {
663 SETERRNO(EBADF,SS$_IVCHAN);
664 }
1193dd27 665
a687059c
LW
666 return retval;
667}
668
669bool
8ac85365 670do_eof(GV *gv)
a687059c 671{
11343788 672 dTHR;
79072805 673 register IO *io;
a687059c
LW
674 int ch;
675
79072805 676 io = GvIO(gv);
a687059c 677
79072805 678 if (!io)
a687059c
LW
679 return TRUE;
680
8990e307 681 while (IoIFP(io)) {
a687059c 682
760ac839
LW
683 if (PerlIO_has_cntptr(IoIFP(io))) { /* (the code works without this) */
684 if (PerlIO_get_cnt(IoIFP(io)) > 0) /* cheat a little, since */
685 return FALSE; /* this is the most usual case */
686 }
a687059c 687
760ac839 688 ch = PerlIO_getc(IoIFP(io));
a687059c 689 if (ch != EOF) {
760ac839 690 (void)PerlIO_ungetc(IoIFP(io),ch);
a687059c
LW
691 return FALSE;
692 }
760ac839
LW
693 if (PerlIO_has_cntptr(IoIFP(io)) && PerlIO_canset_cnt(IoIFP(io))) {
694 if (PerlIO_get_cnt(IoIFP(io)) < -1)
695 PerlIO_set_cnt(IoIFP(io),-1);
696 }
533c011a 697 if (PL_op->op_flags & OPf_SPECIAL) { /* not necessarily a real EOF yet? */
3280af22 698 if (!nextargv(PL_argvgv)) /* get another fp handy */
a687059c
LW
699 return TRUE;
700 }
701 else
702 return TRUE; /* normal fp, definitely end of file */
703 }
704 return TRUE;
705}
706
707long
8ac85365 708do_tell(GV *gv)
a687059c 709{
79072805 710 register IO *io;
96e4d5b1 711 register PerlIO *fp;
a687059c 712
96e4d5b1 713 if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) {
bee1dbe2 714#ifdef ULTRIX_STDIO_BOTCH
96e4d5b1 715 if (PerlIO_eof(fp))
716 (void)PerlIO_seek(fp, 0L, 2); /* ultrix 1.2 workaround */
bee1dbe2 717#endif
8903cb82 718 return PerlIO_tell(fp);
96e4d5b1 719 }
3280af22 720 if (PL_dowarn)
8903cb82 721 warn("tell() on unopened file");
748a9306 722 SETERRNO(EBADF,RMS$_IFI);
a687059c
LW
723 return -1L;
724}
725
726bool
8ac85365 727do_seek(GV *gv, long int pos, int whence)
a687059c 728{
79072805 729 register IO *io;
137443ea 730 register PerlIO *fp;
a687059c 731
137443ea 732 if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) {
bee1dbe2 733#ifdef ULTRIX_STDIO_BOTCH
137443ea 734 if (PerlIO_eof(fp))
735 (void)PerlIO_seek(fp, 0L, 2); /* ultrix 1.2 workaround */
bee1dbe2 736#endif
8903cb82 737 return PerlIO_seek(fp, pos, whence) >= 0;
137443ea 738 }
3280af22 739 if (PL_dowarn)
8903cb82 740 warn("seek() on unopened file");
748a9306 741 SETERRNO(EBADF,RMS$_IFI);
a687059c
LW
742 return FALSE;
743}
744
8903cb82 745long
8ac85365 746do_sysseek(GV *gv, long int pos, int whence)
8903cb82 747{
748 register IO *io;
749 register PerlIO *fp;
750
751 if (gv && (io = GvIO(gv)) && (fp = IoIFP(io)))
3028581b 752 return PerlLIO_lseek(PerlIO_fileno(fp), pos, whence);
3280af22 753 if (PL_dowarn)
8903cb82 754 warn("sysseek() on unopened file");
755 SETERRNO(EBADF,RMS$_IFI);
756 return -1L;
757}
758
6ff81951
GS
759int
760do_binmode(PerlIO *fp, int iotype, int flag)
761{
762 if (flag != TRUE)
763 croak("panic: unsetting binmode"); /* Not implemented yet */
764#ifdef DOSISH
f7eebaad 765#if defined(atarist) || defined(__MINT__)
6ff81951
GS
766 if (!PerlIO_flush(fp) && (fp->_flag |= _IOBIN))
767 return 1;
768 else
769 return 0;
770#else
771 if (PerlLIO_setmode(PerlIO_fileno(fp), OP_BINARY) != -1) {
772#if defined(WIN32) && defined(__BORLANDC__)
773 /* The translation mode of the stream is maintained independent
774 * of the translation mode of the fd in the Borland RTL (heavy
775 * digging through their runtime sources reveal). User has to
776 * set the mode explicitly for the stream (though they don't
777 * document this anywhere). GSAR 97-5-24
778 */
779 PerlIO_seek(fp,0L,0);
873ef191 780 ((FILE*)fp)->flags |= _F_BIN;
6ff81951
GS
781#endif
782 return 1;
783 }
784 else
785 return 0;
786#endif
787#else
788#if defined(USEMYBINMODE)
789 if (my_binmode(fp,iotype) != NULL)
790 return 1;
791 else
792 return 0;
793#else
794 return 1;
795#endif
796#endif
797}
798
a0d0e21e 799#if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE) && defined(F_FREESP)
c2ab57d4 800 /* code courtesy of William Kucharski */
fe14fcc3 801#define HAS_CHSIZE
6eb13c3b 802
517844ec 803I32 my_chsize(fd, length)
79072805 804I32 fd; /* file descriptor */
85e6fe83 805Off_t length; /* length to set file to */
6eb13c3b 806{
6eb13c3b
LW
807 struct flock fl;
808 struct stat filebuf;
809
3028581b 810 if (PerlLIO_fstat(fd, &filebuf) < 0)
6eb13c3b
LW
811 return -1;
812
813 if (filebuf.st_size < length) {
814
815 /* extend file length */
816
3028581b 817 if ((PerlLIO_lseek(fd, (length - 1), 0)) < 0)
6eb13c3b
LW
818 return -1;
819
820 /* write a "0" byte */
821
3028581b 822 if ((PerlLIO_write(fd, "", 1)) != 1)
6eb13c3b
LW
823 return -1;
824 }
825 else {
826 /* truncate length */
827
828 fl.l_whence = 0;
829 fl.l_len = 0;
830 fl.l_start = length;
a0d0e21e 831 fl.l_type = F_WRLCK; /* write lock on file space */
6eb13c3b
LW
832
833 /*
a0d0e21e 834 * This relies on the UNDOCUMENTED F_FREESP argument to
6eb13c3b
LW
835 * fcntl(2), which truncates the file so that it ends at the
836 * position indicated by fl.l_start.
837 *
838 * Will minor miracles never cease?
839 */
840
a0d0e21e 841 if (fcntl(fd, F_FREESP, &fl) < 0)
6eb13c3b
LW
842 return -1;
843
844 }
845
846 return 0;
847}
a0d0e21e 848#endif /* F_FREESP */
ff8e2863 849
a687059c 850bool
6acef3b7 851do_print(register SV *sv, PerlIO *fp)
a687059c
LW
852{
853 register char *tmps;
463ee0b2 854 STRLEN len;
a687059c 855
79072805
LW
856 /* assuming fp is checked earlier */
857 if (!sv)
858 return TRUE;
3280af22 859 if (PL_ofmt) {
8990e307 860 if (SvGMAGICAL(sv))
79072805 861 mg_get(sv);
463ee0b2 862 if (SvIOK(sv) && SvIVX(sv) != 0) {
3280af22 863 PerlIO_printf(fp, PL_ofmt, (double)SvIVX(sv));
760ac839 864 return !PerlIO_error(fp);
79072805 865 }
463ee0b2 866 if ( (SvNOK(sv) && SvNVX(sv) != 0.0)
79072805 867 || (looks_like_number(sv) && sv_2nv(sv) != 0.0) ) {
3280af22 868 PerlIO_printf(fp, PL_ofmt, SvNVX(sv));
760ac839 869 return !PerlIO_error(fp);
79072805 870 }
a687059c 871 }
79072805
LW
872 switch (SvTYPE(sv)) {
873 case SVt_NULL:
3280af22 874 if (PL_dowarn)
8990e307 875 warn(warn_uninit);
ff8e2863 876 return TRUE;
79072805 877 case SVt_IV:
a0d0e21e
LW
878 if (SvIOK(sv)) {
879 if (SvGMAGICAL(sv))
880 mg_get(sv);
760ac839
LW
881 PerlIO_printf(fp, "%ld", (long)SvIVX(sv));
882 return !PerlIO_error(fp);
a0d0e21e
LW
883 }
884 /* FALL THROUGH */
79072805 885 default:
463ee0b2 886 tmps = SvPV(sv, len);
79072805 887 break;
ff8e2863 888 }
760ac839 889 if (len && (PerlIO_write(fp,tmps,len) == 0 || PerlIO_error(fp)))
a687059c 890 return FALSE;
760ac839 891 return !PerlIO_error(fp);
a687059c
LW
892}
893
79072805 894I32
8ac85365 895my_stat(ARGSproto)
a687059c 896{
4e35701f 897 djSP;
79072805 898 IO *io;
748a9306 899 GV* tmpgv;
79072805 900
533c011a 901 if (PL_op->op_flags & OPf_REF) {
924508f0 902 EXTEND(SP,1);
748a9306
LW
903 tmpgv = cGVOP->op_gv;
904 do_fstat:
905 io = GvIO(tmpgv);
8990e307 906 if (io && IoIFP(io)) {
3280af22
NIS
907 PL_statgv = tmpgv;
908 sv_setpv(PL_statname,"");
909 PL_laststype = OP_STAT;
910 return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache));
a687059c
LW
911 }
912 else {
3280af22
NIS
913 if (tmpgv == PL_defgv)
914 return PL_laststatval;
915 if (PL_dowarn)
a687059c 916 warn("Stat on unopened file <%s>",
748a9306 917 GvENAME(tmpgv));
3280af22
NIS
918 PL_statgv = Nullgv;
919 sv_setpv(PL_statname,"");
920 return (PL_laststatval = -1);
a687059c
LW
921 }
922 }
923 else {
748a9306 924 SV* sv = POPs;
4b74e3fb 925 char *s;
36596149 926 STRLEN n_a;
79072805 927 PUTBACK;
748a9306
LW
928 if (SvTYPE(sv) == SVt_PVGV) {
929 tmpgv = (GV*)sv;
930 goto do_fstat;
931 }
932 else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
933 tmpgv = (GV*)SvRV(sv);
934 goto do_fstat;
935 }
936
36596149 937 s = SvPV(sv, n_a);
3280af22
NIS
938 PL_statgv = Nullgv;
939 sv_setpv(PL_statname, s);
940 PL_laststype = OP_STAT;
941 PL_laststatval = PerlLIO_stat(s, &PL_statcache);
942 if (PL_laststatval < 0 && PL_dowarn && strchr(s, '\n'))
bee1dbe2 943 warn(warn_nl, "stat");
3280af22 944 return PL_laststatval;
a687059c
LW
945 }
946}
947
79072805 948I32
8ac85365 949my_lstat(ARGSproto)
c623bd54 950{
4e35701f 951 djSP;
79072805 952 SV *sv;
36596149 953 STRLEN n_a;
533c011a 954 if (PL_op->op_flags & OPf_REF) {
924508f0 955 EXTEND(SP,1);
3280af22
NIS
956 if (cGVOP->op_gv == PL_defgv) {
957 if (PL_laststype != OP_LSTAT)
463ee0b2 958 croak("The stat preceding -l _ wasn't an lstat");
3280af22 959 return PL_laststatval;
fe14fcc3 960 }
463ee0b2 961 croak("You can't use -l on a filehandle");
fe14fcc3 962 }
c623bd54 963
3280af22
NIS
964 PL_laststype = OP_LSTAT;
965 PL_statgv = Nullgv;
79072805
LW
966 sv = POPs;
967 PUTBACK;
36596149 968 sv_setpv(PL_statname,SvPV(sv, n_a));
fe14fcc3 969#ifdef HAS_LSTAT
36596149 970 PL_laststatval = PerlLIO_lstat(SvPV(sv, n_a),&PL_statcache);
c623bd54 971#else
36596149 972 PL_laststatval = PerlLIO_stat(SvPV(sv, n_a),&PL_statcache);
c623bd54 973#endif
36596149 974 if (PL_laststatval < 0 && PL_dowarn && strchr(SvPV(sv, n_a), '\n'))
bee1dbe2 975 warn(warn_nl, "lstat");
3280af22 976 return PL_laststatval;
c623bd54
LW
977}
978
a687059c 979bool
8ac85365 980do_aexec(SV *really, register SV **mark, register SV **sp)
a687059c 981{
a687059c 982 register char **a;
a687059c 983 char *tmps;
36596149 984 STRLEN n_a;
a687059c 985
79072805 986 if (sp > mark) {
11343788 987 dTHR;
3280af22
NIS
988 New(401,PL_Argv, sp - mark + 1, char*);
989 a = PL_Argv;
79072805
LW
990 while (++mark <= sp) {
991 if (*mark)
36596149 992 *a++ = SvPVx(*mark, n_a);
a687059c
LW
993 else
994 *a++ = "";
995 }
996 *a = Nullch;
3280af22 997 if (*PL_Argv[0] != '/') /* will execvp use PATH? */
79072805 998 TAINT_ENV(); /* testing IFS here is overkill, probably */
36596149 999 if (really && *(tmps = SvPV(really, n_a)))
3280af22 1000 PerlProc_execvp(tmps,PL_Argv);
a687059c 1001 else
3280af22
NIS
1002 PerlProc_execvp(PL_Argv[0],PL_Argv);
1003 if (PL_dowarn)
1004 warn("Can't exec \"%s\": %s", PL_Argv[0], Strerror(errno));
a687059c 1005 }
bee1dbe2 1006 do_execfree();
a687059c
LW
1007 return FALSE;
1008}
1009
fe14fcc3 1010void
8ac85365 1011do_execfree(void)
ff8e2863 1012{
3280af22
NIS
1013 if (PL_Argv) {
1014 Safefree(PL_Argv);
1015 PL_Argv = Null(char **);
ff8e2863 1016 }
3280af22
NIS
1017 if (PL_Cmd) {
1018 Safefree(PL_Cmd);
1019 PL_Cmd = Nullch;
ff8e2863
LW
1020 }
1021}
1022
39e571d4 1023#if !defined(OS2) && !defined(WIN32) && !defined(DJGPP)
760ac839 1024
a687059c 1025bool
8ac85365 1026do_exec(char *cmd)
a687059c
LW
1027{
1028 register char **a;
1029 register char *s;
a687059c
LW
1030 char flags[10];
1031
748a9306
LW
1032 while (*cmd && isSPACE(*cmd))
1033 cmd++;
1034
a687059c
LW
1035 /* save an extra exec if possible */
1036
bf38876a 1037#ifdef CSH
3280af22 1038 if (strnEQ(cmd,PL_cshname,PL_cshlen) && strnEQ(cmd+PL_cshlen," -c",3)) {
a687059c 1039 strcpy(flags,"-c");
3280af22 1040 s = cmd+PL_cshlen+3;
a687059c
LW
1041 if (*s == 'f') {
1042 s++;
1043 strcat(flags,"f");
1044 }
1045 if (*s == ' ')
1046 s++;
1047 if (*s++ == '\'') {
1048 char *ncmd = s;
1049
1050 while (*s)
1051 s++;
1052 if (s[-1] == '\n')
1053 *--s = '\0';
1054 if (s[-1] == '\'') {
1055 *--s = '\0';
3280af22 1056 PerlProc_execl(PL_cshname,"csh", flags,ncmd,(char*)0);
a687059c
LW
1057 *s = '\'';
1058 return FALSE;
1059 }
1060 }
1061 }
bf38876a 1062#endif /* CSH */
a687059c
LW
1063
1064 /* see if there are shell metacharacters in it */
1065
748a9306
LW
1066 if (*cmd == '.' && isSPACE(cmd[1]))
1067 goto doshell;
1068
1069 if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
1070 goto doshell;
1071
99b89507 1072 for (s = cmd; *s && isALPHA(*s); s++) ; /* catch VAR=val gizmo */
63f2c1e1
LW
1073 if (*s == '=')
1074 goto doshell;
748a9306 1075
a687059c 1076 for (s = cmd; *s; s++) {
93a17b20 1077 if (*s != ' ' && !isALPHA(*s) && strchr("$&*(){}[]'\";\\|?<>~`\n",*s)) {
a687059c
LW
1078 if (*s == '\n' && !s[1]) {
1079 *s = '\0';
1080 break;
1081 }
1082 doshell:
3280af22 1083 PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char*)0);
a687059c
LW
1084 return FALSE;
1085 }
1086 }
748a9306 1087
3280af22
NIS
1088 New(402,PL_Argv, (s - cmd) / 2 + 2, char*);
1089 PL_Cmd = savepvn(cmd, s-cmd);
1090 a = PL_Argv;
1091 for (s = PL_Cmd; *s;) {
99b89507 1092 while (*s && isSPACE(*s)) s++;
a687059c
LW
1093 if (*s)
1094 *(a++) = s;
99b89507 1095 while (*s && !isSPACE(*s)) s++;
a687059c
LW
1096 if (*s)
1097 *s++ = '\0';
1098 }
1099 *a = Nullch;
3280af22
NIS
1100 if (PL_Argv[0]) {
1101 PerlProc_execvp(PL_Argv[0],PL_Argv);
b1248f16 1102 if (errno == ENOEXEC) { /* for system V NIH syndrome */
ff8e2863 1103 do_execfree();
a687059c 1104 goto doshell;
b1248f16 1105 }
3280af22
NIS
1106 if (PL_dowarn)
1107 warn("Can't exec \"%s\": %s", PL_Argv[0], Strerror(errno));
a687059c 1108 }
ff8e2863 1109 do_execfree();
a687059c
LW
1110 return FALSE;
1111}
1112
6890e559 1113#endif /* OS2 || WIN32 */
760ac839 1114
79072805 1115I32
8ac85365 1116apply(I32 type, register SV **mark, register SV **sp)
a687059c 1117{
11343788 1118 dTHR;
79072805
LW
1119 register I32 val;
1120 register I32 val2;
1121 register I32 tot = 0;
20408e3c 1122 char *what;
a687059c 1123 char *s;
79072805 1124 SV **oldmark = mark;
36596149 1125 STRLEN n_a;
a687059c 1126
20408e3c 1127#define APPLY_TAINT_PROPER() \
3280af22 1128 STMT_START { \
ae39e9e8 1129 if (PL_tainted) { TAINT_PROPER(what); } \
873ef191 1130 } STMT_END
20408e3c
GS
1131
1132 /* This is a first heuristic; it doesn't catch tainting magic. */
3280af22 1133 if (PL_tainting) {
463ee0b2 1134 while (++mark <= sp) {
bbce6d69 1135 if (SvTAINTED(*mark)) {
1136 TAINT;
1137 break;
1138 }
463ee0b2
LW
1139 }
1140 mark = oldmark;
1141 }
a687059c 1142 switch (type) {
79072805 1143 case OP_CHMOD:
20408e3c
GS
1144 what = "chmod";
1145 APPLY_TAINT_PROPER();
79072805 1146 if (++mark <= sp) {
463ee0b2 1147 val = SvIVx(*mark);
20408e3c
GS
1148 APPLY_TAINT_PROPER();
1149 tot = sp - mark;
79072805 1150 while (++mark <= sp) {
36596149 1151 char *name = SvPVx(*mark, n_a);
20408e3c
GS
1152 APPLY_TAINT_PROPER();
1153 if (PerlLIO_chmod(name, val))
a687059c
LW
1154 tot--;
1155 }
1156 }
1157 break;
fe14fcc3 1158#ifdef HAS_CHOWN
79072805 1159 case OP_CHOWN:
20408e3c
GS
1160 what = "chown";
1161 APPLY_TAINT_PROPER();
79072805 1162 if (sp - mark > 2) {
463ee0b2
LW
1163 val = SvIVx(*++mark);
1164 val2 = SvIVx(*++mark);
20408e3c 1165 APPLY_TAINT_PROPER();
a0d0e21e 1166 tot = sp - mark;
79072805 1167 while (++mark <= sp) {
36596149 1168 char *name = SvPVx(*mark, n_a);
20408e3c 1169 APPLY_TAINT_PROPER();
36660982 1170 if (PerlLIO_chown(name, val, val2))
a687059c
LW
1171 tot--;
1172 }
1173 }
1174 break;
b1248f16 1175#endif
dd64f1c3
AD
1176/*
1177XXX Should we make lchown() directly available from perl?
1178For now, we'll let Configure test for HAS_LCHOWN, but do
1179nothing in the core.
1180 --AD 5/1998
1181*/
fe14fcc3 1182#ifdef HAS_KILL
79072805 1183 case OP_KILL:
20408e3c
GS
1184 what = "kill";
1185 APPLY_TAINT_PROPER();
55497cff 1186 if (mark == sp)
1187 break;
36596149 1188 s = SvPVx(*++mark, n_a);
79072805
LW
1189 if (isUPPER(*s)) {
1190 if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1191 s += 3;
1192 if (!(val = whichsig(s)))
463ee0b2 1193 croak("Unrecognized signal name \"%s\"",s);
79072805
LW
1194 }
1195 else
463ee0b2 1196 val = SvIVx(*mark);
20408e3c
GS
1197 APPLY_TAINT_PROPER();
1198 tot = sp - mark;
3595fcef 1199#ifdef VMS
1200 /* kill() doesn't do process groups (job trees?) under VMS */
1201 if (val < 0) val = -val;
1202 if (val == SIGKILL) {
1203# include <starlet.h>
1204 /* Use native sys$delprc() to insure that target process is
1205 * deleted; supervisor-mode images don't pay attention to
1206 * CRTL's emulation of Unix-style signals and kill()
1207 */
1208 while (++mark <= sp) {
1209 I32 proc = SvIVx(*mark);
1210 register unsigned long int __vmssts;
20408e3c 1211 APPLY_TAINT_PROPER();
3595fcef 1212 if (!((__vmssts = sys$delprc(&proc,0)) & 1)) {
1213 tot--;
1214 switch (__vmssts) {
1215 case SS$_NONEXPR:
1216 case SS$_NOSUCHNODE:
1217 SETERRNO(ESRCH,__vmssts);
1218 break;
1219 case SS$_NOPRIV:
1220 SETERRNO(EPERM,__vmssts);
1221 break;
1222 default:
1223 SETERRNO(EVMSERR,__vmssts);
1224 }
1225 }
1226 }
1227 break;
1228 }
1229#endif
79072805
LW
1230 if (val < 0) {
1231 val = -val;
1232 while (++mark <= sp) {
463ee0b2 1233 I32 proc = SvIVx(*mark);
20408e3c 1234 APPLY_TAINT_PROPER();
fe14fcc3 1235#ifdef HAS_KILLPG
3028581b 1236 if (PerlProc_killpg(proc,val)) /* BSD */
a687059c 1237#else
3028581b 1238 if (PerlProc_kill(-proc,val)) /* SYSV */
a687059c 1239#endif
79072805 1240 tot--;
a687059c 1241 }
79072805
LW
1242 }
1243 else {
1244 while (++mark <= sp) {
20408e3c
GS
1245 I32 proc = SvIVx(*mark);
1246 APPLY_TAINT_PROPER();
1247 if (PerlProc_kill(proc, val))
79072805 1248 tot--;
a687059c
LW
1249 }
1250 }
1251 break;
b1248f16 1252#endif
79072805 1253 case OP_UNLINK:
20408e3c
GS
1254 what = "unlink";
1255 APPLY_TAINT_PROPER();
79072805
LW
1256 tot = sp - mark;
1257 while (++mark <= sp) {
36596149 1258 s = SvPVx(*mark, n_a);
20408e3c 1259 APPLY_TAINT_PROPER();
3280af22 1260 if (PL_euid || PL_unsafe) {
a687059c
LW
1261 if (UNLINK(s))
1262 tot--;
1263 }
1264 else { /* don't let root wipe out directories without -U */
fe14fcc3 1265#ifdef HAS_LSTAT
3280af22 1266 if (PerlLIO_lstat(s,&PL_statbuf) < 0 || S_ISDIR(PL_statbuf.st_mode))
a687059c 1267#else
b28d0864 1268 if (PerlLIO_stat(s,&PL_statbuf) < 0 || S_ISDIR(PL_statbuf.st_mode))
a687059c 1269#endif
a687059c
LW
1270 tot--;
1271 else {
1272 if (UNLINK(s))
1273 tot--;
1274 }
1275 }
1276 }
1277 break;
a0d0e21e 1278#ifdef HAS_UTIME
79072805 1279 case OP_UTIME:
20408e3c
GS
1280 what = "utime";
1281 APPLY_TAINT_PROPER();
79072805 1282 if (sp - mark > 2) {
748a9306 1283#if defined(I_UTIME) || defined(VMS)
663a0e37
LW
1284 struct utimbuf utbuf;
1285#else
a687059c 1286 struct {
663a0e37
LW
1287 long actime;
1288 long modtime;
a687059c 1289 } utbuf;
663a0e37 1290#endif
a687059c 1291
afd9f252 1292 Zero(&utbuf, sizeof utbuf, char);
517844ec 1293#ifdef BIG_TIME
1294 utbuf.actime = (Time_t)SvNVx(*++mark); /* time accessed */
1295 utbuf.modtime = (Time_t)SvNVx(*++mark); /* time modified */
1296#else
463ee0b2
LW
1297 utbuf.actime = SvIVx(*++mark); /* time accessed */
1298 utbuf.modtime = SvIVx(*++mark); /* time modified */
517844ec 1299#endif
20408e3c 1300 APPLY_TAINT_PROPER();
79072805
LW
1301 tot = sp - mark;
1302 while (++mark <= sp) {
36596149 1303 char *name = SvPVx(*mark, n_a);
20408e3c
GS
1304 APPLY_TAINT_PROPER();
1305 if (PerlLIO_utime(name, &utbuf))
a687059c
LW
1306 tot--;
1307 }
a687059c
LW
1308 }
1309 else
79072805 1310 tot = 0;
a687059c 1311 break;
a0d0e21e 1312#endif
a687059c
LW
1313 }
1314 return tot;
20408e3c 1315
20408e3c 1316#undef APPLY_TAINT_PROPER
a687059c
LW
1317}
1318
1319/* Do the permissions allow some operation? Assumes statcache already set. */
a0d0e21e 1320#ifndef VMS /* VMS' cando is in vms.c */
79072805 1321I32
8ac85365 1322cando(I32 bit, I32 effective, register struct stat *statbufp)
a687059c 1323{
bee1dbe2 1324#ifdef DOSISH
fe14fcc3
LW
1325 /* [Comments and code from Len Reed]
1326 * MS-DOS "user" is similar to UNIX's "superuser," but can't write
1327 * to write-protected files. The execute permission bit is set
1328 * by the Miscrosoft C library stat() function for the following:
1329 * .exe files
1330 * .com files
1331 * .bat files
1332 * directories
1333 * All files and directories are readable.
1334 * Directories and special files, e.g. "CON", cannot be
1335 * write-protected.
1336 * [Comment by Tom Dinger -- a directory can have the write-protect
1337 * bit set in the file system, but DOS permits changes to
1338 * the directory anyway. In addition, all bets are off
1339 * here for networked software, such as Novell and
1340 * Sun's PC-NFS.]
1341 */
1342
bee1dbe2
LW
1343 /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
1344 * too so it will actually look into the files for magic numbers
1345 */
fe14fcc3
LW
1346 return (bit & statbufp->st_mode) ? TRUE : FALSE;
1347
55497cff 1348#else /* ! DOSISH */
3280af22 1349 if ((effective ? PL_euid : PL_uid) == 0) { /* root is special */
c623bd54
LW
1350 if (bit == S_IXUSR) {
1351 if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))
a687059c
LW
1352 return TRUE;
1353 }
1354 else
1355 return TRUE; /* root reads and writes anything */
1356 return FALSE;
1357 }
3280af22 1358 if (statbufp->st_uid == (effective ? PL_euid : PL_uid) ) {
a687059c
LW
1359 if (statbufp->st_mode & bit)
1360 return TRUE; /* ok as "user" */
1361 }
79072805 1362 else if (ingroup((I32)statbufp->st_gid,effective)) {
a687059c
LW
1363 if (statbufp->st_mode & bit >> 3)
1364 return TRUE; /* ok as "group" */
1365 }
1366 else if (statbufp->st_mode & bit >> 6)
1367 return TRUE; /* ok as "other" */
1368 return FALSE;
55497cff 1369#endif /* ! DOSISH */
a687059c 1370}
a0d0e21e 1371#endif /* ! VMS */
a687059c 1372
79072805 1373I32
8ac85365 1374ingroup(I32 testgid, I32 effective)
a687059c 1375{
3280af22 1376 if (testgid == (effective ? PL_egid : PL_gid))
a687059c 1377 return TRUE;
fe14fcc3 1378#ifdef HAS_GETGROUPS
a687059c
LW
1379#ifndef NGROUPS
1380#define NGROUPS 32
1381#endif
1382 {
a0d0e21e 1383 Groups_t gary[NGROUPS];
79072805 1384 I32 anum;
a687059c
LW
1385
1386 anum = getgroups(NGROUPS,gary);
1387 while (--anum >= 0)
1388 if (gary[anum] == testgid)
1389 return TRUE;
1390 }
1391#endif
1392 return FALSE;
1393}
c2ab57d4 1394
fe14fcc3 1395#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
c2ab57d4 1396
79072805 1397I32
8ac85365 1398do_ipcget(I32 optype, SV **mark, SV **sp)
c2ab57d4 1399{
11343788 1400 dTHR;
c2ab57d4 1401 key_t key;
79072805 1402 I32 n, flags;
c2ab57d4 1403
463ee0b2
LW
1404 key = (key_t)SvNVx(*++mark);
1405 n = (optype == OP_MSGGET) ? 0 : SvIVx(*++mark);
1406 flags = SvIVx(*++mark);
748a9306 1407 SETERRNO(0,0);
c2ab57d4
LW
1408 switch (optype)
1409 {
fe14fcc3 1410#ifdef HAS_MSG
79072805 1411 case OP_MSGGET:
c2ab57d4 1412 return msgget(key, flags);
e5d73d77 1413#endif
fe14fcc3 1414#ifdef HAS_SEM
79072805 1415 case OP_SEMGET:
c2ab57d4 1416 return semget(key, n, flags);
e5d73d77 1417#endif
fe14fcc3 1418#ifdef HAS_SHM
79072805 1419 case OP_SHMGET:
c2ab57d4 1420 return shmget(key, n, flags);
e5d73d77 1421#endif
fe14fcc3 1422#if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
e5d73d77 1423 default:
c07a80fd 1424 croak("%s not implemented", op_desc[optype]);
e5d73d77 1425#endif
c2ab57d4
LW
1426 }
1427 return -1; /* should never happen */
1428}
1429
79072805 1430I32
8ac85365 1431do_ipcctl(I32 optype, SV **mark, SV **sp)
c2ab57d4 1432{
11343788 1433 dTHR;
79072805 1434 SV *astr;
c2ab57d4 1435 char *a;
a0d0e21e
LW
1436 I32 id, n, cmd, infosize, getinfo;
1437 I32 ret = -1;
c2ab57d4 1438
463ee0b2
LW
1439 id = SvIVx(*++mark);
1440 n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
1441 cmd = SvIVx(*++mark);
79072805 1442 astr = *++mark;
c2ab57d4
LW
1443 infosize = 0;
1444 getinfo = (cmd == IPC_STAT);
1445
1446 switch (optype)
1447 {
fe14fcc3 1448#ifdef HAS_MSG
79072805 1449 case OP_MSGCTL:
c2ab57d4
LW
1450 if (cmd == IPC_STAT || cmd == IPC_SET)
1451 infosize = sizeof(struct msqid_ds);
1452 break;
e5d73d77 1453#endif
fe14fcc3 1454#ifdef HAS_SHM
79072805 1455 case OP_SHMCTL:
c2ab57d4
LW
1456 if (cmd == IPC_STAT || cmd == IPC_SET)
1457 infosize = sizeof(struct shmid_ds);
1458 break;
e5d73d77 1459#endif
fe14fcc3 1460#ifdef HAS_SEM
79072805 1461 case OP_SEMCTL:
c2ab57d4
LW
1462 if (cmd == IPC_STAT || cmd == IPC_SET)
1463 infosize = sizeof(struct semid_ds);
1464 else if (cmd == GETALL || cmd == SETALL)
1465 {
8e591e46 1466 struct semid_ds semds;
bd89102f
AD
1467 union semun semun;
1468
84902520 1469 semun.buf = &semds;
c2ab57d4 1470 getinfo = (cmd == GETALL);
9b89d93d
GB
1471 if (Semctl(id, 0, IPC_STAT, semun) == -1)
1472 return -1;
6e21c824
LW
1473 infosize = semds.sem_nsems * sizeof(short);
1474 /* "short" is technically wrong but much more portable
1475 than guessing about u_?short(_t)? */
c2ab57d4
LW
1476 }
1477 break;
e5d73d77 1478#endif
fe14fcc3 1479#if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)
e5d73d77 1480 default:
c07a80fd 1481 croak("%s not implemented", op_desc[optype]);
e5d73d77 1482#endif
c2ab57d4
LW
1483 }
1484
1485 if (infosize)
1486 {
a0d0e21e 1487 STRLEN len;
c2ab57d4
LW
1488 if (getinfo)
1489 {
a0d0e21e
LW
1490 SvPV_force(astr, len);
1491 a = SvGROW(astr, infosize+1);
c2ab57d4
LW
1492 }
1493 else
1494 {
463ee0b2
LW
1495 a = SvPV(astr, len);
1496 if (len != infosize)
9607fc9c 1497 croak("Bad arg length for %s, is %lu, should be %ld",
1498 op_desc[optype], (unsigned long)len, (long)infosize);
c2ab57d4
LW
1499 }
1500 }
1501 else
1502 {
c030ccd9 1503 IV i = SvIV(astr);
c2ab57d4
LW
1504 a = (char *)i; /* ouch */
1505 }
748a9306 1506 SETERRNO(0,0);
c2ab57d4
LW
1507 switch (optype)
1508 {
fe14fcc3 1509#ifdef HAS_MSG
79072805 1510 case OP_MSGCTL:
bee1dbe2 1511 ret = msgctl(id, cmd, (struct msqid_ds *)a);
c2ab57d4 1512 break;
e5d73d77 1513#endif
fe14fcc3 1514#ifdef HAS_SEM
bd89102f
AD
1515 case OP_SEMCTL: {
1516 union semun unsemds;
1517
1518 unsemds.buf = (struct semid_ds *)a;
1519 ret = Semctl(id, n, cmd, unsemds);
1520 }
c2ab57d4 1521 break;
e5d73d77 1522#endif
fe14fcc3 1523#ifdef HAS_SHM
79072805 1524 case OP_SHMCTL:
bee1dbe2 1525 ret = shmctl(id, cmd, (struct shmid_ds *)a);
c2ab57d4 1526 break;
e5d73d77 1527#endif
c2ab57d4
LW
1528 }
1529 if (getinfo && ret >= 0) {
79072805
LW
1530 SvCUR_set(astr, infosize);
1531 *SvEND(astr) = '\0';
a0d0e21e 1532 SvSETMAGIC(astr);
c2ab57d4
LW
1533 }
1534 return ret;
1535}
1536
79072805 1537I32
8ac85365 1538do_msgsnd(SV **mark, SV **sp)
c2ab57d4 1539{
fe14fcc3 1540#ifdef HAS_MSG
11343788 1541 dTHR;
79072805 1542 SV *mstr;
c2ab57d4 1543 char *mbuf;
79072805 1544 I32 id, msize, flags;
463ee0b2 1545 STRLEN len;
c2ab57d4 1546
463ee0b2 1547 id = SvIVx(*++mark);
79072805 1548 mstr = *++mark;
463ee0b2
LW
1549 flags = SvIVx(*++mark);
1550 mbuf = SvPV(mstr, len);
1551 if ((msize = len - sizeof(long)) < 0)
1552 croak("Arg too short for msgsnd");
748a9306 1553 SETERRNO(0,0);
bee1dbe2 1554 return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
e5d73d77 1555#else
463ee0b2 1556 croak("msgsnd not implemented");
e5d73d77 1557#endif
c2ab57d4
LW
1558}
1559
79072805 1560I32
8ac85365 1561do_msgrcv(SV **mark, SV **sp)
c2ab57d4 1562{
fe14fcc3 1563#ifdef HAS_MSG
11343788 1564 dTHR;
79072805 1565 SV *mstr;
c2ab57d4
LW
1566 char *mbuf;
1567 long mtype;
79072805 1568 I32 id, msize, flags, ret;
463ee0b2 1569 STRLEN len;
79072805 1570
463ee0b2 1571 id = SvIVx(*++mark);
79072805 1572 mstr = *++mark;
463ee0b2
LW
1573 msize = SvIVx(*++mark);
1574 mtype = (long)SvIVx(*++mark);
1575 flags = SvIVx(*++mark);
ed6116ce
LW
1576 if (SvTHINKFIRST(mstr)) {
1577 if (SvREADONLY(mstr))
1578 croak("Can't msgrcv to readonly var");
1579 if (SvROK(mstr))
1580 sv_unref(mstr);
1581 }
a0d0e21e
LW
1582 SvPV_force(mstr, len);
1583 mbuf = SvGROW(mstr, sizeof(long)+msize+1);
1584
748a9306 1585 SETERRNO(0,0);
bee1dbe2 1586 ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
c2ab57d4 1587 if (ret >= 0) {
79072805
LW
1588 SvCUR_set(mstr, sizeof(long)+ret);
1589 *SvEND(mstr) = '\0';
c2ab57d4
LW
1590 }
1591 return ret;
e5d73d77 1592#else
463ee0b2 1593 croak("msgrcv not implemented");
e5d73d77 1594#endif
c2ab57d4
LW
1595}
1596
79072805 1597I32
8ac85365 1598do_semop(SV **mark, SV **sp)
c2ab57d4 1599{
fe14fcc3 1600#ifdef HAS_SEM
11343788 1601 dTHR;
79072805 1602 SV *opstr;
c2ab57d4 1603 char *opbuf;
463ee0b2
LW
1604 I32 id;
1605 STRLEN opsize;
c2ab57d4 1606
463ee0b2 1607 id = SvIVx(*++mark);
79072805 1608 opstr = *++mark;
463ee0b2 1609 opbuf = SvPV(opstr, opsize);
c2ab57d4
LW
1610 if (opsize < sizeof(struct sembuf)
1611 || (opsize % sizeof(struct sembuf)) != 0) {
748a9306 1612 SETERRNO(EINVAL,LIB$_INVARG);
c2ab57d4
LW
1613 return -1;
1614 }
748a9306 1615 SETERRNO(0,0);
6e21c824 1616 return semop(id, (struct sembuf *)opbuf, opsize/sizeof(struct sembuf));
e5d73d77 1617#else
463ee0b2 1618 croak("semop not implemented");
e5d73d77 1619#endif
c2ab57d4
LW
1620}
1621
79072805 1622I32
8ac85365 1623do_shmio(I32 optype, SV **mark, SV **sp)
c2ab57d4 1624{
fe14fcc3 1625#ifdef HAS_SHM
11343788 1626 dTHR;
79072805 1627 SV *mstr;
c2ab57d4 1628 char *mbuf, *shm;
79072805 1629 I32 id, mpos, msize;
463ee0b2 1630 STRLEN len;
c2ab57d4 1631 struct shmid_ds shmds;
c2ab57d4 1632
463ee0b2 1633 id = SvIVx(*++mark);
79072805 1634 mstr = *++mark;
463ee0b2
LW
1635 mpos = SvIVx(*++mark);
1636 msize = SvIVx(*++mark);
748a9306 1637 SETERRNO(0,0);
c2ab57d4
LW
1638 if (shmctl(id, IPC_STAT, &shmds) == -1)
1639 return -1;
1640 if (mpos < 0 || msize < 0 || mpos + msize > shmds.shm_segsz) {
748a9306 1641 SETERRNO(EFAULT,SS$_ACCVIO); /* can't do as caller requested */
c2ab57d4
LW
1642 return -1;
1643 }
8ac85365 1644 shm = (char *)shmat(id, (char*)NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
c2ab57d4
LW
1645 if (shm == (char *)-1) /* I hate System V IPC, I really do */
1646 return -1;
79072805 1647 if (optype == OP_SHMREAD) {
a0d0e21e
LW
1648 SvPV_force(mstr, len);
1649 mbuf = SvGROW(mstr, msize+1);
1650
bee1dbe2 1651 Copy(shm + mpos, mbuf, msize, char);
79072805
LW
1652 SvCUR_set(mstr, msize);
1653 *SvEND(mstr) = '\0';
a0d0e21e 1654 SvSETMAGIC(mstr);
c2ab57d4
LW
1655 }
1656 else {
79072805 1657 I32 n;
c2ab57d4 1658
a0d0e21e 1659 mbuf = SvPV(mstr, len);
463ee0b2 1660 if ((n = len) > msize)
c2ab57d4 1661 n = msize;
bee1dbe2 1662 Copy(mbuf, shm + mpos, n, char);
c2ab57d4 1663 if (n < msize)
bee1dbe2 1664 memzero(shm + mpos + n, msize - n);
c2ab57d4
LW
1665 }
1666 return shmdt(shm);
e5d73d77 1667#else
463ee0b2 1668 croak("shm I/O not implemented");
e5d73d77 1669#endif
c2ab57d4
LW
1670}
1671
fe14fcc3 1672#endif /* SYSV IPC */
4e35701f 1673