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?

有帮助吗?

解决方案

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:

Ptr f;
try
{
    f.Open( file );
}
catch
....

Option 2:

try
{
    Ptr f( file );
    f.read();
}
catch
.....

其他提示

its probably a scoping issue, replace it with:

bool getResult(const char* path) 
{
  try
  {
     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;
     }
  ...
  } 
  catch(Exception& e) 
  {
    vlog.error("Could not open file at %s",path);
    return false;
  }
  return true;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top