简体   繁体   中英

How to detect if ofstream is writing to /dev/null

Is there any (simple) way to detect in some_function() if ofs is writing to /dev/null or not?

#include <fstream>

some_function(std::ofstream & ofs);

int main()
{
    std::ofstream ofs("/dev/null");
    ofs << "lorem ipsum";

    some_function(ofs); // Testing in here

    return 0;
}

is there any (simple) way to detect in some_function(std::ofstream ofs) if ofs is writing to /dev/null or not?

No, there isn't.

The fact that you are looking for a way to get that information indicates to me that some_function has branching code depending on whether you are writing to /dev/null or not.

You can address that problem by adding another argument to the function and let the client code provide that information to you.

void some_function(std::ofstream& ofs, bool isDevNull);

and use it as:

std::ofstream ofs ("/dev/null", std::ofstream::out);
ofs << "lorem ipsum";
some_function(ofs, true);

from std::ofstream , no.

From a FILE* , yes but it's not portable.

Here's a version for linux:

#include <fstream>
#include <unistd.h>
#include <stdio.h>
#include <memory>
#include <stdexcept>
#include <iostream>
#include <sstream>

struct file_closer
{
    void operator()(FILE*p) const noexcept
    {
        if (p)
            fclose(p);
    }
};

auto open_write(const char* path) -> std::unique_ptr<FILE, file_closer>
{
    auto result = std::unique_ptr<FILE, file_closer>(fopen(path, "w"));

    if (!result.get())
        throw std::runtime_error("not opened");
    return result;
}

size_t do_readlink(const char* path, char* buffer, size_t buflen)
{
    auto len = readlink(path, buffer, buflen);
    if (len < 0)
        throw std::runtime_error("failed to read link");
    return size_t(len);
}

bool is_dev_null(FILE* fp)
{
    int fd = fileno(fp);
    std::ostringstream procpath;
    procpath << "/proc/self/fd/" << fd;
    auto spath = procpath.str(); 

    size_t bufs = 1024;
    std::string path(bufs, ' ');
    auto len = do_readlink(spath.c_str(), &path[0], bufs);
    while(len > bufs)
    {
        bufs = len;
        path.resize(bufs);
        len = do_readlink(spath.c_str(), &path[0], bufs);
    }

    path.resize(len);
    return path == "/dev/null";
}

int main()
{
    auto fp = open_write("/dev/null");
    std::cout << is_dev_null(fp.get());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM