Path: utzoo!utgpu!jarvis.csri.toronto.edu!neat.cs.toronto.edu!rayan Newsgroups: comp.bugs.sys5 From: rayan@cs.toronto.edu (Rayan Zachariassen) Subject: closedir() bug report (SVr3.1) Message-ID: <89Oct23.223414edt.2151@neat.cs.toronto.edu> Date: 24 Oct 89 02:34:47 GMT [ I post this here because we have no official way of notifying AT&T (nor, I suspect, enough incentive to do so or their attention if we did), and several machines running 3.1-derived code has this bug so this also notifies all the vendors of such machines. A bug report has been called in to SGI. ] OS version: System V 3.1 Description: closedir() is supposed to deallocate the DIR * returned by opendir(), and close the filedescriptor whose value is stored in the DIR * structure. This is done by first freeing the DIR * structure and then trying to get the value of the file descriptor stored within it. The semantics of free doesn't guarantee data integrity of freed memory. Symptom: an application repeatedly scanning a directory (i.e. opendir() readdir() closedir() in a loop) will run out of file descriptors when linked with a version of free that scribbles on the memory it frees (in order to catch these kinds of problems). Workaround: instead of a normal closedir(), use the sequence: close(dirp->dd_fd); (void) closedir(dirp); /* will return failure indication */ Severity: Embarrassing... Should be fixed in future releases (if someone can check on V.4 and let us and/or AT&T know...). Fix: in lib/libc/port/gen/closedir.c RCS file: RCS/closedir.c,v retrieving revision 1.1 diff -b -c -r1.1 closedir.c *** /tmp/,RCSt1a09053 Mon Oct 23 22:01:05 1989 --- closedir.c Mon Oct 23 22:01:06 1989 *************** *** 35,41 **** closedir( dirp ) register DIR *dirp; /* stream from opendir() */ { free( dirp->dd_buf ); free( (char *)dirp ); ! return(close( dirp->dd_fd )); } --- 35,43 ---- closedir( dirp ) register DIR *dirp; /* stream from opendir() */ { + int fd = dirp->dd_fd; + free( dirp->dd_buf ); free( (char *)dirp ); ! return(close( fd )); }