1#include "removefile.h" 2#include <assert.h> 3#include <errno.h> 4#include <stdio.h> 5#include <fcntl.h> 6#include <pthread.h> 7#include <unistd.h> 8 9static struct timeval tv; 10static void start_timer(const char* str) { 11 fprintf(stderr, "%s... ", str); 12 assert(gettimeofday(&tv, NULL) == 0); 13} 14 15static void stop_timer() { 16 struct timeval tv2; 17 assert(gettimeofday(&tv2, NULL) == 0); 18 long sec = tv2.tv_sec - tv.tv_sec; 19 long usec; 20 if (sec == 0) { 21 usec = tv2.tv_usec - tv.tv_usec; 22 } else { 23 usec = tv2.tv_usec + (1000000 - tv.tv_usec); 24 } 25 fprintf(stderr, "%d.%03d\n", sec, usec); 26} 27 28 29static int removefile_confirm_callback(removefile_state_t state, const char * path, void * context) { 30 assert(context == (void*)1234); 31 fprintf(stderr, "confirm callback: %s\n", path); 32 return REMOVEFILE_PROCEED; 33} 34 35static int removefile_error_callback(removefile_state_t state, const char * path, void * context) { 36 assert(context == (void*)4567); 37 int err = 0; 38 assert(removefile_state_get(state, REMOVEFILE_STATE_ERRNO, &err) == 0); 39 fprintf(stderr, "error callback: %s: %s (%d)\n", path, strerror(err), err); 40 return REMOVEFILE_PROCEED; 41} 42 43static int removefile_status_callback(removefile_state_t state, const char * path, void * context) { 44 fprintf(stderr, "status callback: %s\n", path); 45 return REMOVEFILE_PROCEED; 46} 47 48 49int mkdirs() { 50 start_timer("Creating directory structure"); 51 assert(mkdir("/tmp/removefile-test", 0755) == 0); 52 assert(mkdir("/tmp/removefile-test/foo", 0755) == 0); 53 assert(mkdir("/tmp/removefile-test/foo/bar", 0755) == 0); 54 assert(mkdir("/tmp/removefile-test/foo/baz", 0755) == 0); 55 int fd; 56 assert((fd = open("/tmp/removefile-test/foo/baz/woot", O_CREAT | O_TRUNC | O_WRONLY, 0644)) != -1); 57 write(fd, "Hello World\n", 12); 58 close(fd); 59 assert((fd = open("/tmp/removefile-test/foo/baz/wootage", O_CREAT | O_TRUNC | O_WRONLY, 0644)) != -1); 60 write(fd, "Hello World\n", 12); 61 assert(lseek(fd, 1024*1024*30, SEEK_SET) != -1); 62 write(fd, "Goodbye Moon\n", 13); 63 close(fd); 64 stop_timer(); 65} 66 67void* threadproc(void* state) { 68 sleep(1); 69 fprintf(stderr, "cancelling...\n"); 70 assert(removefile_cancel(state) == 0); 71 return NULL; 72} 73 74int main(int argc, char *argv[]) { 75 removefile_state_t state = NULL; 76 removefile_callback_t callback = NULL; 77 pthread_t thread = NULL; 78 int err = 0; 79 80 mkdirs(); 81 start_timer("removefile(NULL)"); 82 assert(removefile("/tmp/removefile-test", NULL, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == 0); 83 stop_timer(); 84 85 86 mkdirs(); 87 assert((state = removefile_state_alloc()) != NULL); 88 assert(pthread_create(&thread, NULL, threadproc, state) == 0); 89 start_timer("removefile(state) with cancel"); 90 assert(removefile_state_set(state, REMOVEFILE_STATE_ERROR_CALLBACK, removefile_error_callback) == 0); 91 assert(removefile_state_set(state, REMOVEFILE_STATE_ERROR_CONTEXT, (void*)4567) == 0); 92 assert(removefile("/tmp/removefile-test", state, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == -1 && errno == ECANCELED); 93 stop_timer(); 94 95 start_timer("removefile(NULL)"); 96 assert(removefile("/tmp/removefile-test", NULL, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == 0); 97 stop_timer(); 98 99 mkdirs(); 100 assert(removefile_state_set(state, 1234567, (void*)1234567) == -1 && errno == EINVAL); 101 102 assert(removefile_state_set(state, REMOVEFILE_STATE_CONFIRM_CALLBACK, removefile_confirm_callback) == 0); 103 assert(removefile_state_get(state, REMOVEFILE_STATE_CONFIRM_CALLBACK, &callback) == 0); 104 assert(callback == removefile_confirm_callback); 105 assert(removefile_state_set(state, REMOVEFILE_STATE_CONFIRM_CONTEXT, (void*)1234) == 0); 106 107 assert(removefile_state_set(state, REMOVEFILE_STATE_ERROR_CALLBACK, removefile_error_callback) == 0); 108 assert(removefile_state_get(state, REMOVEFILE_STATE_ERROR_CALLBACK, &callback) == 0); 109 assert(callback == removefile_error_callback); 110 assert(removefile_state_set(state, REMOVEFILE_STATE_ERROR_CONTEXT, (void*)4567) == 0); 111 112 assert(removefile_state_set(state, REMOVEFILE_STATE_STATUS_CALLBACK, removefile_status_callback) == 0); 113 assert(removefile_state_get(state, REMOVEFILE_STATE_STATUS_CALLBACK, &callback) == 0); 114 assert(callback == removefile_status_callback); 115 assert(removefile_state_set(state, REMOVEFILE_STATE_STATUS_CONTEXT, (void*)5678) == 0); 116 117 start_timer("removefile(state)"); 118 assert(removefile("/tmp/removefile-test", state, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == 0); 119 stop_timer(); 120 121 return 0; 122} 123