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
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 );
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.
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.
This merge request was closed by Alexandre Julliard.
If there's no app that needs this it can be closed until we find one.