1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-16 15:32:43 +01:00

libutil: guess or invent a path from file descriptors

This is useful for certain error recovery paths (no pun intended) that
does not thread through the original path name.

Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
Signed-off-by: Raito Bezarius <raito@lix.systems>
This commit is contained in:
Raito Bezarius 2025-03-26 01:04:12 +01:00 committed by Jörg Thalheim
parent b9b510d692
commit 7226a116a0
3 changed files with 45 additions and 0 deletions

View file

@ -1,5 +1,8 @@
#include "nix/util/serialise.hh"
#include "nix/util/util.hh"
#include "nix/util/file-system.hh"
#include "util-config-private.hh"
#include <fcntl.h>
#include <unistd.h>
@ -74,6 +77,29 @@ Descriptor AutoCloseFD::get() const
return fd;
}
std::string guessOrInventPathFromFD(Descriptor fd)
{
assert(fd >= 0);
/* On Linux, there's no F_GETPATH available.
* But we can read /proc/ */
#if defined(__linux__)
try {
return readLink(fmt("/proc/self/fd/%1%", fd));
} catch (...) {
}
#elif defined (HAVE_F_GETPATH) && HAVE_F_GETPATH
std::string fdName(PATH_MAX, '\0');
if (fcntl(fd, F_GETPATH, fdName.data()) != -1) {
fdName.resize(strlen(fdName.c_str()));
return fdName;
}
#else
#error "No implementation for retrieving file descriptors path."
#endif
return fmt("<fd %i>", fd);
}
void AutoCloseFD::close()
{

View file

@ -106,6 +106,14 @@ void drainFD(
#endif
);
/*
* Will attempt to guess *A* path associated that might lead to the same file as used by this
* file descriptor.
*
* The returned string should NEVER be used as a valid path.
*/
std::string guessOrInventPathFromFD(Descriptor fd);
/**
* Get [Standard Input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin))
*/
@ -160,6 +168,15 @@ public:
AutoCloseFD& operator =(const AutoCloseFD & fd) = delete;
AutoCloseFD& operator =(AutoCloseFD&& fd);
Descriptor get() const;
/**
* Will attempt to guess *A* path associated that might lead to the same file as used by this
* file descriptor.
*
* The returned string should NEVER be used as a valid path.
*/
std::string guessOrInventPath() const { return guessOrInventPathFromFD(fd); }
explicit operator bool() const;
Descriptor release();
void close();

View file

@ -37,6 +37,8 @@ foreach funcspec : check_funcs
configdata.set(define_name, define_value, description: funcspec[1])
endforeach
configdata.set('HAVE_F_GETPATH', cxx.has_header_symbol('fcntl.h', 'F_GETPATH').to_int())
subdir('nix-meson-build-support/libatomic')
if host_machine.system() == 'windows'