add improved xseg loging system. plus remove tons of warning messages
[archipelago] / xseg / sys / user / xseg_user.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <stdarg.h>
4 #include <time.h>
5 #include <string.h>
6 #include <dlfcn.h>
7 #include <unistd.h>
8 #include <stdint.h>
9 #include <sys/syscall.h>
10 #include <errno.h>
11 #include <sys/util.h>
12 #include <sys/time.h>
13
14 #include <sys/domain.h>
15 #include <xtypes/domain.h>
16 #include <xseg/domain.h>
17
18 #include <xtypes/xlock.h>
19
20 int (*xseg_snprintf)(char *str, size_t size, const char *format, ...) = snprintf;
21
22 char __xseg_errbuf[4096];
23
24 static struct xlock __lock = { .owner = Noone};
25
26 void __lock_domain(void)
27 {
28         (void)xlock_acquire(&__lock, 1);
29 }
30
31 void __unlock_domain(void)
32 {
33         xlock_release(&__lock);
34 }
35
36 void __load_plugin(const char *name)
37 {
38         void *dl;
39         void (*init)(void);
40         char _name[128];
41         unsigned int namelen = strlen(name);
42
43         strncpy(_name, "xseg_", 5);
44         strncpy(_name + 5, name, 80);
45         strncpy(_name + 5 + namelen, ".so", 3);
46         _name[5 + namelen + 3 ] = 0;
47         dl = dlopen(_name, RTLD_NOW);
48         if (!dl) {
49                 XSEGLOG("Cannot load plugin '%s': %s\n", _name, dlerror());
50                 return;
51         }
52
53         strncpy(_name + 5 + namelen, "_init", 5);
54         _name[127] = 0;
55         init = (void (*)(void))(long)dlsym(dl, _name);
56         if (!init) {
57                 XSEGLOG("Init function '%s' not found!\n", _name);
58                 return;
59         }
60
61         init();
62         //XSEGLOG("Plugin '%s' loaded.\n", name);
63 }
64
65 uint64_t __get_id(void)
66 {
67         return (uint64_t)syscall(SYS_gettid);
68 }
69
70 void __xseg_log(const char *msg)
71 {
72         (void)puts(msg);
73 }
74
75 void *xtypes_malloc(unsigned long size)
76 {
77         return malloc(size);
78 }
79
80 void xtypes_free(void *ptr)
81 {
82         free(ptr);
83 }
84
85 void __get_current_time(struct timeval *tv) {
86         gettimeofday(tv, NULL);
87 }
88
89
90 int user_init_logctx(struct log_ctx *lc, char *peer_name, enum log_level log_level, char *logfile)
91 {
92         FILE *file;
93         lc->peer_name = peer_name;
94         lc->log_level = log_level;
95         if (!logfile) {
96                 lc->logfile = stderr;
97                 return 0;
98         }
99
100         file = fopen(logfile, "a");
101         if (!file) {
102                 lc->logfile = stderr;
103                 return -1;
104         }
105         lc->logfile = file;
106         return 0;
107 }
108 int (*init_logctx)(struct log_ctx *lc, char *peer_name, enum log_level log_level, char *logfile) = user_init_logctx;
109
110 void __xseg_log2(struct log_ctx *lc, enum log_level level, char *fmt, ...)
111 {
112         va_list ap;
113         time_t timeval; 
114         char timebuf[1024], buffer[4096];
115         char *buf = buffer;
116         char *t = NULL, *pn = NULL;
117
118         va_start(ap, fmt);
119         switch (level) {
120                 case E: t = "XSEG[EE]"; break;
121                 case W: t = "XSEG[WW]"; break;
122                 case I: t = "XSEG[II]"; break;
123                 case D: t = "XSEG[DD]"; break;
124                 default: t = "XSEG[UNKNONW]"; break;
125         }
126         pn = lc->peer_name;
127         if (!pn)
128                 pn = "Invalid peer name";
129
130         time(&timeval);
131         ctime_r(&timeval, timebuf);
132         *strchr(timebuf, '\n') = '\0';
133         
134         buf += sprintf(buf, "%s: %s: ", t, lc->peer_name);
135         buf += sprintf(buf, "%s (%ld):\n\t", timebuf, timeval);
136         buf += vsprintf(buf, fmt, ap);
137         buf += sprintf(buf, "\n");
138
139         fprintf(lc->logfile, "%s", buffer);
140         fflush(lc->logfile);
141         va_end(ap);
142
143         return;
144 }