aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2016-05-29 18:34:09 -0400
committerDavid Robillard <d@drobilla.net>2016-05-29 18:34:09 -0400
commit8f7cac4752d427f833969d316542d7a82b4602ea (patch)
tree27dcc29cbca11aee2127ddcdc71a246fbed077e9
parent78e55b937ce347eef6387499ddd91d06d73e3a7c (diff)
downloadserd-8f7cac4752d427f833969d316542d7a82b4602ea.tar.gz
serd-8f7cac4752d427f833969d316542d7a82b4602ea.tar.bz2
serd-8f7cac4752d427f833969d316542d7a82b4602ea.zip
Fix handling of file I/O errors
-rw-r--r--NEWS3
-rw-r--r--src/reader.c13
-rw-r--r--src/serdi.c12
-rw-r--r--wscript11
4 files changed, 31 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index e85744a8..d334bc48 100644
--- a/NEWS
+++ b/NEWS
@@ -1,11 +1,12 @@
serd (0.22.3) unstable;
+ * Report I/O errors with message and return appropriate status code
* Fix potential out of bounds read
* Fix unaligned memory access, undefined behaviour which breaks on ARM
* Fix documentation generation
* Update serdi man page
- -- David Robillard <d@drobilla.net> Tue, 17 May 2016 11:58:20 -0400
+ -- David Robillard <d@drobilla.net> Sun, 29 May 2016 18:33:41 -0400
serd (0.22.0) stable;
diff --git a/src/reader.c b/src/reader.c
index e6af0b1c..5465dba6 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -87,6 +87,7 @@ struct SerdReaderImpl {
bool paging; ///< True iff reading a page at a time
bool strict; ///< True iff strict parsing
bool eof;
+ bool error;
bool seen_genid;
#ifdef SERD_STACK_CHECK
Ref* allocs; ///< Stack of push offsets
@@ -115,7 +116,13 @@ page(SerdReader* reader)
if (n_read == 0) {
reader->file_buf[0] = '\0';
reader->eof = true;
- return ferror(reader->fd) ? SERD_ERR_UNKNOWN : SERD_FAILURE;
+ if (ferror(reader->fd)) {
+ reader->error = true;
+ return r_err(reader, SERD_ERR_UNKNOWN,
+ "read error: %s\n", strerror(errno));
+ } else {
+ return SERD_FAILURE;
+ }
} else if (n_read < SERD_PAGE_SIZE) {
reader->file_buf[n_read] = '\0';
}
@@ -1446,7 +1453,7 @@ read_statement(SerdReader* reader)
switch (peek_byte(reader)) {
case '\0':
reader->eof = true;
- return true;
+ return !reader->error;
case '@':
TRY_RET(read_directive(reader));
read_ws_star(reader);
@@ -1472,7 +1479,7 @@ read_turtleDoc(SerdReader* reader)
while (!reader->eof) {
TRY_RET(read_statement(reader));
}
- return true;
+ return !reader->error;
}
SERD_API
diff --git a/src/serdi.c b/src/serdi.c
index 2054470e..9332519b 100644
--- a/src/serdi.c
+++ b/src/serdi.c
@@ -252,15 +252,19 @@ main(int argc, char** argv)
}
serd_reader_free(reader);
+ serd_writer_finish(writer);
+ serd_writer_free(writer);
+ serd_env_free(env);
+ serd_node_free(&base);
if (from_file) {
fclose(in_fd);
}
- serd_writer_finish(writer);
- serd_writer_free(writer);
- serd_env_free(env);
- serd_node_free(&base);
+ if (fclose(out_fd)) {
+ perror("serdi: write error");
+ status = SERD_ERR_UNKNOWN;
+ }
return (status > SERD_FAILURE) ? 1 : 0;
}
diff --git a/wscript b/wscript
index c8b314ff..59416f9c 100644
--- a/wscript
+++ b/wscript
@@ -416,6 +416,17 @@ def test(ctx):
'serdi_static %s > %s' % (nul, nul)],
0, name='serdi-cmd-good')
+ # Test read error by reading a directory
+ autowaf.run_test(ctx, APPNAME,
+ 'serdi_static "file://%s/"' % srcdir,
+ 1, name='read_error')
+
+ # Test write error by writing to /dev/full
+ if os.path.exists('/dev/full'):
+ autowaf.run_test(ctx, APPNAME,
+ 'serdi_static "file://%s/tests/good/manifest.ttl" > /dev/full' % srcdir,
+ 1, name='write_error')
+
autowaf.run_tests(ctx, APPNAME, [
'serdi_static -q "file://%s/tests/bad-id-clash.ttl" > %s' % (srcdir, nul),
'serdi_static > %s' % nul,