master
h 125 lines 4.34 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_PROCFILE_H
4 #define NETDATA_PROCFILE_H 1
5
6 #include "../libnetdata.h"
7
8 // ----------------------------------------------------------------------------
9 // An array of words
10
11 typedef struct {
12 size_t len; // used entries
13 size_t size; // capacity
14 char *words[]; // array of pointers
15 } pfwords;
16
17
18 // ----------------------------------------------------------------------------
19 // An array of lines
20
21 typedef struct {
22 uint32_t words; // how many words this line has
23 uint32_t first; // the id of the first word of this line in the words array
24 } ffline;
25
26 typedef struct {
27 size_t len; // used entries
28 size_t size; // capacity
29 ffline lines[]; // array of lines
30 } pflines;
31
32
33 // ----------------------------------------------------------------------------
34 // The procfile
35
36 #define PROCFILE_FLAG_DEFAULT 0x00000000 // To store inside `collector.log`
37 #define PROCFILE_FLAG_NO_ERROR_ON_FILE_IO 0x00000001 // Do not log anything
38 #define PROCFILE_FLAG_ERROR_ON_ERROR_LOG 0x00000002 // Store inside `error.log`
39 #define PROCFILE_FLAG_NONSEEKABLE 0x00000004 // File doesn't support lseek(), reopen instead
40
41 typedef enum __attribute__ ((__packed__)) procfile_separator {
42 PF_CHAR_IS_SEPARATOR,
43 PF_CHAR_IS_NEWLINE,
44 PF_CHAR_IS_WORD,
45 PF_CHAR_IS_QUOTE,
46 PF_CHAR_IS_OPEN,
47 PF_CHAR_IS_CLOSE
48 } PF_CHAR_TYPE;
49
50 struct procfile_stats {
51 size_t opens;
52 size_t reads;
53 size_t resizes;
54 size_t memory;
55 size_t total_read_bytes;
56 size_t max_source_bytes;
57 size_t max_lines;
58 size_t max_words;
59 size_t max_read_size;
60 };
61
62
63 typedef struct procfile {
64 // this structure is malloc'd (you need to initialize it at procfile_open()
65
66 char *filename; // not populated until procfile_filename() is called
67 uint32_t flags;
68 int fd; // the file descriptor
69 size_t len; // the bytes we have placed into data
70 size_t size; // the bytes we have allocated for data
71 pflines *lines;
72 pfwords *words;
73 PF_CHAR_TYPE separators[256];
74 struct procfile_stats stats;
75 char data[]; // allocated buffer to keep file contents
76 } procfile;
77
78 // close the proc file and free all related memory
79 void procfile_close(procfile *ff);
80
81 // (re)read and parse the proc file
82 procfile *procfile_readall(procfile *ff);
83
84 // open a /proc or /sys file
85 procfile *procfile_open(const char *filename, const char *separators, uint32_t flags);
86
87 // re-open a file
88 // if separators == NULL, the last separators are used
89 procfile *procfile_reopen(procfile *ff, const char *filename, const char *separators, uint32_t flags);
90
91 // example walk-through a procfile parsed file
92 void procfile_print(procfile *ff);
93
94 void procfile_set_quotes(procfile *ff, const char *quotes);
95 void procfile_set_open_close(procfile *ff, const char *open, const char *close);
96
97 char *procfile_filename(procfile *ff);
98
99 // ----------------------------------------------------------------------------
100
101 // set to the O_XXXX flags, to have procfile_open and procfile_reopen use them when opening proc files
102 extern int procfile_open_flags;
103
104 // call this with true and the expected initial sizes to allow procfile learn the sizes needed
105 void procfile_set_adaptive_allocation(bool enable, size_t bytes, size_t lines, size_t words);
106
107 // return the number of lines present
108 #define procfile_lines(ff) ((ff)->lines->len)
109
110 // return the number of words of the Nth line
111 #define procfile_linewords(ff, line) (((line) < procfile_lines(ff)) ? (ff)->lines->lines[(line)].words : 0)
112
113 // return the Nth word of the file, or empty string
114 #define procfile_word(ff, word) (((word) < (ff)->words->len) ? (ff)->words->words[(word)] : "")
115
116 // return the first word of the Nth line, or empty string
117 #define procfile_line(ff, line) (((line) < procfile_lines(ff)) ? procfile_word((ff), (ff)->lines->lines[(line)].first) : "")
118
119 // return the Nth word of the current line
120 #define procfile_lineword(ff, line, word) (((line) < procfile_lines(ff) && (word) < procfile_linewords((ff), (line))) ? procfile_word((ff), (ff)->lines->lines[(line)].first + (word)) : "")
121
122 // Open file without logging file IO error if any
123 #define procfile_open_no_log(filename, separators, flags) procfile_open(filename, separators, flags | PROCFILE_FLAG_NO_ERROR_ON_FILE_IO)
124
125 #endif /* NETDATA_PROCFILE_H */