ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/staticperl/perl/doio.c
Revision: 1.1
Committed: Thu Jun 30 14:26:41 2005 UTC (21 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

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