1 /* $Header: util.c,v 3.0.1.7 90/08/13 22:40:26 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 3.0.1.7 90/08/13 22:40:26 lwall
10 * patch28: the NSIG hack didn't work right on Xenix
11 * patch28: rename was busted on systems without rename system call
13 * Revision 3.0.1.6 90/08/09 05:44:55 lwall
14 * patch19: fixed double include of <signal.h>
15 * patch19: various MSDOS and OS/2 patches folded in
16 * patch19: open(STDOUT,"|command") left wrong descriptor attached to STDOUT
18 * Revision 3.0.1.5 90/03/27 16:35:13 lwall
19 * patch16: MSDOS support
20 * patch16: support for machines that can't cast negative floats to unsigned ints
21 * patch16: tail anchored pattern could dump if string to search was shorter
23 * Revision 3.0.1.4 90/03/01 10:26:48 lwall
24 * patch9: fbminstr() called instr() rather than ninstr()
25 * patch9: nested evals clobbered their longjmp environment
26 * patch9: piped opens returned undefined rather than 0 in child
27 * patch9: the x operator is now up to 10 times faster
29 * Revision 3.0.1.3 89/12/21 20:27:41 lwall
30 * patch7: errno may now be a macro with an lvalue
32 * Revision 3.0.1.2 89/11/17 15:46:35 lwall
33 * patch5: BZERO separate from BCOPY now
34 * patch5: byteorder now is a hex value
36 * Revision 3.0.1.1 89/11/11 05:06:13 lwall
37 * patch2: made dup2 a little better
39 * Revision 3.0 89/10/18 15:32:43 lwall
47 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
61 static char nomem[] = "Out of memory!\n";
63 /* paranoid version of malloc */
69 /* NOTE: Do not call the next three routines directly. Use the macros
70 * in handy.h, so that we can easily redefine everything to do tracking of
71 * allocated hunks back to the original New to track down any memory leaks.
87 fprintf(stderr, "Allocation too large: %lx\n", size) FLUSH;
91 ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */
95 fprintf(stderr,"0x%x: (%05d) malloc %d bytes\n",ptr,an++,size);
98 fprintf(stderr,"0x%lx: (%05d) malloc %d bytes\n",ptr,an++,size);
104 fputs(nomem,stdout) FLUSH;
113 /* paranoid version of realloc */
116 saferealloc(where,size)
129 fprintf(stderr, "Reallocation too large: %lx\n", size) FLUSH;
134 fatal("Null realloc");
135 ptr = realloc(where,size?size:1); /* realloc(0) is NASTY on our system */
139 fprintf(stderr,"0x%x: (%05d) rfree\n",where,an++);
140 fprintf(stderr,"0x%x: (%05d) realloc %d bytes\n",ptr,an++,size);
144 fprintf(stderr,"0x%lx: (%05d) rfree\n",where,an++);
145 fprintf(stderr,"0x%lx: (%05d) realloc %d bytes\n",ptr,an++,size);
152 fputs(nomem,stdout) FLUSH;
161 /* safe version of free */
170 fprintf(stderr,"0x%x: (%05d) free\n",where,an++);
173 fprintf(stderr,"0x%lx: (%05d) free\n",where,an++);
183 #define ALIGN sizeof(long)
190 register char *where;
192 where = safemalloc(size + ALIGN);
196 return where + ALIGN;
200 safexrealloc(where,size)
204 return saferealloc(where - ALIGN, size + ALIGN) + ALIGN;
216 x = where[0] + 100 * where[1];
225 for (i = 0; i < MAXXCOUNT; i++) {
226 if (xcount[i] != lastxcount[i]) {
227 fprintf(stderr,"%2d %2d\t%ld\n", i / 100, i % 100, xcount[i]);
228 lastxcount[i] = xcount[i];
233 #endif /* LEAKTEST */
235 /* copy a string up to some (non-backslashed) delimiter, if any */
238 cpytill(to,from,fromend,delim,retlen)
241 register char *fromend;
247 for (; from < fromend; from++,to++) {
249 if (from[1] == delim)
251 else if (from[1] == '\\')
254 else if (*from == delim)
259 *retlen = to - origto;
263 /* return ptr to little string in big string, NULL if not found */
264 /* This routine was donated by Corey Satten. */
269 register char *little;
271 register char *s, *x;
282 for (x=big,s=little; *s; /**/ ) {
296 /* same as instr but allow embedded nulls */
299 ninstr(big, bigend, little, lend)
301 register char *bigend;
305 register char *s, *x;
306 register int first = *little;
307 register char *littleend = lend;
309 if (!first && little > littleend)
311 bigend -= littleend - little++;
312 while (big <= bigend) {
315 for (x=big,s=little; s < littleend; /**/ ) {
327 /* reverse of the above--find last substring */
330 rninstr(big, bigend, little, lend)
336 register char *bigbeg;
337 register char *s, *x;
338 register int first = *little;
339 register char *littleend = lend;
341 if (!first && little > littleend)
344 big = bigend - (littleend - little++);
345 while (big >= bigbeg) {
348 for (x=big+2,s=little; s < littleend; /**/ ) {
360 unsigned char fold[] = {
361 0, 1, 2, 3, 4, 5, 6, 7,
362 8, 9, 10, 11, 12, 13, 14, 15,
363 16, 17, 18, 19, 20, 21, 22, 23,
364 24, 25, 26, 27, 28, 29, 30, 31,
365 32, 33, 34, 35, 36, 37, 38, 39,
366 40, 41, 42, 43, 44, 45, 46, 47,
367 48, 49, 50, 51, 52, 53, 54, 55,
368 56, 57, 58, 59, 60, 61, 62, 63,
369 64, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
370 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
371 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
372 'x', 'y', 'z', 91, 92, 93, 94, 95,
373 96, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
374 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
375 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
376 'X', 'Y', 'Z', 123, 124, 125, 126, 127,
377 128, 129, 130, 131, 132, 133, 134, 135,
378 136, 137, 138, 139, 140, 141, 142, 143,
379 144, 145, 146, 147, 148, 149, 150, 151,
380 152, 153, 154, 155, 156, 157, 158, 159,
381 160, 161, 162, 163, 164, 165, 166, 167,
382 168, 169, 170, 171, 172, 173, 174, 175,
383 176, 177, 178, 179, 180, 181, 182, 183,
384 184, 185, 186, 187, 188, 189, 190, 191,
385 192, 193, 194, 195, 196, 197, 198, 199,
386 200, 201, 202, 203, 204, 205, 206, 207,
387 208, 209, 210, 211, 212, 213, 214, 215,
388 216, 217, 218, 219, 220, 221, 222, 223,
389 224, 225, 226, 227, 228, 229, 230, 231,
390 232, 233, 234, 235, 236, 237, 238, 239,
391 240, 241, 242, 243, 244, 245, 246, 247,
392 248, 249, 250, 251, 252, 253, 254, 255
395 static unsigned char freq[] = {
396 1, 2, 84, 151, 154, 155, 156, 157,
397 165, 246, 250, 3, 158, 7, 18, 29,
398 40, 51, 62, 73, 85, 96, 107, 118,
399 129, 140, 147, 148, 149, 150, 152, 153,
400 255, 182, 224, 205, 174, 176, 180, 217,
401 233, 232, 236, 187, 235, 228, 234, 226,
402 222, 219, 211, 195, 188, 193, 185, 184,
403 191, 183, 201, 229, 181, 220, 194, 162,
404 163, 208, 186, 202, 200, 218, 198, 179,
405 178, 214, 166, 170, 207, 199, 209, 206,
406 204, 160, 212, 216, 215, 192, 175, 173,
407 243, 172, 161, 190, 203, 189, 164, 230,
408 167, 248, 227, 244, 242, 255, 241, 231,
409 240, 253, 169, 210, 245, 237, 249, 247,
410 239, 168, 252, 251, 254, 238, 223, 221,
411 213, 225, 177, 197, 171, 196, 159, 4,
412 5, 6, 8, 9, 10, 11, 12, 13,
413 14, 15, 16, 17, 19, 20, 21, 22,
414 23, 24, 25, 26, 27, 28, 30, 31,
415 32, 33, 34, 35, 36, 37, 38, 39,
416 41, 42, 43, 44, 45, 46, 47, 48,
417 49, 50, 52, 53, 54, 55, 56, 57,
418 58, 59, 60, 61, 63, 64, 65, 66,
419 67, 68, 69, 70, 71, 72, 74, 75,
420 76, 77, 78, 79, 80, 81, 82, 83,
421 86, 87, 88, 89, 90, 91, 92, 93,
422 94, 95, 97, 98, 99, 100, 101, 102,
423 103, 104, 105, 106, 108, 109, 110, 111,
424 112, 113, 114, 115, 116, 117, 119, 120,
425 121, 122, 123, 124, 125, 126, 127, 128,
426 130, 131, 132, 133, 134, 135, 136, 137,
427 138, 139, 141, 142, 143, 144, 145, 146
431 fbmcompile(str, iflag)
435 register unsigned char *s;
436 register unsigned char *table;
438 register int len = str->str_cur;
442 Str_Grow(str,len+258);
444 table = (unsigned char*)(str->str_ptr + len + 1);
446 table = Null(unsigned char*);
449 for (i = 0; i < 256; i++) {
454 while (s >= (unsigned char*)(str->str_ptr))
457 if (table[*s] == len) {
460 table[*s] = table[fold[*s]] = i;
474 str->str_pok |= SP_FBM; /* deep magic */
477 s = (unsigned char*)(str->str_ptr); /* deeper magic */
479 s = Null(unsigned char*);
482 register int tmp, foldtmp;
483 str->str_pok |= SP_CASEFOLD;
484 for (i = 0; i < len; i++) {
486 foldtmp=freq[fold[s[i]]];
487 if (tmp < frequency && foldtmp < frequency) {
489 /* choose most frequent among the two */
490 frequency = (tmp > foldtmp) ? tmp : foldtmp;
495 for (i = 0; i < len; i++) {
496 if (freq[s[i]] < frequency) {
498 frequency = freq[s[i]];
502 str->str_rare = s[rarest];
503 str->str_state = rarest;
506 fprintf(stderr,"rarest char %c at %d\n",str->str_rare, str->str_state);
511 fbminstr(big, bigend, littlestr)
513 register unsigned char *bigend;
516 register unsigned char *s;
518 register int littlelen;
519 register unsigned char *little;
520 register unsigned char *table;
521 register unsigned char *olds;
522 register unsigned char *oldlittle;
525 if (!(littlestr->str_pok & SP_FBM))
526 return ninstr((char*)big,(char*)bigend,
527 littlestr->str_ptr, littlestr->str_ptr + littlestr->str_cur);
530 littlelen = littlestr->str_cur;
532 if (littlestr->str_pok & SP_TAIL && !multiline) { /* tail anchored? */
533 if (littlelen > bigend - big)
535 little = (unsigned char*)littlestr->str_ptr;
536 if (littlestr->str_pok & SP_CASEFOLD) { /* oops, fake it */
537 big = bigend - littlelen; /* just start near end */
538 if (bigend[-1] == '\n' && little[littlelen-1] != '\n')
542 s = bigend - littlelen;
543 if (*s == *little && bcmp(s,little,littlelen)==0)
544 return (char*)s; /* how sweet it is */
545 else if (bigend[-1] == '\n' && little[littlelen-1] != '\n') {
547 if (*s == *little && bcmp(s,little,littlelen)==0)
553 table = (unsigned char*)(littlestr->str_ptr + littlelen + 1);
555 table = Null(unsigned char*);
557 if (--littlelen >= bigend - big)
560 oldlittle = little = table - 2;
561 if (littlestr->str_pok & SP_CASEFOLD) { /* case insensitive? */
564 if (tmp = table[*s]) {
566 if (bigend - s > tmp) {
571 if ((s += tmp) < bigend)
577 tmp = littlelen; /* less expensive than calling strncmp() */
580 if (*--s == *--little || fold[*s] == *little)
582 s = olds + 1; /* here we pay the price for failure */
584 if (s < bigend) /* fake up continue to outer loop */
597 if (tmp = table[*s]) {
599 if (bigend - s > tmp) {
604 if ((s += tmp) < bigend)
610 tmp = littlelen; /* less expensive than calling strncmp() */
613 if (*--s == *--little)
615 s = olds + 1; /* here we pay the price for failure */
617 if (s < bigend) /* fake up continue to outer loop */
631 screaminstr(bigstr, littlestr)
635 register unsigned char *s, *x;
636 register unsigned char *big;
638 register int previous;
640 register unsigned char *little;
641 register unsigned char *bigend;
642 register unsigned char *littleend;
644 if ((pos = screamfirst[littlestr->str_rare]) < 0)
647 little = (unsigned char *)(littlestr->str_ptr);
649 little = Null(unsigned char *);
651 littleend = little + littlestr->str_cur;
653 previous = littlestr->str_state;
655 big = (unsigned char *)(bigstr->str_ptr);
657 big = Null(unsigned char*);
659 bigend = big + bigstr->str_cur;
661 while (pos < previous) {
663 if (!(pos += screamnext[pos]))
667 if (littlestr->str_pok & SP_CASEFOLD) { /* case insignificant? */
669 if (big[pos] != first && big[pos] != fold[first])
671 for (x=big+pos+1,s=little; s < littleend; /**/ ) {
674 if (*s++ != *x++ && fold[*(s-1)] != *(x-1)) {
681 return (char *)(big+pos);
687 pos += screamnext[pos] /* does this goof up anywhere? */
695 if (big[pos] != first)
697 for (x=big+pos+1,s=little; s < littleend; /**/ ) {
707 return (char *)(big+pos);
713 pos += screamnext[pos]
722 /* copy a string to a safe spot */
728 register char *newaddr;
730 New(902,newaddr,strlen(str)+1,char);
731 (void)strcpy(newaddr,str);
735 /* same thing but with a known length */
742 register char *newaddr;
744 New(903,newaddr,len+1,char);
745 (void)bcopy(str,newaddr,len); /* might not be null terminated */
746 newaddr[len] = '\0'; /* is now */
750 /* grow a static string to at least a certain length */
753 growstr(strptr,curlen,newlen)
758 if (newlen > *curlen) { /* need more room? */
760 Renew(*strptr,newlen,char);
762 New(905,*strptr,newlen,char);
769 mess(pat,a1,a2,a3,a4)
776 (void)sprintf(s,pat,a1,a2,a3,a4);
779 if (curcmd->c_line) {
780 (void)sprintf(s," at %s line %ld", filename, (long)curcmd->c_line);
784 stab_io(last_in_stab) &&
785 stab_io(last_in_stab)->lines ) {
786 (void)sprintf(s,", <%s> line %ld",
787 last_in_stab == argvstab ? "" : stab_name(last_in_stab),
788 (long)stab_io(last_in_stab)->lines);
791 (void)strcpy(s,".\n");
796 fatal(pat,a1,a2,a3,a4)
801 extern char *e_tmpname;
804 mess(pat,a1,a2,a3,a4);
806 str_set(stab_val(stabent("@",TRUE)),buf);
808 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
809 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
812 deb("(Skipping label #%d %s)\n",loop_ptr,
813 loop_stack[loop_ptr].loop_label);
820 deb("(Found label #%d %s)\n",loop_ptr,
821 loop_stack[loop_ptr].loop_label);
826 fatal("Bad label: %s", tmps);
828 longjmp(loop_stack[loop_ptr].loop_env, 1);
831 (void)fflush(stderr);
833 (void)UNLINK(e_tmpname);
835 exit(errno?errno:(statusvalue?statusvalue:255));
839 warn(pat,a1,a2,a3,a4)
843 mess(pat,a1,a2,a3,a4);
851 (void)fflush(stderr);
870 pat = va_arg(args, char *);
872 (void) vsprintf(s,pat,args);
876 if (curcmd->c_line) {
877 (void)sprintf(s," at %s line %ld", filename, (long)curcmd->c_line);
881 stab_io(last_in_stab) &&
882 stab_io(last_in_stab)->lines ) {
883 (void)sprintf(s,", <%s> line %ld",
884 last_in_stab == argvstab ? "" : last_in_stab->str_magic->str_ptr,
885 (long)stab_io(last_in_stab)->lines);
888 (void)strcpy(s,".\n");
898 extern char *e_tmpname;
909 str_set(stab_val(stabent("@",TRUE)),buf);
911 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
912 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
915 deb("(Skipping label #%d %s)\n",loop_ptr,
916 loop_stack[loop_ptr].loop_label);
923 deb("(Found label #%d %s)\n",loop_ptr,
924 loop_stack[loop_ptr].loop_label);
929 fatal("Bad label: %s", tmps);
931 longjmp(loop_stack[loop_ptr].loop_env, 1);
934 (void)fflush(stderr);
936 (void)UNLINK(e_tmpname);
938 exit((int)(errno?errno:(statusvalue?statusvalue:255)));
962 (void)fflush(stderr);
966 static bool firstsetenv = TRUE;
967 extern char **environ;
973 register int i=envix(nam); /* where does it go? */
977 environ[i] = environ[i+1];
982 if (!environ[i]) { /* does not exist yet */
983 if (firstsetenv) { /* need we copy environment? */
987 New(901,tmpenv, i+2, char*);
989 for (j=0; j<i; j++) /* copy environment */
990 tmpenv[j] = environ[j];
991 environ = tmpenv; /* tell exec where it is now */
994 Renew(environ, i+2, char*); /* just expand it a bit */
995 environ[i+1] = Nullch; /* make sure it's null terminated */
997 New(904, environ[i], strlen(nam) + strlen(val) + 2, char);
998 /* this may or may not be in */
999 /* the old environ structure */
1001 (void)sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
1003 /* MS-DOS requires environment variable names to be in uppercase */
1004 strcpy(environ[i],nam); strupr(environ[i],nam);
1005 (void)sprintf(environ[i] + strlen(nam),"=%s",val);
1013 register int i, len = strlen(nam);
1015 for (i = 0; environ[i]; i++) {
1016 if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
1017 break; /* strnEQ must come first to avoid */
1018 } /* potential SEGV's */
1023 unlnk(f) /* unlink all versions of a file */
1028 for (i = 0; unlink(f) >= 0; i++) ;
1037 register char *from;
1072 vsprintf(dest, pat, args)
1073 char *dest, *pat, *args;
1077 fakebuf._ptr = dest;
1078 fakebuf._cnt = 32767;
1079 fakebuf._flag = _IOWRT|_IOSTRG;
1080 _doprnt(pat, args, &fakebuf); /* what a kludge */
1081 (void)putc('\0', &fakebuf);
1085 return 0; /* perl doesn't use return value */
1091 vfprintf(fd, pat, args)
1095 _doprnt(pat, args, fd);
1096 return 0; /* wrong, but perl doesn't use the return value */
1099 #endif /* VPRINTF */
1100 #endif /* VARARGS */
1103 #if BYTEORDER != 0x4321
1108 #if (BYTEORDER & 1) == 0
1111 result = ((s & 255) << 8) + ((s >> 8) & 255);
1124 char c[sizeof(long)];
1127 #if BYTEORDER == 0x1234
1128 u.c[0] = (l >> 24) & 255;
1129 u.c[1] = (l >> 16) & 255;
1130 u.c[2] = (l >> 8) & 255;
1134 #if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
1135 fatal("Unknown BYTEORDER\n");
1140 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1141 u.c[o & 0xf] = (l >> s) & 255;
1154 char c[sizeof(long)];
1157 #if BYTEORDER == 0x1234
1158 u.c[0] = (l >> 24) & 255;
1159 u.c[1] = (l >> 16) & 255;
1160 u.c[2] = (l >> 8) & 255;
1164 #if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
1165 fatal("Unknown BYTEORDER\n");
1172 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1173 l |= (u.c[o & 0xf] & 255) << s;
1180 #endif /* BYTEORDER != 0x4321 */
1190 register int this, that;
1193 int doexec = strNE(cmd,"-");
1197 this = (*mode == 'w');
1199 while ((pid = (doexec?vfork():fork())) < 0) {
1200 if (errno != EAGAIN) {
1203 fatal("Can't fork");
1212 if (p[THIS] != (*mode == 'r')) {
1213 dup2(p[THIS], *mode == 'r');
1217 #if !defined(FCNTL) || !defined(F_SETFD)
1223 for (fd = 3; fd < NOFILE; fd++)
1226 do_exec(cmd); /* may or may not use the shell */
1229 if (tmpstab = stabent("$",allstabs))
1230 str_numset(STAB_STR(tmpstab),(double)getpid());
1236 do_execfree(); /* free any memory malloced by child on vfork */
1238 if (p[that] < p[this]) {
1239 dup2(p[this], p[that]);
1243 str = afetch(pidstatary,p[this],TRUE);
1244 str_numset(str,(double)pid);
1247 return fdopen(p[this], mode);
1256 struct stat tmpstatbuf;
1258 fprintf(stderr,"%s", s);
1259 for (fd = 0; fd < 32; fd++) {
1260 if (fstat(fd,&tmpstatbuf) >= 0)
1261 fprintf(stderr," %d",fd);
1263 fprintf(stderr,"\n");
1272 #if defined(FCNTL) && defined(F_DUPFD)
1274 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(pidstatary,fileno(ptr),TRUE);
1305 pid = (int)str_gnum(str);
1308 hstat = signal(SIGHUP, SIG_IGN);
1309 istat = signal(SIGINT, SIG_IGN);
1310 qstat = signal(SIGQUIT, SIG_IGN);
1312 if (wait4(pid,&status,0,Null(struct rusage *)) < 0)
1315 if (pid < 0) /* already exited? */
1316 status = str->str_cur;
1320 while ((result = wait(&status)) != pid && result >= 0)
1321 pidgone(result,status);
1326 signal(SIGHUP, hstat);
1327 signal(SIGINT, istat);
1328 signal(SIGQUIT, qstat);
1329 str_numset(str,0.0);
1344 for (count = pidstatary->ary_fill; count >= 0; --count) {
1345 if ((str = afetch(pidstatary,count,FALSE)) &&
1346 ((int)str->str_u.str_nval) == pid) {
1347 str_numset(str, -str->str_u.str_nval);
1348 str->str_cur = status;
1357 register unsigned char *s1;
1358 register unsigned char *s2;
1364 if (tmp = *s1++ - *s2++)
1372 repeatcpy(to,from,len,count)
1374 register char *from;
1379 register char *frombase = from;
1387 while (count-- > 0) {
1388 for (todo = len; todo > 0; todo--) {
1395 #ifndef CASTNEGFLOAT
1403 return (unsigned long)f;
1405 return (unsigned long)along;
1415 char *fa = rindex(a,'/');
1416 char *fb = rindex(b,'/');
1417 struct stat tmpstatbuf1;
1418 struct stat tmpstatbuf2;
1420 #define MAXPATHLEN 1024
1422 char tmpbuf[MAXPATHLEN+1];
1437 strncpy(tmpbuf, a, fa - a);
1438 if (stat(tmpbuf, &tmpstatbuf1) < 0)
1443 strncpy(tmpbuf, b, fb - b);
1444 if (stat(tmpbuf, &tmpstatbuf2) < 0)
1446 return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev &&
1447 tmpstatbuf1.st_ino == tmpstatbuf2.st_ino;
1449 #endif /* !RENAME */