libCurl SSL error after fork()
curl, fork, fuse, libcurl, linux
Solution
To make this work, you need to call `curl_global_cleanup` before `fork` and `curl_global_init` again after `fork`. Someone in the libcurl mailing list mentioned that this is a common problem when calling `fork` after initializing libraries that need to be initialized.
Problem
I'm developing a FUSE driver and when I run it as a daemon (without the -f or -d flags) all https request made through libcurl fail. I was able to reproduce the error by making an https request, forking and returning the parent process, and then making a second request from the new process. If I remove the `fork` call or make an http request there are no errors. I'm making an official bug report right now, but does anyone know how I can make it work? Here's my code and the (logfile) output: Note: if you run my program, pipe to /dev/null because libcurl sends the received buffer to stdout by default. ``` #include <curl/curl.h> #include <string> #include <unistd.h> #include <iostream> using namespace std; void log(string str) { //TODO: remove static const char logfile[] = "/home/austin/megalog"; FILE *f = fopen(logfile, "a"); fwrite(str.data(), str.size(), 1, f); fclose(f); cout << str; } int main(int argc, char *argv[]) { string url = "https://www.google.com/"; char errBuf[1024]; CURLcode err; curl_global_init(CURL_GLOBAL_DEFAULT); CURL *handle = curl_easy_init(); curl_easy_setopt(handle, CURLOPT_URL, url.c_str()); curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errBuf); if ((err = curl_easy_perform(handle))) { log("first request failed\n"); return 1; } curl_easy_cleanup(handle); if(fork()) return 0; handle = curl_easy_init(); curl_easy_setopt(handle, CURLOPT_URL, url.c_str()); curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errBuf); if ((err = curl_easy_perform(handle))) { log(string("curl error while sending: (") + to_string(err) + ") " + curl_easy_strerror(err) + "\n"); log(errBuf); } else log("no error\n"); return 0; } ``` ...and the output: ``` $ g++ -std=c++11 main.cpp -lcurl $ rm -f log $ ./a.out > /dev/null $ cat log curl error while sending: (35) SSL connect error A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot. ``` I'm using (the latest) libcurl version 7.29.0, (the latest) openssl version 1.0.1e, and I'm running Fedora 18 with kernel version 3.7.4.