summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/monkey/mk_core/mk_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/monkey/mk_core/mk_utils.c')
-rw-r--r--fluent-bit/lib/monkey/mk_core/mk_utils.c393
1 files changed, 393 insertions, 0 deletions
diff --git a/fluent-bit/lib/monkey/mk_core/mk_utils.c b/fluent-bit/lib/monkey/mk_core/mk_utils.c
new file mode 100644
index 000000000..54cdd3938
--- /dev/null
+++ b/fluent-bit/lib/monkey/mk_core/mk_utils.c
@@ -0,0 +1,393 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Monkey HTTP Server
+ * ==================
+ * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <mk_core/mk_utils.h>
+
+#include <mk_core/mk_unistd.h>
+
+#if defined (__linux__)
+#include <sys/prctl.h>
+#elif defined (_WIN32)
+#include <winsock2.h>
+
+#ifndef localtime_r
+ struct tm *localtime_r(time_t *_clock, struct tm *_result)
+ {
+ struct tm *p = localtime(_clock);
+ if (p)
+ *(_result) = *p;
+ return p;
+ }
+ #endif
+ struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of DST correction */
+ };
+
+ int gettimeofday(struct timeval *tv, struct timezone *tz)
+ {
+ FILETIME result;
+ ULARGE_INTEGER temp;
+
+ memset(&result, 0, sizeof(FILETIME));
+
+ GetSystemTimeAsFileTime(&result);
+
+ if (NULL != tv) {
+ temp.LowPart = result.dwLowDateTime;
+ temp.HighPart = result.dwHighDateTime;
+
+ tv->tv_usec = ((temp.QuadPart / 10LL) % 1000000LL);
+ tv->tv_sec = ((temp.QuadPart - (116444736000000000LL)) / 10000000LL);
+ }
+
+ return 0;
+ }
+
+#endif
+
+/* core init time variable */
+/*
+ * Max amount of pid digits. Glibc's pid_t is implemented as a signed
+ * 32bit integer, for both 32 and 64bit systems - max value: 2147483648.
+ */
+#define MK_MAX_PID_LEN 10
+
+#include <mk_core/mk_macros.h>
+#include <mk_core/mk_utils.h>
+
+pthread_mutex_t mutex_trace;
+pthread_key_t mk_utils_error_key; /* Initialized by MK_INIT_INITIALIZE_TLS_UNIVERSAL */
+
+#ifdef MK_HAVE_TRACE
+#ifdef _WIN32
+/* struct timeval is defined in winsock.h according to msdn */
+#include <winsock2.h>
+#else
+#include <sys/time.h>
+#endif
+
+static time_t mk_core_init_time;
+static char *env_trace_filter;
+
+void mk_utils_trace(const char *component, int color, const char *function,
+ char *file, int line, const char* format, ...)
+{
+ va_list args;
+ char *color_function = NULL;
+ char *color_fileline = NULL;
+ char *color_component = NULL;
+
+ char *reset_color = ANSI_RESET;
+ char *magenta_color = ANSI_RESET ANSI_MAGENTA;
+ char *red_color = ANSI_RESET ANSI_RED;
+ char *time_color = ANSI_RESET "\033[38;5;241m";
+
+ struct timeval tv;
+ struct timezone tz;
+
+ if (env_trace_filter) {
+ if (!strstr(env_trace_filter, file)) {
+ return;
+ }
+ }
+
+ /* Mutex lock */
+ //pthread_mutex_lock(&mutex_trace);
+
+ gettimeofday(&tv, &tz);
+
+ switch(color) {
+ case MK_TRACE_CORE:
+ color_component = ANSI_GREEN;
+ color_function = ANSI_YELLOW;
+ color_fileline = ANSI_WHITE;
+ break;
+ case MK_TRACE_PLUGIN:
+ color_component = ANSI_BLUE;
+ color_function = ANSI_BLUE;
+ color_fileline = ANSI_WHITE;
+ break;
+ }
+
+ /* Only print colors to a terminal */
+ if (!isatty(STDOUT_FILENO)) {
+ color_function = "";
+ color_fileline = "";
+ reset_color = "";
+ magenta_color = "";
+ red_color = "";
+ time_color = "";
+ }
+
+ va_start( args, format );
+
+ printf("~ %s%2lu.%lu%s %s[%s%s%s|%s:%-3i%s] %s%s()%s ",
+ time_color, (tv.tv_sec - mk_core_init_time),
+ tv.tv_usec, reset_color,
+ magenta_color, color_component, component, color_fileline, file,
+ line, magenta_color,
+ color_function, function, red_color);
+ vprintf(format, args );
+ va_end(args);
+ printf("%s\n", reset_color);
+ fflush(stdout);
+
+ /* Mutex unlock */
+ //pthread_mutex_unlock(&mutex_trace);
+}
+
+int mk_utils_print_errno(int n)
+{
+ switch(n) {
+ case EAGAIN:
+ MK_TRACE("EAGAIN");
+ return -1;
+ case EBADF:
+ MK_TRACE("EBADF");
+ return -1;
+ case EFAULT:
+ MK_TRACE("EFAULT");
+ return -1;
+ case EFBIG:
+ MK_TRACE("EFBIG");
+ return -1;
+ case EINTR:
+ MK_TRACE("EINTR");
+ return -1;
+ case EINVAL:
+ MK_TRACE("EINVAL");
+ return -1;
+ case EPIPE:
+ MK_TRACE("EPIPE");
+ return -1;
+ default:
+ MK_TRACE("DONT KNOW");
+ return 0;
+ }
+
+ return 0;
+}
+#endif
+
+void mk_print(int type, const char *format, ...)
+{
+ time_t now;
+ struct tm *current;
+
+ const char *header_color = NULL;
+ const char *header_title = NULL;
+ const char *bold_color = ANSI_BOLD;
+ const char *reset_color = ANSI_RESET;
+ const char *white_color = ANSI_WHITE;
+ va_list args;
+
+ va_start(args, format);
+
+ switch (type) {
+ case MK_INFO:
+ header_title = "Info";
+ header_color = ANSI_GREEN;
+ break;
+ case MK_ERR:
+ header_title = "Error";
+ header_color = ANSI_RED;
+ break;
+ case MK_WARN:
+ header_title = "Warning";
+ header_color = ANSI_YELLOW;
+ break;
+ case MK_BUG:
+#ifdef DEBUG
+ mk_utils_stacktrace();
+#endif
+ header_title = " BUG !";
+ header_color = ANSI_BOLD ANSI_RED;
+ break;
+ }
+
+ /* Only print colors to a terminal */
+ if (!isatty(STDOUT_FILENO)) {
+ header_color = "";
+ bold_color = "";
+ reset_color = "";
+ white_color = "";
+ }
+
+ now = time(NULL);
+ struct tm result;
+ current = localtime_r(&now, &result);
+ printf("%s[%s%i/%02i/%02i %02i:%02i:%02i%s]%s ",
+ bold_color, reset_color,
+ current->tm_year + 1900,
+ current->tm_mon + 1,
+ current->tm_mday,
+ current->tm_hour,
+ current->tm_min,
+ current->tm_sec,
+ bold_color, reset_color);
+
+ printf("%s[%s%7s%s]%s ",
+ bold_color, header_color, header_title, white_color, reset_color);
+
+ vprintf(format, args);
+ va_end(args);
+ printf("%s\n", reset_color);
+ fflush(stdout);
+}
+
+int mk_utils_worker_rename(const char *title)
+{
+#if defined (__linux__)
+ return prctl(PR_SET_NAME, title, 0, 0, 0);
+#elif defined (__APPLE__)
+ return pthread_setname_np(title);
+#else
+ (void) title;
+ return -1;
+#endif
+}
+
+int mk_utils_worker_spawn(void (*func) (void *), void *arg, pthread_t *tid)
+{
+ pthread_attr_t thread_attr;
+
+ pthread_attr_init(&thread_attr);
+ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
+ if (pthread_create(tid, &thread_attr, (void *) func, arg) < 0) {
+ mk_libc_error("pthread_create");
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifndef _WIN32
+/* Run current process in background mode (daemon, evil Monkey >:) */
+int mk_utils_set_daemon()
+{
+ pid_t pid;
+
+ if ((pid = fork()) < 0) {
+ mk_err("Error: Failed creating to switch to daemon mode(fork failed)");
+ return -1;
+ }
+
+ if (pid > 0) { /* parent */
+ exit(EXIT_SUCCESS);
+ }
+
+ /* set files mask */
+ umask(0);
+
+ /* Create new session */
+ setsid();
+
+ if (chdir("/") < 0) { /* make sure we can unmount the inherited filesystem */
+ mk_err("Error: Unable to unmount the inherited filesystem in the daemon process");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Our last STDOUT messages */
+ mk_info("Background mode ON");
+
+ fclose(stderr);
+ fclose(stdout);
+
+ return 0;
+}
+
+/* Write Monkey's PID */
+int mk_utils_register_pid(char *path)
+{
+ int fd;
+ int ret;
+ char pidstr[MK_MAX_PID_LEN + 1];
+ struct flock lock;
+ struct stat sb;
+
+ if (stat(path, &sb) == 0) {
+ /* file exists, perhaps previously kepts by SIGKILL */
+ ret = unlink(path);
+ if (ret == -1) {
+ mk_err("Could not remove old PID-file path: %s", path);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if ((fd = open(path,
+ O_WRONLY | O_CREAT | O_CLOEXEC, 0444)) < 0) {
+ mk_err("I cannot create PID file '%s'", path);
+ return -1;
+ }
+
+ /* create a write exclusive lock for the entire file */
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+
+ if (fcntl(fd, F_SETLK, &lock) < 0) {
+ close(fd);
+ mk_err("I cannot set the lock for the PID file '%s'", path);
+ return -1;
+ }
+
+ sprintf(pidstr, "%ld", (long) getpid());
+ ssize_t write_len = strlen(pidstr);
+ if (write(fd, pidstr, write_len) != write_len) {
+ close(fd);
+ mk_err("I cannot write PID number at '%s' file", path);
+ return -1;
+ }
+
+ close(fd);
+ return 0;
+}
+
+/* Remove PID file */
+int mk_utils_remove_pid(char *path)
+{
+ if (unlink(path)) {
+ mk_warn("cannot delete pidfile\n");
+ }
+ return 0;
+}
+#endif
+
+int mk_core_init()
+{
+#ifdef MK_HAVE_TRACE
+ mk_core_init_time = time(NULL);
+ env_trace_filter = getenv("MK_TRACE_FILTER");
+#endif
+
+ return 0;
+}