This simplifies future tests that check for object name of devices.
-- v2: server: Fix object name resolution of \Device\Null. server: Make explicit the ownership of the unix_name buffer.
From: Jinoh Kang jinoh.kang.kr@gmail.com
This permits fd->unix_name to be NULL while fd->closed->unix_name is non-NULL. --- server/fd.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/server/fd.c b/server/fd.c index eaebe044f37..64946303bad 100644 --- a/server/fd.c +++ b/server/fd.c @@ -163,7 +163,7 @@ struct closed_fd struct list entry; /* entry in inode closed list */ int unix_fd; /* the unix file descriptor */ int unlink; /* whether to unlink on close: -1 - implicit FILE_DELETE_ON_CLOSE, 1 - explicit disposition */ - char *unix_name; /* name to unlink on close, points to parent fd unix_name */ + char *unix_name; /* name to unlink on close (buffer may be shared with parent fd) */ };
struct fd @@ -178,7 +178,7 @@ struct fd unsigned int access; /* file access (FILE_READ_DATA etc.) */ unsigned int options; /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */ unsigned int sharing; /* file sharing mode */ - char *unix_name; /* unix file name */ + char *unix_name; /* unix file name (owned by closed->unix_name if inode != NULL) */ WCHAR *nt_name; /* NT file name */ data_size_t nt_namelen; /* length of NT file name */ int unix_fd; /* unix file descriptor */ @@ -1755,16 +1755,22 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha { unsigned int err; struct fd *fd = alloc_fd_object(); + char *orig_unix_name, *new_unix_name = NULL;
if (!fd) return NULL;
fd->options = options; fd->cacheable = orig->cacheable;
- if (orig->unix_name) + orig_unix_name = orig->inode ? orig->closed->unix_name : orig->unix_name; + if (orig_unix_name) { - if (!(fd->unix_name = mem_alloc( strlen(orig->unix_name) + 1 ))) goto failed; - strcpy( fd->unix_name, orig->unix_name ); + if (!(new_unix_name = mem_alloc( strlen(orig_unix_name) + 1 ))) goto failed; + strcpy( new_unix_name, orig_unix_name ); + if (orig->unix_name == orig_unix_name) + { + fd->unix_name = new_unix_name; + } } if (orig->nt_namelen) { @@ -1784,7 +1790,7 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha } closed->unix_fd = fd->unix_fd; closed->unlink = 0; - closed->unix_name = fd->unix_name; + closed->unix_name = new_unix_name; fd->closed = closed; fd->inode = (struct inode *)grab_object( orig->inode ); list_add_head( &fd->inode->open, &fd->inode_entry ); @@ -1802,6 +1808,11 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha return fd;
failed: + if (!fd->inode) + { + free( new_unix_name ); + fd->unix_name = NULL; + } release_object( fd ); return NULL; }
From: Jinoh Kang jinoh.kang.kr@gmail.com
--- dlls/ntdll/tests/om.c | 2 +- server/device.c | 6 +++++- server/fd.c | 6 ++++++ server/file.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index ddbdce0281c..d0e8d088e52 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -1911,7 +1911,7 @@ static void test_query_object(void)
handle = CreateFileA( "nul", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() ); - test_object_name( handle, L"\Device\Null", TRUE ); + test_object_name( handle, L"\Device\Null", FALSE ); test_object_type( handle, L"File" ); test_file_info( handle ); pNtClose( handle ); diff --git a/server/device.c b/server/device.c index 436dac6bfe9..f3124f1210d 100644 --- a/server/device.c +++ b/server/device.c @@ -440,7 +440,11 @@ static struct object *device_open_file( struct object *obj, unsigned int access, access = file->obj.ops->map_access( &file->obj, access ); nt_name.str = device->obj.ops->get_full_name( &device->obj, &nt_name.len ); file->fd = open_fd( NULL, device->unix_path, nt_name, O_NONBLOCK, &mode, access, sharing, options ); - if (file->fd) set_fd_user( file->fd, &device_file_fd_ops, &file->obj ); + if (file->fd) + { + fd_forget_unix_name( file->fd ); + set_fd_user( file->fd, &device_file_fd_ops, &file->obj ); + } } else file->fd = alloc_pseudo_fd( &device_file_fd_ops, &file->obj, options );
diff --git a/server/fd.c b/server/fd.c index 64946303bad..9200b8d43bd 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1899,6 +1899,12 @@ void get_nt_name( struct fd *fd, struct unicode_str *name ) name->len = fd->nt_namelen; }
+void fd_forget_unix_name( struct fd *fd ) +{ + if (!fd->inode) free( fd->unix_name ); + fd->unix_name = NULL; +} + /* open() wrapper that returns a struct fd with no fd user set */ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_name, int flags, mode_t *mode, unsigned int access, diff --git a/server/file.h b/server/file.h index 0ffe0e2c8dc..26c1f77309a 100644 --- a/server/file.h +++ b/server/file.h @@ -104,6 +104,7 @@ extern void allow_fd_caching( struct fd *fd ); extern void set_fd_signaled( struct fd *fd, int signaled ); extern char *dup_fd_name( struct fd *root, const char *name ); extern void get_nt_name( struct fd *fd, struct unicode_str *name ); +extern void fd_forget_unix_name( struct fd *fd );
extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ); extern int default_fd_get_poll_events( struct fd *fd );
This merge request was closed by Alexandre Julliard.
Superseded by 9e8ab49bf57bba926c76339c03ab45b50e3ce79b.