summaryrefslogtreecommitdiffstats
path: root/hw4/chttpd-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw4/chttpd-log.c')
-rw-r--r--hw4/chttpd-log.c89
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;
}