]> arthur.barton.de Git - netdata.git/blob - src/common.c
Merge pull request #668 from ktsaou/master
[netdata.git] / src / common.c
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 #include <sys/syscall.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <errno.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <sys/mman.h>
13 #include <time.h>
14
15 #include "log.h"
16 #include "common.h"
17 #include "appconfig.h"
18 #include "../config.h"
19
20 char *global_host_prefix = "";
21 int enable_ksm = 1;
22
23 // time(NULL) in milliseconds
24 unsigned long long timems(void) {
25         struct timeval now;
26         gettimeofday(&now, NULL);
27         return now.tv_sec * 1000000ULL + now.tv_usec;
28 }
29
30 int usecsleep(unsigned long long usec) {
31
32 #ifndef NETDATA_WITH_USLEEP
33         // we expect microseconds (1.000.000 per second)
34         // but timespec is nanoseconds (1.000.000.000 per second)
35         struct timespec req = { .tv_sec = usec / 1000000, .tv_nsec = (usec % 1000000) * 1000 }, rem;
36
37         while(nanosleep(&req, &rem) == -1) {
38                 if(likely(errno == EINTR)) {
39                         info("nanosleep() interrupted (while sleeping for %llu microseconds).", usec);
40                         req.tv_sec = rem.tv_sec;
41                         req.tv_nsec = rem.tv_nsec;
42                 }
43                 else {
44                         error("Cannot nanosleep() for %llu microseconds.", usec);
45                         break;
46                 }
47         }
48
49         return 0;
50 #else
51         int ret = usleep(usec);
52         if(unlikely(ret == -1 && errno == EINVAL)) {
53                 // on certain systems, usec has to be up to 999999
54                 if(usec > 999999) {
55                         int counter = usec / 999999;
56                         while(counter--)
57                                 usleep(999999);
58
59                         usleep(usec % 999999);
60                 }
61                 else {
62                         error("Cannot usleep() for %llu microseconds.", usec);
63                         return ret;
64                 }
65         }
66
67         if(ret != 0)
68                 error("usleep() failed for %llu microseconds.", usec);
69
70         return ret;
71 #endif
72 }
73
74 unsigned char netdata_map_chart_names[256] = {
75                 [0] = '\0', //
76                 [1] = '_', //
77                 [2] = '_', //
78                 [3] = '_', //
79                 [4] = '_', //
80                 [5] = '_', //
81                 [6] = '_', //
82                 [7] = '_', //
83                 [8] = '_', //
84                 [9] = '_', //
85                 [10] = '_', //
86                 [11] = '_', //
87                 [12] = '_', //
88                 [13] = '_', //
89                 [14] = '_', //
90                 [15] = '_', //
91                 [16] = '_', //
92                 [17] = '_', //
93                 [18] = '_', //
94                 [19] = '_', //
95                 [20] = '_', //
96                 [21] = '_', //
97                 [22] = '_', //
98                 [23] = '_', //
99                 [24] = '_', //
100                 [25] = '_', //
101                 [26] = '_', //
102                 [27] = '_', //
103                 [28] = '_', //
104                 [29] = '_', //
105                 [30] = '_', //
106                 [31] = '_', //
107                 [32] = '_', //
108                 [33] = '_', // !
109                 [34] = '_', // "
110                 [35] = '_', // #
111                 [36] = '_', // $
112                 [37] = '_', // %
113                 [38] = '_', // &
114                 [39] = '_', // '
115                 [40] = '_', // (
116                 [41] = '_', // )
117                 [42] = '_', // *
118                 [43] = '_', // +
119                 [44] = '.', // ,
120                 [45] = '-', // -
121                 [46] = '.', // .
122                 [47] = '/', // /
123                 [48] = '0', // 0
124                 [49] = '1', // 1
125                 [50] = '2', // 2
126                 [51] = '3', // 3
127                 [52] = '4', // 4
128                 [53] = '5', // 5
129                 [54] = '6', // 6
130                 [55] = '7', // 7
131                 [56] = '8', // 8
132                 [57] = '9', // 9
133                 [58] = '_', // :
134                 [59] = '_', // ;
135                 [60] = '_', // <
136                 [61] = '_', // =
137                 [62] = '_', // >
138                 [63] = '_', // ?
139                 [64] = '_', // @
140                 [65] = 'a', // A
141                 [66] = 'b', // B
142                 [67] = 'c', // C
143                 [68] = 'd', // D
144                 [69] = 'e', // E
145                 [70] = 'f', // F
146                 [71] = 'g', // G
147                 [72] = 'h', // H
148                 [73] = 'i', // I
149                 [74] = 'j', // J
150                 [75] = 'k', // K
151                 [76] = 'l', // L
152                 [77] = 'm', // M
153                 [78] = 'n', // N
154                 [79] = 'o', // O
155                 [80] = 'p', // P
156                 [81] = 'q', // Q
157                 [82] = 'r', // R
158                 [83] = 's', // S
159                 [84] = 't', // T
160                 [85] = 'u', // U
161                 [86] = 'v', // V
162                 [87] = 'w', // W
163                 [88] = 'x', // X
164                 [89] = 'y', // Y
165                 [90] = 'z', // Z
166                 [91] = '_', // [
167                 [92] = '/', // backslash
168                 [93] = '_', // ]
169                 [94] = '_', // ^
170                 [95] = '_', // _
171                 [96] = '_', // `
172                 [97] = 'a', // a
173                 [98] = 'b', // b
174                 [99] = 'c', // c
175                 [100] = 'd', // d
176                 [101] = 'e', // e
177                 [102] = 'f', // f
178                 [103] = 'g', // g
179                 [104] = 'h', // h
180                 [105] = 'i', // i
181                 [106] = 'j', // j
182                 [107] = 'k', // k
183                 [108] = 'l', // l
184                 [109] = 'm', // m
185                 [110] = 'n', // n
186                 [111] = 'o', // o
187                 [112] = 'p', // p
188                 [113] = 'q', // q
189                 [114] = 'r', // r
190                 [115] = 's', // s
191                 [116] = 't', // t
192                 [117] = 'u', // u
193                 [118] = 'v', // v
194                 [119] = 'w', // w
195                 [120] = 'x', // x
196                 [121] = 'y', // y
197                 [122] = 'z', // z
198                 [123] = '_', // {
199                 [124] = '_', // |
200                 [125] = '_', // }
201                 [126] = '_', // ~
202                 [127] = '_', //
203                 [128] = '_', //
204                 [129] = '_', //
205                 [130] = '_', //
206                 [131] = '_', //
207                 [132] = '_', //
208                 [133] = '_', //
209                 [134] = '_', //
210                 [135] = '_', //
211                 [136] = '_', //
212                 [137] = '_', //
213                 [138] = '_', //
214                 [139] = '_', //
215                 [140] = '_', //
216                 [141] = '_', //
217                 [142] = '_', //
218                 [143] = '_', //
219                 [144] = '_', //
220                 [145] = '_', //
221                 [146] = '_', //
222                 [147] = '_', //
223                 [148] = '_', //
224                 [149] = '_', //
225                 [150] = '_', //
226                 [151] = '_', //
227                 [152] = '_', //
228                 [153] = '_', //
229                 [154] = '_', //
230                 [155] = '_', //
231                 [156] = '_', //
232                 [157] = '_', //
233                 [158] = '_', //
234                 [159] = '_', //
235                 [160] = '_', //
236                 [161] = '_', //
237                 [162] = '_', //
238                 [163] = '_', //
239                 [164] = '_', //
240                 [165] = '_', //
241                 [166] = '_', //
242                 [167] = '_', //
243                 [168] = '_', //
244                 [169] = '_', //
245                 [170] = '_', //
246                 [171] = '_', //
247                 [172] = '_', //
248                 [173] = '_', //
249                 [174] = '_', //
250                 [175] = '_', //
251                 [176] = '_', //
252                 [177] = '_', //
253                 [178] = '_', //
254                 [179] = '_', //
255                 [180] = '_', //
256                 [181] = '_', //
257                 [182] = '_', //
258                 [183] = '_', //
259                 [184] = '_', //
260                 [185] = '_', //
261                 [186] = '_', //
262                 [187] = '_', //
263                 [188] = '_', //
264                 [189] = '_', //
265                 [190] = '_', //
266                 [191] = '_', //
267                 [192] = '_', //
268                 [193] = '_', //
269                 [194] = '_', //
270                 [195] = '_', //
271                 [196] = '_', //
272                 [197] = '_', //
273                 [198] = '_', //
274                 [199] = '_', //
275                 [200] = '_', //
276                 [201] = '_', //
277                 [202] = '_', //
278                 [203] = '_', //
279                 [204] = '_', //
280                 [205] = '_', //
281                 [206] = '_', //
282                 [207] = '_', //
283                 [208] = '_', //
284                 [209] = '_', //
285                 [210] = '_', //
286                 [211] = '_', //
287                 [212] = '_', //
288                 [213] = '_', //
289                 [214] = '_', //
290                 [215] = '_', //
291                 [216] = '_', //
292                 [217] = '_', //
293                 [218] = '_', //
294                 [219] = '_', //
295                 [220] = '_', //
296                 [221] = '_', //
297                 [222] = '_', //
298                 [223] = '_', //
299                 [224] = '_', //
300                 [225] = '_', //
301                 [226] = '_', //
302                 [227] = '_', //
303                 [228] = '_', //
304                 [229] = '_', //
305                 [230] = '_', //
306                 [231] = '_', //
307                 [232] = '_', //
308                 [233] = '_', //
309                 [234] = '_', //
310                 [235] = '_', //
311                 [236] = '_', //
312                 [237] = '_', //
313                 [238] = '_', //
314                 [239] = '_', //
315                 [240] = '_', //
316                 [241] = '_', //
317                 [242] = '_', //
318                 [243] = '_', //
319                 [244] = '_', //
320                 [245] = '_', //
321                 [246] = '_', //
322                 [247] = '_', //
323                 [248] = '_', //
324                 [249] = '_', //
325                 [250] = '_', //
326                 [251] = '_', //
327                 [252] = '_', //
328                 [253] = '_', //
329                 [254] = '_', //
330                 [255] = '_'  //
331 };
332
333 // make sure the supplied string
334 // is good for a netdata chart/dimension ID/NAME
335 void netdata_fix_chart_name(char *s) {
336         while((*s = netdata_map_chart_names[(unsigned char)*s])) s++;
337 }
338
339 unsigned char netdata_map_chart_ids[256] = {
340                 [0] = '\0', //
341                 [1] = '_', //
342                 [2] = '_', //
343                 [3] = '_', //
344                 [4] = '_', //
345                 [5] = '_', //
346                 [6] = '_', //
347                 [7] = '_', //
348                 [8] = '_', //
349                 [9] = '_', //
350                 [10] = '_', //
351                 [11] = '_', //
352                 [12] = '_', //
353                 [13] = '_', //
354                 [14] = '_', //
355                 [15] = '_', //
356                 [16] = '_', //
357                 [17] = '_', //
358                 [18] = '_', //
359                 [19] = '_', //
360                 [20] = '_', //
361                 [21] = '_', //
362                 [22] = '_', //
363                 [23] = '_', //
364                 [24] = '_', //
365                 [25] = '_', //
366                 [26] = '_', //
367                 [27] = '_', //
368                 [28] = '_', //
369                 [29] = '_', //
370                 [30] = '_', //
371                 [31] = '_', //
372                 [32] = '_', //
373                 [33] = '_', // !
374                 [34] = '_', // "
375                 [35] = '_', // #
376                 [36] = '_', // $
377                 [37] = '_', // %
378                 [38] = '_', // &
379                 [39] = '_', // '
380                 [40] = '_', // (
381                 [41] = '_', // )
382                 [42] = '_', // *
383                 [43] = '_', // +
384                 [44] = '.', // ,
385                 [45] = '-', // -
386                 [46] = '.', // .
387                 [47] = '_', // /
388                 [48] = '0', // 0
389                 [49] = '1', // 1
390                 [50] = '2', // 2
391                 [51] = '3', // 3
392                 [52] = '4', // 4
393                 [53] = '5', // 5
394                 [54] = '6', // 6
395                 [55] = '7', // 7
396                 [56] = '8', // 8
397                 [57] = '9', // 9
398                 [58] = '_', // :
399                 [59] = '_', // ;
400                 [60] = '_', // <
401                 [61] = '_', // =
402                 [62] = '_', // >
403                 [63] = '_', // ?
404                 [64] = '_', // @
405                 [65] = 'a', // A
406                 [66] = 'b', // B
407                 [67] = 'c', // C
408                 [68] = 'd', // D
409                 [69] = 'e', // E
410                 [70] = 'f', // F
411                 [71] = 'g', // G
412                 [72] = 'h', // H
413                 [73] = 'i', // I
414                 [74] = 'j', // J
415                 [75] = 'k', // K
416                 [76] = 'l', // L
417                 [77] = 'm', // M
418                 [78] = 'n', // N
419                 [79] = 'o', // O
420                 [80] = 'p', // P
421                 [81] = 'q', // Q
422                 [82] = 'r', // R
423                 [83] = 's', // S
424                 [84] = 't', // T
425                 [85] = 'u', // U
426                 [86] = 'v', // V
427                 [87] = 'w', // W
428                 [88] = 'x', // X
429                 [89] = 'y', // Y
430                 [90] = 'z', // Z
431                 [91] = '_', // [
432                 [92] = '/', // backslash
433                 [93] = '_', // ]
434                 [94] = '_', // ^
435                 [95] = '_', // _
436                 [96] = '_', // `
437                 [97] = 'a', // a
438                 [98] = 'b', // b
439                 [99] = 'c', // c
440                 [100] = 'd', // d
441                 [101] = 'e', // e
442                 [102] = 'f', // f
443                 [103] = 'g', // g
444                 [104] = 'h', // h
445                 [105] = 'i', // i
446                 [106] = 'j', // j
447                 [107] = 'k', // k
448                 [108] = 'l', // l
449                 [109] = 'm', // m
450                 [110] = 'n', // n
451                 [111] = 'o', // o
452                 [112] = 'p', // p
453                 [113] = 'q', // q
454                 [114] = 'r', // r
455                 [115] = 's', // s
456                 [116] = 't', // t
457                 [117] = 'u', // u
458                 [118] = 'v', // v
459                 [119] = 'w', // w
460                 [120] = 'x', // x
461                 [121] = 'y', // y
462                 [122] = 'z', // z
463                 [123] = '_', // {
464                 [124] = '_', // |
465                 [125] = '_', // }
466                 [126] = '_', // ~
467                 [127] = '_', //
468                 [128] = '_', //
469                 [129] = '_', //
470                 [130] = '_', //
471                 [131] = '_', //
472                 [132] = '_', //
473                 [133] = '_', //
474                 [134] = '_', //
475                 [135] = '_', //
476                 [136] = '_', //
477                 [137] = '_', //
478                 [138] = '_', //
479                 [139] = '_', //
480                 [140] = '_', //
481                 [141] = '_', //
482                 [142] = '_', //
483                 [143] = '_', //
484                 [144] = '_', //
485                 [145] = '_', //
486                 [146] = '_', //
487                 [147] = '_', //
488                 [148] = '_', //
489                 [149] = '_', //
490                 [150] = '_', //
491                 [151] = '_', //
492                 [152] = '_', //
493                 [153] = '_', //
494                 [154] = '_', //
495                 [155] = '_', //
496                 [156] = '_', //
497                 [157] = '_', //
498                 [158] = '_', //
499                 [159] = '_', //
500                 [160] = '_', //
501                 [161] = '_', //
502                 [162] = '_', //
503                 [163] = '_', //
504                 [164] = '_', //
505                 [165] = '_', //
506                 [166] = '_', //
507                 [167] = '_', //
508                 [168] = '_', //
509                 [169] = '_', //
510                 [170] = '_', //
511                 [171] = '_', //
512                 [172] = '_', //
513                 [173] = '_', //
514                 [174] = '_', //
515                 [175] = '_', //
516                 [176] = '_', //
517                 [177] = '_', //
518                 [178] = '_', //
519                 [179] = '_', //
520                 [180] = '_', //
521                 [181] = '_', //
522                 [182] = '_', //
523                 [183] = '_', //
524                 [184] = '_', //
525                 [185] = '_', //
526                 [186] = '_', //
527                 [187] = '_', //
528                 [188] = '_', //
529                 [189] = '_', //
530                 [190] = '_', //
531                 [191] = '_', //
532                 [192] = '_', //
533                 [193] = '_', //
534                 [194] = '_', //
535                 [195] = '_', //
536                 [196] = '_', //
537                 [197] = '_', //
538                 [198] = '_', //
539                 [199] = '_', //
540                 [200] = '_', //
541                 [201] = '_', //
542                 [202] = '_', //
543                 [203] = '_', //
544                 [204] = '_', //
545                 [205] = '_', //
546                 [206] = '_', //
547                 [207] = '_', //
548                 [208] = '_', //
549                 [209] = '_', //
550                 [210] = '_', //
551                 [211] = '_', //
552                 [212] = '_', //
553                 [213] = '_', //
554                 [214] = '_', //
555                 [215] = '_', //
556                 [216] = '_', //
557                 [217] = '_', //
558                 [218] = '_', //
559                 [219] = '_', //
560                 [220] = '_', //
561                 [221] = '_', //
562                 [222] = '_', //
563                 [223] = '_', //
564                 [224] = '_', //
565                 [225] = '_', //
566                 [226] = '_', //
567                 [227] = '_', //
568                 [228] = '_', //
569                 [229] = '_', //
570                 [230] = '_', //
571                 [231] = '_', //
572                 [232] = '_', //
573                 [233] = '_', //
574                 [234] = '_', //
575                 [235] = '_', //
576                 [236] = '_', //
577                 [237] = '_', //
578                 [238] = '_', //
579                 [239] = '_', //
580                 [240] = '_', //
581                 [241] = '_', //
582                 [242] = '_', //
583                 [243] = '_', //
584                 [244] = '_', //
585                 [245] = '_', //
586                 [246] = '_', //
587                 [247] = '_', //
588                 [248] = '_', //
589                 [249] = '_', //
590                 [250] = '_', //
591                 [251] = '_', //
592                 [252] = '_', //
593                 [253] = '_', //
594                 [254] = '_', //
595                 [255] = '_'  //
596 };
597
598 // make sure the supplied string
599 // is good for a netdata chart/dimension ID/NAME
600 void netdata_fix_chart_id(char *s) {
601         while((*s = netdata_map_chart_ids[(unsigned char)*s])) s++;
602 }
603
604 /*
605 // http://stackoverflow.com/questions/7666509/hash-function-for-string
606 uint32_t simple_hash(const char *name)
607 {
608         const char *s = name;
609         uint32_t hash = 5381;
610         int i;
611
612         while((i = *s++)) hash = ((hash << 5) + hash) + i;
613
614         // fprintf(stderr, "HASH: %lu %s\n", hash, name);
615
616         return hash;
617 }
618 */
619
620
621 // http://isthe.com/chongo/tech/comp/fnv/#FNV-1a
622 uint32_t simple_hash(const char *name) {
623         unsigned char *s = (unsigned char *)name;
624         uint32_t hval = 0x811c9dc5;
625
626         // FNV-1a algorithm
627         while (*s) {
628                 // multiply by the 32 bit FNV magic prime mod 2^32
629                 // NOTE: No need to optimize with left shifts.
630                 //       GCC will use imul instruction anyway.
631                 //       Tested with 'gcc -O3 -S'
632                 //hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
633                 hval *= 16777619;
634
635                 // xor the bottom with the current octet
636                 hval ^= (uint32_t)*s++;
637         }
638
639         // fprintf(stderr, "HASH: %u = %s\n", hval, name);
640         return hval;
641 }
642
643 uint32_t simple_uhash(const char *name) {
644         unsigned char *s = (unsigned char *)name;
645         uint32_t hval = 0x811c9dc5, c;
646
647         // FNV-1a algorithm
648         while((c = *s++)) {
649                 if(unlikely(c >= 'A' && c <= 'Z')) c += 'a' - 'A';
650                 hval *= 16777619;
651                 hval ^= c;
652         }
653         return hval;
654 }
655
656 /*
657 // http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
658 // one at a time hash
659 uint32_t simple_hash(const char *name) {
660         unsigned char *s = (unsigned char *)name;
661         uint32_t h = 0;
662
663         while(*s) {
664                 h += *s++;
665                 h += (h << 10);
666                 h ^= (h >> 6);
667         }
668
669         h += (h << 3);
670         h ^= (h >> 11);
671         h += (h << 15);
672
673         // fprintf(stderr, "HASH: %u = %s\n", h, name);
674
675         return h;
676 }
677 */
678
679 void strreverse(char* begin, char* end)
680 {
681         char aux;
682
683         while (end > begin)
684         {
685                 // clearer code.
686                 aux = *end;
687                 *end-- = *begin;
688                 *begin++ = aux;
689         }
690 }
691
692 char *mystrsep(char **ptr, char *s)
693 {
694         char *p = "";
695         while ( p && !p[0] && *ptr ) p = strsep(ptr, s);
696         return(p);
697 }
698
699 char *trim(char *s)
700 {
701         // skip leading spaces
702         // and 'comments' as well!?
703         while(*s && isspace(*s)) s++;
704         if(!*s || *s == '#') return NULL;
705
706         // skip tailing spaces
707         // this way is way faster. Writes only one NUL char.
708         ssize_t l = strlen(s);
709   if (--l >= 0)
710         {
711                 char *p = s + l;
712                 while (p > s && isspace(*p)) p--;
713                 *++p = '\0';
714         }
715
716         if(!*s) return NULL;
717
718         return s;
719 }
720
721 void *mymmap(const char *filename, size_t size, int flags, int ksm)
722 {
723         int fd;
724         void *mem = NULL;
725
726         errno = 0;
727         fd = open(filename, O_RDWR|O_CREAT|O_NOATIME, 0664);
728         if(fd != -1) {
729                 if(lseek(fd, size, SEEK_SET) == (off_t)size) {
730                         if(write(fd, "", 1) == 1) {
731                                 if(ftruncate(fd, size))
732                                         error("Cannot truncate file '%s' to size %zu. Will use the larger file.", filename, size);
733
734 #ifdef MADV_MERGEABLE
735                                 if(flags & MAP_SHARED || !enable_ksm || !ksm) {
736 #endif
737                                         mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
738                                         if(mem != MAP_FAILED) {
739                                                 int advise = MADV_SEQUENTIAL|MADV_DONTFORK;
740                                                 if(flags & MAP_SHARED) advise |= MADV_WILLNEED;
741
742                                                 if(madvise(mem, size, advise) != 0)
743                                                         error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
744                                         }
745 #ifdef MADV_MERGEABLE
746                                 }
747                                 else {
748 /*
749                                         // test - load the file into memory
750                                         mem = calloc(1, size);
751                                         if(mem) {
752                                                 if(lseek(fd, 0, SEEK_SET) == 0) {
753                                                         if(read(fd, mem, size) != (ssize_t)size)
754                                                                 error("Cannot read from file '%s'", filename);
755                                                 }
756                                                 else
757                                                         error("Cannot seek to beginning of file '%s'.", filename);
758                                         }
759 */
760                                         mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags|MAP_ANONYMOUS, -1, 0);
761                                         if(mem != MAP_FAILED) {
762                                                 if(lseek(fd, 0, SEEK_SET) == 0) {
763                                                         if(read(fd, mem, size) != (ssize_t)size)
764                                                                 error("Cannot read from file '%s'", filename);
765                                                 }
766                                                 else
767                                                         error("Cannot seek to beginning of file '%s'.", filename);
768
769                                                 // don't use MADV_SEQUENTIAL|MADV_DONTFORK, they disable MADV_MERGEABLE
770                                                 if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK) != 0)
771                                                         error("Cannot advise the kernel about the memory usage (MADV_SEQUENTIAL|MADV_DONTFORK) of file '%s'.", filename);
772
773                                                 if(madvise(mem, size, MADV_MERGEABLE) != 0)
774                                                         error("Cannot advise the kernel about the memory usage (MADV_MERGEABLE) of file '%s'.", filename);
775                                         }
776                                         else
777                                                 error("Cannot allocate PRIVATE ANONYMOUS memory for KSM for file '%s'.", filename);
778                                 }
779 #endif
780                         }
781                         else error("Cannot write to file '%s' at position %zu.", filename, size);
782                 }
783                 else error("Cannot seek file '%s' to size %zu.", filename, size);
784
785                 close(fd);
786         }
787         else error("Cannot create/open file '%s'.", filename);
788
789         return mem;
790 }
791
792 int savememory(const char *filename, void *mem, size_t size)
793 {
794         char tmpfilename[FILENAME_MAX + 1];
795
796         snprintfz(tmpfilename, FILENAME_MAX, "%s.%ld.tmp", filename, (long)getpid());
797
798         int fd = open(tmpfilename, O_RDWR|O_CREAT|O_NOATIME, 0664);
799         if(fd < 0) {
800                 error("Cannot create/open file '%s'.", filename);
801                 return -1;
802         }
803
804         if(write(fd, mem, size) != (ssize_t)size) {
805                 error("Cannot write to file '%s' %ld bytes.", filename, (long)size);
806                 close(fd);
807                 return -1;
808         }
809
810         close(fd);
811
812         if(rename(tmpfilename, filename)) {
813                 error("Cannot rename '%s' to '%s'", tmpfilename, filename);
814                 return -1;
815         }
816
817         return 0;
818 }
819
820 int fd_is_valid(int fd) {
821     return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
822 }
823
824 /*
825  ***************************************************************************
826  * Get number of clock ticks per second.
827  ***************************************************************************
828  */
829 unsigned int hz;
830
831 void get_HZ(void)
832 {
833         long ticks;
834
835         if ((ticks = sysconf(_SC_CLK_TCK)) == -1) {
836                 perror("sysconf");
837         }
838
839         hz = (unsigned int) ticks;
840 }
841
842 pid_t gettid(void)
843 {
844         return syscall(SYS_gettid);
845 }
846
847 char *fgets_trim_len(char *buf, size_t buf_size, FILE *fp, size_t *len) {
848         char *s = fgets(buf, buf_size, fp);
849         if(!s) return NULL;
850
851         char *t = s;
852         if(*t != '\0') {
853                 // find the string end
854                 while (*++t != '\0');
855
856                 // trim trailing spaces/newlines/tabs
857                 while (--t > s && *t == '\n')
858                         *t = '\0';
859         }
860
861         if(len)
862                 *len = t - s + 1;
863
864         return s;
865 }
866
867 char *strncpyz(char *dst, const char *src, size_t n) {
868         char *p = dst;
869
870         while(*src && n--)
871                 *dst++ = *src++;
872
873         *dst = '\0';
874
875         return p;
876 }
877
878 int vsnprintfz(char *dst, size_t n, const char *fmt, va_list args) {
879         int size;
880
881         size = vsnprintf(dst, n, fmt, args);
882
883         if(unlikely((size_t)size > n)) {
884                 // there is bug in vsnprintf() and it returns
885                 // a number higher to len, but it does not
886                 // overflow the buffer.
887                 size = n;
888         }
889
890         dst[size] = '\0';
891         return size;
892 }
893
894 int snprintfz(char *dst, size_t n, const char *fmt, ...) {
895         va_list args;
896
897         va_start(args, fmt);
898         int ret = vsnprintfz(dst, n, fmt, args);
899         va_end(args);
900
901         return ret;
902 }