diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | stdlib/longlong.h | 67 | ||||
-rw-r--r-- | sysdeps/posix/getcwd.c | 20 |
3 files changed, 80 insertions, 11 deletions
@@ -1,3 +1,7 @@ +1999-05-25 Ulrich Drepper <drepper@cygnus.com> + + * sysdeps/posix/getcwd.c (__getcwd): Fix potential memory leaks. + 1999-05-26 Jakub Jelinek <jj@ultra.linux.cz> * stdlib/longlong.h (add_ssaaaa, sub_ddmmss, umul_ppmm): diff --git a/stdlib/longlong.h b/stdlib/longlong.h index d10fa43..7ac63bf 100644 --- a/stdlib/longlong.h +++ b/stdlib/longlong.h @@ -1,5 +1,5 @@ /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. - Copyright (C) 1991, 92, 93, 94, 96, 97, 98 Free Software Foundation, Inc. + Copyright (C) 1991,92,93,94,96,97,98,99 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -1174,6 +1174,71 @@ extern USItype __udiv_qrnnd __P ((USItype *, USItype, USItype, USItype)); #endif /* udiv_qrnnd */ #endif /* __sparc__ */ +#if (defined (__sparc_v9__) || (defined (__sparc__) && defined (__arch64__)) \ + || defined (__sparcv9)) && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %4,%5,%1 + add %2,%3,%0 + bcs,a,pn %%xcc, 1f + add %0, 1, %0 + 1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "r" ((UDItype)(ah)), \ + "r" ((UDItype)(bh)), \ + "r" ((UDItype)(al)), \ + "r" ((UDItype)(bl)) \ + : "cc") + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %4,%5,%1 + sub %2,%3,%0 + bcs,a,pn %%xcc, 1f + sub %0, 1, %0 + 1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "r" ((UDItype)(ah)), \ + "r" ((UDItype)(bh)), \ + "r" ((UDItype)(al)), \ + "r" ((UDItype)(bl)) \ + : "cc") + +#define umul_ppmm(wh, wl, u, v) \ + do { \ + UDItype tmp1, tmp2, tmp3, tmp4; \ + __asm__ __volatile__ ( \ + "srl %7,0,%3 + mulx %3,%6,%1 + srlx %6,32,%2 + mulx %2,%3,%4 + sllx %4,32,%5 + srl %6,0,%3 + sub %1,%5,%5 + srlx %5,32,%5 + addcc %4,%5,%4 + srlx %7,32,%5 + mulx %3,%5,%3 + mulx %2,%5,%5 + sethi 0x80000000,%2 + addcc %4,%3,%4 + srlx %4,32,%4 + add %2,%2,%2 + movcc %%xcc,%%g0,%2 + addcc %5,%4,%5 + sllx %3,32,%3 + add %1,%3,%1 + add %5,%2,%0" \ + : "=r" ((UDItype)(wh)), \ + "=&r" ((UDItype)(wl)), \ + "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ + : "r" ((UDItype)(u)), \ + "r" ((UDItype)(v)) \ + : "cc"); \ + } while (0) +#define UMUL_TIME 96 +#endif /* __sparc_v9__ */ + #if defined (__vax__) && W_TYPE_SIZE == 32 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addl2 %5,%1 diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c index df48804..fe094b5 100644 --- a/sysdeps/posix/getcwd.c +++ b/sysdeps/posix/getcwd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc. +/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -211,8 +211,9 @@ __getcwd (buf, size) = "../../../../../../../../../../../../../../../../../../../../../../../\ ../../../../../../../../../../../../../../../../../../../../../../../../../../\ ../../../../../../../../../../../../../../../../../../../../../../../../../.."; - const char *dotp, *dotlist; - size_t dotsize; + const char *dotp = &dots[sizeof (dots)]; + const char *dotlist = dots; + size_t dotsize = sizeof (dots) - 1; dev_t rootdev, thisdev; ino_t rootino, thisino; char *path; @@ -244,18 +245,15 @@ __getcwd (buf, size) *--pathp = '\0'; if (__lstat (".", &st) < 0) - return NULL; + goto lose2; thisdev = st.st_dev; thisino = st.st_ino; if (__lstat ("/", &st) < 0) - return NULL; + goto lose2; rootdev = st.st_dev; rootino = st.st_ino; - dotsize = sizeof (dots) - 1; - dotp = &dots[sizeof (dots)]; - dotlist = dots; while (!(thisdev == rootdev && thisino == rootino)) { register DIR *dirstream; @@ -273,7 +271,7 @@ __getcwd (buf, size) { new = malloc (dotsize * 2 + 1); if (new == NULL) - return NULL; + goto lose; #ifdef HAVE_MEMPCPY dotp = mempcpy (new, dots, dotsize); #else @@ -375,7 +373,6 @@ __getcwd (buf, size) if (tmp == NULL) { (void) __closedir (dirstream); - free (path); __set_errno (ENOMEM);/* closedir might have changed it.*/ goto lose; } @@ -412,6 +409,9 @@ __getcwd (buf, size) lose: if (dotlist != dots) free ((__ptr_t) dotlist); + lose2: + if (buf == NULL) + free (path); return NULL; } |