fix numerous bugs in mt-mapperd, pfiled, xhash
[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         fflush(stdout);
74 }
75
76 void *xtypes_malloc(unsigned long size)
77 {
78         return malloc(size);
79 }
80
81 void xtypes_free(void *ptr)
82 {
83         free(ptr);
84 }
85
86 void __get_current_time(struct timeval *tv) {
87         gettimeofday(tv, NULL);
88 }
89
90
91 int user_init_logctx(struct log_ctx *lc, char *peer_name, enum log_level log_level, char *logfile)
92 {
93         FILE *file;
94         lc->peer_name = peer_name;
95         lc->log_level = log_level;
96         if (!logfile) {
97                 lc->logfile = stderr;
98                 return 0;
99         }
100
101         file = fopen(logfile, "a");
102         if (!file) {
103                 lc->logfile = stderr;
104                 return -1;
105         }
106         lc->logfile = file;
107         return 0;
108 }
109 int (*init_logctx)(struct log_ctx *lc, char *peer_name, enum log_level log_level, char *logfile) = user_init_logctx;
110
111 void __xseg_log2(struct log_ctx *lc, enum log_level level, char *fmt, ...)
112 {
113         va_list ap;
114         time_t timeval; 
115         char timebuf[1024], buffer[4096];
116         char *buf = buffer;
117         char *t = NULL, *pn = NULL;
118
119         va_start(ap, fmt);
120         switch (level) {
121                 case E: t = "XSEG[EE]"; break;
122                 case W: t = "XSEG[WW]"; break;
123                 case I: t = "XSEG[II]"; break;
124                 case D: t = "XSEG[DD]"; break;
125                 default: t = "XSEG[UNKNONW]"; break;
126         }
127         pn = lc->peer_name;
128         if (!pn)
129                 pn = "Invalid peer name";
130
131         time(&timeval);
132         ctime_r(&timeval, timebuf);
133         *strchr(timebuf, '\n') = '\0';
134         
135         buf += sprintf(buf, "%s: %s: ", t, lc->peer_name);
136         buf += sprintf(buf, "%s (%ld):\n\t", timebuf, timeval);
137         buf += vsprintf(buf, fmt, ap);
138         buf += sprintf(buf, "\n");
139
140         fprintf(lc->logfile, "%s", buffer);
141         fflush(lc->logfile);
142         va_end(ap);
143
144         return;
145 }