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