summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2014-01-13 02:06:02 +0800
committerLAN-TW <lantw44@gmail.com>2014-01-13 02:06:02 +0800
commit99e1a8d891c28d0ddde865260d5c3164b3fcfdd9 (patch)
tree8d924bf3904fab643cab15355230b7ad73d5da7d
parentba60d74714815661bc16f49ac02b5976abe78a5e (diff)
downloadsp2013-99e1a8d891c28d0ddde865260d5c3164b3fcfdd9.tar
sp2013-99e1a8d891c28d0ddde865260d5c3164b3fcfdd9.tar.gz
sp2013-99e1a8d891c28d0ddde865260d5c3164b3fcfdd9.tar.bz2
sp2013-99e1a8d891c28d0ddde865260d5c3164b3fcfdd9.tar.lz
sp2013-99e1a8d891c28d0ddde865260d5c3164b3fcfdd9.tar.xz
sp2013-99e1a8d891c28d0ddde865260d5c3164b3fcfdd9.tar.zst
sp2013-99e1a8d891c28d0ddde865260d5c3164b3fcfdd9.zip
HW4: 加入 ChttpdLog 的實作與修正問題
-rw-r--r--hw4/chttpd-log.c89
-rw-r--r--hw4/chttpd-log.h17
-rw-r--r--hw4/configure.ac2
-rw-r--r--hw4/l4basic/l4str.c22
-rw-r--r--hw4/l4basic/l4str.h2
-rw-r--r--hw4/memwrap.c2
6 files changed, 118 insertions, 16 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;
}
diff --git a/hw4/chttpd-log.h b/hw4/chttpd-log.h
index c29d421..92b2e5d 100644
--- a/hw4/chttpd-log.h
+++ b/hw4/chttpd-log.h
@@ -3,26 +3,27 @@
#include <l4list.h>
+#include <stddef.h>
#include <pthread.h>
#include <sys/types.h>
typedef struct {
- unsigned ref_count;
char* name;
+ unsigned ref_count;
pid_t pid;
int log_fd;
- LbsList* log_data;
+ LbsListMeta* log_data;
pthread_rwlock_t rwlock;
} ChttpdLog;
ChttpdLog* chttpd_log_new (const char* name, int log_fd);
ChttpdLog* chttpd_log_new_file (const char* name, const char* file);
-ChttpdLog* chttpd_log_ref (ChttpdLog* log);
-void chttpd_log_unref (ChttpdLog* log);
+ChttpdLog* chttpd_log_ref (ChttpdLog* hlog);
+void chttpd_log_unref (ChttpdLog* hlog);
-int chttpd_log_read_start (ChttpdLog* log);
-void chttpd_log_read_stop (ChttpdLog* log);
-int chttpd_log_write (ChttpdLog* log, const char* format, ...);
-int chttpd_log_write_str (ChttpdLog* log, const char* string);
+int chttpd_log_read_start (ChttpdLog* hlog);
+void chttpd_log_read_stop (ChttpdLog* hlog);
+size_t chttpd_log_write (ChttpdLog* hlog, const char* format, ...);
+size_t chttpd_log_write_str (ChttpdLog* hlog, const char* string);
#endif /* CHTTPD_LOG_H */
diff --git a/hw4/configure.ac b/hw4/configure.ac
index 255a1b0..2c16ab5 100644
--- a/hw4/configure.ac
+++ b/hw4/configure.ac
@@ -9,6 +9,8 @@ AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign])
AM_SILENT_RULES([yes])
+AC_DEFINE([_POSIX_C_SOURCE], [200809L], [Enable POSIX.1-2008 support])
+AC_DEFINE([_XOPEN_SOURCE], [700], [Enable X/OPEN system interfaces])
# Checks for programs.
AC_PROG_CC([clang gcc cc])
diff --git a/hw4/l4basic/l4str.c b/hw4/l4basic/l4str.c
index ad8c2e6..c1f6c51 100644
--- a/hw4/l4basic/l4str.c
+++ b/hw4/l4basic/l4str.c
@@ -25,18 +25,28 @@ bool lbs_str_has_suffix (const char* str, const char* suffix) {
char* lbs_str_printf (const char* format, ...) {
va_list ap;
char* newstr;
- int len;
va_start (ap, format);
- len = vsnprintf (NULL, 0, format, ap) + 1;
+ newstr = lbs_str_vprintf (format, ap);
va_end (ap);
+ return newstr;
+}
+
+char* lbs_str_vprintf (const char* format, va_list ap) {
+ va_list ap1, ap2;
+ char* newstr;
+ int len;
+
+ va_copy (ap1, ap);
+ len = vsnprintf (NULL, 0, format, ap1) + 1;
+ va_end (ap1);
+
newstr = xmalloc (len);
- va_start (ap, format);
- vsnprintf (newstr, len, format, ap);
- va_end (ap);
+ va_copy (ap2, ap);
+ vsnprintf (newstr, len, format, ap2);
+ va_end (ap2);
return newstr;
}
-
diff --git a/hw4/l4basic/l4str.h b/hw4/l4basic/l4str.h
index cda3c1d..b041e22 100644
--- a/hw4/l4basic/l4str.h
+++ b/hw4/l4basic/l4str.h
@@ -3,11 +3,13 @@
#define LBS_STR_H
#include <l4common.h>
+#include <stdarg.h>
#define LBS_STR_STATIC_STRLEN(x) (sizeof(x)/sizeof(char) - 1)
#define LBS_STR_ARRAY_LEN(x,t) (sizeof(x)/sizeof(t))
bool lbs_str_has_suffix (const char* str, const char* suffix);
char* lbs_str_printf (const char* format, ...);
+char* lbs_str_vprintf (const char* format, va_list ap);
#endif /* LBS_STR_H */
diff --git a/hw4/memwrap.c b/hw4/memwrap.c
index 5a09258..a1547d7 100644
--- a/hw4/memwrap.c
+++ b/hw4/memwrap.c
@@ -23,7 +23,7 @@ static void show_errmsg (void) {
char err_msg[MSG_BUF_LEN];
size_t err_len;
- if (strerror_r (errno_backup, err_msg, err_len)) {
+ if (strerror_r (errno_backup, err_msg, MSG_BUF_LEN)) {
const char unknown_msg[] = "Unknown error code";
const size_t unknown_len = LBS_STR_STATIC_STRLEN (unknown_msg);
write (STDERR_FILENO, unknown_msg, unknown_len);