From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- server/change.c | 2 +- server/fd.c | 25 +++++++++++++++++++++++++ server/file.c | 1 + server/file.h | 3 +++ 4 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/server/change.c b/server/change.c index 843e495411c..073bc19ae26 100644 --- a/server/change.c +++ b/server/change.c @@ -721,7 +721,7 @@ static unsigned int filter_from_inode( struct inode *inode, int is_parent ) return filter; }
-static char *get_path_from_fd( int fd, int sz ) +char *get_path_from_fd( int fd, int sz ) { #ifdef linux char *ret = malloc( 32 + sz ); diff --git a/server/fd.c b/server/fd.c index 8576882aaa9..a5cca8a8305 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2071,6 +2071,31 @@ 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 ) +{ + char *path_from_fd = get_path_from_fd( fd->unix_fd, 0 ); + struct stat path_st; + char path[PATH_MAX]; + ssize_t len; + + if (!path_from_fd) return; + + len = readlink( path_from_fd, path, sizeof(path) ); + free( path_from_fd ); + 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 ); +} + /* 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 76c687833c9..5624e621eac 100644 --- a/server/file.c +++ b/server/file.c @@ -155,6 +155,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 7f2d1637863..18df54b04b3 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"
@@ -85,6 +86,8 @@ extern struct fd *open_fd( struct fd *root, const char *name, struct unicode_str 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 char *get_path_from_fd( int fd, int sz ); +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 );