2012-10-19 42 views
1

我基于在样本程序生成在C于RHEL 4的Linux SMTP客户端程序:适当的方式来传递C文件指针curl_easy_setopt功能

http://curl.haxx.se/libcurl/c/simplesmtp.html

每当所述消息体文本传递给该程序通过stdin,该程序正常工作。但是,当我尝试将FILE指针传递给curl_easy_setopt()函数时,我遇到了段错误。注释(来自示例程序simplesmtp.c)声明可以将文件指针而不是stdin传递给curl_easy_setopt函数。从simplesmtp.c

/* You provide the payload (headers and the body of the message) as the 
* "data" element. There are two choices, either: 
* - provide a callback function and specify the function name using the 
* CURLOPT_READFUNCTION option; or 
* - just provide a FILE pointer that can be used to read the data from. 
* The easiest case is just to read from standard input, (which is available 
* as a FILE pointer) as shown here. 
*/ 
curl_easy_setopt(curl, CURLOPT_READDATA, stdin); 

相关的注释部分,这些都是从与CURLOPT_VERBOSE选项设置控制台错误线。

< 250 2.1.5 <[email protected]>... Recipient ok 
> DATA 
< 354 Enter mail, end with "." on a line by itself 
./r: line 5: 21282 Segmentation fault  ./mysmtpcli -r rcp.txt -m msg.txt 

BTW:./r是我的shell脚本,呼吁./mysmtpcli -r rcp.txt -m msg.txt

我的代码

FILE *f_msg; 
f_msg = fopen(msg_file, "r"); 
if(!f_msg){ 
    fprintf(stderr, "Could not load message file: %s\n", msg_file); 
    return 1; 
} 

curl_easy_setopt(curl, CURLOPT_READDATA, f_msg); 

fclose(f_msg); 
的片段

注意:msg_file变量是从命令行参数填充的,并且是包含以下内容的有效文本文件:

主题:测试消息

这是测试消息!

当使用“cat msg.txt | ./mysmtpcli -r rcp.txt”通过stdin将相同的文件传递给程序时,程序正常执行。不过,这需要用stdin替换f_msg。

curl_easy_setopt(curl, CURLOPT_READDATA, f_msg); 

我是否正确传递FILE指针?

回答

1

是的,你确实传递了一个文件指针。尽管看起来你马上关闭它。如果你这样做,curl稍后会尝试从该文件读取并崩溃。只有在不再需要时才必须关闭它。

+0

我可能不明白内部。看起来你只需要用你的文件指针替换“stdin”,并且库完成剩下的工作。我应该做什么其他处理? – JTP

+0

@jtp:区别在于没有人调用'fclose(stdin);'以便“文件”打开。然后一切正常。但是在你的代码片段中,你可以调用'fclose(f_msg);',它会关闭文件,并且什么都不起作用。你必须避免直到后来调用'fclose',当curl完成它的工作。 – 2012-10-19 00:31:57

+0

漂亮!后来我在代码中移动了fclose语句,并且段错误消失了。我现在正在从服务器上得到一个“500 5.5.1 Command unrecognized:”,但电子邮件正在发送,我将继续从这里进行调试。谢谢。 – JTP