about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--stdlib/longlong.h67
-rw-r--r--sysdeps/posix/getcwd.c20
3 files changed, 80 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 097bdfd178..f6f27f87ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 d10fa43e9b..7ac63bf4c8 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 df48804f7a..fe094b5a35 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;
 }