> the little operating system we wrote eventually panic'd (overflowed
> heap); standalone ufs.c implementation we've used leaks f_buf
> everytime ufs_open fails
This is correct, but you may be leaking fp->f_blk[] as well. What about
this instead?
Index: ufs.c
===================================================================
RCS file: /cvs/src/sys/lib/libsa/ufs.c,v
retrieving revision 1.19
diff -u -p -r1.19 ufs.c
--- ufs.c 6 Jan 2008 11:17:18 -0000 1.19
+++ ufs.c 23 Aug 2010 22:03:12 -0000
@@ -98,6 +98,7 @@ static int read_inode(ino_t, struct open
static int block_map(struct open_file *, daddr_t, daddr_t *);
static int buf_read_file(struct open_file *, char **, size_t *);
static int search_directory(char *, struct open_file *, ino_t *);
+static int ufs_close_internal(struct file *);
#ifdef COMPAT_UFS
static void ffs_oldfscompat(struct fs *);
#endif
@@ -526,10 +527,9 @@ ufs_open(char *path, struct open_file *f
out:
if (buf)
free(buf, fs->fs_bsize);
- if (rc) {
- free(fp->f_fs, SBSIZE);
- free(fp, sizeof(struct file));
- }
+ if (rc)
+ (void)ufs_close_internal(fp);
+
return (rc);
}
@@ -537,11 +537,18 @@ int
ufs_close(struct open_file *f)
{
struct file *fp = (struct file *)f->f_fsdata;
- int level;
f->f_fsdata = (void *)0;
if (fp == (struct file *)0)
return (0);
+
+ return (ufs_close_internal(fp));
+}
+
+static void
+ufs_close_internal(struct file *fp)
+{
+ int level;
for (level = 0; level < NIADDR; level++) {
if (fp->f_blk[level])