在某些情况下,我需要将子进程的输出通过管道传递到ifstream
。
我都尝试使用以下方法从文件描述符创建ifstream:How to construct a c++ fstream from a POSIX file descriptor?
并且我还试图使用从子stderr到我自己的stdin的管道,并使用cin作为我的流。
在两种情况下,我打电话给Tellg都得到-1。
这是我的代码,其中包含从子stderr到父stdin的管道:
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
using namespace std;
int
main()
{
int mypipe[2];
pipe(mypipe);
dup2(mypipe[0], STDIN_FILENO);
dup2(mypipe[1], STDERR_FILENO);
__pid_t pid = fork();
if(pid == 0)
{
// this is a process that outputs stuff into std::err
char* argv[] = {"copy-feats", nullptr};
int ret = execvp(argv[0], argv);
exit(ret);
}
int status;
waitpid(pid, &status, WNOHANG);
cin.clear(); // attempting to clear the error state. Not working.
long size = cin.tellg();
cout << size << endl;
}
所以我说过Tellg的输出是-1。
如果我尝试使用getline(cin,some_string),我实际上将能够看到子程序的输出。
我尝试通过管道创建流,但仍然给我-1。
这是我使用的代码:
#include <iostream>
#include <fstream>
#include <ext/stdio_filebuf.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#define READ_FD 0
#define WRITE_FD 1
using namespace std;
using FilebufType = __gnu_cxx::stdio_filebuf<std::ifstream::char_type>;
int
main()
{
int mypipe[2];
pipe(mypipe);
__pid_t pid = fork();
if(pid == 0)
{
dup2(mypipe[WRITE_FD], STDERR_FILENO);
char* argv[] = {"copy-feats", nullptr};
int ret = execvp(argv[0], argv);
exit(ret);
}
int status;
waitpid(pid, &status, WNOHANG);
FilebufType filebuf(mypipe[READ_FD], std::ios::in);
istream is(&filebuf);
is.clear();
auto size = is.tellg();
cout << size << endl;
}
谢谢。
答案 0 :(得分:1)
实际上,tellg()
仅在输入流是实际文件时才返回实际文件位置。也就是说,当输入流是std::ifstream
时,然后仅在基础文件是纯文件时。
管道和其他非普通文件没有文件位置的概念。
在您正在使用的Linux上,tellg()
通常是通过使用lseek(2)
来实现的(间接的,但在这里不相关),而lseek(2)
's documentation明确指定它返回一个{{ 1}}错误,如果文件描述符是管道。错误返回最终将转化为ESPIPE
返回-1。