Commit eaff1465 authored by Rusty Russell's avatar Rusty Russell

failtest: fix failpath on open.

And separate out the code which follows --failpath so failtest_close()
can use it too.
parent 2006aa03
...@@ -495,6 +495,32 @@ static NORETURN void failtest_cleanup(bool forced_cleanup, int status) ...@@ -495,6 +495,32 @@ static NORETURN void failtest_cleanup(bool forced_cleanup, int status)
exit(status); exit(status);
} }
static bool following_path(void)
{
if (!failpath)
return false;
/* + means continue after end, like normal. */
if (*failpath == '+') {
failpath = NULL;
return false;
}
return true;
}
static bool follow_path(struct failtest_call *call)
{
if (*failpath == '\0') {
/* Continue, but don't inject errors. */
return call->fail = false;
}
if (tolower((unsigned char)*failpath) != info_to_arg[call->type])
errx(1, "Failpath expected '%s' got '%c'\n",
failpath, info_to_arg[call->type]);
call->fail = cisupper(*(failpath++));
return call->fail;
}
static bool should_fail(struct failtest_call *call) static bool should_fail(struct failtest_call *call)
{ {
int status; int status;
...@@ -508,22 +534,8 @@ static bool should_fail(struct failtest_call *call) ...@@ -508,22 +534,8 @@ static bool should_fail(struct failtest_call *call)
if (call == &unrecorded_call) if (call == &unrecorded_call)
return false; return false;
if (failpath) { if (following_path())
/* + means continue after end, like normal. */ return follow_path(call);
if (*failpath == '+')
failpath = NULL;
else if (*failpath == '\0') {
/* Continue, but don't inject errors. */
return call->fail = false;
} else {
if (tolower((unsigned char)*failpath)
!= info_to_arg[call->type])
errx(1, "Failpath expected '%s' got '%c'\n",
failpath, info_to_arg[call->type]);
call->fail = cisupper(*(failpath++));
return call->fail;
}
}
/* Attach debugger if they asked for it. */ /* Attach debugger if they asked for it. */
if (debugpath) { if (debugpath) {
...@@ -850,6 +862,8 @@ int failtest_open(const char *pathname, ...@@ -850,6 +862,8 @@ int failtest_open(const char *pathname,
p->u.open.ret = open(pathname, call.flags, call.mode); p->u.open.ret = open(pathname, call.flags, call.mode);
if (p->u.open.ret == -1) { if (p->u.open.ret == -1) {
if (following_path())
follow_path(p);
p->fail = false; p->fail = false;
p->error = errno; p->error = errno;
} else if (should_fail(p)) { } else if (should_fail(p)) {
...@@ -1090,10 +1104,11 @@ int failtest_close(int fd, const char *file, unsigned line) ...@@ -1090,10 +1104,11 @@ int failtest_close(int fd, const char *file, unsigned line)
p = add_history(FAILTEST_CLOSE, file, line, &call); p = add_history(FAILTEST_CLOSE, file, line, &call);
p->fail = false; p->fail = false;
/* Consume close from failpath. */ /* Consume close from failpath (shouldn't tell us to fail). */
if (failpath) if (following_path()) {
if (should_fail(p)) if (follow_path(p))
abort(); abort();
}
if (fd < 0) if (fd < 0)
return close(fd); return close(fd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment