Почему инициализация указателя файла внутри блока try приводит к разрыву канала? - PullRequest
1 голос
/ 15 ноября 2011

У меня есть скрипт 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

Что происходит?

Ответы [ 2 ]

3 голосов
/ 15 ноября 2011

Когда вы вызываете Ptr f (путь) в блоке try, вы создаете совершенно новую переменную с именем f, которая будет уничтожена при выходе из блока try.

Тогда любой код, который использует f вне блока try, будет использовать неинициализированный F, который вы создали в начале.

У вас есть 2 варианта, которые я вижу:

Добавьте метод Open или аналогичный Ptr и вызовите его из блока try или, возможно, оберните весь код чтения / записи файла в блок try, чтобы избежать необходимости возвращать false, как и весь код будет пропущено при возникновении исключения.

Вариант 1:

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

Вариант 2:

try
{
    Ptr f( file );
    f.read();
}
catch
.....
1 голос
/ 15 ноября 2011

вероятно, это проблема с областью видимости, замените ее на:

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