]> git.scottworley.com Git - tl-append/blobdiff - tl-append-test.c
test: Fix memory leak
[tl-append] / tl-append-test.c
index 20ae7fb6a7d807563f001e68ab7c56099a45f086..30cfaaec299f3c994215e00d8c0362698e479084 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/file.h>
 #include <time.h>
 #include <unistd.h>
 
 #include <time.h>
 #include <unistd.h>
 
@@ -27,9 +28,12 @@ const ex_t CONSUMED = {((time_t)-2), ((time_t)-2), NULL};
 static int is_end(ex_t exp) {
   return exp.a == END.a && exp.b == END.b && exp.message == END.message;
 }
 static int is_end(ex_t exp) {
   return exp.a == END.a && exp.b == END.b && exp.message == END.message;
 }
+static void consume(ex_t *exp) {
+  exp->a = CONSUMED.a;
+  exp->b = CONSUMED.b;
+}
 static int is_consumed(ex_t exp) {
 static int is_consumed(ex_t exp) {
-  return exp.a == CONSUMED.a && exp.b == CONSUMED.b &&
-         exp.message == CONSUMED.message;
+  return exp.a == CONSUMED.a && exp.b == CONSUMED.b;
 }
 static ex_t expectation(time_t a, time_t b, const char *message) {
   ex_t exp;
 }
 static ex_t expectation(time_t a, time_t b, const char *message) {
   ex_t exp;
@@ -125,7 +129,7 @@ static void verify_log_contents(const ex_t exps[]) {
 static void consume_expectation(ex_t exps[], const char *line) {
   for (size_t i = 0; !is_end(exps[i]); i++) {
     if (line_problem(&exps[i], line) == NULL) {
 static void consume_expectation(ex_t exps[], const char *line) {
   for (size_t i = 0; !is_end(exps[i]); i++) {
     if (line_problem(&exps[i], line) == NULL) {
-      exps[i] = CONSUMED;
+      consume(&exps[i]);
       return;
     }
   }
       return;
     }
   }
@@ -170,7 +174,7 @@ static void test_encode_time() {
   if (tt == (time_t)-1)
     die_err("Can't pack time?");
 
   if (tt == (time_t)-1)
     die_err("Can't pack time?");
 
-  const char *encoded = encode_time(tt);
+  char *encoded = encode_time(tt);
   /* Loose check to allow for daylight savings time changes between the current
    * time and the target time.  :( */
   assert(encoded[0] == '2');
   /* Loose check to allow for daylight savings time changes between the current
    * time and the target time.  :( */
   assert(encoded[0] == '2');
@@ -193,21 +197,26 @@ static void test_encode_time() {
   assert(encoded[17] == '1');
   assert(encoded[18] == '6');
   assert(encoded[19] == '\0');
   assert(encoded[17] == '1');
   assert(encoded[18] == '6');
   assert(encoded[19] == '\0');
+  free(encoded);
 }
 
 }
 
-static FILE *take_lock() {
-  FILE *f = fopen(FILENAME, "a");
-  if (f == NULL)
-    die_err("Couldn't open file for locking");
+static FILE *take_lock(FILE *f, char *lock_type) {
   int fd = fileno(f);
   if (fd == -1)
     die_err("Couldn't get file descriptor for locking");
   int fd = fileno(f);
   if (fd == -1)
     die_err("Couldn't get file descriptor for locking");
-  if (fcntl(fd, F_SETLK,
-            &(struct flock){.l_type = F_WRLCK,
-                            .l_whence = SEEK_SET,
-                            .l_start = 0,
-                            .l_len = 0}) == -1)
-    die_err("Couldn't take lock");
+  if (strcmp(lock_type, "fcntl") == 0) {
+    if (fcntl(fd, F_SETLK,
+              &(struct flock){.l_type = F_WRLCK,
+                              .l_whence = SEEK_SET,
+                              .l_start = 0,
+                              .l_len = 0}) == -1)
+      die_err("Couldn't take fcntl lock");
+  } else if (strcmp(lock_type, "flock") == 0) {
+    if (flock(fd, LOCK_EX) == -1)
+      die_err("Couldn't take flock lock");
+  } else {
+    die("Bad lock type");
+  }
   return f;
 }
 
   return f;
 }
 
@@ -217,7 +226,7 @@ static void release_lock(FILE *f) {
 }
 
 static void *release_lock_after_delay(void *f) {
 }
 
 static void *release_lock_after_delay(void *f) {
-  sleep(2);
+  sleep(1);
   release_lock((FILE *)f);
   return NULL;
 }
   release_lock((FILE *)f);
   return NULL;
 }
@@ -247,13 +256,17 @@ static void write_and_read_two_lines() {
   verify_log_contents((ex_t[]){e1, e2, END});
 }
 
   verify_log_contents((ex_t[]){e1, e2, END});
 }
 
-static void write_to_locked_log() {
+static void write_to_locked_log(char *lock_types[]) {
   remove_logfile();
   ex_t e1 = write_to_tl_append("begin\n");
   remove_logfile();
   ex_t e1 = write_to_tl_append("begin\n");
-  FILE *lock = take_lock();
+  FILE *f = fopen(FILENAME, "ae");
+  if (f == NULL)
+    die_err("Couldn't open file for locking");
+  for (int i = 0; lock_types[i]; i++)
+    take_lock(f, lock_types[0]);
   pthread_t unlock_thread;
   int create_ret =
   pthread_t unlock_thread;
   int create_ret =
-      pthread_create(&unlock_thread, NULL, &release_lock_after_delay, lock);
+      pthread_create(&unlock_thread, NULL, &release_lock_after_delay, f);
   if (create_ret != 0) {
     errno = create_ret;
     die_err("Couldn't start thread");
   if (create_ret != 0) {
     errno = create_ret;
     die_err("Couldn't start thread");
@@ -295,12 +308,19 @@ static void write_concurrently() {
   }
   results[PARALLELISM] = END;
   verify_log_contents_unordered(results);
   }
   results[PARALLELISM] = END;
   verify_log_contents_unordered(results);
+  for (int i = 0; i < PARALLELISM; i++) {
+    free((void *)results[i].message);
+  }
 }
 
 int main() {
   test_encode_time();
   write_and_read_line();
   write_and_read_two_lines();
 }
 
 int main() {
   test_encode_time();
   write_and_read_line();
   write_and_read_two_lines();
-  write_to_locked_log();
+  write_to_locked_log((char *[]){NULL});
+  write_to_locked_log((char *[]){"fcntl", NULL});
+  write_to_locked_log((char *[]){"flock", NULL});
+  write_to_locked_log((char *[]){"flock", "fcntl", NULL}); /* Deadlock risk! */
+  write_to_locked_log((char *[]){"fcntl", "flock", NULL});
   write_concurrently();
 }
   write_concurrently();
 }