diff options
Diffstat (limited to 'hw4/chttpd-log.c')
-rw-r--r-- | hw4/chttpd-log.c | 89 |
1 files changed, 88 insertions, 1 deletions
diff --git a/hw4/chttpd-log.c b/hw4/chttpd-log.c index 24dae72..d93f378 100644 --- a/hw4/chttpd-log.c +++ b/hw4/chttpd-log.c @@ -4,10 +4,97 @@ #endif #include "chttpd-log.h" +#include "memwrap.h" #include <l4list.h> +#include <l4posix.h> +#include <fcntl.h> +#include <pthread.h> +#include <stdlib.h> #include <string.h> +#include <unistd.h> ChttpdLog* chttpd_log_new (const char* name, int log_fd) { - return NULL; + size_t name_len = (name == NULL) ? 0 : strlen (name); + char* mem = xmalloc (sizeof (ChttpdLog) + name_len + 1); + void* mem_generic = mem; + + ChttpdLog* hlog = mem_generic; + hlog->name = mem + sizeof (ChttpdLog); + if (name != NULL) { + strncpy (hlog->name, name, name_len + 1); + } + hlog->name[name_len] = '\0'; + + hlog->ref_count = 1; + hlog->pid = getpid (); + hlog->log_fd = log_fd; + hlog->log_data = lbs_list_meta_new (free); + pthread_rwlock_init (&hlog->rwlock, NULL); + + return hlog; +} + +ChttpdLog* chttpd_log_new_file (const char* name, const char* file) { + int log_fd = open (file, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, 0600); + if (log_fd < 0) { + return NULL; + } + + return chttpd_log_new (name, log_fd); +} + +ChttpdLog* chttpd_log_ref (ChttpdLog* hlog) { + hlog->ref_count++; + return hlog; +} + +void chttpd_log_unref (ChttpdLog* hlog) { + hlog->ref_count--; + if (hlog->ref_count <= 0) { + free (hlog); + } +} + +int chttpd_log_read_start (ChttpdLog* hlog) { + return pthread_rwlock_tryrdlock (&hlog->rwlock); +} + +void chttpd_log_read_stop (ChttpdLog* hlog) { + pthread_rwlock_unlock (&hlog->rwlock); +} + +size_t chttpd_log_write (ChttpdLog* hlog, const char* format, ...) { + va_list ap; + char* str; + size_t r; + + va_start (ap, format); + str = lbs_str_vprintf (format, ap); + va_end (ap); + + r = chttpd_log_write_str (hlog, str); + free (str); + return r; +} + +size_t chttpd_log_write_str (ChttpdLog* hlog, const char* string) { + time_t t; + struct tm tmd; + char* msg; + size_t r; + + time (&t); + localtime_r (&t, &tmd); + msg = lbs_str_printf ("%04d-%02d-%02d %02d:%02d:%02d %s[%ld]: %s\n", + tmd.tm_year, tmd.tm_mon + 1, tmd.tm_mday, + tmd.tm_hour, tmd.tm_min, tmd.tm_sec, + hlog->name, (long)(hlog->pid), string); + + pthread_rwlock_wrlock (&hlog->rwlock); + lbs_list_push_back (hlog->log_data, msg, NULL); + r = write (hlog->log_fd, msg, 0); + pthread_rwlock_unlock (&hlog->rwlock); + + return r; } |