diff options
author | LAN-TW <lantw44@gmail.com> | 2013-12-20 22:55:55 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-12-20 22:58:54 +0800 |
commit | ec5ac2e9141ac6e7230ad97720c286c2e1b4c18a (patch) | |
tree | 17deeefae31643242e2634ffacea9588e26d5957 | |
parent | 3d38621c19589aad16a66af27796742404090810 (diff) | |
download | cn2013-ec5ac2e9141ac6e7230ad97720c286c2e1b4c18a.tar.gz cn2013-ec5ac2e9141ac6e7230ad97720c286c2e1b4c18a.tar.zst cn2013-ec5ac2e9141ac6e7230ad97720c286c2e1b4c18a.zip |
HW2: 匯入與修改舊有的函式庫
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | hw2/Makefile.am | 20 | ||||
-rw-r--r-- | hw2/agent-main.c | 22 | ||||
-rw-r--r-- | hw2/configure.ac | 2 | ||||
-rw-r--r-- | hw2/l4logger.c | 213 | ||||
-rw-r--r-- | hw2/l4logger.h | 32 | ||||
-rw-r--r-- | hw2/ump-app.h | 3 | ||||
-rw-r--r-- | hw2/ump-pkt.h | 3 | ||||
-rw-r--r-- | hw2/xwrap.c | 223 | ||||
-rw-r--r-- | hw2/xwrap.h | 33 |
10 files changed, 544 insertions, 8 deletions
@@ -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 */ |