Merge branch 'wip/pwithnall/procfs-refactor' into 'main'

tests: Factor out a function to convert FD to path

See merge request GNOME/glib!4396
This commit is contained in:
Philip Withnall 2024-11-26 12:06:28 +00:00
commit c64f82fa79

View File

@ -206,15 +206,52 @@ handle_request (GFakeDesktopPortalThread *self,
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
/* This is currently private as theres only one user of it, but it could become
* a public API in future. */
static char *
_g_fd_query_path (int fd,
GError **error)
{
#if defined(__FreeBSD__)
struct kinfo_file kf;
kf.kf_structsize = sizeof (kf);
if (fcntl (fd, F_KINFO, &kf) < 0)
{
int saved_errno = errno;
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error querying file information for FD %d: %s",
fd, g_strerror (saved_errno));
return NULL;
}
return g_strdup (kf.kf_path);
#elif defined(G_OS_UNIX)
char *path = NULL;
char *proc_path = g_strdup_printf ("/proc/self/fd/%d", fd);
path = g_file_read_link (proc_path, error);
g_free (proc_path);
return g_steal_pointer (&path);
#else
/* - A NetBSD implementation would probably use `fcntl()` with `F_GETPATH`:
* https://man.netbsd.org/fcntl.2
* - A Windows implementation would probably use `GetFinalPathNameByHandleW()`:
* https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlea
* - A Hurd implementation could open("/dev/fd/%u"):
* https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4396#note_2279923
*/
#error "_g_fd_query_path() not supported on this platform"
#endif
}
static char *
handle_to_uri (GVariant *handle,
GUnixFDList *fd_list)
{
int fd = -1;
int fd_id;
char *proc_path = NULL;
char *path;
char *uri;
GError *local_error = NULL;
fd_id = g_variant_get_handle (handle);
fd = g_unix_fd_list_get (fd_list, fd_id, NULL);
@ -222,21 +259,10 @@ handle_to_uri (GVariant *handle,
if (fd == -1)
return NULL;
#ifdef __FreeBSD__
struct kinfo_file kf;
kf.kf_structsize = sizeof (kf);
if (fcntl (fd, F_KINFO, &kf) == -1)
return NULL;
path = g_strdup (kf.kf_path);
#else
proc_path = g_strdup_printf ("/proc/self/fd/%d", fd);
path = g_file_read_link (proc_path, NULL);
#endif
g_assert_nonnull (path);
path = _g_fd_query_path (fd, &local_error);
g_assert_no_error (local_error);
uri = g_filename_to_uri (path, NULL, NULL);
g_free (proc_path);
g_free (path);
close (fd);