Fixed a potential memory leak in devfs_open().

Correctly implemented devfs_create() - it will now open the an already
existing file if O_EXCL is not set, and no longer fail with EROFS.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9716 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-11-01 20:20:37 +00:00
parent 26fbfbaa64
commit fa00c58619

View File

@ -873,9 +873,68 @@ devfs_remove_vnode(fs_volume _fs, fs_vnode _v, bool reenter)
static status_t
devfs_create(fs_volume _fs, fs_vnode _dir, const char *name, int omode, int perms, fs_cookie *_cookie, vnode_id *new_vnid)
devfs_create(fs_volume _fs, fs_vnode _dir, const char *name, int openMode, int perms,
fs_cookie *_cookie, vnode_id *_newVnodeID)
{
return EROFS;
struct devfs_vnode *dir = (struct devfs_vnode *)_dir;
struct devfs *fs = (struct devfs *)_fs;
struct devfs_cookie *cookie;
struct devfs_vnode *vnode, *vdummy;
status_t status = B_OK;
TRACE(("devfs_create: vnode %p, oflags 0x%x, fs_cookie %p \n", vnode, openMode, _cookie));
mutex_lock(&fs->lock);
// look it up
vnode = devfs_find_in_dir(dir, name);
if (!vnode) {
status = EROFS;
goto err1;
}
if (openMode & O_EXCL)
return B_FILE_EXISTS;
status = get_vnode(fs->id, vnode->id, (fs_vnode *)&vdummy);
if (status < B_OK)
goto err1;
*_newVnodeID = vnode->id;
cookie = (struct devfs_cookie *)malloc(sizeof(struct devfs_cookie));
if (cookie == NULL) {
status = B_NO_MEMORY;
goto err2;
}
if (S_ISCHR(vnode->stream.type)) {
if (vnode->stream.u.dev.node != NULL) {
status = vnode->stream.u.dev.info->open(
vnode->stream.u.dev.node->parent->cookie, openMode,
&cookie->u.dev.dcookie);
} else {
char buffer[B_FILE_NAME_LENGTH];
get_device_name(vnode, buffer, sizeof(buffer));
status = vnode->stream.u.dev.ops->open(buffer, openMode,
&cookie->u.dev.dcookie);
}
}
if (status < B_OK)
goto err3;
*_cookie = cookie;
mutex_unlock(&fs->lock);
return B_OK;
err3:
free(cookie);
err2:
put_vnode(fs->id, vnode->id);
err1:
mutex_unlock(&fs->lock);
return status;
}
@ -905,7 +964,9 @@ devfs_open(fs_volume _fs, fs_vnode _vnode, int openMode, fs_cookie *_cookie)
&cookie->u.dev.dcookie);
}
}
if (status < B_OK)
free(cookie);
else
*_cookie = cookie;
return status;