1 /* $Header: util.c,v 4.0 91/03/20 01:56:39 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 4.0 91/03/20 01:56:39 lwall
17 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
33 # include <sys/file.h>
38 static char nomem[] = "Out of memory!\n";
40 /* paranoid version of malloc */
46 /* NOTE: Do not call the next three routines directly. Use the macros
47 * in handy.h, so that we can easily redefine everything to do tracking of
48 * allocated hunks back to the original New to track down any memory leaks.
62 #endif /* ! __STDC__ */
66 fprintf(stderr, "Allocation too large: %lx\n", size) FLUSH;
72 fatal("panic: malloc");
74 ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */
78 fprintf(stderr,"0x%x: (%05d) malloc %d bytes\n",ptr,an++,size);
81 fprintf(stderr,"0x%lx: (%05d) malloc %d bytes\n",ptr,an++,size);
87 fputs(nomem,stderr) FLUSH;
96 /* paranoid version of realloc */
99 saferealloc(where,size)
110 #endif /* ! __STDC__ */
114 fprintf(stderr, "Reallocation too large: %lx\n", size) FLUSH;
119 fatal("Null realloc");
122 fatal("panic: realloc");
124 ptr = realloc(where,size?size:1); /* realloc(0) is NASTY on our system */
128 fprintf(stderr,"0x%x: (%05d) rfree\n",where,an++);
129 fprintf(stderr,"0x%x: (%05d) realloc %d bytes\n",ptr,an++,size);
133 fprintf(stderr,"0x%lx: (%05d) rfree\n",where,an++);
134 fprintf(stderr,"0x%lx: (%05d) realloc %d bytes\n",ptr,an++,size);
141 fputs(nomem,stderr) FLUSH;
150 /* safe version of free */
159 fprintf(stderr,"0x%x: (%05d) free\n",where,an++);
162 fprintf(stderr,"0x%lx: (%05d) free\n",where,an++);
172 #define ALIGN sizeof(long)
179 register char *where;
181 where = safemalloc(size + ALIGN);
185 return where + ALIGN;
189 safexrealloc(where,size)
193 return saferealloc(where - ALIGN, size + ALIGN) + ALIGN;
205 x = where[0] + 100 * where[1];
214 for (i = 0; i < MAXXCOUNT; i++) {
215 if (xcount[i] != lastxcount[i]) {
216 fprintf(stderr,"%2d %2d\t%ld\n", i / 100, i % 100, xcount[i]);
217 lastxcount[i] = xcount[i];
222 #endif /* LEAKTEST */
224 /* copy a string up to some (non-backslashed) delimiter, if any */
227 cpytill(to,from,fromend,delim,retlen)
230 register char *fromend;
236 for (; from < fromend; from++,to++) {
238 if (from[1] == delim)
240 else if (from[1] == '\\')
243 else if (*from == delim)
248 *retlen = to - origto;
252 /* return ptr to little string in big string, NULL if not found */
253 /* This routine was donated by Corey Satten. */
258 register char *little;
260 register char *s, *x;
271 for (x=big,s=little; *s; /**/ ) {
285 /* same as instr but allow embedded nulls */
288 ninstr(big, bigend, little, lend)
290 register char *bigend;
294 register char *s, *x;
295 register int first = *little;
296 register char *littleend = lend;
298 if (!first && little > littleend)
300 bigend -= littleend - little++;
301 while (big <= bigend) {
304 for (x=big,s=little; s < littleend; /**/ ) {
316 /* reverse of the above--find last substring */
319 rninstr(big, bigend, little, lend)
325 register char *bigbeg;
326 register char *s, *x;
327 register int first = *little;
328 register char *littleend = lend;
330 if (!first && little > littleend)
333 big = bigend - (littleend - little++);
334 while (big >= bigbeg) {
337 for (x=big+2,s=little; s < littleend; /**/ ) {
349 unsigned char fold[] = {
350 0, 1, 2, 3, 4, 5, 6, 7,
351 8, 9, 10, 11, 12, 13, 14, 15,
352 16, 17, 18, 19, 20, 21, 22, 23,
353 24, 25, 26, 27, 28, 29, 30, 31,
354 32, 33, 34, 35, 36, 37, 38, 39,
355 40, 41, 42, 43, 44, 45, 46, 47,
356 48, 49, 50, 51, 52, 53, 54, 55,
357 56, 57, 58, 59, 60, 61, 62, 63,
358 64, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
359 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
360 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
361 'x', 'y', 'z', 91, 92, 93, 94, 95,
362 96, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
363 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
364 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
365 'X', 'Y', 'Z', 123, 124, 125, 126, 127,
366 128, 129, 130, 131, 132, 133, 134, 135,
367 136, 137, 138, 139, 140, 141, 142, 143,
368 144, 145, 146, 147, 148, 149, 150, 151,
369 152, 153, 154, 155, 156, 157, 158, 159,
370 160, 161, 162, 163, 164, 165, 166, 167,
371 168, 169, 170, 171, 172, 173, 174, 175,
372 176, 177, 178, 179, 180, 181, 182, 183,
373 184, 185, 186, 187, 188, 189, 190, 191,
374 192, 193, 194, 195, 196, 197, 198, 199,
375 200, 201, 202, 203, 204, 205, 206, 207,
376 208, 209, 210, 211, 212, 213, 214, 215,
377 216, 217, 218, 219, 220, 221, 222, 223,
378 224, 225, 226, 227, 228, 229, 230, 231,
379 232, 233, 234, 235, 236, 237, 238, 239,
380 240, 241, 242, 243, 244, 245, 246, 247,
381 248, 249, 250, 251, 252, 253, 254, 255
384 static unsigned char freq[] = {
385 1, 2, 84, 151, 154, 155, 156, 157,
386 165, 246, 250, 3, 158, 7, 18, 29,
387 40, 51, 62, 73, 85, 96, 107, 118,
388 129, 140, 147, 148, 149, 150, 152, 153,
389 255, 182, 224, 205, 174, 176, 180, 217,
390 233, 232, 236, 187, 235, 228, 234, 226,
391 222, 219, 211, 195, 188, 193, 185, 184,
392 191, 183, 201, 229, 181, 220, 194, 162,
393 163, 208, 186, 202, 200, 218, 198, 179,
394 178, 214, 166, 170, 207, 199, 209, 206,
395 204, 160, 212, 216, 215, 192, 175, 173,
396 243, 172, 161, 190, 203, 189, 164, 230,
397 167, 248, 227, 244, 242, 255, 241, 231,
398 240, 253, 169, 210, 245, 237, 249, 247,
399 239, 168, 252, 251, 254, 238, 223, 221,
400 213, 225, 177, 197, 171, 196, 159, 4,
401 5, 6, 8, 9, 10, 11, 12, 13,
402 14, 15, 16, 17, 19, 20, 21, 22,
403 23, 24, 25, 26, 27, 28, 30, 31,
404 32, 33, 34, 35, 36, 37, 38, 39,
405 41, 42, 43, 44, 45, 46, 47, 48,
406 49, 50, 52, 53, 54, 55, 56, 57,
407 58, 59, 60, 61, 63, 64, 65, 66,
408 67, 68, 69, 70, 71, 72, 74, 75,
409 76, 77, 78, 79, 80, 81, 82, 83,
410 86, 87, 88, 89, 90, 91, 92, 93,
411 94, 95, 97, 98, 99, 100, 101, 102,
412 103, 104, 105, 106, 108, 109, 110, 111,
413 112, 113, 114, 115, 116, 117, 119, 120,
414 121, 122, 123, 124, 125, 126, 127, 128,
415 130, 131, 132, 133, 134, 135, 136, 137,
416 138, 139, 141, 142, 143, 144, 145, 146
420 fbmcompile(str, iflag)
424 register unsigned char *s;
425 register unsigned char *table;
427 register int len = str->str_cur;
429 unsigned int frequency = 256;
431 Str_Grow(str,len+258);
433 table = (unsigned char*)(str->str_ptr + len + 1);
435 table = Null(unsigned char*);
438 for (i = 0; i < 256; i++) {
443 while (s >= (unsigned char*)(str->str_ptr))
446 if (table[*s] == len) {
449 table[*s] = table[fold[*s]] = i;
463 str->str_pok |= SP_FBM; /* deep magic */
466 s = (unsigned char*)(str->str_ptr); /* deeper magic */
468 s = Null(unsigned char*);
471 register unsigned int tmp, foldtmp;
472 str->str_pok |= SP_CASEFOLD;
473 for (i = 0; i < len; i++) {
475 foldtmp=freq[fold[s[i]]];
476 if (tmp < frequency && foldtmp < frequency) {
478 /* choose most frequent among the two */
479 frequency = (tmp > foldtmp) ? tmp : foldtmp;
484 for (i = 0; i < len; i++) {
485 if (freq[s[i]] < frequency) {
487 frequency = freq[s[i]];
491 str->str_rare = s[rarest];
492 str->str_state = rarest;
495 fprintf(stderr,"rarest char %c at %d\n",str->str_rare, str->str_state);
500 fbminstr(big, bigend, littlestr)
502 register unsigned char *bigend;
505 register unsigned char *s;
507 register int littlelen;
508 register unsigned char *little;
509 register unsigned char *table;
510 register unsigned char *olds;
511 register unsigned char *oldlittle;
514 if (!(littlestr->str_pok & SP_FBM))
515 return ninstr((char*)big,(char*)bigend,
516 littlestr->str_ptr, littlestr->str_ptr + littlestr->str_cur);
519 littlelen = littlestr->str_cur;
521 if (littlestr->str_pok & SP_TAIL && !multiline) { /* tail anchored? */
522 if (littlelen > bigend - big)
524 little = (unsigned char*)littlestr->str_ptr;
525 if (littlestr->str_pok & SP_CASEFOLD) { /* oops, fake it */
526 big = bigend - littlelen; /* just start near end */
527 if (bigend[-1] == '\n' && little[littlelen-1] != '\n')
531 s = bigend - littlelen;
532 if (*s == *little && bcmp(s,little,littlelen)==0)
533 return (char*)s; /* how sweet it is */
534 else if (bigend[-1] == '\n' && little[littlelen-1] != '\n'
537 if (*s == *little && bcmp(s,little,littlelen)==0)
543 table = (unsigned char*)(littlestr->str_ptr + littlelen + 1);
545 table = Null(unsigned char*);
547 if (--littlelen >= bigend - big)
550 oldlittle = little = table - 2;
551 if (littlestr->str_pok & SP_CASEFOLD) { /* case insensitive? */
554 if (tmp = table[*s]) {
556 if (bigend - s > tmp) {
561 if ((s += tmp) < bigend)
567 tmp = littlelen; /* less expensive than calling strncmp() */
570 if (*--s == *--little || fold[*s] == *little)
572 s = olds + 1; /* here we pay the price for failure */
574 if (s < bigend) /* fake up continue to outer loop */
587 if (tmp = table[*s]) {
589 if (bigend - s > tmp) {
594 if ((s += tmp) < bigend)
600 tmp = littlelen; /* less expensive than calling strncmp() */
603 if (*--s == *--little)
605 s = olds + 1; /* here we pay the price for failure */
607 if (s < bigend) /* fake up continue to outer loop */
621 screaminstr(bigstr, littlestr)
625 register unsigned char *s, *x;
626 register unsigned char *big;
628 register int previous;
630 register unsigned char *little;
631 register unsigned char *bigend;
632 register unsigned char *littleend;
634 if ((pos = screamfirst[littlestr->str_rare]) < 0)
637 little = (unsigned char *)(littlestr->str_ptr);
639 little = Null(unsigned char *);
641 littleend = little + littlestr->str_cur;
643 previous = littlestr->str_state;
645 big = (unsigned char *)(bigstr->str_ptr);
647 big = Null(unsigned char*);
649 bigend = big + bigstr->str_cur;
651 while (pos < previous) {
653 if (!(pos += screamnext[pos]))
657 if (littlestr->str_pok & SP_CASEFOLD) { /* case insignificant? */
659 if (big[pos] != first && big[pos] != fold[first])
661 for (x=big+pos+1,s=little; s < littleend; /**/ ) {
664 if (*s++ != *x++ && fold[*(s-1)] != *(x-1)) {
671 return (char *)(big+pos);
677 pos += screamnext[pos] /* does this goof up anywhere? */
685 if (big[pos] != first)
687 for (x=big+pos+1,s=little; s < littleend; /**/ ) {
697 return (char *)(big+pos);
703 pos += screamnext[pos]
712 /* copy a string to a safe spot */
718 register char *newaddr;
720 New(902,newaddr,strlen(str)+1,char);
721 (void)strcpy(newaddr,str);
725 /* same thing but with a known length */
732 register char *newaddr;
734 New(903,newaddr,len+1,char);
735 (void)bcopy(str,newaddr,len); /* might not be null terminated */
736 newaddr[len] = '\0'; /* is now */
740 /* grow a static string to at least a certain length */
743 growstr(strptr,curlen,newlen)
748 if (newlen > *curlen) { /* need more room? */
750 Renew(*strptr,newlen,char);
752 New(905,*strptr,newlen,char);
759 mess(pat,a1,a2,a3,a4)
766 (void)sprintf(s,pat,a1,a2,a3,a4);
769 if (curcmd->c_line) {
770 (void)sprintf(s," at %s line %ld",
771 stab_val(curcmd->c_filestab)->str_ptr, (long)curcmd->c_line);
775 stab_io(last_in_stab) &&
776 stab_io(last_in_stab)->lines ) {
777 (void)sprintf(s,", <%s> line %ld",
778 last_in_stab == argvstab ? "" : stab_name(last_in_stab),
779 (long)stab_io(last_in_stab)->lines);
782 (void)strcpy(s,".\n");
787 fatal(pat,a1,a2,a3,a4)
792 extern char *e_tmpname;
795 mess(pat,a1,a2,a3,a4);
797 str_set(stab_val(stabent("@",TRUE)),buf);
799 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
800 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
803 deb("(Skipping label #%d %s)\n",loop_ptr,
804 loop_stack[loop_ptr].loop_label);
811 deb("(Found label #%d %s)\n",loop_ptr,
812 loop_stack[loop_ptr].loop_label);
817 fatal("Bad label: %s", tmps);
819 longjmp(loop_stack[loop_ptr].loop_env, 1);
822 (void)fflush(stderr);
824 (void)UNLINK(e_tmpname);
826 exit((int)((errno&255)?errno:((statusvalue&255)?statusvalue:255)));
830 warn(pat,a1,a2,a3,a4)
834 mess(pat,a1,a2,a3,a4);
842 (void)fflush(stderr);
861 pat = va_arg(args, char *);
863 (void) vsprintf(s,pat,args);
867 if (curcmd->c_line) {
868 (void)sprintf(s," at %s line %ld",
869 stab_val(curcmd->c_filestab)->str_ptr, (long)curcmd->c_line);
873 stab_io(last_in_stab) &&
874 stab_io(last_in_stab)->lines ) {
875 (void)sprintf(s,", <%s> line %ld",
876 last_in_stab == argvstab ? "" : last_in_stab->str_magic->str_ptr,
877 (long)stab_io(last_in_stab)->lines);
880 (void)strcpy(s,".\n");
890 extern char *e_tmpname;
901 str_set(stab_val(stabent("@",TRUE)),buf);
903 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
904 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
907 deb("(Skipping label #%d %s)\n",loop_ptr,
908 loop_stack[loop_ptr].loop_label);
915 deb("(Found label #%d %s)\n",loop_ptr,
916 loop_stack[loop_ptr].loop_label);
921 fatal("Bad label: %s", tmps);
923 longjmp(loop_stack[loop_ptr].loop_env, 1);
926 (void)fflush(stderr);
928 (void)UNLINK(e_tmpname);
930 exit((int)((errno&255)?errno:((statusvalue&255)?statusvalue:255)));
954 (void)fflush(stderr);
959 extern char **environ;
966 register int i=envix(nam); /* where does it go? */
968 if (environ == origenviron) { /* need we copy environment? */
973 for (max = i; environ[max]; max++) ;
974 New(901,tmpenv, max+2, char*);
975 for (j=0; j<max; j++) /* copy environment */
976 tmpenv[j] = savestr(environ[j]);
977 tmpenv[max] = Nullch;
978 environ = tmpenv; /* tell exec where it is now */
982 environ[i] = environ[i+1];
987 if (!environ[i]) { /* does not exist yet */
988 Renew(environ, i+2, char*); /* just expand it a bit */
989 environ[i+1] = Nullch; /* make sure it's null terminated */
992 Safefree(environ[i]);
993 New(904, environ[i], strlen(nam) + strlen(val) + 2, char);
995 (void)sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
997 /* MS-DOS requires environment variable names to be in uppercase */
998 /* [Tom Dinger, 27 August 1990: Well, it doesn't _require_ it, but
999 * some utilities and applications may break because they only look
1000 * for upper case strings. (Fixed strupr() bug here.)]
1002 strcpy(environ[i],nam); strupr(environ[i]);
1003 (void)sprintf(environ[i] + strlen(nam),"=%s",val);
1011 register int i, len = strlen(nam);
1013 for (i = 0; environ[i]; i++) {
1014 if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
1015 break; /* strnEQ must come first to avoid */
1016 } /* potential SEGV's */
1021 unlnk(f) /* unlink all versions of a file */
1026 for (i = 0; unlink(f) >= 0; i++) ;
1035 register char *from;
1070 vsprintf(dest, pat, args)
1071 char *dest, *pat, *args;
1075 fakebuf._ptr = dest;
1076 fakebuf._cnt = 32767;
1077 fakebuf._flag = _IOWRT|_IOSTRG;
1078 _doprnt(pat, args, &fakebuf); /* what a kludge */
1079 (void)putc('\0', &fakebuf);
1083 return 0; /* perl doesn't use return value */
1089 vfprintf(fd, pat, args)
1093 _doprnt(pat, args, fd);
1094 return 0; /* wrong, but perl doesn't use the return value */
1097 #endif /* HAS_VPRINTF */
1098 #endif /* VARARGS */
1101 #if BYTEORDER != 0x4321
1106 #if (BYTEORDER & 1) == 0
1109 result = ((s & 255) << 8) + ((s >> 8) & 255);
1122 char c[sizeof(long)];
1125 #if BYTEORDER == 0x1234
1126 u.c[0] = (l >> 24) & 255;
1127 u.c[1] = (l >> 16) & 255;
1128 u.c[2] = (l >> 8) & 255;
1132 #if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
1133 fatal("Unknown BYTEORDER\n");
1138 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1139 u.c[o & 0xf] = (l >> s) & 255;
1152 char c[sizeof(long)];
1155 #if BYTEORDER == 0x1234
1156 u.c[0] = (l >> 24) & 255;
1157 u.c[1] = (l >> 16) & 255;
1158 u.c[2] = (l >> 8) & 255;
1162 #if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
1163 fatal("Unknown BYTEORDER\n");
1170 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1171 l |= (u.c[o & 0xf] & 255) << s;
1178 #endif /* BYTEORDER != 0x4321 */
1179 #endif /* HAS_HTONS */
1188 register int this, that;
1191 int doexec = strNE(cmd,"-");
1195 this = (*mode == 'w');
1197 while ((pid = (doexec?vfork():fork())) < 0) {
1198 if (errno != EAGAIN) {
1201 fatal("Can't fork");
1210 if (p[THIS] != (*mode == 'r')) {
1211 dup2(p[THIS], *mode == 'r');
1215 #if !defined(I_FCNTL) || !defined(F_SETFD)
1221 for (fd = 3; fd < NOFILE; fd++)
1224 do_exec(cmd); /* may or may not use the shell */
1227 if (tmpstab = stabent("$",allstabs))
1228 str_numset(STAB_STR(tmpstab),(double)getpid());
1230 hclear(pidstatus, FALSE); /* we have no children */
1235 do_execfree(); /* free any memory malloced by child on vfork */
1237 if (p[that] < p[this]) {
1238 dup2(p[this], p[that]);
1242 str = afetch(fdpid,p[this],TRUE);
1243 str->str_u.str_useful = pid;
1245 return fdopen(p[this], mode);
1254 struct stat tmpstatbuf;
1256 fprintf(stderr,"%s", s);
1257 for (fd = 0; fd < 32; fd++) {
1258 if (fstat(fd,&tmpstatbuf) >= 0)
1259 fprintf(stderr," %d",fd);
1261 fprintf(stderr,"\n");
1270 #if defined(HAS_FCNTL) && defined(F_DUPFD)
1272 fcntl(oldfd, F_DUPFD, newfd);
1281 while ((fd = dup(oldfd)) != newfd) /* good enough for low fd's */
1284 close(fdtmp[--fdx]);
1295 void (*hstat)(), (*istat)(), (*qstat)();
1297 int (*hstat)(), (*istat)(), (*qstat)();
1303 str = afetch(fdpid,fileno(ptr),TRUE);
1304 astore(fdpid,fileno(ptr),Nullstr);
1306 pid = (int)str->str_u.str_useful;
1307 hstat = signal(SIGHUP, SIG_IGN);
1308 istat = signal(SIGINT, SIG_IGN);
1309 qstat = signal(SIGQUIT, SIG_IGN);
1310 pid = wait4pid(pid, &status, 0);
1311 signal(SIGHUP, hstat);
1312 signal(SIGINT, istat);
1313 signal(SIGQUIT, qstat);
1314 return(pid < 0 ? pid : status);
1318 wait4pid(pid,statusp,flags)
1330 return wait4((pid==-1)?0:pid,statusp,flags,Null(struct rusage *));
1333 return waitpid(pid,statusp,flags);
1336 sprintf(spid, "%d", pid);
1337 str = hfetch(pidstatus,spid,strlen(spid),FALSE);
1338 if (str != &str_undef) {
1339 *statusp = (int)str->str_u.str_useful;
1340 hdelete(pidstatus,spid,strlen(spid));
1347 hiterinit(pidstatus);
1348 if (entry = hiternext(pidstatus)) {
1349 pid = atoi(hiterkey(entry,statusp));
1350 str = hiterval(entry);
1351 *statusp = (int)str->str_u.str_useful;
1352 sprintf(spid, "%d", pid);
1353 hdelete(pidstatus,spid,strlen(spid));
1358 fatal("Can't do waitpid with flags");
1360 while ((result = wait(statusp)) != pid && pid > 0 && result >= 0)
1361 pidgone(result,*statusp);
1374 #if defined(HAS_WAIT4) || defined(HAS_WAITPID)
1379 sprintf(spid, "%d", pid);
1380 str = hfetch(pidstatus,spid,strlen(spid),TRUE);
1381 str->str_u.str_useful = status;
1389 register unsigned char *s1;
1390 register unsigned char *s2;
1396 if (tmp = *s1++ - *s2++)
1401 #endif /* HAS_MEMCMP */
1404 repeatcpy(to,from,len,count)
1406 register char *from;
1411 register char *frombase = from;
1419 while (count-- > 0) {
1420 for (todo = len; todo > 0; todo--) {
1427 #ifndef CASTNEGFLOAT
1435 # define BIGDOUBLE 2147483648.0
1437 return (unsigned long)(f-(long)(f/BIGDOUBLE)*BIGDOUBLE)|0x80000000;
1440 return (unsigned long)f;
1442 return (unsigned long)along;
1452 char *fa = rindex(a,'/');
1453 char *fb = rindex(b,'/');
1454 struct stat tmpstatbuf1;
1455 struct stat tmpstatbuf2;
1457 #define MAXPATHLEN 1024
1459 char tmpbuf[MAXPATHLEN+1];
1474 strncpy(tmpbuf, a, fa - a);
1475 if (stat(tmpbuf, &tmpstatbuf1) < 0)
1480 strncpy(tmpbuf, b, fb - b);
1481 if (stat(tmpbuf, &tmpstatbuf2) < 0)
1483 return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev &&
1484 tmpstatbuf1.st_ino == tmpstatbuf2.st_ino;
1486 #endif /* !HAS_RENAME */
1489 scanoct(start, len, retlen)
1494 register char *s = start;
1495 register unsigned long retval = 0;
1497 while (len-- && *s >= '0' && *s <= '7') {
1499 retval |= *s++ - '0';
1501 *retlen = s - start;
1506 scanhex(start, len, retlen)
1511 register char *s = start;
1512 register unsigned long retval = 0;
1515 while (len-- && *s && (tmp = index(hexdigit, *s))) {
1517 retval |= (tmp - hexdigit) & 15;
1520 *retlen = s - start;