在我编写测试时,有一个FILE *的特殊情况我可以这样处理:
// first we open the file
bool FileOutput::open(std::string const& filename)
{
if(f_file.is_open())
{
throw std::runtime_error("already open");
}
f_file.open(filename.c_str());
if(!f_file.is_open())
{
return false;
}
return true;
}
// later we write to it
void FileOutput::internal_write(std::string const& data)
{
f_file << data;
if(!f_file)
{
throw std::runtime_error("I/O error: could not write to output.");
}
}
在我编写测试时,我想在internal_write()中引发I / O错误。换句话说,我是&lt;&lt;运算符(以及任何基础I / O函数)生成错误,以使!f_file
成为真。
这是一个测试,以确保错误确实最终投掷。所以我不打算以不同的方式编写代码。
请注意,关闭文件不是一个好主意,并且f_file不能从外部访问,并且没有close()
函数(当对象被销毁时它会关闭。)
我看了锁,但看起来不会起作用。当线程阻塞文件一段时间时,它会在没有超时的情况下阻塞。还有什么可以做的?
答案 0 :(得分:1)
请注意,关闭文件并不是一个好主意,并且外部无法访问f_file,也没有close()函数(当对象被销毁时它会关闭。)
只是因为f_file
无法访问而关闭不好吗?如果是,那么编写一个shell脚本,在测试程序运行时获取测试程序的PID并关闭所需的文件句柄。
脚本执行两个步骤:
1)运行lsof
以获取文件的文件句柄
lsof -p PID | grep yourfile | awk '{print $4}' | tr -d wru
在第4个字段中,将有文件的文件句柄编号。将它分配给环境变量HANDLE_ID_FROM_LSOF。
2)运行gdb以关闭需要变坏的句柄
gdb --batch-silent your-program -p PID -ex "call close($HANDLE_ID_FROM_LSOF)" -ex "detach"
运行gdb
后,文件句柄将被关闭,希望您将收到所需的错误。至少strace
看起来像这样:
write(1, "10606216\n10606217\n10606218\n10606"..., 65536) = 65536
write(1, "7\n10613498\n10613499\n10613500\n106"..., 65536) = 65536
write(1, "779\n10620780\n10620781\n10620782\n1"..., 65536) = 65536
write(1, "\n15827311\n15827312\n15827313\n1582"..., 65536) = -1 EBADF (Bad file descriptor)
write(1, "\n15834593\n15834594\n15834595\n1583"..., 65536) = -1 EBADF (Bad file descriptor)
write(1, "\n15841875\n15841876\n15841877\n1584"..., 65536) = -1 EBADF (Bad file descriptor)
这是此脚本的一个示例:
$ cat close_file.sh
#!/bin/sh
TARGET_PROG=$1
TARGET_PID=$2
TARGET_FILE=$3
TARGET_FILE_FD=$(lsof -p $TARGET_PID | grep seq.txt | awk '{print $4}' | tr -d wur)
gdb --batch-silent $TARGET_PROG -p $TARGET_PID -ex "call close($TARGET_FILE_FD)" -ex "detach"
第一个参数 - 程序的完整路径,第二个参数 - 进程ID,第三个参数 - 需要关闭的文件的名称。
此示例显示了如何运行此脚本。首先运行您的测试程序。然后运行脚本。这是运行它的一个例子:
$ ./close_file.sh /usr/bin/seq 16640 seq.txt