diff --git a/libc3/facts.c b/libc3/facts.c
index e41ae7b..74c0f3f 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -10,9 +10,9 @@
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
-#include <err.h>
#include <errno.h>
-#include <stdlib.h>
+#include <string.h>
+#include "alloc.h"
#include "assert.h"
#include "buf.h"
#include "buf_file.h"
@@ -24,6 +24,7 @@
#include "facts.h"
#include "facts_cursor.h"
#include "facts_with.h"
+#include "file.h"
#include "io.h"
#include "list.h"
#include "log.h"
@@ -56,7 +57,8 @@ s_fact * facts_add_fact (s_facts *facts, const s_fact *fact)
}
tmp.id = facts->next_id;
if (facts->next_id == UW_MAX) {
- errx(1, "facts serial id exhausted");
+ err_puts("facts_add_fact: facts serial id exhausted");
+ assert(! "facts_add_fact: facts serial id exhausted");
return NULL;
}
facts->next_id++;
@@ -174,10 +176,9 @@ sw facts_dump_file (s_facts *facts, const char *path)
assert(facts);
assert(path);
buf_init(&buf, false, sizeof(b), b);
- if (! (fp = fopen(path, "wb"))) {
- warn("fopen: %s", path);
+ fp = file_open(path, "wb");
+ if (! fp)
return -1;
- }
buf_file_open_w(&buf, fp);
r = facts_dump(facts, &buf);
buf_file_close(&buf);
@@ -292,15 +293,17 @@ sw facts_load (s_facts *facts, s_buf *buf, const s_str *path)
facts_lock_unlock_w(facts);
return result;
ko_header:
- warnx("facts_load: %s: invalid or missing header",
- path->ptr.pchar);
+ err_write_1("facts_load: invalid or missing header: ");
+ err_puts(path->ptr.pchar);
return -1;
ko_fact:
facts_lock_unlock_w(facts);
- warnx("facts_load: %s: %s fact line %lu",
- path->ptr.pchar,
- r ? "invalid" : "missing",
- (unsigned long) line);
+ err_write_1("facts_load: ");
+ err_write_1(r ? "invalid" : "missing");
+ err_write_1(" fact line ");
+ err_inspect_u64(&line);
+ err_write_1(": ");
+ err_write_1(path->ptr.pchar);
return -1;
}
@@ -313,10 +316,9 @@ sw facts_load_file (s_facts *facts, const s_str *path)
assert(facts);
assert(path);
buf_init(&buf, false, sizeof(b), b);
- if (! (fp = fopen(path->ptr.pchar, "rb"))) {
- warn("facts_load_file: %s", path->ptr.pchar);
+ fp = file_open(path->ptr.pchar, "rb");
+ if (! fp)
return -1;
- }
buf_file_open_r(&buf, fp);
result = facts_load(facts, &buf, path);
buf_file_close(&buf);
@@ -324,67 +326,90 @@ sw facts_load_file (s_facts *facts, const s_str *path)
return result;
}
-void facts_lock_clean (s_facts *facts)
+s_facts * facts_lock_clean (s_facts *facts)
{
assert(facts);
- if (pthread_rwlock_destroy(&facts->rwlock))
- errx(1, "facts_lock_clean: pthread_rwlock_destroy");
+ if (pthread_rwlock_destroy(&facts->rwlock)) {
+ err_puts("facts_lock_clean: pthread_rwlock_destroy");
+ assert(! "facts_lock_clean: pthread_rwlock_destroy");
+ return NULL;
+ }
+ return facts;
}
-void facts_lock_init (s_facts *facts)
+s_facts * facts_lock_init (s_facts *facts)
{
assert(facts);
- if (pthread_rwlock_init(&facts->rwlock, NULL))
- errx(1, "facts_lock_init: pthread_rwlock_init");
+ if (pthread_rwlock_init(&facts->rwlock, NULL)) {
+ err_puts("facts_lock_init: pthread_rwlock_init");
+ assert(! "facts_lock_init: pthread_rwlock_init");
+ return NULL;
+ }
facts->rwlock_count = 0;
facts->rwlock_thread = 0;
+ return facts;
}
-void facts_lock_r (s_facts *facts)
+s_facts * facts_lock_r (s_facts *facts)
{
pthread_t thread;
assert(facts);
thread = pthread_self();
- if (facts->rwlock_thread == thread)
- return;
- if (pthread_rwlock_rdlock(&facts->rwlock))
- errx(1, "facts_lock_r: pthread_rwlock_rdlock");
+ if (facts->rwlock_thread != thread &&
+ pthread_rwlock_rdlock(&facts->rwlock)) {
+ err_puts("facts_lock_r: pthread_rwlock_rdlock");
+ assert(! "facts_lock_r: pthread_rwlock_rdlock");
+ return NULL;
+ }
+ return facts;
}
-void facts_lock_unlock_r (s_facts *facts)
+s_facts * facts_lock_unlock_r (s_facts *facts)
{
pthread_t thread;
assert(facts);
thread = pthread_self();
- if (facts->rwlock_thread == thread)
- return;
- if (pthread_rwlock_unlock(&facts->rwlock))
- errx(1, "facts_lock_unlock_r: pthread_rwlock_unlock");
+ if (facts->rwlock_thread != thread &&
+ pthread_rwlock_unlock(&facts->rwlock)) {
+ err_puts("facts_lock_unlock_r: pthread_rwlock_unlock");
+ assert(! "facts_lock_unlock_r: pthread_rwlock_unlock");
+ return NULL;
+ }
+ return facts;
}
-void facts_lock_unlock_w (s_facts *facts)
+s_facts * facts_lock_unlock_w (s_facts *facts)
{
assert(facts);
+ assert(facts->rwlock_count);
facts->rwlock_count--;
if (! facts->rwlock_count) {
facts->rwlock_thread = 0;
- if (pthread_rwlock_unlock(&facts->rwlock))
- errx(1, "facts_lock_unlock_w: pthread_rwlock_unlock");
+ if (pthread_rwlock_unlock(&facts->rwlock)) {
+ err_puts("facts_lock_unlock_w: pthread_rwlock_unlock");
+ assert(! "facts_lock_unlock_w: pthread_rwlock_unlock");
+ return NULL;
+ }
}
+ return facts;
}
-void facts_lock_w (s_facts *facts)
+s_facts * facts_lock_w (s_facts *facts)
{
pthread_t thread;
assert(facts);
thread = pthread_self();
if (facts->rwlock_thread != thread) {
- if (pthread_rwlock_wrlock(&facts->rwlock))
- errx(1, "facts_lock_w: pthread_rwlock_wrlock");
+ if (pthread_rwlock_wrlock(&facts->rwlock)) {
+ err_puts("facts_lock_w: pthread_rwlock_wrlock");
+ assert(! "facts_lock_w: pthread_rwlock_wrlock");
+ return NULL;
+ }
facts->rwlock_thread = thread;
facts->rwlock_count = 0;
}
facts->rwlock_count++;
+ return facts;
}
sw facts_log_add (s_log *log, const s_fact *fact)
@@ -423,10 +448,15 @@ sw facts_log_remove (s_log *log, const s_fact *fact)
s_facts * facts_new (void)
{
- s_facts *n;
- if (! (n = malloc(sizeof(s_facts))))
- errx(1, "facts_new: out of memory");
- return facts_init(n);
+ s_facts *facts;
+ facts = alloc(sizeof(s_facts));
+ if (! facts)
+ return NULL;
+ if (! facts_init(facts)) {
+ free(facts);
+ return NULL;
+ }
+ return facts;
}
sw facts_open_buf (s_facts *facts, s_buf *buf, const s_str *path)
@@ -450,7 +480,8 @@ sw facts_open_file (s_facts *facts, const s_str *path)
sw r;
sw result = 0;
buf_init(&in, false, sizeof(i), i);
- if (! (fp = fopen(path->ptr.pchar, "rb"))) {
+ fp = fopen(path->ptr.pchar, "rb");
+ if (! fp) {
if (errno == ENOENT)
return facts_open_file_create(facts, path);
return -1;
@@ -460,10 +491,9 @@ sw facts_open_file (s_facts *facts, const s_str *path)
return r;
result += r;
buf_file_close(&in);
- if (! (fp = fopen(path->ptr.pchar, "ab"))) {
- warn("facts_open_file: fopen: %s", path->ptr.pchar);
+ fp = file_open(path->ptr.pchar, "ab");
+ if (! fp)
return -1;
- }
if (! (facts->log = log_new()))
return -1;
log_open(facts->log, fp);
@@ -476,16 +506,16 @@ sw facts_open_file_create (s_facts *facts, const s_str *path)
s_buf *out;
sw r;
sw result = 0;
- if (! (fp = fopen(path->ptr.pchar, "wb"))) {
- warn("facts_open_file_create: fopen: %s", path->ptr.pchar);
+ fp = file_open(path->ptr.pchar, "wb");
+ if (! fp)
return -1;
- }
if (facts_count(facts)) {
/* TODO: clear facts
facts_close(facts);
facts_remove_all(facts);
*/
- warnx("facts_open_file: not supported");
+ err_puts("facts_open_file: not implemented");
+ assert(! "facts_open_file: not implemented");
return -1;
}
out = buf_new_alloc(BUF_SIZE);
@@ -672,10 +702,9 @@ sw facts_save_file (s_facts *facts, const char *path)
assert(path);
assert(! facts->log);
buf_init(&buf, false, sizeof(b), b);
- if (! (fp = fopen(path, "wb"))) {
- warn("fopen: %s", path);
+ fp = file_open(path, "wb");
+ if (! fp)
return -1;
- }
buf_file_open_w(&buf, fp);
if ((r = facts_dump(facts, &buf)) < 0)
goto ko;
diff --git a/libc3/facts.h b/libc3/facts.h
index 9603dad..60773e7 100644
--- a/libc3/facts.h
+++ b/libc3/facts.h
@@ -30,32 +30,32 @@ s_facts * facts_new (void);
void facts_delete (s_facts *facts);
/* Modifiers */
-s_fact * facts_add_fact (s_facts *facts, const s_fact *fact);
-s_fact * facts_add_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object);
-void facts_close (s_facts *facts);
-sw facts_load (s_facts *facts, s_buf *buf, const s_str *path);
-sw facts_load_file (s_facts *facts, const s_str *path);
-void facts_lock_clean (s_facts *facts);
-void facts_lock_init (s_facts *facts);
-void facts_lock_r (s_facts *facts);
-void facts_lock_unlock_r (s_facts *facts);
-void facts_lock_unlock_w (s_facts *facts);
-void facts_lock_w (s_facts *facts);
-sw facts_open_file (s_facts *facts, const s_str *path);
-s_tag * facts_ref_tag (s_facts *facts, const s_tag *tag);
-bool facts_remove_fact (s_facts *facts, const s_fact *fact);
-bool facts_remove_fact_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object);
-void facts_remove_all (s_facts *facts);
-s_fact * facts_replace_fact (s_facts *facts, const s_fact *fact);
-s_fact * facts_replace_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object);
-sw facts_save_file (s_facts *facts, const char *path);
-bool facts_unref_tag (s_facts *facts, const s_tag *tag);
+s_fact * facts_add_fact (s_facts *facts, const s_fact *fact);
+s_fact * facts_add_tags (s_facts *facts, const s_tag *subject,
+ const s_tag *predicate,
+ const s_tag *object);
+void facts_close (s_facts *facts);
+sw facts_load (s_facts *facts, s_buf *buf, const s_str *path);
+sw facts_load_file (s_facts *facts, const s_str *path);
+s_facts * facts_lock_clean (s_facts *facts);
+s_facts * facts_lock_init (s_facts *facts);
+s_facts * facts_lock_r (s_facts *facts);
+s_facts * facts_lock_unlock_r (s_facts *facts);
+s_facts * facts_lock_unlock_w (s_facts *facts);
+s_facts * facts_lock_w (s_facts *facts);
+sw facts_open_file (s_facts *facts, const s_str *path);
+s_tag * facts_ref_tag (s_facts *facts, const s_tag *tag);
+bool facts_remove_fact (s_facts *facts, const s_fact *fact);
+bool facts_remove_fact_tags (s_facts *facts, const s_tag *subject,
+ const s_tag *predicate,
+ const s_tag *object);
+void facts_remove_all (s_facts *facts);
+s_fact * facts_replace_fact (s_facts *facts, const s_fact *fact);
+s_fact * facts_replace_tags (s_facts *facts, const s_tag *subject,
+ const s_tag *predicate,
+ const s_tag *object);
+sw facts_save_file (s_facts *facts, const char *path);
+bool facts_unref_tag (s_facts *facts, const s_tag *tag);
/* Observers */
sw facts_dump (s_facts *facts, s_buf *buf);
diff --git a/libc3/facts_cursor.c b/libc3/facts_cursor.c
index 8020776..9c4afe7 100644
--- a/libc3/facts_cursor.c
+++ b/libc3/facts_cursor.c
@@ -10,9 +10,7 @@
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
-#include <assert.h>
-#include <err.h>
-#include <stdlib.h>
+#include "assert.h"
#include "facts.h"
#include "facts_cursor.h"
#include "skiplist__fact.h"
@@ -64,8 +62,11 @@ s_facts_cursor * facts_cursor_init (s_facts *facts,
s_facts_cursor * facts_cursor_lock (s_facts_cursor *cursor)
{
assert(cursor);
- if (pthread_mutex_lock(&cursor->mutex))
- errx(1, "facts_cursor_lock: pthread_mutex_lock");
+ if (pthread_mutex_lock(&cursor->mutex)) {
+ err_puts("facts_cursor_lock: pthread_mutex_lock");
+ assert(! "facts_cursor_lock: pthread_mutex_lock");
+ return NULL;
+ }
facts_lock_r(cursor->facts);
return cursor;
}
@@ -73,16 +74,22 @@ s_facts_cursor * facts_cursor_lock (s_facts_cursor *cursor)
s_facts_cursor * facts_cursor_lock_clean (s_facts_cursor *cursor)
{
assert(cursor);
- if (pthread_mutex_destroy(&cursor->mutex))
- errx(1, "facts_cursor_lock_clean: pthread_mutex_destroy");
+ if (pthread_mutex_destroy(&cursor->mutex)) {
+ err_puts("facts_cursor_lock_clean: pthread_mutex_destroy");
+ assert(! "facts_cursor_lock_clean: pthread_mutex_destroy");
+ return NULL;
+ }
return cursor;
}
s_facts_cursor * facts_cursor_lock_init (s_facts_cursor *cursor)
{
assert(cursor);
- if (pthread_mutex_init(&cursor->mutex, NULL))
- errx(1, "facts_cursor_lock_init: pthread_mutex_init");
+ if (pthread_mutex_init(&cursor->mutex, NULL)) {
+ err_puts("facts_cursor_lock_init: pthread_mutex_init");
+ assert(! "facts_cursor_lock_init: pthread_mutex_init");
+ return NULL;
+ }
return cursor;
}
@@ -90,8 +97,11 @@ s_facts_cursor * facts_cursor_lock_unlock (s_facts_cursor *cursor)
{
assert(cursor);
facts_lock_unlock_r(cursor->facts);
- if (pthread_mutex_unlock(&cursor->mutex))
- errx(1, "facts_cursor_lock_unlock: pthread_mutex_unlock");
+ if (pthread_mutex_unlock(&cursor->mutex)) {
+ err_puts("facts_cursor_lock_unlock: pthread_mutex_unlock");
+ assert(! "facts_cursor_lock_unlock: pthread_mutex_unlock");
+ return NULL;
+ }
return cursor;
}
diff --git a/libc3/facts_with_cursor.c b/libc3/facts_with_cursor.c
index 44a482e..082efd0 100644
--- a/libc3/facts_with_cursor.c
+++ b/libc3/facts_with_cursor.c
@@ -11,7 +11,6 @@
* THIS SOFTWARE.
*/
#include "assert.h"
-#include <stdlib.h>
#include "buf.h"
#include "buf_inspect.h"
#include "env.h"
diff --git a/libc3/file.c b/libc3/file.c
index 7c4215d..298a5c7 100644
--- a/libc3/file.c
+++ b/libc3/file.c
@@ -12,8 +12,8 @@
*/
#include "assert.h"
#include <fcntl.h>
-#include <err.h>
#include <errno.h>
+#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "buf.h"
@@ -55,9 +55,10 @@ bool * file_access (const s_str *path, const s_sym *mode,
return dest;
}
-sw file_copy_1 (const char *from, const char *to)
+sw file_copy (const char *from, const char *to)
{
char buf[4096];
+ s32 e;
sw fd_from = -1;
sw fd_to = -1;
char *out;
@@ -65,11 +66,21 @@ sw file_copy_1 (const char *from, const char *to)
sw saved_errno;
sw w;
if ((fd_from = open(from, O_RDONLY | O_BINARY)) < 0) {
- warn("cp: %s", from);
+ e = errno;
+ err_write_1("file_copy: ");
+ err_write_1(strerror(e));
+ err_write_1(": ");
+ err_puts(from);
+ assert(! "file_copy: failed to open file for reading");
return -1;
}
if ((fd_to = open(to, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) < 0) {
- warn("cp: %s", to);
+ e = errno;
+ err_write_1("file_copy: ");
+ err_write_1(strerror(e));
+ err_write_1(": ");
+ err_puts(to);
+ assert(! "file_copy: failed to open file for writing");
goto error;
}
while ((r = read(fd_from, buf, sizeof buf)) > 0) {
@@ -114,11 +125,16 @@ s_str * file_dirname (const s_str *path, s_str *dest)
s_tag * file_mtime (const s_str *path, s_tag *dest)
{
+ s32 e;
struct stat sb;
assert(path);
assert(dest);
if (stat(path->ptr.pchar, &sb)) {
- warn("file_mtime: %s", path->ptr.pchar);
+ e = errno;
+ err_write_1("file_mtime: ");
+ err_write_1(strerror(e));
+ err_write_1(": ");
+ err_puts(path->ptr.pchar);
return NULL;
}
#if HAVE_STAT_MTIM
@@ -131,6 +147,23 @@ s_tag * file_mtime (const s_str *path, s_tag *dest)
#endif
}
+FILE * file_open (const char *path, const char *mode)
+{
+ s32 e;
+ FILE *fp;
+ fp = fopen(path, mode);
+ if (! fp) {
+ e = errno;
+ err_write_1("file_open: ");
+ err_write_1(strerror(e));
+ err_write_1(": ");
+ err_puts(path);
+ assert(! "facts_open_file: fopen");
+ return NULL;
+ }
+ return fp;
+}
+
s_str * file_search (const s_str *suffix, const s_sym *mode,
s_str *dest)
{
diff --git a/libc3/file.h b/libc3/file.h
index 9813e1e..3eed5e8 100644
--- a/libc3/file.h
+++ b/libc3/file.h
@@ -27,10 +27,13 @@
/* Observers */
bool * file_access (const s_str *path, const s_sym *mode,
bool *dest);
-sw file_copy_1 (const char *from, const char *to);
+sw file_copy (const char *from, const char *to);
s_str * file_dirname (const s_str *path, s_str *dest);
s_tag * file_mtime (const s_str *path, s_tag *dest);
s_str * file_search (const s_str *suffix, const s_sym *mode,
s_str *dest);
+/* Operators. */
+FILE * file_open (const char *path, const char *mode);
+
#endif /* LIBC3_FILE_H */
diff --git a/test/facts_test.c b/test/facts_test.c
index de7c8cc..27d27ac 100644
--- a/test/facts_test.c
+++ b/test/facts_test.c
@@ -447,9 +447,9 @@ TEST_CASE(facts_open_file)
s_fact fact;
s_facts facts;
s_str path;
- if (file_copy_1("facts_test_open_file.1.in.facts",
- "facts_test_open_file.1.facts")) {
- fprintf(stderr, "%s:%i: %s: file_copy_1\n", __FILE__, __LINE__,
+ if (file_copy("facts_test_open_file.1.in.facts",
+ "facts_test_open_file.1.facts")) {
+ fprintf(stderr, "%s:%i: %s: file_copy\n", __FILE__, __LINE__,
__func__);
exit(1);
}
@@ -480,9 +480,9 @@ TEST_CASE(facts_open_file)
if (g_test_last_ok)
unlink("facts_test_open_file.1.facts");
facts_init(&facts);
- if (file_copy_1("facts_test_open_file.2.in.facts",
- "facts_test_open_file.2.facts")) {
- fprintf(stderr, "%s:%i: %s: file_copy_1", __FILE__, __LINE__,
+ if (file_copy("facts_test_open_file.2.in.facts",
+ "facts_test_open_file.2.facts")) {
+ fprintf(stderr, "%s:%i: %s: file_copy", __FILE__, __LINE__,
__func__);
exit(1);
}
@@ -510,9 +510,9 @@ TEST_CASE(facts_open_file)
if (g_test_last_ok)
unlink("facts_test_open_file.2.facts");
facts_init(&facts);
- if (file_copy_1("facts_test_open_file.3.in.facts",
- "facts_test_open_file.3.facts")) {
- fprintf(stderr, "%s:%i: %s: file_copy_1", __FILE__, __LINE__,
+ if (file_copy("facts_test_open_file.3.in.facts",
+ "facts_test_open_file.3.facts")) {
+ fprintf(stderr, "%s:%i: %s: file_copy", __FILE__, __LINE__,
__func__);
exit(1);
}