agoo 2.5.1 → 2.5.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of agoo might be problematic. Click here for more details.

Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +12 -1
  4. data/ext/agoo/agoo.c +4 -3
  5. data/ext/agoo/bind.c +51 -11
  6. data/ext/agoo/bind.h +9 -0
  7. data/ext/agoo/con.c +127 -89
  8. data/ext/agoo/con.h +24 -8
  9. data/ext/agoo/debug.c +2 -0
  10. data/ext/agoo/debug.h +1 -0
  11. data/ext/agoo/err.c +1 -1
  12. data/ext/agoo/err.h +2 -5
  13. data/ext/agoo/foo/agoo.c +109 -0
  14. data/ext/agoo/foo/con.c +1220 -0
  15. data/ext/agoo/foo/con.h +65 -0
  16. data/ext/agoo/foo/page.c +699 -0
  17. data/ext/agoo/foo/pub.c +131 -0
  18. data/ext/agoo/foo/pub.h +40 -0
  19. data/ext/agoo/foo/rserver.c +1016 -0
  20. data/ext/agoo/foo/server.c +303 -0
  21. data/ext/agoo/foo/server.h +67 -0
  22. data/ext/agoo/foo/upgraded.c +182 -0
  23. data/ext/agoo/hook.c +31 -0
  24. data/ext/agoo/hook.h +9 -10
  25. data/ext/agoo/{types.h → kinds.h} +3 -3
  26. data/ext/agoo/log.c +168 -83
  27. data/ext/agoo/log.h +6 -2
  28. data/ext/agoo/page.c +38 -32
  29. data/ext/agoo/pub.c +16 -0
  30. data/ext/agoo/pub.h +1 -0
  31. data/ext/agoo/queue.h +1 -0
  32. data/ext/agoo/req.c +95 -0
  33. data/ext/agoo/req.h +48 -0
  34. data/ext/agoo/request.c +10 -38
  35. data/ext/agoo/request.h +1 -34
  36. data/ext/agoo/res.h +1 -3
  37. data/ext/agoo/response.c +6 -248
  38. data/ext/agoo/response.h +2 -6
  39. data/ext/agoo/rlog.c +2 -1
  40. data/ext/agoo/rresponse.c +252 -0
  41. data/ext/agoo/rresponse.h +14 -0
  42. data/ext/agoo/rserver.c +43 -45
  43. data/ext/agoo/rserver.h +3 -24
  44. data/ext/agoo/rupgraded.c +303 -0
  45. data/ext/agoo/rupgraded.h +17 -0
  46. data/ext/agoo/server.c +125 -8
  47. data/ext/agoo/server.h +26 -4
  48. data/ext/agoo/sse.c +3 -1
  49. data/ext/agoo/upgraded.c +42 -280
  50. data/ext/agoo/upgraded.h +16 -8
  51. data/ext/agoo/websocket.c +13 -9
  52. data/lib/agoo/base.rb +84 -0
  53. data/lib/agoo/client.rb +25 -0
  54. data/lib/agoo/version.rb +1 -1
  55. data/test/bind_test.rb +2 -2
  56. metadata +22 -4
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include "debug.h"
7
7
  #include "hook.h"
8
+ #include "req.h"
8
9
 
9
10
  Hook
10
11
  hook_create(Method method, const char *pattern, void *handler, HookType type, Queue q) {
@@ -33,6 +34,33 @@ hook_create(Method method, const char *pattern, void *handler, HookType type, Qu
33
34
  return hook;
34
35
  }
35
36
 
37
+ Hook
38
+ hook_func_create(Method method, const char *pattern, void (*func)(Req req), Queue q) {
39
+ Hook hook = (Hook)malloc(sizeof(struct _Hook));
40
+
41
+ if (NULL != hook) {
42
+ char *pat = NULL;
43
+
44
+ DEBUG_ALLOC(mem_hook, hook);
45
+ if (NULL == pattern) {
46
+ if (NONE != method) {
47
+ pat = strdup("");
48
+ }
49
+ } else {
50
+ pat = strdup(pattern);
51
+ }
52
+ hook->pattern = pat;
53
+
54
+ hook->next = NULL;
55
+ DEBUG_ALLOC(mem_hook_pattern, hook->pattern)
56
+ hook->method = method;
57
+ hook->func = func;
58
+ hook->type = FUNC_HOOK;
59
+ hook->queue = q;
60
+ }
61
+ return hook;
62
+ }
63
+
36
64
  void
37
65
  hook_destroy(Hook hook) {
38
66
  if (NULL != hook->pattern) {
@@ -49,6 +77,9 @@ hook_match(Hook hook, Method method, const Seg path) {
49
77
  char *p = path->start;
50
78
  char *end = path->end;
51
79
 
80
+ if (1 < end - p && '/' == *(end - 1)) {
81
+ end--;
82
+ }
52
83
  if (method != hook->method && ALL != hook->method) {
53
84
  return false;
54
85
  }
@@ -9,21 +9,16 @@
9
9
  #include "queue.h"
10
10
  #include "seg.h"
11
11
 
12
+ struct _Req;
13
+
12
14
  typedef enum {
13
15
  NO_HOOK = '\0',
14
16
  RACK_HOOK = 'R',
15
17
  BASE_HOOK = 'B',
16
18
  WAB_HOOK = 'W',
17
19
  PUSH_HOOK = 'P',
18
- STDIO_HOOK = 'S', // for OpO
19
- FAST_HOOK = 'F', // for OpO
20
- GET_HOOK = 'G', // for OpO
21
- TNEW_HOOK = 'c', // for OpO
22
- TGET_HOOK = 'r', // for OpO
23
- TUP_HOOK = 'u', // for OpO
24
- TDEL_HOOK = 'd', // for OpO
25
- TQL_HOOK = 'T', // for OpO
26
- GRAPHQL_HOOK = 'Q', // for OpO
20
+ FUNC_HOOK = 'F',
21
+ FAST_HOOK = 'O', // for OpO
27
22
  } HookType;
28
23
 
29
24
  typedef struct _Hook {
@@ -31,11 +26,15 @@ typedef struct _Hook {
31
26
  Method method;
32
27
  char *pattern;
33
28
  HookType type;
34
- void* handler;
29
+ union {
30
+ void *handler;
31
+ void (*func)(struct _Req *req);
32
+ };
35
33
  Queue queue;
36
34
  } *Hook;
37
35
 
38
36
  extern Hook hook_create(Method method, const char *pattern, void *handler, HookType type, Queue q);
37
+ extern Hook hook_func_create(Method method, const char *pattern, void (*func)(struct _Req *req), Queue q);
39
38
  extern void hook_destroy(Hook hook);
40
39
 
41
40
  extern bool hook_match(Hook hook, Method method, const Seg seg);
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
2
 
3
- #ifndef __AGOO_TYPES_H__
4
- #define __AGOO_TYPES_H__
3
+ #ifndef __AGOO_KINDS_H__
4
+ #define __AGOO_KINDS_H__
5
5
 
6
6
  typedef enum {
7
7
  CON_ANY = '\0',
@@ -10,4 +10,4 @@ typedef enum {
10
10
  CON_SSE = 'S',
11
11
  } ConKind;
12
12
 
13
- #endif // __AGOO_TYPES_H__
13
+ #endif // __AGOO_KINDS_H__
@@ -25,14 +25,6 @@
25
25
  #define RESET_COLOR "\033[0m"
26
26
  #define RESET_SIZE 4
27
27
 
28
- static const char log_name[] = "agoo.log";
29
- static const char log_prefix[] = "agoo.log.";
30
- static const char log_format[] = "%s/agoo.log.%d";
31
-
32
- static const char log_pid_name[] = "agoo.log_%d";
33
- static const char log_pid_prefix[] = "agoo.log_%d.";
34
- static const char log_pid_format[] = "%s/agoo.log_%d.%d";
35
-
36
28
  static struct _Color colors[] = {
37
29
  { .name = "black", .ansi = "\033[30;1m" },
38
30
  { .name = "red", .ansi = "\033[31;1m" },
@@ -153,15 +145,26 @@ log_queue_pop(double timeout) {
153
145
  static int
154
146
  jwrite(LogEntry e, FILE *file) {
155
147
  // TBD make e->what JSON friendly
156
- return fprintf(file, "{\"when\":%lld.%09lld,\"where\":\"%s\",\"level\":%d,\"what\":\"%s\"}\n",
157
- (long long)(e->when / 1000000000LL),
158
- (long long)(e->when % 1000000000LL),
159
- e->cat->label,
160
- e->cat->level,
161
- (NULL == e->whatp ? e->what : e->whatp));
148
+ if (NULL == e->tidp && '\0' == *e->tid) {
149
+ return fprintf(file, "{\"when\":%lld.%09lld,\"where\":\"%s\",\"level\":%d,\"what\":\"%s\"}\n",
150
+ (long long)(e->when / 1000000000LL),
151
+ (long long)(e->when % 1000000000LL),
152
+ e->cat->label,
153
+ e->cat->level,
154
+ (NULL == e->whatp ? e->what : e->whatp));
155
+ } else {
156
+ return fprintf(file, "{\"when\":%lld.%09lld,\"tid\":\"%s\",\"where\":\"%s\",\"level\":%d,\"what\":\"%s\"}\n",
157
+ (long long)(e->when / 1000000000LL),
158
+ (long long)(e->when % 1000000000LL),
159
+ (NULL == e->tidp ? e->tid : e->tidp),
160
+ e->cat->label,
161
+ e->cat->level,
162
+ (NULL == e->whatp ? e->what : e->whatp));
163
+ }
162
164
  }
163
165
 
164
- //I 2015/05/23 11:22:33.123456789 label: The contents of the what field.
166
+ // I 2015/05/23 11:22:33.123456789 label: The contents of the what field.
167
+ // I 2015/05/23 11:22:33.123456789 [tid] label: The contents of the what field.
165
168
  static int
166
169
  classic_write(LogEntry e, FILE *file) {
167
170
  time_t t = (time_t)(e->when / 1000000000LL);
@@ -189,16 +192,33 @@ classic_write(LogEntry e, FILE *file) {
189
192
  the_log.day_end = the_log.day_start + 86400;
190
193
  }
191
194
  if (the_log.colorize) {
192
- cnt = fprintf(file, "%s%c %s%02d:%02d:%02d.%09lld %s: %s%s\n",
193
- e->cat->color->ansi, levelc, the_log.day_buf, hour, min, sec, frac,
194
- e->cat->label,
195
- (NULL == e->whatp ? e->what : e->whatp),
196
- RESET_COLOR);
195
+ if (NULL == e->tidp && '\0' == *e->tid) {
196
+ cnt = fprintf(file, "%s%c %s%02d:%02d:%02d.%09lld %s: %s%s\n",
197
+ e->cat->color->ansi, levelc, the_log.day_buf, hour, min, sec, frac,
198
+ e->cat->label,
199
+ (NULL == e->whatp ? e->what : e->whatp),
200
+ RESET_COLOR);
201
+ } else {
202
+ cnt = fprintf(file, "%s%c %s%02d:%02d:%02d.%09lld [%s] %s: %s%s\n",
203
+ e->cat->color->ansi, levelc, the_log.day_buf, hour, min, sec, frac,
204
+ (NULL == e->tidp ? e->tid : e->tidp),
205
+ e->cat->label,
206
+ (NULL == e->whatp ? e->what : e->whatp),
207
+ RESET_COLOR);
208
+ }
197
209
  } else {
198
- cnt += fprintf(file, "%c %s%02d:%02d:%02d.%09lld %s: %s\n",
199
- levelc, the_log.day_buf, hour, min, sec, frac,
200
- e->cat->label,
201
- (NULL == e->whatp ? e->what : e->whatp));
210
+ if (NULL == e->tidp && '\0' == *e->tid) {
211
+ cnt += fprintf(file, "%c %s%02d:%02d:%02d.%09lld %s: %s\n",
212
+ levelc, the_log.day_buf, hour, min, sec, frac,
213
+ e->cat->label,
214
+ (NULL == e->whatp ? e->what : e->whatp));
215
+ } else {
216
+ cnt += fprintf(file, "%c %s%02d:%02d:%02d.%09lld [%s] %s: %s\n",
217
+ levelc, the_log.day_buf, hour, min, sec, frac,
218
+ (NULL == e->tidp ? e->tid : e->tidp),
219
+ e->cat->label,
220
+ (NULL == e->whatp ? e->what : e->whatp));
221
+ }
202
222
  }
203
223
  return cnt;
204
224
  }
@@ -212,17 +232,16 @@ remove_old_logs() {
212
232
  char *end;
213
233
  char path[1500];
214
234
  DIR *dir = opendir(the_log.dir);
215
- char prefix[32];
235
+ char prefix[64];
216
236
  int psize;
217
- char name[32];
237
+ char name[64];
218
238
 
219
239
  if (the_log.with_pid) {
220
- psize = sprintf(prefix, log_pid_prefix, getpid());
221
- sprintf(name, log_pid_name, getpid());
240
+ psize = sprintf(prefix, "%s_%d.log.", the_log.app, getpid());
241
+ sprintf(name, "%s_%d.log", the_log.app, getpid());
222
242
  } else {
223
- memcpy(prefix, log_prefix, sizeof(log_prefix));
224
- psize = (int)sizeof(log_prefix) - 1;
225
- memcpy(name, log_name, sizeof(log_name));
243
+ psize = sprintf(prefix, "%s.log.", the_log.app);
244
+ sprintf(name, "%s.log", the_log.app);
226
245
  }
227
246
  while (NULL != (de = readdir(dir))) {
228
247
  if ('.' == *de->d_name || '\0' == *de->d_name) {
@@ -256,22 +275,22 @@ log_rotate() {
256
275
  if (the_log.with_pid) {
257
276
  char name[32];
258
277
 
259
- sprintf(name, log_pid_name, getpid());
278
+ sprintf(name, "%s_%d.log", the_log.app, getpid());
260
279
  for (int seq = the_log.max_files; 0 < seq; seq--) {
261
- snprintf(to, sizeof(to) - 1, log_pid_format, the_log.dir, getpid(), seq + 1);
262
- snprintf(from, sizeof(from) - 1, log_pid_format, the_log.dir, getpid(), seq);
280
+ snprintf(to, sizeof(to) - 1, "%s/%s_%d.log.%d", the_log.dir, the_log.app, getpid(), seq + 1);
281
+ snprintf(from, sizeof(from) - 1, "%s/%s_%d.log.%d", the_log.dir, the_log.app, getpid(), seq);
263
282
  rename(from, to);
264
283
  }
265
- snprintf(to, sizeof(to) - 1, log_pid_format, the_log.dir, getpid(), 1);
284
+ snprintf(to, sizeof(to) - 1, "%s/%s_%d.log.%d", the_log.dir, the_log.app, getpid(), 1);
266
285
  snprintf(from, sizeof(from) - 1, "%s/%s", the_log.dir, name);
267
286
  } else {
268
287
  for (int seq = the_log.max_files; 0 < seq; seq--) {
269
- snprintf(to, sizeof(to) - 1, log_format, the_log.dir, seq + 1);
270
- snprintf(from, sizeof(from) - 1, log_format, the_log.dir, seq);
288
+ snprintf(to, sizeof(to) - 1, "%s/%s.log.%d", the_log.dir, the_log.app, seq + 1);
289
+ snprintf(from, sizeof(from) - 1, "%s/%s.log.%d", the_log.dir, the_log.app, seq);
271
290
  rename(from, to);
272
291
  }
273
- snprintf(to, sizeof(to) - 1, log_format, the_log.dir, 1);
274
- snprintf(from, sizeof(from) - 1, "%s/%s", the_log.dir, log_name);
292
+ snprintf(to, sizeof(to) - 1, "%s/%s.log.%d", the_log.dir, the_log.app, 1);
293
+ snprintf(from, sizeof(from) - 1, "%s/%s.log", the_log.dir, the_log.app);
275
294
  }
276
295
  rename(from, to);
277
296
 
@@ -308,6 +327,10 @@ loop(void *ctx) {
308
327
  free(e->whatp);
309
328
  DEBUG_FREE(mem_log_what, e->whatp)
310
329
  }
330
+ if (NULL != e->tidp) {
331
+ free(e->tidp);
332
+ DEBUG_FREE(mem_log_tid, e->tidp)
333
+ }
311
334
  e->ready = false;
312
335
  }
313
336
  }
@@ -335,9 +358,9 @@ open_log_file() {
335
358
  char path[1500];
336
359
 
337
360
  if (the_log.with_pid) {
338
- snprintf(path, sizeof(path), "%s/%s_%d", the_log.dir, log_name, getpid());
361
+ snprintf(path, sizeof(path), "%s/%s_%d.log", the_log.dir, the_log.app, getpid());
339
362
  } else {
340
- snprintf(path, sizeof(path), "%s/%s", the_log.dir, log_name);
363
+ snprintf(path, sizeof(path), "%s/%s.log", the_log.dir, the_log.app);
341
364
  }
342
365
  the_log.file = fopen(path, "a");
343
366
  if (NULL == the_log.file) {
@@ -366,27 +389,38 @@ log_close() {
366
389
  fclose(the_log.file);
367
390
  the_log.file = NULL;
368
391
  }
369
- DEBUG_FREE(mem_log_entry, the_log.q)
370
- free(the_log.q);
371
- the_log.q = NULL;
372
- the_log.end = NULL;
392
+ if (NULL != the_log.q) {
393
+ DEBUG_FREE(mem_log_entry, the_log.q);
394
+ free(the_log.q);
395
+ the_log.q = NULL;
396
+ the_log.end = NULL;
397
+ }
373
398
  if (0 < the_log.wsock) {
374
399
  close(the_log.wsock);
400
+ the_log.wsock = 0;
375
401
  }
376
402
  if (0 < the_log.rsock) {
377
403
  close(the_log.rsock);
404
+ the_log.rsock = 0;
378
405
  }
379
406
  }
380
407
 
381
408
  void
382
409
  log_cat_reg(LogCat cat, const char *label, LogLevel level, const char *color, bool on) {
410
+ LogCat xcat = log_cat_find(label);
411
+
412
+ if (NULL != xcat) {
413
+ cat = xcat;
414
+ }
383
415
  strncpy(cat->label, label, sizeof(cat->label));
384
416
  cat->label[sizeof(cat->label) - 1] = '\0';
385
417
  cat->level = level;
386
418
  cat->color = find_color(color);
387
419
  cat->on = on;
388
- cat->next = the_log.cats;
389
- the_log.cats = cat;
420
+ if (NULL == xcat) {
421
+ cat->next = the_log.cats;
422
+ the_log.cats = cat;
423
+ }
390
424
  }
391
425
 
392
426
  void
@@ -413,56 +447,92 @@ log_cat_find(const char *label) {
413
447
  return NULL;
414
448
  }
415
449
 
450
+ #ifdef CLOCK_REALTIME
451
+ static int64_t
452
+ now_nano() {
453
+ struct timespec ts;
454
+
455
+ clock_gettime(CLOCK_REALTIME, &ts);
456
+
457
+ return (int64_t)ts.tv_sec * 1000000000LL + (int64_t)ts.tv_nsec;
458
+ }
459
+ #else
460
+ static int64_t
461
+ now_nano() {
462
+ struct timeval tv;
463
+ struct timezone tz;
464
+
465
+ gettimeofday(&tv, &tz);
466
+ return (int64_t)tv.tv_sec * 1000000000LL + (int64_t)tv.tv_usec * 1000.0;
467
+ }
468
+ #endif
469
+
470
+ static void
471
+ set_entry(LogEntry e, LogCat cat, const char *tid, const char *fmt, va_list ap) {
472
+ int cnt;
473
+ va_list ap2;
474
+
475
+ va_copy(ap2, ap);
476
+
477
+ e->cat = cat;
478
+ e->when = now_nano();
479
+ e->whatp = NULL;
480
+ if ((int)sizeof(e->what) <= (cnt = vsnprintf(e->what, sizeof(e->what), fmt, ap))) {
481
+ e->whatp = (char*)malloc(cnt + 1);
482
+
483
+ DEBUG_ALLOC(mem_log_what, e->whatp)
484
+
485
+ if (NULL != e->whatp) {
486
+ vsnprintf(e->whatp, cnt + 1, fmt, ap2);
487
+ }
488
+ }
489
+ if (NULL != tid) {
490
+ if (strlen(tid) < sizeof(e->tid)) {
491
+ strcpy(e->tid, tid);
492
+ e->tidp = NULL;
493
+ } else {
494
+ e->tidp = strdup(tid);
495
+ *e->tid = '\0';
496
+ }
497
+ } else {
498
+ e->tidp = NULL;
499
+ *e->tid = '\0';
500
+ }
501
+ va_end(ap2);
502
+ }
503
+
416
504
  void
417
- log_catv(LogCat cat, const char *fmt, va_list ap) {
505
+ log_catv(LogCat cat, const char *tid, const char *fmt, va_list ap) {
418
506
  if (cat->on && !the_log.done) {
419
507
  LogEntry e;
420
508
  LogEntry tail;
421
- int cnt;
422
- va_list ap2;
423
-
424
- va_copy(ap2, ap);
425
509
 
426
510
  while (atomic_flag_test_and_set(&the_log.push_lock)) {
427
511
  dsleep(RETRY_SECS);
428
512
  }
513
+ if (0 == the_log.thread) {
514
+ struct _LogEntry entry;
515
+
516
+ set_entry(&entry, cat, tid, fmt, ap);
517
+ if (the_log.classic) {
518
+ classic_write(&entry, stdout);
519
+ } else {
520
+ jwrite(&entry, stdout);
521
+ }
522
+ atomic_flag_clear(&the_log.push_lock);
523
+ }
429
524
  // Wait for head to move on.
430
525
  while (atomic_load(&the_log.head) == the_log.tail) {
431
526
  dsleep(RETRY_SECS);
432
527
  }
433
528
  e = the_log.tail;
434
- e->cat = cat;
435
- {
436
- #ifdef CLOCK_REALTIME
437
- struct timespec ts;
438
-
439
- clock_gettime(CLOCK_REALTIME, &ts);
440
- e->when = (int64_t)ts.tv_sec * 1000000000LL + (int64_t)ts.tv_nsec;
441
- #else
442
- struct timeval tv;
443
- struct timezone tz;
444
-
445
- gettimeofday(&tv, &tz);
446
- e->when = (int64_t)tv.tv_sec * 1000000000LL + (int64_t)tv.tv_usec * 1000.0;
447
- #endif
448
- }
449
- e->whatp = NULL;
450
- if ((int)sizeof(e->what) <= (cnt = vsnprintf(e->what, sizeof(e->what), fmt, ap))) {
451
- e->whatp = (char*)malloc(cnt + 1);
452
-
453
- DEBUG_ALLOC(mem_log_what, e->whatp)
454
-
455
- if (NULL != e->whatp) {
456
- vsnprintf(e->whatp, cnt + 1, fmt, ap2);
457
- }
458
- }
529
+ set_entry(e, cat, tid, fmt, ap);
459
530
  tail = the_log.tail + 1;
460
531
  if (the_log.end <= tail) {
461
532
  tail = the_log.q;
462
533
  }
463
534
  atomic_store(&the_log.tail, tail);
464
535
  atomic_flag_clear(&the_log.push_lock);
465
- va_end(ap2);
466
536
 
467
537
  if (0 != the_log.wsock && WAITING == atomic_load(&the_log.wait_state)) {
468
538
  if (write(the_log.wsock, ".", 1)) {}
@@ -476,19 +546,32 @@ log_cat(LogCat cat, const char *fmt, ...) {
476
546
  va_list ap;
477
547
 
478
548
  va_start(ap, fmt);
479
- log_catv(cat, fmt, ap);
549
+ log_catv(cat, NULL, fmt, ap);
550
+ va_end(ap);
551
+ }
552
+
553
+ void
554
+ log_tid_cat(LogCat cat, const char *tid, const char *fmt, ...) {
555
+ va_list ap;
556
+
557
+ va_start(ap, fmt);
558
+ log_catv(cat, tid, fmt, ap);
480
559
  va_end(ap);
481
560
  }
482
561
 
483
562
  void
484
563
  log_start(bool with_pid) {
564
+ if (0 != the_log.thread) {
565
+ // Already started.
566
+ return;
567
+ }
485
568
  if (NULL != the_log.file) {
486
569
  fclose(the_log.file);
487
570
  the_log.file = NULL;
488
571
  // TBD close rsock and wsock
489
572
  }
490
573
  the_log.with_pid = with_pid;
491
- if (with_pid && '\0' != *the_log.dir) {
574
+ if ('\0' != *the_log.dir) {
492
575
  if (0 != mkdir(the_log.dir, 0770) && EEXIST != errno) {
493
576
  struct _Err err;
494
577
 
@@ -501,11 +584,13 @@ log_start(bool with_pid) {
501
584
  }
502
585
 
503
586
  void
504
- log_init() {
587
+ log_init(const char *app) {
505
588
  time_t t = time(NULL);
506
589
  struct tm *tm = localtime(&t);
507
590
  int qsize = 1024;
508
-
591
+
592
+ strncpy(the_log.app, app, sizeof(the_log.app));
593
+ the_log.app[sizeof(the_log.app) - 1] = '\0';
509
594
  the_log.cats = NULL;
510
595
  *the_log.dir = '\0';
511
596
  the_log.file = NULL;
@@ -547,5 +632,5 @@ log_init() {
547
632
  log_cat_reg(&eval_cat, "eval", INFO, BLUE, false);
548
633
  log_cat_reg(&push_cat, "push", INFO, DARK_CYAN, false);
549
634
 
550
- log_start(false);
635
+ //log_start(false);
551
636
  }