I want to capture the libcurl
error output that is normally sent to stderr
into a std::string
instead.
This is the code I have come up with so far:
#include <windows.h>
#include <streambuf>
#include <iostream>
#include <io.h>
#include <sstream>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include "curl\curl.h"
std::string data; //will hold the url's contents
// callback function for curl
size_t writeCallback(char* buf, size_t size, size_t nmemb, void* up)
{ //callback must have this declaration
//buf is a pointer to the data that curl has for us
//size*nmemb is the size of the buffer
for (int c = 0; c < size * nmemb; c++)
{
data.push_back(buf[c]);
}
return size * nmemb; //tell curl how many bytes we handled
}
int main()
{
CURL* curl; //our curl object
curl_global_init(CURL_GLOBAL_ALL); //pretty obvious
curl = curl_easy_init();
CURLcode res;
char errbuf[CURL_ERROR_SIZE];
curl_easy_setopt(curl, CURLOPT_URL, "http://ww.example.com/path");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeCallback);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //tell curl to output its progress
int old;
FILE* DataFile;
old = _dup(2); // redirect stderr to "old"
if (fopen_s(&DataFile, "data", "w") != 0)
{
puts("Can't open file 'Datafile'\n");
exit(1);
}
// stderr now refers to file "Datafile"
if (-1 == _dup2(_fileno(DataFile), 2))
{
perror("Can't _dup2 stderr");
exit(1);
}
res = curl_easy_perform(curl);
// Flush stderr stream buffer so it goes to correct file
fflush(stderr);
fclose(DataFile);
// Restore original stderr
_dup2(old, 2);
curl_easy_cleanup(curl);
curl_global_cleanup();
std::ifstream filetoread(DataFile);
if (filetoread)
{
// get length of file:
filetoread.seekg(0, filetoread.end);
int length = filetoread.tellg();
filetoread.seekg(0, filetoread.beg);
char* buffer = new (std::nothrow) char[length];
if (buffer == nullptr)
{
std::cout << "Error allocating buffer.\nvariable 'length' is: " << length << std::endl;
return 0;
}
std::cout << "Reading " << length << " characters... ";
// read data as a block:
filetoread.read(buffer, length);
if (filetoread)
std::cout << "all characters read successfully.";
else
std::cout << "error: only " << filetoread.gcount() << " could be read";
filetoread.close();
// ...buffer contains the entire file...
std::string buffertext(buffer);
delete[] buffer;
}
_flushall();
}
It seems to me that the file Datafile
is empty since the variable length is -1. Can anybody help with this code? The examples in redirect stdout/stderr to a string haven't proved to be a solution to my question so far.