summaryrefslogtreecommitdiff
path: root/doio.c
diff options
context:
space:
mode:
authorLarry Wall <lwall@netlabs.com>1992-06-08 04:52:08 +0000
committerLarry Wall <lwall@netlabs.com>1992-06-08 04:52:08 +0000
commitbee1dbe28446f1b188ddf14e24e7f65771825d8f (patch)
treef86e23246374104de23fe22cee4dfa6a9cca86e1 /doio.c
parent8adcabd8d9cf3c71e660c45cb7165ae4694308d4 (diff)
downloadperl-bee1dbe28446f1b188ddf14e24e7f65771825d8f.tar.gz
perl 4.0 patch 26: patch #20, continued
See patch #20.
Diffstat (limited to 'doio.c')
-rw-r--r--doio.c285
1 files changed, 197 insertions, 88 deletions
diff --git a/doio.c b/doio.c
index 0c5a1c946a..aa85abe8d2 100644
--- a/doio.c
+++ b/doio.c
@@ -1,4 +1,4 @@
-/* $RCSfile: doio.c,v $$Revision: 4.0.1.4 $$Date: 91/11/05 16:51:43 $
+/* $RCSfile: doio.c,v $$Revision: 4.0.1.5 $$Date: 92/06/08 13:00:21 $
*
* Copyright (c) 1991, Larry Wall
*
@@ -6,6 +6,16 @@
* License or the Artistic License, as specified in the README file.
*
* $Log: doio.c,v $
+ * Revision 4.0.1.5 92/06/08 13:00:21 lwall
+ * patch20: some machines don't define ENOTSOCK in errno.h
+ * patch20: new warnings for failed use of stat operators on filenames with \n
+ * patch20: wait failed when STDOUT or STDERR reopened to a pipe
+ * patch20: end of file latch not reset on reopen of STDIN
+ * patch20: seek(HANDLE, 0, 1) went to eof because of ancient Ultrix workaround
+ * patch20: fixed memory leak on system() for vfork() machines
+ * patch20: get*by* routines now return something useful in a scalar context
+ * patch20: h_errno now accessible via $?
+ *
* Revision 4.0.1.4 91/11/05 16:51:43 lwall
* patch11: prepared for ctype implementations that don't define isascii()
* patch11: perl mistook some streams for sockets because they return mode 0 too
@@ -41,6 +51,9 @@
#ifdef HAS_SOCKET
#include <sys/socket.h>
#include <netdb.h>
+#ifndef ENOTSOCK
+#include <net/errno.h>
+#endif
#endif
#ifdef HAS_SELECT
@@ -83,6 +96,8 @@
int laststatval = -1;
int laststype = O_STAT;
+static char* warn_nl = "Unsuccessful %s on filename containing newline";
+
bool
do_open(stab,name,len)
STAB *stab;
@@ -100,6 +115,7 @@ int len;
FILE *saveofp = Nullfp;
char savetype = ' ';
+ mode[0] = mode[1] = mode[2] = '\0';
name = myname;
forkprocess = 1; /* assume true if no fork */
while (len && isSPACE(name[len-1]))
@@ -130,7 +146,7 @@ int len;
result = fclose(stio->ifp);
if (result == EOF && fd > maxsysfd)
fprintf(stderr,"Warning: unable to close filehandle %s properly.\n",
- stab_name(stab));
+ stab_ename(stab));
stio->ofp = stio->ifp = Nullfp;
}
if (*name == '+' && len > 1 && name[len-1] != '|') { /* scary */
@@ -244,9 +260,13 @@ int len;
fp = fopen(name,"r");
}
}
- Safefree(myname);
- if (!fp)
+ if (!fp) {
+ if (dowarn && stio->type == '<' && index(name, '\n'))
+ warn(warn_nl, "open");
+ Safefree(myname);
goto say_false;
+ }
+ Safefree(myname);
if (stio->type &&
stio->type != '|' && stio->type != '-') {
if (fstat(fileno(fp),&statbuf) < 0) {
@@ -263,7 +283,9 @@ int len;
!statbuf.st_mode
#endif
) {
- if (getsockname(fileno(fp), tokenbuf, 0) >= 0 || errno != ENOTSOCK)
+ int buflen = sizeof tokenbuf;
+ if (getsockname(fileno(fp), tokenbuf, &buflen) >= 0
+ || errno != ENOTSOCK)
stio->type = 's'; /* some OS's return 0 on fstat()ed socket */
/* but some return 0 for streams too, sigh */
}
@@ -280,10 +302,20 @@ int len;
}
}
if (fd != fileno(fp)) {
+ int pid;
+ STR *str;
+
dup2(fileno(fp), fd);
+ str = afetch(fdpid,fileno(fp),TRUE);
+ pid = str->str_u.str_useful;
+ str->str_u.str_useful = 0;
+ str = afetch(fdpid,fd,TRUE);
+ str->str_u.str_useful = pid;
fclose(fp);
+
}
fp = saveifp;
+ clearerr(fp);
}
#if defined(HAS_FCNTL) && defined(F_SETFD)
fd = fileno(fp);
@@ -384,7 +416,7 @@ register STAB *stab;
}
#endif
#ifdef HAS_RENAME
-#ifndef MSDOS
+#ifndef DOSISH
if (rename(oldname,str->str_ptr) < 0) {
warn("Can't rename %s to %s: %s, skipping file",
oldname, str->str_ptr, strerror(errno) );
@@ -411,7 +443,7 @@ register STAB *stab;
#endif
}
else {
-#ifndef MSDOS
+#ifndef DOSISH
if (UNLINK(oldname) < 0) {
warn("Can't rename %s to %s: %s, skipping file",
oldname, str->str_ptr, strerror(errno) );
@@ -536,7 +568,7 @@ bool explicit;
stio = stab_io(stab);
if (!stio) { /* never opened */
if (dowarn && explicit)
- warn("Close on unopened file <%s>",stab_name(stab));
+ warn("Close on unopened file <%s>",stab_ename(stab));
return FALSE;
}
if (stio->ifp) {
@@ -621,8 +653,10 @@ STAB *stab;
if (!stio || !stio->ifp)
goto phooey;
+#ifdef ULTRIX_STDIO_BOTCH
if (feof(stio->ifp))
(void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
+#endif
return ftell(stio->ifp);
@@ -648,8 +682,10 @@ int whence;
if (!stio || !stio->ifp)
goto nuts;
+#ifdef ULTRIX_STDIO_BOTCH
if (feof(stio->ifp))
(void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
+#endif
return fseek(stio->ifp, pos, whence) >= 0;
@@ -700,7 +736,7 @@ STR *argstr;
}
else {
retval = (int)str_gnum(argstr);
-#ifdef MSDOS
+#ifdef DOSISH
s = (char*)(long)retval; /* ouch */
#else
s = (char*)retval; /* ouch */
@@ -711,7 +747,7 @@ STR *argstr;
if (optype == O_IOCTL)
retval = ioctl(fileno(stio->ifp), func, s);
else
-#ifdef MSDOS
+#ifdef DOSISH
fatal("fcntl is not implemented");
#else
#ifdef HAS_FCNTL
@@ -768,8 +804,11 @@ int *arglast;
else
#endif
laststatval = stat(str_get(statname),&statcache);
- if (laststatval < 0)
+ if (laststatval < 0) {
+ if (dowarn && index(str_get(statname), '\n'))
+ warn(warn_nl, "stat");
max = 0;
+ }
}
if (gimme != G_ARRAY) {
@@ -1000,7 +1039,7 @@ FILE *fp;
if (*tmps == 'S' && tmps[1] == 't' && tmps[2] == 'B' && tmps[3] == '\0'
&& str->str_cur == sizeof(STBP) && strlen(tmps) < str->str_cur) {
STR *tmpstr = str_mortal(&str_undef);
- stab_fullname(tmpstr,((STAB*)str));/* a stab value, be nice */
+ stab_efullname(tmpstr,((STAB*)str));/* a stab value, be nice */
str = tmpstr;
tmps = str->str_ptr;
putc('*',fp);
@@ -1072,7 +1111,7 @@ STR *str;
return laststatval;
if (dowarn)
warn("Stat on unopened file <%s>",
- stab_name(arg[1].arg_ptr.arg_stab));
+ stab_ename(arg[1].arg_ptr.arg_stab));
statstab = Nullstab;
str_set(statname,"");
return (laststatval = -1);
@@ -1082,7 +1121,10 @@ STR *str;
statstab = Nullstab;
str_set(statname,str_get(str));
laststype = O_STAT;
- return (laststatval = stat(str_get(str),&statcache));
+ laststatval = stat(str_get(str),&statcache);
+ if (laststatval < 0 && dowarn && index(str_get(str), '\n'))
+ warn(warn_nl, "stat");
+ return laststatval;
}
}
@@ -1104,10 +1146,13 @@ STR *str;
statstab = Nullstab;
str_set(statname,str_get(str));
#ifdef HAS_LSTAT
- return (laststatval = lstat(str_get(str),&statcache));
+ laststatval = lstat(str_get(str),&statcache);
#else
- return (laststatval = stat(str_get(str),&statcache));
+ laststatval = stat(str_get(str),&statcache);
#endif
+ if (laststatval < 0 && dowarn && index(str_get(str), '\n'))
+ warn(warn_nl, "lstat");
+ return laststatval;
}
STR *
@@ -1137,7 +1182,7 @@ STR *str;
stio = stab_io(statstab);
}
if (stio && stio->ifp) {
-#ifdef STDSTDIO
+#if defined(STDSTDIO) || defined(atarist) /* this will work with atariST */
fstat(fileno(stio->ifp),&statcache);
if (S_ISDIR(statcache.st_mode)) /* handle NFS glitch */
return arg->arg_type == O_FTTEXT ? &str_no : &str_yes;
@@ -1157,7 +1202,7 @@ STR *str;
else {
if (dowarn)
warn("Test on unopened file <%s>",
- stab_name(arg[1].arg_ptr.arg_stab));
+ stab_ename(arg[1].arg_ptr.arg_stab));
errno = EBADF;
return &str_undef;
}
@@ -1167,8 +1212,11 @@ STR *str;
str_set(statname,str_get(str));
really_filename:
i = open(str_get(str),0);
- if (i < 0)
+ if (i < 0) {
+ if (dowarn && index(str_get(str), '\n'))
+ warn(warn_nl, "open");
return &str_undef;
+ }
fstat(i,&statcache);
len = read(i,tbuf,512);
(void)close(i);
@@ -1201,6 +1249,9 @@ STR *str;
return &str_yes;
}
+static char **Argv = Null(char **);
+static char *Cmd = Nullch;
+
bool
do_aexec(really,arglast)
STR *really;
@@ -1210,12 +1261,11 @@ int *arglast;
register int sp = arglast[1];
register int items = arglast[2] - sp;
register char **a;
- char **argv;
char *tmps;
if (items) {
- New(401,argv, items+1, char*);
- a = argv;
+ New(401,Argv, items+1, char*);
+ a = Argv;
for (st += ++sp; items > 0; items--,st++) {
if (*st)
*a++ = str_get(*st);
@@ -1224,21 +1274,18 @@ int *arglast;
}
*a = Nullch;
#ifdef TAINT
- if (*argv[0] != '/') /* will execvp use PATH? */
+ if (*Argv[0] != '/') /* will execvp use PATH? */
taintenv(); /* testing IFS here is overkill, probably */
#endif
if (really && *(tmps = str_get(really)))
- execvp(tmps,argv);
+ execvp(tmps,Argv);
else
- execvp(argv[0],argv);
- Safefree(argv);
+ execvp(Argv[0],Argv);
}
+ do_execfree();
return FALSE;
}
-static char **Argv = Null(char **);
-static char *Cmd = Nullch;
-
void
do_execfree()
{
@@ -1551,8 +1598,8 @@ int *arglast;
register int sp = arglast[1];
register STIO *stio;
int fd;
- int lvl;
- int optname;
+ unsigned int lvl;
+ unsigned int optname;
if (!stab)
goto nuts;
@@ -1562,14 +1609,15 @@ int *arglast;
goto nuts;
fd = fileno(stio->ifp);
- lvl = (int)str_gnum(st[sp+1]);
- optname = (int)str_gnum(st[sp+2]);
+ lvl = (unsigned int)str_gnum(st[sp+1]);
+ optname = (unsigned int)str_gnum(st[sp+2]);
switch (optype) {
case O_GSOCKOPT:
st[sp] = str_2mortal(Str_new(22,257));
st[sp]->str_cur = 256;
st[sp]->str_pok = 1;
- if (getsockopt(fd, lvl, optname, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
+ if (getsockopt(fd, lvl, optname, st[sp]->str_ptr,
+ (int*)&st[sp]->str_cur) < 0)
goto nuts;
break;
case O_SSOCKOPT:
@@ -1615,11 +1663,11 @@ int *arglast;
fd = fileno(stio->ifp);
switch (optype) {
case O_GETSOCKNAME:
- if (getsockname(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
+ if (getsockname(fd, st[sp]->str_ptr, (int*)&st[sp]->str_cur) < 0)
goto nuts2;
break;
case O_GETPEERNAME:
- if (getpeername(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
+ if (getpeername(fd, st[sp]->str_ptr, (int*)&st[sp]->str_cur) < 0)
goto nuts2;
break;
}
@@ -1654,11 +1702,6 @@ int *arglast;
struct hostent *hent;
unsigned long len;
- if (gimme != G_ARRAY) {
- astore(ary, ++sp, str_mortal(&str_undef));
- return sp;
- }
-
if (which == O_GHBYNAME) {
char *name = str_get(ary->ary_array[sp+1]);
@@ -1677,6 +1720,28 @@ int *arglast;
#else
fatal("gethostent not implemented");
#endif
+
+#ifdef HOST_NOT_FOUND
+ if (!hent)
+ statusvalue = (unsigned short)h_errno & 0xffff;
+#endif
+
+ if (gimme != G_ARRAY) {
+ astore(ary, ++sp, str = str_mortal(&str_undef));
+ if (hent) {
+ if (which == O_GHBYNAME) {
+#ifdef h_addr
+ str_nset(str, *hent->h_addr, hent->h_length);
+#else
+ str_nset(str, hent->h_addr, hent->h_length);
+#endif
+ }
+ else
+ str_set(str, hent->h_name);
+ }
+ return sp;
+ }
+
if (hent) {
#ifndef lint
(void)astore(ary, ++sp, str = str_mortal(&str_no));
@@ -1726,11 +1791,6 @@ int *arglast;
struct netent *getnetent();
struct netent *nent;
- if (gimme != G_ARRAY) {
- astore(ary, ++sp, str_mortal(&str_undef));
- return sp;
- }
-
if (which == O_GNBYNAME) {
char *name = str_get(ary->ary_array[sp+1]);
@@ -1745,6 +1805,17 @@ int *arglast;
else
nent = getnetent();
+ if (gimme != G_ARRAY) {
+ astore(ary, ++sp, str = str_mortal(&str_undef));
+ if (nent) {
+ if (which == O_GNBYNAME)
+ str_numset(str, (double)nent->n_net);
+ else
+ str_set(str, nent->n_name);
+ }
+ return sp;
+ }
+
if (nent) {
#ifndef lint
(void)astore(ary, ++sp, str = str_mortal(&str_no));
@@ -1784,11 +1855,6 @@ int *arglast;
struct protoent *getprotoent();
struct protoent *pent;
- if (gimme != G_ARRAY) {
- astore(ary, ++sp, str_mortal(&str_undef));
- return sp;
- }
-
if (which == O_GPBYNAME) {
char *name = str_get(ary->ary_array[sp+1]);
@@ -1802,6 +1868,17 @@ int *arglast;
else
pent = getprotoent();
+ if (gimme != G_ARRAY) {
+ astore(ary, ++sp, str = str_mortal(&str_undef));
+ if (pent) {
+ if (which == O_GPBYNAME)
+ str_numset(str, (double)pent->p_proto);
+ else
+ str_set(str, pent->p_name);
+ }
+ return sp;
+ }
+
if (pent) {
#ifndef lint
(void)astore(ary, ++sp, str = str_mortal(&str_no));
@@ -1839,11 +1916,6 @@ int *arglast;
struct servent *getservent();
struct servent *sent;
- if (gimme != G_ARRAY) {
- astore(ary, ++sp, str_mortal(&str_undef));
- return sp;
- }
-
if (which == O_GSBYNAME) {
char *name = str_get(ary->ary_array[sp+1]);
char *proto = str_get(ary->ary_array[sp+2]);
@@ -1861,6 +1933,23 @@ int *arglast;
}
else
sent = getservent();
+
+ if (gimme != G_ARRAY) {
+ astore(ary, ++sp, str = str_mortal(&str_undef));
+ if (sent) {
+ if (which == O_GSBYNAME) {
+#ifdef HAS_NTOHS
+ str_numset(str, (double)ntohs(sent->s_port));
+#else
+ str_numset(str, (double)(sent->s_port));
+#endif
+ }
+ else
+ str_set(str, sent->s_name);
+ }
+ return sp;
+ }
+
if (sent) {
#ifndef lint
(void)astore(ary, ++sp, str = str_mortal(&str_no));
@@ -2007,6 +2096,7 @@ int *arglast;
for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
s[(k % masksize) + offset] = fd_sets[i][j+offset];
}
+ Safefree(fd_sets[i]);
}
}
#endif
@@ -2098,11 +2188,6 @@ int *arglast;
struct passwd *getpwent();
struct passwd *pwent;
- if (gimme != G_ARRAY) {
- astore(ary, ++sp, str_mortal(&str_undef));
- return sp;
- }
-
if (which == O_GPWNAM) {
char *name = str_get(ary->ary_array[sp+1]);
@@ -2116,6 +2201,17 @@ int *arglast;
else
pwent = getpwent();
+ if (gimme != G_ARRAY) {
+ astore(ary, ++sp, str = str_mortal(&str_undef));
+ if (pwent) {
+ if (which == O_GPWNAM)
+ str_numset(str, (double)pwent->pw_uid);
+ else
+ str_set(str, pwent->pw_name);
+ }
+ return sp;
+ }
+
if (pwent) {
(void)astore(ary, ++sp, str = str_mortal(&str_no));
str_set(str, pwent->pw_name);
@@ -2179,11 +2275,6 @@ int *arglast;
struct group *getgrent();
struct group *grent;
- if (gimme != G_ARRAY) {
- astore(ary, ++sp, str_mortal(&str_undef));
- return sp;
- }
-
if (which == O_GGRNAM) {
char *name = str_get(ary->ary_array[sp+1]);
@@ -2197,6 +2288,17 @@ int *arglast;
else
grent = getgrent();
+ if (gimme != G_ARRAY) {
+ astore(ary, ++sp, str = str_mortal(&str_undef));
+ if (grent) {
+ if (which == O_GGRNAM)
+ str_numset(str, (double)grent->gr_gid);
+ else
+ str_set(str, grent->gr_name);
+ }
+ return sp;
+ }
+
if (grent) {
(void)astore(ary, ++sp, str = str_mortal(&str_no));
str_set(str, grent->gr_name);
@@ -2231,9 +2333,6 @@ int *arglast;
register int sp = arglast[1];
register STIO *stio;
long along;
-#ifndef telldir
- long telldir();
-#endif
#ifndef apollo
struct DIRENT *readdir();
#endif
@@ -2278,30 +2377,36 @@ int *arglast;
#endif
}
break;
-#if MACH
- case O_TELLDIR:
- case O_SEEKDIR:
- goto nope;
-#else
- case O_TELLDIR:
- st[sp] = str_mortal(&str_undef);
- str_numset(st[sp], (double)telldir(stio->dirp));
- break;
+#if defined(HAS_TELLDIR) || defined(telldir)
+ case O_TELLDIR: {
+#ifndef telldir
+ long telldir();
+#endif
+ st[sp] = str_mortal(&str_undef);
+ str_numset(st[sp], (double)telldir(stio->dirp));
+ break;
+ }
+#endif
+#if defined(HAS_SEEKDIR) || defined(seekdir)
case O_SEEKDIR:
st[sp] = str_mortal(&str_undef);
along = (long)str_gnum(st[sp+1]);
(void)seekdir(stio->dirp,along);
break;
#endif
+#if defined(HAS_REWINDDIR) || defined(rewinddir)
case O_REWINDDIR:
st[sp] = str_mortal(&str_undef);
(void)rewinddir(stio->dirp);
break;
+#endif
case O_CLOSEDIR:
st[sp] = str_mortal(&str_undef);
(void)closedir(stio->dirp);
stio->dirp = 0;
break;
+ default:
+ goto phooey;
}
return sp;
@@ -2311,11 +2416,12 @@ nope:
errno = EBADF;
return sp;
-#else
- fatal("Unimplemented directory operation");
#endif
+phooey:
+ fatal("Unimplemented directory operation");
}
+int
apply(type,arglast)
int type;
int *arglast;
@@ -2469,7 +2575,7 @@ int bit;
int effective;
register struct stat *statbufp;
{
-#ifdef MSDOS
+#ifdef DOSISH
/* [Comments and code from Len Reed]
* MS-DOS "user" is similar to UNIX's "superuser," but can't write
* to write-protected files. The execute permission bit is set
@@ -2488,6 +2594,9 @@ register struct stat *statbufp;
* Sun's PC-NFS.]
*/
+ /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat
+ * too so it will actually look into the files for magic numbers
+ */
return (bit & statbufp->st_mode) ? TRUE : FALSE;
#else /* ! MSDOS */
@@ -2658,7 +2767,7 @@ int *arglast;
{
#ifdef HAS_MSG
case O_MSGCTL:
- ret = msgctl(id, cmd, a);
+ ret = msgctl(id, cmd, (struct msqid_ds *)a);
break;
#endif
#ifdef HAS_SEM
@@ -2668,7 +2777,7 @@ int *arglast;
#endif
#ifdef HAS_SHM
case O_SHMCTL:
- ret = shmctl(id, cmd, a);
+ ret = shmctl(id, cmd, (struct shmid_ds *)a);
break;
#endif
}
@@ -2699,7 +2808,7 @@ int *arglast;
return -1;
}
errno = 0;
- return msgsnd(id, mbuf, msize, flags);
+ return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
#else
fatal("msgsnd not implemented");
#endif
@@ -2728,7 +2837,7 @@ int *arglast;
mbuf = str_get(mstr);
}
errno = 0;
- ret = msgrcv(id, mbuf, msize, mtype, flags);
+ ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);
if (ret >= 0) {
mstr->str_cur = sizeof(long)+ret;
mstr->str_ptr[sizeof(long)+ret] = '\0';
@@ -2802,7 +2911,7 @@ int *arglast;
STR_GROW(mstr, msize+1);
mbuf = str_get(mstr);
}
- bcopy(shm + mpos, mbuf, msize);
+ Copy(shm + mpos, mbuf, msize, char);
mstr->str_cur = msize;
mstr->str_ptr[msize] = '\0';
}
@@ -2811,9 +2920,9 @@ int *arglast;
if ((n = mstr->str_cur) > msize)
n = msize;
- bcopy(mbuf, shm + mpos, n);
+ Copy(mbuf, shm + mpos, n, char);
if (n < msize)
- bzero(shm + mpos + n, msize - n);
+ memzero(shm + mpos + n, msize - n);
}
return shmdt(shm);
#else