2013-03-17 18 views
5

Sto sviluppando un driver FUSE e quando lo eseguo come un demone (senza i flag -f o -d) tutte le richieste https effettuate tramite libcurl falliscono. Sono stato in grado di riprodurre l'errore effettuando una richiesta https, biforcando e restituendo il processo padre e quindi facendo una seconda richiesta dal nuovo processo. Se rimuovo la chiamata fork o faccio una richiesta http non ci sono errori.libCurl Errore SSL dopo fork()

Sto facendo un bug report ufficiale in questo momento, ma qualcuno sa come posso farlo funzionare?

Ecco il mio codice e la (file di log) Uscita:

Nota: se si esegue il mio programma, il tubo a/dev/null perché libcurl invia il buffer ricevuto a stdout per 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; 
} 

... e l'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. 

sto usando (l'ultima) libcurl versione 7.29.0, (l'ultima) versione openssl 1.0.1e, e sto correndo Fedora 18 con la versione del kernel 3.7.4.

risposta

4

Per fare questo lavoro, è necessario chiamare curl_global_cleanup prima fork e curl_global_init nuovo dopo fork. Qualcuno nella mailing list di libcurl ha detto che questo è un problema comune quando si chiama fork dopo aver inizializzato le librerie che devono essere inizializzate.

+0

Per quelli con lo stesso problema in altre lingue (perl nel mio caso), si noti che sembra che il problema si verifica solo quando curl è collegato in nss invece di openssl. Quindi potresti ricomporre il tuo ricciolo solo per usare openssl. – FlorianB

+0

Questa soluzione è OK, ma rende il ricciolo non disponibile per il genitore dopo la forchetta. Esiste una soluzione che permetta al genitore di continuare a lavorare e usare l'arricciatura dopo la forchetta? (ad esempio un processo che richiede di registrare alcuni dati usando curl ma che forchetta child che anche utente culr per la registrazione) – lulop

+0

Questo mi ha salvato il bacon. Grazie! –