svn commit: trunk/uClibc/libc/misc/dirent

vapier at uclibc.org vapier at uclibc.org
Sat Feb 4 03:24:27 UTC 2006


Author: vapier
Date: 2006-02-03 19:24:24 -0800 (Fri, 03 Feb 2006)
New Revision: 13831

Log:
rfelker reports in Bug 683 that we leak file descriptors if the fcntl() fails ... so fix that.  add back in fstat() ofter we open() the directory as we need the blocksize further down in the code.  unify the memory error handling to shrink the code there a little.


Modified:
   trunk/uClibc/libc/misc/dirent/opendir.c


Changeset:
Modified: trunk/uClibc/libc/misc/dirent/opendir.c
===================================================================
--- trunk/uClibc/libc/misc/dirent/opendir.c	2006-02-04 03:10:45 UTC (rev 13830)
+++ trunk/uClibc/libc/misc/dirent/opendir.c	2006-02-04 03:24:24 UTC (rev 13831)
@@ -27,7 +27,6 @@
 {
 	int fd;
 	struct stat statbuf;
-	char *buf;
 	DIR *ptr;
 
 #ifndef O_DIRECTORY
@@ -42,21 +41,27 @@
 #endif
 	if ((fd = open(name, O_RDONLY|O_NDELAY|O_DIRECTORY)) < 0)
 		return NULL;
+
 	/* Note: we should check to make sure that between the stat() and open()
 	 * call, 'name' didnt change on us, but that's only if O_DIRECTORY isnt
 	 * defined and since Linux has supported it for like ever, i'm not going
 	 * to worry about it right now (if ever). */
+	if (fstat(fd, &statbuf) < 0)
+		goto close_and_ret;
 
 	/* According to POSIX, directory streams should be closed when
 	 * exec. From "Anna Pluzhnikov" <besp at midway.uchicago.edu>.
 	 */
-	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
-		return NULL;
-	if (!(ptr = malloc(sizeof(*ptr)))) {
+	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
+		int saved_errno;
+close_and_ret:
+		saved_errno = errno;
 		close(fd);
-		__set_errno(ENOMEM);
+		__set_errno(saved_errno);
 		return NULL;
 	}
+	if (!(ptr = malloc(sizeof(*ptr))))
+		goto nomem_close_and_ret;
 
 	ptr->dd_fd = fd;
 	ptr->dd_nextloc = ptr->dd_size = ptr->dd_nextoff = 0;
@@ -65,13 +70,13 @@
 	if (ptr->dd_max < 512)
 		ptr->dd_max = 512;
 
-	if (!(buf = calloc(1, ptr->dd_max))) {
+	if (!(ptr->dd_buf = calloc(1, ptr->dd_max))) {
+		free(ptr);
+nomem_close_and_ret:
 		close(fd);
-		free(ptr);
 		__set_errno(ENOMEM);
 		return NULL;
 	}
-	ptr->dd_buf = buf;
 	__pthread_mutex_init(&(ptr->dd_lock), NULL);
 	return ptr;
 }




More information about the uClibc-cvs mailing list