-/* $Header: util.c,v 3.0.1.11 91/01/11 18:33:10 lwall Locked $
+/* $RCSfile: util.c,v $$Revision: 4.0.1.2 $$Date: 91/06/07 12:10:42 $
*
- * Copyright (c) 1989, Larry Wall
+ * Copyright (c) 1991, Larry Wall
*
- * You may distribute under the terms of the GNU General Public License
- * as specified in the README file that comes with the perl 3.0 kit.
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
*
* $Log: util.c,v $
- * Revision 3.0.1.11 91/01/11 18:33:10 lwall
- * patch42: die could exit with 0 value on some machines
- * patch42: Configure checks typecasting behavior better
+ * Revision 4.0.1.2 91/06/07 12:10:42 lwall
+ * patch4: new copyright notice
+ * patch4: made some allowances for "semi-standard" C
+ * patch4: index() could blow up searching for null string
+ * patch4: taintchecks could improperly modify parent in vfork()
+ * patch4: exec would close files even if you cleared close-on-exec flag
*
- * Revision 3.0.1.10 90/11/10 02:19:28 lwall
- * patch38: random cleanup
- * patch38: sequence of s/^x//; s/x$//; could screw up malloc
+ * Revision 4.0.1.1 91/04/12 09:19:25 lwall
+ * patch1: random cleanup in cpp namespace
*
- * Revision 3.0.1.9 90/10/20 02:21:01 lwall
- * patch37: tried to take strlen of integer on systems without wait4 or waitpid
- * patch37: unreachable return eliminated
- *
- * Revision 3.0.1.8 90/10/16 11:26:57 lwall
- * patch29: added waitpid
- * patch29: various portability fixes
- * patch29: scripts now run at almost full speed under the debugger
- *
- * Revision 3.0.1.7 90/08/13 22:40:26 lwall
- * patch28: the NSIG hack didn't work right on Xenix
- * patch28: rename was busted on systems without rename system call
- *
- * Revision 3.0.1.6 90/08/09 05:44:55 lwall
- * patch19: fixed double include of <signal.h>
- * patch19: various MSDOS and OS/2 patches folded in
- * patch19: open(STDOUT,"|command") left wrong descriptor attached to STDOUT
- *
- * Revision 3.0.1.5 90/03/27 16:35:13 lwall
- * patch16: MSDOS support
- * patch16: support for machines that can't cast negative floats to unsigned ints
- * patch16: tail anchored pattern could dump if string to search was shorter
- *
- * Revision 3.0.1.4 90/03/01 10:26:48 lwall
- * patch9: fbminstr() called instr() rather than ninstr()
- * patch9: nested evals clobbered their longjmp environment
- * patch9: piped opens returned undefined rather than 0 in child
- * patch9: the x operator is now up to 10 times faster
- *
- * Revision 3.0.1.3 89/12/21 20:27:41 lwall
- * patch7: errno may now be a macro with an lvalue
- *
- * Revision 3.0.1.2 89/11/17 15:46:35 lwall
- * patch5: BZERO separate from BCOPY now
- * patch5: byteorder now is a hex value
- *
- * Revision 3.0.1.1 89/11/11 05:06:13 lwall
- * patch2: made dup2 a little better
- *
- * Revision 3.0 89/10/18 15:32:43 lwall
- * 3.0 baseline
+ * Revision 4.0 91/03/20 01:56:39 lwall
+ * 4.0 baseline.
*
*/
# include <varargs.h>
#endif
+#ifdef I_FCNTL
+# include <fcntl.h>
+#endif
+#ifdef I_SYS_FILE
+# include <sys/file.h>
+#endif
+
#define FLUSH
static char nomem[] = "Out of memory!\n";
#endif /* MSDOS */
{
char *ptr;
+#ifndef STANDARD_C
char *malloc();
+#endif /* ! STANDARD_C */
#ifdef MSDOS
if (size > 0xffff) {
#endif /* MSDOS */
{
char *ptr;
+#ifndef STANDARD_C
char *realloc();
+#endif /* ! STANDARD_C */
#ifdef MSDOS
if (size > 0xffff) {
register unsigned char *oldlittle;
#ifndef lint
- if (!(littlestr->str_pok & SP_FBM))
+ if (!(littlestr->str_pok & SP_FBM)) {
+ if (!littlestr->str_ptr)
+ return (char*)big;
return ninstr((char*)big,(char*)bigend,
littlestr->str_ptr, littlestr->str_ptr + littlestr->str_cur);
+ }
#endif
littlelen = littlestr->str_cur;
}
}
-#ifndef VARARGS
+#ifndef I_VARARGS
/*VARARGS1*/
mess(pat,a1,a2,a3,a4)
char *pat;
{
char *pat;
char *s;
+#ifndef HAS_VPRINTF
#ifdef CHARVSPRINTF
char *vsprintf();
#else
int vsprintf();
#endif
+#endif
s = buf;
#ifdef lint
}
#endif
-static bool firstsetenv = TRUE;
-extern char **environ;
-
void
setenv(nam,val)
char *nam, *val;
{
register int i=envix(nam); /* where does it go? */
+ if (environ == origenviron) { /* need we copy environment? */
+ int j;
+ int max;
+ char **tmpenv;
+
+ for (max = i; environ[max]; max++) ;
+ New(901,tmpenv, max+2, char*);
+ for (j=0; j<max; j++) /* copy environment */
+ tmpenv[j] = savestr(environ[j]);
+ tmpenv[max] = Nullch;
+ environ = tmpenv; /* tell exec where it is now */
+ }
if (!val) {
while (environ[i]) {
environ[i] = environ[i+1];
return;
}
if (!environ[i]) { /* does not exist yet */
- if (firstsetenv) { /* need we copy environment? */
- int j;
- char **tmpenv;
-
- New(901,tmpenv, i+2, char*);
- firstsetenv = FALSE;
- for (j=0; j<i; j++) /* copy environment */
- tmpenv[j] = environ[j];
- environ = tmpenv; /* tell exec where it is now */
- }
- else
- Renew(environ, i+2, char*); /* just expand it a bit */
+ Renew(environ, i+2, char*); /* just expand it a bit */
environ[i+1] = Nullch; /* make sure it's null terminated */
}
+ else
+ Safefree(environ[i]);
New(904, environ[i], strlen(nam) + strlen(val) + 2, char);
- /* this may or may not be in */
- /* the old environ structure */
#ifndef MSDOS
(void)sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
#else
/* MS-DOS requires environment variable names to be in uppercase */
- strcpy(environ[i],nam); strupr(environ[i],nam);
+ /* [Tom Dinger, 27 August 1990: Well, it doesn't _require_ it, but
+ * some utilities and applications may break because they only look
+ * for upper case strings. (Fixed strupr() bug here.)]
+ */
+ strcpy(environ[i],nam); strupr(environ[i]);
(void)sprintf(environ[i] + strlen(nam),"=%s",val);
#endif /* MSDOS */
}
}
#endif
-#ifndef MEMCPY
-#ifndef BCOPY
+#ifndef HAS_MEMCPY
+#ifndef HAS_BCOPY
char *
bcopy(from,to,len)
register char *from;
}
#endif
-#ifndef BZERO
+#ifndef HAS_BZERO
char *
bzero(loc,len)
register char *loc;
#endif
#endif
-#ifdef VARARGS
-#ifndef VPRINTF
+#ifdef I_VARARGS
+#ifndef HAS_VPRINTF
#ifdef CHARVSPRINTF
char *
fakebuf._ptr = dest;
fakebuf._cnt = 32767;
+#ifndef _IOSTRG
+#define _IOSTRG 0
+#endif
fakebuf._flag = _IOWRT|_IOSTRG;
_doprnt(pat, args, &fakebuf); /* what a kludge */
(void)putc('\0', &fakebuf);
return 0; /* wrong, but perl doesn't use the return value */
}
#endif
-#endif /* VPRINTF */
-#endif /* VARARGS */
+#endif /* HAS_VPRINTF */
+#endif /* I_VARARGS */
#ifdef MYSWAP
#if BYTEORDER != 0x4321
}
#endif /* BYTEORDER != 0x4321 */
-#endif /* HTONS */
+#endif /* HAS_HTONS */
#ifndef MSDOS
FILE *
return Nullfp;
this = (*mode == 'w');
that = !this;
+#ifdef TAINT
+ if (doexec) {
+ taintenv();
+ taintproper("Insecure dependency in exec");
+ }
+#endif
while ((pid = (doexec?vfork():fork())) < 0) {
if (errno != EAGAIN) {
close(p[this]);
close(p[THIS]);
}
if (doexec) {
-#if !defined(FCNTL) || !defined(F_SETFD)
+#if !defined(HAS_FCNTL) || !defined(F_SETFD)
int fd;
#ifndef NOFILE
#define NOFILE 20
#endif
- for (fd = 3; fd < NOFILE; fd++)
+ for (fd = maxsysfd + 1; fd < NOFILE; fd++)
close(fd);
#endif
do_exec(cmd); /* may or may not use the shell */
if (tmpstab = stabent("$",allstabs))
str_numset(STAB_STR(tmpstab),(double)getpid());
forkprocess = 0;
- hclear(pidstatus); /* we have no children */
+ hclear(pidstatus, FALSE); /* we have no children */
return Nullfp;
#undef THIS
#undef THAT
}
#endif
-#ifndef DUP2
+#ifndef HAS_DUP2
dup2(oldfd,newfd)
int oldfd;
int newfd;
{
-#if defined(FCNTL) && defined(F_DUPFD)
+#if defined(HAS_FCNTL) && defined(F_DUPFD)
close(newfd);
fcntl(oldfd, F_DUPFD, newfd);
#else
- int fdtmp[20];
+ int fdtmp[256];
int fdx = 0;
int fd;
+ if (oldfd == newfd)
+ return 0;
close(newfd);
while ((fd = dup(oldfd)) != newfd) /* good enough for low fd's */
fdtmp[fdx++] = fd;
if (!pid)
return -1;
-#ifdef WAIT4
- return wait4(pid,statusp,flags,Null(struct rusage *));
+#ifdef HAS_WAIT4
+ return wait4((pid==-1)?0:pid,statusp,flags,Null(struct rusage *));
#else
-#ifdef WAITPID
+#ifdef HAS_WAITPID
return waitpid(pid,statusp,flags);
#else
if (pid > 0) {
if (flags)
fatal("Can't do waitpid with flags");
else {
- register int count;
- register STR *str;
-
while ((result = wait(statusp)) != pid && pid > 0 && result >= 0)
pidgone(result,*statusp);
if (result < 0)
#endif
#endif
}
-#endif /* !MSDOS */
pidgone(pid,status)
int pid;
int status;
{
-#if defined(WAIT4) || defined(WAITPID)
+#if defined(HAS_WAIT4) || defined(HAS_WAITPID)
#else
register STR *str;
char spid[16];
#endif
return;
}
+#endif /* !MSDOS */
-#ifndef MEMCMP
+#ifndef HAS_MEMCMP
memcmp(s1,s2,len)
register unsigned char *s1;
register unsigned char *s2;
}
return 0;
}
-#endif /* MEMCMP */
+#endif /* HAS_MEMCMP */
void
repeatcpy(to,from,len,count)
}
#endif
-#ifndef RENAME
+#ifndef HAS_RENAME
int
same_dirent(a,b)
char *a;
return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev &&
tmpstatbuf1.st_ino == tmpstatbuf2.st_ino;
}
-#endif /* !RENAME */
+#endif /* !HAS_RENAME */
+
+unsigned long
+scanoct(start, len, retlen)
+char *start;
+int len;
+int *retlen;
+{
+ register char *s = start;
+ register unsigned long retval = 0;
+
+ while (len-- && *s >= '0' && *s <= '7') {
+ retval <<= 3;
+ retval |= *s++ - '0';
+ }
+ *retlen = s - start;
+ return retval;
+}
+
+unsigned long
+scanhex(start, len, retlen)
+char *start;
+int len;
+int *retlen;
+{
+ register char *s = start;
+ register unsigned long retval = 0;
+ char *tmp;
+
+ while (len-- && *s && (tmp = index(hexdigit, *s))) {
+ retval <<= 4;
+ retval |= (tmp - hexdigit) & 15;
+ s++;
+ }
+ *retlen = s - start;
+ return retval;
+}