[PATCH] server: Try to retrieve the unix name on handles created from file descriptors.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Thu Jan 30 06:55:45 CST 2020
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46070
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
It also fixes the game Unity of Command II (same bug).
server/fd.c | 39 +++++++++++++++++++++++++++++++++++++++
server/file.c | 1 +
server/file.h | 2 ++
3 files changed, 42 insertions(+)
diff --git a/server/fd.c b/server/fd.c
index 5d80e21..2530287 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1922,6 +1922,45 @@ struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops, int unix_fd, s
return NULL;
}
+void set_unix_name_of_fd( struct fd *fd, const struct stat *fd_st )
+{
+#ifdef __linux__
+ static const char procfs_fmt[] = "/proc/self/fd/%d";
+
+ char path[PATH_MAX], procfs_path[sizeof(procfs_fmt) - 2 /* %d */ + 11];
+ struct stat path_st;
+ ssize_t len;
+
+ sprintf( procfs_path, procfs_fmt, fd->unix_fd );
+ len = readlink( procfs_path, path, sizeof(path) );
+ if (len == -1 || len >= sizeof(path) )
+ return;
+ path[len] = '\0';
+
+ /* Make sure it's an absolute path, has at least one hardlink, and the same inode */
+ if (path[0] != '/' || stat( path, &path_st ) || path_st.st_nlink < 1 ||
+ path_st.st_dev != fd_st->st_dev || path_st.st_ino != fd_st->st_ino)
+ return;
+
+ if (!(fd->unix_name = mem_alloc( len + 1 )))
+ return;
+ memcpy( fd->unix_name, path, len + 1 );
+
+#elif defined(F_GETPATH)
+ char path[PATH_MAX];
+ size_t size;
+
+ if (fcntl( fd->unix_fd, F_GETPATH, path ) == -1 || path[0] != '/')
+ return;
+
+ size = strlen(path) + 1;
+ if (!(fd->unix_name = mem_alloc( size )))
+ return;
+ memcpy( fd->unix_name, path, size );
+
+#endif
+}
+
/* retrieve the object that is using an fd */
void *get_fd_user( struct fd *fd )
{
diff --git a/server/file.c b/server/file.c
index 71b8448..1db6c7c 100644
--- a/server/file.c
+++ b/server/file.c
@@ -145,6 +145,7 @@ struct file *create_file_for_fd( int fd, unsigned int access, unsigned int shari
release_object( file );
return NULL;
}
+ set_unix_name_of_fd( file->fd, &st );
allow_fd_caching( file->fd );
return file;
}
diff --git a/server/file.h b/server/file.h
index 4341ad3..5c6054b 100644
--- a/server/file.h
+++ b/server/file.h
@@ -22,6 +22,7 @@
#define __WINE_SERVER_FILE_H
#include <sys/types.h>
+#include <sys/stat.h>
#include "object.h"
@@ -82,6 +83,7 @@ extern struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t
unsigned int access, unsigned int sharing, unsigned int options );
extern struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops,
int unix_fd, struct object *user, unsigned int options );
+extern void set_unix_name_of_fd( struct fd *fd, const struct stat *fd_st );
extern struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sharing,
unsigned int options );
extern struct fd *get_fd_object_for_mapping( struct fd *fd, unsigned int access, unsigned int sharing );
--
2.21.0
More information about the wine-devel
mailing list