为什么在 try 块内初始化文件指针会导致管道损坏?
我有一个 bash 脚本,我正在从程序中读取结果。 Ptr
是一个简单的popen()
包装器。
bool getResult(const char* path){
Ptr f(path);
char buf[1024];
while (fgets(buf, sizeof(buf), f) == 0) {
if(errno == EINTR)
continue;
log.error("Error (%d) : %s",errno,path);
return false;
}
...
return true;
}
这工作正常,但是 Ptr f(path)
不是异常安全的,所以我将其替换为:
Ptr f; // empty constructor, does nothing
char buf[1024];
try{
Ptr f(path);
}catch(Exception& e){
vlog.error("Could not open file at %s",path);
return false;
}
运行时(并且文件存在)我收到以下错误:
/etc/my_script: line 165: echo: write error: Broken pipe
脚本的该行只是:
echo $result
到底是怎么回事?
I have a bash script which I'm reading the results from in my program. Ptr
is a simple popen()
wrapper.
bool getResult(const char* path){
Ptr f(path);
char buf[1024];
while (fgets(buf, sizeof(buf), f) == 0) {
if(errno == EINTR)
continue;
log.error("Error (%d) : %s",errno,path);
return false;
}
...
return true;
}
This works fine, but Ptr f(path)
is not exception safe, so I replace it with:
Ptr f; // empty constructor, does nothing
char buf[1024];
try{
Ptr f(path);
}catch(Exception& e){
vlog.error("Could not open file at %s",path);
return false;
}
When run (and the file exists) I get the following error:
/etc/my_script: line 165: echo: write error: Broken pipe
That line of the script is just:
echo $result
What is going on?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您在 try 块中调用 Ptr f(path) 时,您正在创建一个名为 f 的全新变量,当您退出 try 块时,该变量将被销毁。
然后,在 try 块之外使用 f 的任何代码都将使用您在开始时创建的未初始化的 F。
我可以看到你有 2 个选项:
添加一个 Open 方法或类似于 Ptr 的方法,并从 try 块中调用它,或者将所有文件读取/写入代码包装在 try 块中,这样就可以避免返回 false ,因为抛出异常时所有代码都将被跳过。
选项 1:
选项 2:
When you call Ptr f(path) in the try block, you're creating a whole new variable called f, that will be destroyed when you exit the try block.
Then any code that uses f outsidde the try block will be using the uninitialised F that you created at the start.
You have 2 options I can see:
Add an Open method or similar to Ptr and call that from within the try block, or perhaps wrap all your file reading/writing code in the try block, that way you can avoid the need for returning false, as all the code will have been skipped when an exception was thrown.
Option 1:
Option 2:
这可能是一个范围问题,请将其替换为:
its probably a scoping issue, replace it with: