2013-03-17 33 views
5

Tôi đang phát triển trình điều khiển FUSE và khi tôi chạy nó như một daemon (không có cờ -f hoặc -d) tất cả yêu cầu https được thực hiện thông qua lỗi libcurl. Tôi đã có thể tạo lại lỗi bằng cách thực hiện yêu cầu https, giả mạo và trả lại quy trình gốc và sau đó thực hiện yêu cầu thứ hai từ quy trình mới. Nếu tôi xóa cuộc gọi fork hoặc thực hiện yêu cầu http thì không có lỗi.Lỗi libCurl SSL sau ngã ba()

Tôi đang tạo báo cáo lỗi chính thức ngay bây giờ, nhưng có ai biết cách tôi có thể làm cho nó hoạt động không?

Dưới đây là mã của tôi và (logfile) đầu ra:

Lưu ý: nếu bạn chạy chương trình của tôi, ống vào/dev/null vì libcurl gửi bộ đệm nhận được để thiết bị xuất chuẩn theo mặc định.

#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; 
} 

... và đầu ra:

$ 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. 

Tôi đang sử dụng (chậm nhất) libcurl phiên bản 7.29.0, (mới nhất) phiên bản openssl 1.0.1e, và tôi đang chạy Fedora 18 với phiên bản kernel 3.7.4.

Trả lời

4

Để thực hiện công việc này, bạn cần gọi curl_global_cleanup trước forkcurl_global_init lại sau fork. Một người nào đó trong danh sách gửi thư của libcurl đã đề cập rằng đây là một vấn đề phổ biến khi gọi fork sau khi khởi tạo các thư viện cần được khởi tạo.

+0

Đối với những người có cùng một vấn đề trong các ngôn ngữ khác (perl trong trường hợp của tôi), lưu ý rằng có vẻ như vấn đề chỉ xảy ra khi curl được liên kết trong nss thay vì openssl. Vì vậy, bạn cũng có thể biên dịch lại curl của bạn để chỉ sử dụng openssl. – FlorianB

+0

Giải pháp này là ok nhưng làm cho curl không có sẵn cho phụ huynh sau khi ngã ba. Có một giải pháp cho phép phụ huynh tiếp tục làm việc và sử dụng curl sau ngã ba không? (ví dụ: một quy trình cần phải ghi lại một số dữ liệu bằng cách sử dụng curl nhưng các nhánh đó cũng là con của người dùng để đăng nhập) – lulop

+0

Điều này đã lưu thịt xông khói của tôi. Cảm ơn! –

Các vấn đề liên quan