summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-12-20 22:55:55 +0800
committerLAN-TW <lantw44@gmail.com>2013-12-20 22:58:54 +0800
commitec5ac2e9141ac6e7230ad97720c286c2e1b4c18a (patch)
tree17deeefae31643242e2634ffacea9588e26d5957
parent3d38621c19589aad16a66af27796742404090810 (diff)
downloadcn2013-ec5ac2e9141ac6e7230ad97720c286c2e1b4c18a.tar.gz
cn2013-ec5ac2e9141ac6e7230ad97720c286c2e1b4c18a.tar.zst
cn2013-ec5ac2e9141ac6e7230ad97720c286c2e1b4c18a.zip
HW2: 匯入與修改舊有的函式庫
-rw-r--r--.gitignore1
-rw-r--r--hw2/Makefile.am20
-rw-r--r--hw2/agent-main.c22
-rw-r--r--hw2/configure.ac2
-rw-r--r--hw2/l4logger.c213
-rw-r--r--hw2/l4logger.h32
-rw-r--r--hw2/ump-app.h3
-rw-r--r--hw2/ump-pkt.h3
-rw-r--r--hw2/xwrap.c223
-rw-r--r--hw2/xwrap.h33
10 files changed, 544 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore
index 4cccae8..723a3b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@ core.*
*.a
*.lo
*.la
+*.gch
*.core
*.log
*.aux
diff --git a/hw2/Makefile.am b/hw2/Makefile.am
index ccfb78f..f63533f 100644
--- a/hw2/Makefile.am
+++ b/hw2/Makefile.am
@@ -2,18 +2,24 @@ NULL =
EXTRA_DIST = autogen.sh
-bin_PROGRAMS = ump-trans ump-agent
-noinst_LIBRARIES = libump.a
+bin_PROGRAMS = ump-agent ump-trans
+noinst_LIBRARIES = liblbs.a libump.a
+
+liblbs_a_SOURCES = \
+ xwrap.c xwrap.h \
+ l4logger.c l4logger.h \
+ $(NULL)
libump_a_SOURCES = \
- ump-common.h \
+ ump-common.h ump-app.h \
ump-pkt.c ump-pkt.h \
$(NULL)
-ump_trans_SOURCES = \
+ump_agent_SOURCES = \
+ agent-main.c \
$(NULL)
-ump_trans_LDADD = $(top_builddir)/libump.a
+ump_agent_LDADD = $(top_builddir)/liblbs.a $(top_builddir)/libump.a
-ump_agent_SOURCES = \
+ump_trans_SOURCES = \
$(NULL)
-ump_agent_LDADD = $(top_builddir)/libump.a
+ump_trans_LDADD = $(top_builddir)/liblbs.a $(top_builddir)/libump.a
diff --git a/hw2/agent-main.c b/hw2/agent-main.c
new file mode 100644
index 0000000..9db9294
--- /dev/null
+++ b/hw2/agent-main.c
@@ -0,0 +1,22 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "l4logger.h"
+
+#include <locale.h>
+#include <time.h>
+
+int main (int argc, char* argv[]) {
+ setlocale (LC_ALL, "");
+ tzset ();
+
+ LbsLogger lbs_log_struct;
+ LbsLogger* lbs_log = &lbs_log_struct;
+ lbs_logger_init (lbs_log, LBS_LOGGER_FILE_STDOUT, LBS_LOGGER_COLOR_AUTO,
+ argv[0], "UMP_AGENT_FILE", "UMP_AGENT_COLOR");
+
+ lbs_logger_destroy (lbs_log);
+
+ return 0;
+}
diff --git a/hw2/configure.ac b/hw2/configure.ac
index 164e3d3..78964f8 100644
--- a/hw2/configure.ac
+++ b/hw2/configure.ac
@@ -29,7 +29,7 @@ esac
# Checks for programs.
AC_PROG_CC
-AC_PROG_CC_C99
+AC_PROG_CC_STDC
AC_PROG_RANLIB
# Checks for libraries.
diff --git a/hw2/l4logger.c b/hw2/l4logger.c
new file mode 100644
index 0000000..4430c99
--- /dev/null
+++ b/hw2/l4logger.c
@@ -0,0 +1,213 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "l4logger.h"
+#include "xwrap.h"
+
+#include <fcntl.h>
+#include <locale.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+
+static bool is_in_set (const char* str, const char* const* set) {
+ for (int i = 0; set[i] != NULL; i++) {
+ if (strcasecmp (str, set[i]) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void lbs_logger_init (LbsLogger* lbs_log, int default_file, int default_color,
+ const char* static_name, const char* env_file, const char* env_color) {
+
+ lbs_log->name = strrchr (static_name, '/');
+ if (lbs_log->name == NULL) {
+ lbs_log->name = (char*)static_name;
+ } else {
+ lbs_log->name++;
+ }
+ lbs_log->pid = getpid ();
+
+ const char* f; /* value of env_file */
+ const char* c; /* value of env_color */
+ int opt_file; /* real option of log file */
+ int opt_color; /* real option of color */
+
+ if (env_file == NULL || (f = getenv (env_file)) == NULL || *f == '\0') {
+ opt_file = default_file, f = NULL;
+ } else {
+ const char* disabled_values[] =
+ { "disabled", "disable", "no", "n", NULL };
+ const char* stdout_values[] =
+ { "stdout", "out", "output", "console", "con", "cons", NULL };
+ const char* stderr_values[] =
+ { "stderr", "err", "error", NULL };
+
+ if (is_in_set (f, disabled_values)) {
+ opt_file = LBS_LOGGER_FILE_DISABLED, f = NULL;
+ } else if (is_in_set (f, stdout_values)) {
+ opt_file = LBS_LOGGER_FILE_STDOUT, f = NULL;
+ } else if (is_in_set (f, stderr_values)) {
+ opt_file = LBS_LOGGER_FILE_STDERR, f = NULL;
+ }
+ }
+
+ if (f == NULL) {
+ lbs_log->log = NULL;
+ switch (opt_file) {
+ case LBS_LOGGER_FILE_STDOUT:
+ lbs_log->log_fd = STDOUT_FILENO;
+ lbs_log->log_file = stdout;
+ lbs_log->enabled = true;
+ break;
+ case LBS_LOGGER_FILE_STDERR:
+ lbs_log->log_fd = STDERR_FILENO;
+ lbs_log->log_file = stderr;
+ lbs_log->enabled = true;
+ break;
+ case LBS_LOGGER_FILE_DISABLED:
+ default:
+ lbs_log->enabled = false;
+ }
+ } else {
+ /* regular log file */
+
+ lbs_log->enabled = false;
+
+ int fd = open (f, O_WRONLY | O_CREAT | O_APPEND, S_IWUSR | S_IRUSR);
+ if (fd < 0) {
+ return;
+ }
+
+ xfaddfd (fd, FD_CLOEXEC);
+
+ FILE* fp = fdopen (fd, "wb");
+ if (fp == NULL) {
+ close (fd);
+ return;
+ }
+
+ lbs_log->log = xstrdup (f);
+ lbs_log->log_fd = fd;
+ lbs_log->log_file = fp;
+ lbs_log->enabled = true;
+ }
+
+ if (!lbs_log->enabled) {
+ return;
+ }
+
+ setvbuf (lbs_log->log_file, NULL, _IOLBF, 0);
+
+ if (env_color == NULL || (c = getenv (env_color)) == NULL || *c == '\0') {
+ opt_color = default_color;
+ } else {
+ const char* never_values[] =
+ { "0", "f", "false", "n", "no", "never" };
+ const char* auto_values[] =
+ { "a", "auto", "check", "only", "tty", "terminal", "console" };
+ const char* always_values[] =
+ { "1", "always", "must", "color", "all" };
+
+ if (is_in_set (c, never_values)) {
+ opt_color = LBS_LOGGER_COLOR_NEVER;
+ } else if (is_in_set (c, auto_values)) {
+ opt_color = LBS_LOGGER_COLOR_AUTO;
+ } else if (is_in_set (c, always_values)) {
+ opt_color = LBS_LOGGER_COLOR_ALWAYS;
+ } else {
+ opt_color = default_color;
+ }
+ }
+
+ switch (opt_color) {
+ case LBS_LOGGER_COLOR_NEVER:
+ lbs_log->colorized = false;
+ break;
+ case LBS_LOGGER_COLOR_ALWAYS:
+ lbs_log->colorized = true;
+ break;
+ case LBS_LOGGER_COLOR_AUTO:
+ default:
+ if (isatty (lbs_log->log_fd)) {
+ lbs_log->colorized = true;
+ } else {
+ lbs_log->colorized = false;
+ }
+ }
+}
+
+void lbs_logger_destroy (LbsLogger* lbs_log) {
+ if (!lbs_log->enabled) {
+ return;
+ }
+
+ if (lbs_log->log != NULL) {
+ free (lbs_log->log);
+ fclose (lbs_log->log_file);
+ }
+}
+
+void lbs_logger_string (LbsLogger* lbs_log, const char* string) {
+ lbs_logger_format (lbs_log, NULL, string);
+}
+
+void lbs_logger_format (LbsLogger* lbs_log, const char* format, ...) {
+ if (!lbs_log->enabled) {
+ return;
+ }
+
+ time_t t;
+ struct tm tmd;
+
+ time (&t);
+ localtime_r (&t, &tmd);
+
+ struct flock lock_info = {
+ .l_type = F_WRLCK,
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = 0
+ };
+ fcntl (lbs_log->log_fd, F_SETLKW, &lock_info);
+
+ char pid_color[] = "\033[1;44;37m";
+ pid_color[5] = lbs_log->pid % 6 + '1';
+ fprintf (lbs_log->log_file,
+ "%s%04d-%02d-%02d %s%02d:%02d:%02d %s%s[%s%d%s]: %s",
+ lbs_log->colorized ? "\033[31m" : "",
+ tmd.tm_year + 1900, tmd.tm_mon + 1, tmd.tm_mday,
+ lbs_log->colorized ? "\033[32m" : "",
+ tmd.tm_hour, tmd.tm_min, tmd.tm_sec,
+ lbs_log->colorized ? "\033[33m" : "",
+ lbs_log->name,
+ lbs_log->colorized ? pid_color : "",
+ lbs_log->pid,
+ lbs_log->colorized ? "\033[0m\033[33m" : "",
+ lbs_log->colorized ? "\033[0m" : "");
+
+ if (format == NULL) {
+ va_list ap;
+ va_start (ap, format);
+ fputs (va_arg (ap, char*), lbs_log->log_file);
+ va_end (ap);
+ } else {
+ va_list ap;
+ va_start (ap, format);
+ vfprintf (lbs_log->log_file, format, ap);
+ va_end (ap);
+ }
+
+ putc ('\n', lbs_log->log_file);
+
+ lock_info.l_type = F_UNLCK;
+ fcntl (lbs_log->log_fd, F_SETLK, &lock_info);
+}
diff --git a/hw2/l4logger.h b/hw2/l4logger.h
new file mode 100644
index 0000000..5dad1c5
--- /dev/null
+++ b/hw2/l4logger.h
@@ -0,0 +1,32 @@
+#ifndef LBS_LOGGER_H
+#define LBS_LOGGER_H
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+typedef struct LbsLoggerStruct {
+ char* name; /* Constant: DO NOT free it! */
+ pid_t pid;
+ char* log;
+ int log_fd;
+ FILE* log_file;
+ int enabled : 1;
+ int colorized : 1;
+} LbsLogger;
+
+#define LBS_LOGGER_FILE_DISABLED 0
+#define LBS_LOGGER_FILE_STDOUT 1
+#define LBS_LOGGER_FILE_STDERR 2
+
+#define LBS_LOGGER_COLOR_NEVER 0
+#define LBS_LOGGER_COLOR_AUTO 1
+#define LBS_LOGGER_COLOR_ALWAYS 2
+
+void lbs_logger_init (LbsLogger* lbs_log, int default_file, int default_color,
+ const char* static_name, const char* env_file, const char* env_color);
+void lbs_logger_destroy (LbsLogger* lbs_log);
+void lbs_logger_string (LbsLogger* lbs_log, const char* string);
+void lbs_logger_format (LbsLogger* lbs_log, const char* format, ...);
+
+#endif /* LBS_LOGGER_H */
diff --git a/hw2/ump-app.h b/hw2/ump-app.h
index 215f480..df0cf82 100644
--- a/hw2/ump-app.h
+++ b/hw2/ump-app.h
@@ -77,6 +77,9 @@ static inline void* ump_app_get_real_data (UmpApp* app_data) {
static inline size_t ump_app_get_real_data_len (UmpApp* app_data) {
return app_data->real_data_len;
}
+static inline size_t ump_app_get_real_data_max (UmpApp* app_data) {
+ return (uint8_t*)ump_app_get_real_data (app_data) - (uint8_t*)app_data;
+}
static inline void ump_app_set_real_data (
UmpApp* app_data, const void* data, size_t len) {
diff --git a/hw2/ump-pkt.h b/hw2/ump-pkt.h
index fed548a..f1f3d7c 100644
--- a/hw2/ump-pkt.h
+++ b/hw2/ump-pkt.h
@@ -57,6 +57,9 @@ static inline uint8_t* ump_pkt_get_app_data (UmpPkt* pkt) {
static inline size_t ump_pkt_get_app_data_len (UmpPkt* pkt) {
return pkt->app_data_len;
}
+static inline size_t ump_pkt_get_app_data_max (UmpPkt* pkt) {
+ return UMP_PKT_SIZE - ump_pkt_get_data_offset (pkt);
+}
static inline void ump_pkt_set_app_data (
UmpPkt* pkt, const uint8_t* data, size_t len) {
diff --git a/hw2/xwrap.c b/hw2/xwrap.c
new file mode 100644
index 0000000..5dc82d5
--- /dev/null
+++ b/hw2/xwrap.c
@@ -0,0 +1,223 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "xwrap.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#define RETRY_SEC 0
+#define RETRY_NSEC 250000000
+
+static const char fail_msg[] = "Fail to allocate memory. Retry ...\n";
+static const size_t fail_len = STATIC_STRLEN (fail_msg);
+
+int xatol (const char* str, long* result) {
+ int errno_save, rval;
+ long lres;
+ char* endptr;
+
+ errno_save = errno;
+ errno = 0, rval = 0;
+
+ lres = strtol (str, &endptr, 10);
+ if (str == endptr || errno != 0) {
+ rval = -1;
+ } else {
+ *result = lres;
+ }
+
+ errno = errno_save;
+
+ return rval;
+}
+
+void* xmalloc (size_t size) {
+ void* memptr;
+
+ while ((memptr = malloc (size)) == NULL) {
+ nanosleep (&(struct timespec) { RETRY_SEC, RETRY_NSEC }, NULL);
+ write (STDERR_FILENO, fail_msg, fail_len);
+ }
+
+ return memptr;
+}
+
+void* xrealloc (void* ptr, size_t size) {
+ void* newptr;
+
+ while ((newptr = realloc (ptr, size)) == NULL) {
+ nanosleep (&(struct timespec) { RETRY_SEC, RETRY_NSEC }, NULL);
+ write (STDERR_FILENO, fail_msg, fail_len);
+ }
+
+ return newptr;
+}
+
+bool xstrend (const char* str, const char* suffix) {
+ size_t len = strlen (str);
+ size_t suflen = strlen (suffix);
+ int i, j;
+ for (i = len - 1, j = suflen - 1; i >= 0 && j >= 0; i--, j--) {
+ if (str[i] != suffix[j]) {
+ return false;
+ }
+ }
+ if (i < 0 && j >= 0) {
+ return false;
+ }
+ return true;
+}
+
+char* xstrcat (const char* str, ...) {
+ va_list ap;
+ char* strp;
+ char* strnow;
+ char* newstr;
+ int len = strlen (str);
+
+ va_start (ap, str);
+ while ((strp = va_arg (ap, char*)) != NULL) {
+ len += strlen (strp);
+ }
+ va_end (ap);
+
+ newstr = xmalloc (len + 1);
+
+ va_start (ap, str);
+ strnow = stpcpy (newstr, str);
+ while ((strp = va_arg (ap, char*)) != NULL) {
+ strnow = stpcpy (strnow, strp);
+ }
+ newstr[len] = '\0';
+ va_end (ap);
+
+ return newstr;
+}
+
+char* xstrdup (const char* str) {
+ char* newstr;
+
+ while ((newstr = strdup (str)) == NULL) {
+ nanosleep (&(struct timespec) { RETRY_SEC, RETRY_NSEC }, NULL);
+ write (STDERR_FILENO, fail_msg, fail_len);
+ }
+
+ return newstr;
+}
+
+char* xsprintf (const char* format, ...) {
+ va_list ap;
+ char* newstr;
+ int len;
+
+ va_start (ap, format);
+ len = vsnprintf (NULL, 0, format, ap) + 1;
+ va_end (ap);
+
+ newstr = xmalloc (len);
+
+ va_start (ap, format);
+ vsnprintf (newstr, len, format, ap);
+ va_end (ap);
+
+ return newstr;
+}
+
+int xfaddfd (int fd, int fdflags) {
+ int orgfd = fcntl (fd, F_GETFD);
+ if (orgfd < 0) {
+ return -1;
+ }
+ return fcntl (fd, F_SETFD, orgfd | fdflags);
+}
+
+int xfdelfd (int fd, int fdflags) {
+ int orgfd = fcntl (fd, F_GETFD);
+ if (orgfd < 0) {
+ return -1;
+ }
+ return fcntl (fd, F_SETFD, orgfd & ~(fdflags));
+}
+
+int xfaddfl (int fd, int flflags) {
+ int orgfl = fcntl (fd, F_GETFL);
+ if (orgfl < 0) {
+ return -1;
+ }
+ return fcntl (fd, F_SETFL, orgfl | flflags);
+}
+
+int xfdelfl (int fd, int flflags) {
+ int orgfl = fcntl (fd, F_GETFL);
+ if (orgfl < 0) {
+ return -1;
+ }
+ return fcntl (fd, F_SETFL, orgfl & ~(flflags));
+}
+
+char* xreadlink (const char* filename) {
+ struct stat st;
+ if (lstat (filename, &st) < 0) {
+ return NULL;
+ }
+ size_t bufsize = st.st_size ? st.st_size : 8192;
+ char* buf = malloc (bufsize + 1);
+ if (buf == NULL) {
+ return NULL;
+ }
+ ssize_t written = readlink (filename, buf, bufsize);
+ if (written < 0) {
+ free (buf);
+ return NULL;
+ }
+ buf[written] = '\0';
+ return buf;
+}
+
+char* xgetcwd (void) {
+ char *cwd, *result;
+ size_t size = pathconf (".", _PC_PATH_MAX);
+
+ size = size > 0 ? size : 256;
+ cwd = xmalloc (sizeof (char) * size);
+
+ while ((result = getcwd (cwd, size)) == NULL && errno == ERANGE) {
+ size *= 2;
+ cwd = xrealloc (cwd, size);
+ }
+
+ return cwd;
+}
+
+size_t xwrite (int fd, const char* str, size_t size) {
+ ssize_t wtn = 0;
+ if (size <= 0) {
+ size = strlen (str);
+ }
+ size_t rem = size;
+ while (rem > 0) {
+ wtn = write (fd, str, rem);
+ if (wtn < 0) {
+ if (errno != EINTR && errno != EAGAIN) {
+ break;
+ }
+ continue;
+ }
+ str += wtn;
+ rem -= wtn;
+ }
+
+ rem = rem > 0 ? rem : 0;
+ return size - rem;
+}
diff --git a/hw2/xwrap.h b/hw2/xwrap.h
new file mode 100644
index 0000000..f541f05
--- /dev/null
+++ b/hw2/xwrap.h
@@ -0,0 +1,33 @@
+#ifndef X_GENERAL_WRAPPER
+#define X_GENERAL_WRAPPER
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#define STATIC_STRLEN(x) (sizeof(x)/sizeof(char) - 1)
+#define ARRAY_LEN(x,t) (sizeof(x)/sizeof(t))
+
+int xatol (const char* str, long* result);
+void* xmalloc (size_t size);
+void* xrealloc (void* ptr, size_t size);
+bool xstrend (const char* str, const char* suffix);
+char* xstrcat (const char* str, ...);
+char* xstrdup (const char* str);
+char* xsprintf (const char* format, ...);
+int xfaddfd (int fd, int fdflags);
+int xfdelfd (int fd, int fdflags);
+int xfaddfl (int fd, int flflags);
+int xfdelfl (int fd, int flflags);
+char* xreadlink (const char* filename);
+char* xgetcwd (void);
+size_t xwrite (int fd, const char* str, size_t size);
+
+static inline int xmax (int a, int b) {
+ return a > b ? a : b;
+}
+static inline int xmin (int a, int b) {
+ return a < b ? a : b;
+}
+
+#endif /* X_GENERAL_WRAPPER */