سؤال

I have a program reading from a file "foo" using C++ using:

pFile = fopen ("foo" , "r");

I want it to stop executing the rest of the function if the file is a named pipe. Is there a way to check if the file is a named pipe before opening it?

I found the exact same question using python: Check if file is a named pipe (fifo) in python? Can I do something similar in C++?

هل كانت مفيدة؟

المحلول

From man 2 stat:

int fstat(int filedes, struct stat *buf);

...The following POSIX macros are defined to check the file type using the st_mode field:

         S_ISFIFO(m) FIFO (named pipe)?

So struct stat st; ... !fstat(fileno(pFile, &st) && S_ISFIFO(st.st_mode) should work.

Edit: See also SzG's excellent answer, and Brian's comment to it.

نصائح أخرى

It might be a bit too late to stop the execution AFTER fopen(). It's because the open() syscall will block until someone has opened the FIFO for writing. Instead, use the stat() syscall (on Unix/Linux) before fopen() to find out.

In modern C++ there is also filesystem library, it is available since C++17 #include <experimental/filesystem>, in C++14 it was experimental #include <experimental/filesystem>

So you can you use is_fifo() now. filesystem::path class is constructible from std::string, which is construcible from const char*, so filesystem::is_fifo("/path/to/file") will work as expected. But this version can throw an exception, so bool is_fifo( const std::filesystem::path& p, std::error_code& ec ) noexcept; is your choice.

#if __cplusplus >= 201703L
  #include <filesystem>
  namespace filesystem = std::filesystem;
#else
  #include <experimental/filesystem>
  namespace filesystem = std::experimental::filesystem;
#endif

bool is_fifo(const char *path)
{
    std::error_code ec;
    bool res = filesystem::is_fifo(path, ec);
    if (ec.value() != 0)
        std::cerr << ec.message() << std::endl;
    return res;
}

And don't forget this notice:

GNU implementation prior to 9.1 requires linking with -lstdc++fs and LLVM implementation prior to LLVM 9.0 requires linking with -lc++fs.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top