[PATCH v2 0/1] MR5083: server: Try to retrieve the unix name on handles created from file descriptors.
Useful with unix integration of redirected standard handles. Simple testcase: ```c #include <windows.h> #include <stdio.h> int main(int argc, char **argv) { char buf[4096] = {0}; FILE_NAME_INFO *name_info = (FILE_NAME_INFO*)buf; if (!GetFileInformationByHandleEx(GetStdHandle(STD_OUTPUT_HANDLE), FileNameInfo, name_info, sizeof(buf))) { fprintf(stderr, "GetFileInformationByHandleEx failed %08lx\n", GetLastError()); return 1; } WriteFile(GetStdHandle(STD_ERROR_HANDLE), name_info->FileName, name_info->FileNameLength, NULL, NULL); return 0; } ``` On Windows: ``` test.exe > C:\Temp\test.txt ``` Output: ``` \Temp\test.txt ``` On wine: ``` wine test.exe > /tmp/wine/testprefix/drive_c/Temp/test.txt ``` Upstream output: ``` GetFileInformationByHandleEx failed 00000006 ``` With this MR: ``` \Temp\test.txt ``` -- v2: server: Try to retrieve the unix name on handles created from file https://gitlab.winehq.org/wine/wine/-/merge_requests/5083
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)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 ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5083
Changed it so it uses `get_path_from_fd` as suggested, I really don't find it worth arguing over platforms I can't even test tbh, just felt wrong to me to readlink unnecessarily on them. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5083#note_61924
Is there something I should be doing with this? Or is it something we don't want now? There's no app that I'm aware of that needs it anymore (since 1b0d8428dfc13b0fa5ea7d576dfef7aaf8a8c927), although in theory it could. So let me know if I should close it if it's not going to go anywhere. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5083#note_63411
This merge request was closed by Alexandre Julliard. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5083
If there's no app that needs this it can be closed until we find one. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5083#note_63427
participants (2)
-
Alexandre Julliard (@julliard) -
Gabriel Ivăncescu