Merge "Corrected and optimized usage of fork and waitpid." into tizen
[platform/core/connectivity/stc-manager.git] / include / stc-manager-util.h
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __STC_MANAGER_UTIL_H__
18 #define __STC_MANAGER_UTIL_H__
19
20 #include <dirent.h>
21 #include <glib.h>
22 #include <gio/gio.h>
23 #include <stdio.h>
24 #include <stdbool.h>  /* bool */
25 #include <stdint.h> /* uint32_t, uint63_t */
26 #include <string.h>
27 #include <sqlite3.h>  /* database handling */
28 #include <time.h>  /* time function */
29 #include <vconf/vconf.h>
30 #include <unistd.h>
31
32 #ifdef USE_DLOG
33 #include <dlog.h>
34
35 #undef LOG_TAG
36 #define LOG_TAG "STC_MANAGER"
37
38 #define STC_LOGD(format, args...) LOGD(format, ##args)
39 #define STC_LOGI(format, args...) LOGI(format, ##args)
40 #define STC_LOGW(format, args...) LOGW(format, ##args)
41 #define STC_LOGE(format, args...) LOGE(format, ##args)
42
43 #define __STC_LOG_FUNC_ENTER__ LOGD("Enter")
44 #define __STC_LOG_FUNC_EXIT__ LOGD("Quit")
45
46 #else /* USE_DLOG */
47
48 #define STC_LOGD(format, args...)
49 #define STC_LOGI(format, args...)
50 #define STC_LOGW(format, args...)
51 #define STC_LOGE(format, args...)
52
53 #define __STC_LOG_FUNC_ENTER__
54 #define __STC_LOG_FUNC_EXIT__
55
56 #endif /* USE_DLOG */
57
58 #define APP_ID_LEN_MAX 1024
59
60 #define GPOINTER_TO_PID(x) (pid_t)GPOINTER_TO_INT((x))
61 #define PID_TO_GPOINTER(x) GINT_TO_POINTER((pid_t)(x))
62
63 #define MALLOC0(t, n) ((t*) g_try_malloc0((n) * sizeof(t)))
64 #define FREE(p) do { \
65         if (p) { \
66                 g_free(p); \
67                 p = NULL; \
68         } \
69 } while (0)
70
71 #define EXEC(error_code, command) do { \
72         if (error_code != command) { \
73                 __STC_LOG_FUNC_EXIT__; \
74                 goto handle_error; \
75         } \
76 } while (0)
77
78 #define DEBUG_GDBUS_VARIANT(str, parameters) do { \
79         gchar *params_str = NULL; \
80         if (parameters) { \
81                 params_str = g_variant_print(parameters, \
82                                              TRUE); \
83         } \
84         STC_LOGD("%s[%s]", str, \
85                  params_str ? params_str : "NULL"); \
86         g_free(params_str); \
87 } while (0)
88
89 #define DEBUG_GDBUS_KEY_VALUE(key, value) do { \
90         if (key) { \
91                 STC_LOGD("Key : [%s]", key); \
92         } \
93         if (value) { \
94                 DEBUG_GDBUS_VARIANT("Value: ", value); \
95         } \
96 } while (0)
97
98 #define _pure_ __attribute__ ((pure))
99 #define _cleanup_(x) __attribute__((cleanup(x)))
100
101 static inline void freep(void *p)
102 {
103         FREE(*(void**) p);
104 }
105
106 static inline void closep(int *fd)
107 {
108         if (*fd >= 0)
109                 close(*fd);
110 }
111
112 static inline void fclosep(FILE **f)
113 {
114         if (*f)
115                 fclose(*f);
116 }
117
118 static inline void pclosep(FILE **f)
119 {
120         if (*f)
121                 pclose(*f);
122 }
123
124 static inline void closedirp(DIR **d)
125 {
126         if (*d)
127                 closedir(*d);
128 }
129
130 #define _cleanup_free_ _cleanup_(freep)
131 #define _cleanup_close_ _cleanup_(closep)
132 #define _cleanup_fclose_ _cleanup_(fclosep)
133 #define _cleanup_pclose_ _cleanup_(pclosep)
134 #define _cleanup_closedir_ _cleanup_(closedirp)
135
136 #define NUM_DIFF(x, y) ((x > y) ? (x - y) : (y -x))
137
138 #define BYTE_TO_KBYTE(b) ((b) >> 10)
139 #define BYTE_TO_MBYTE(b) ((b) >> 20)
140 #define BYTE_TO_GBYTE(b) ((b) >> 30)
141 #define BYTE_TO_PAGE(b) ((b) >> 12)
142
143 #define KBYTE_TO_BYTE(k) ((k) << 10)
144 #define KBYTE_TO_MBYTE(k) ((k) >> 10)
145 #define KBYTE_TO_GBYTE(k) ((k) >> 20)
146
147 #define MBYTE_TO_BYTE(m) ((m) << 20)
148 #define MBYTE_TO_KBYTE(m) ((m) << 10)
149 #define MBYTE_TO_GBYTE(m) ((m) >> 10)
150
151 #define GBYTE_TO_BYTE(g) ((g) << 30)
152 #define GBYTE_TO_KBYTE(g) ((g) << 20)
153 #define GBYTE_TO_MBYTE(g) ((g) << 10)
154
155 #define streq(a, b) (strncmp((a), (b), strlen(b)+1) == 0)
156 #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
157 #define strcaseeq(a, b) (strcasecmp((a), (b)) == 0)
158 #define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
159
160 static inline bool is_empty(const char *p)
161 {
162         return !p || !p[0];
163 }
164
165 static inline bool strstart_with(const char *str, const char *with)
166 {
167         return strncmp(str, with, strlen(with)) == 0;
168 }
169
170 #define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
171         for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); \
172              (word); \
173              (word) = split((s), &(length), (separator), &(state)))
174
175 #define FOREACH_WORD(word, length, s, state) \
176         FOREACH_WORD_SEPARATOR(word, length, s, WHITESPACE, state)
177
178 #define FOREACH_DIRENT(de, d, result, on_error) \
179         for (errno  = readdir_r(d, &de, &result);; errno = readdir_r(d, &de, &result)) \
180                 if (errno || !result) { \
181                         if (errno) \
182                                 on_error; \
183                         break; \
184                 } else if (streq(de.d_name, ".") || \
185                            streq(de.d_name, "..")) \
186                         continue; \
187                 else
188
189 #define FOREACH_STRV(s, l) \
190         for ((s) = (l); (s) && *(s); (s)++)
191
192 #define execute_once                            \
193         static int __func__##guardian;          \
194         for (;                                  \
195              __func__##guardian == 0;           \
196              __func__##guardian = 1)
197
198 #ifndef API
199 #define API __attribute__((visibility("default")))
200 #endif
201
202 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
203
204 #define DECLARE_WRAPPER(fn_name, inner_fn)                              \
205         static void fn_name(void *data, void __attribute__((__unused__)) *not_used) \
206         {                                                               \
207                 return inner_fn(data);                                  \
208         }
209
210 #define UNUSED __attribute__((__unused__))
211
212 #define MAX_SIZE2(a, b) sizeof(a) + sizeof(b) - 1
213 #define MAX_SIZE3(a, b, c) MAX_SIZE2(a, b) + sizeof(c) - 1
214
215 /*
216  * One byte digit has 3 position in decimal representation
217  * 2 - 5
218  * 4 - 10
219  * 8 - 20
220  * >8 - compile time error
221  * plus 1 null termination byte
222  * plus 1 for negative prefix
223  */
224 #define MAX_DEC_SIZE(type)                              \
225         (2 + (sizeof(type) <= 1 ? 3 :                   \
226               sizeof(type) <= 2 ? 5 :                   \
227               sizeof(type) <= 4 ? 10 :                  \
228               sizeof(type) <= 8 ? 20 :                  \
229               sizeof(int[-2*(sizeof(type) > 8)])))
230
231 #define SET_BIT(a, bit)                         \
232         ((a) |= (bit))
233
234 #define UNSET_BIT(a, bit)                       \
235         ((a) &= ~(bit))
236
237 #define CHECK_BIT(a, bit)                       \
238         ((a) & (bit))
239
240 #define ret_msg_if(expr, fmt, arg...) do {      \
241         if (expr) {                             \
242                 STC_LOGE(fmt, ##arg);           \
243                 return;                         \
244         }                                       \
245 } while (0)
246
247 #define ret_value_if(expr, val) do {                                    \
248         if (expr) {                                                     \
249                 STC_LOGE("(%s) -> %s():%d return", #expr, __FUNCTION__, __LINE__); \
250                 return (val);                                           \
251         }                                                               \
252 } while (0)
253
254 #define ret_value_msg_if(expr, val, fmt, arg...) do {   \
255         if (expr) {                                     \
256                 STC_LOGE(fmt, ##arg);                   \
257                 return val;                             \
258         }                                               \
259 } while (0)
260
261 #define ret_value_errno_msg_if(expr, val, fmt, arg...) do { \
262         if (expr) {                                         \
263                 STC_LOGE(fmt, ##arg);                       \
264                 return val;                                 \
265         }                                                   \
266 } while (0)
267
268
269 /*
270  * @brief Copy from source to destination
271  * destination should not be on heap.
272  * Destination will be null terminated
273  */
274 #define STRING_SAVE_COPY(destination, source) do {                      \
275         if (destination && source) {                                    \
276                 size_t null_pos = strlen(source);                       \
277                 strncpy(destination, source, sizeof(destination));      \
278                 null_pos = sizeof(destination) - 1 < null_pos ?         \
279                         sizeof(destination) - 1 : null_pos;             \
280                 destination[null_pos] = '\0';                           \
281         }                                                               \
282 } while (0)
283
284 /* FIXME: Do we really need pointers? */
285 #define array_foreach(key, type, array)                                 \
286                 guint _array_foreach_index;                             \
287                 type *key;                                              \
288                 for (_array_foreach_index = 0;                          \
289                      array && _array_foreach_index < array->len &&      \
290                              (key = &g_array_index(array, type, _array_foreach_index)); \
291                      ++_array_foreach_index)
292
293 #define slist_foreach(key, type, list)                                  \
294         type *key;                                                      \
295         GSList *_slist_foreach_copy_list = list;                        \
296         for (;                                                          \
297              _slist_foreach_copy_list &&                                \
298                      ((key = _slist_foreach_copy_list->data) || 1);     \
299              _slist_foreach_copy_list = _slist_foreach_copy_list->next)
300
301 #define gslist_for_each_item(item, list)                                \
302         for (item = list; item != NULL; item = g_slist_next(item))
303
304 #define gslist_for_each(head, elem, node)                               \
305         for (elem = head, node = NULL; elem && ((node = elem->data) != NULL); elem = elem->next, node = NULL)
306
307 #define gslist_for_each_safe(head, elem, elem_next, node)               \
308         for (elem = head, elem_next = g_slist_next(elem), node = NULL;  \
309              elem && ((node = elem->data) != NULL);                     \
310              elem = elem_next, elem_next = g_slist_next(elem), node = NULL)
311
312 #define TASK_FILE_NAME "tasks"
313 #define CGROUP_FILE_NAME "cgroup.procs"
314 #define UNKNOWN_APP "(unknown)"
315
316 #define MAX_PATH_LENGTH 512
317 #define MAX_NAME_LENGTH 256
318 #define MAX_IFACE_LENGTH 32
319 #define MAX_APPID_LENGTH 128
320 #define MAX_PKGNAME_LENGTH 128
321
322 #define PROC_BUF_MAX 64
323 #define PROC_NAME_MAX 1024
324
325 #define COMMA_DELIMETER ","
326
327 #define COUNTER_UPDATE_PERIOD 60
328 #define COUNTER_FLUSH_PERIOD 60
329
330 #define NONE_QUOTA_ID 0
331
332 #define TIME_TO_SAFE_DATA 1 /* one second */
333
334 /*
335  * @desc reserved classid enums
336  * internal structure, we don't provide it externally
337  */
338 enum stc_reserved_classid {
339         STC_UNKNOWN_CLASSID,
340         STC_ALL_APP_CLASSID,            /**< kernel expects 1 for
341                                           handling restriction for all
342                                           applications  */
343         STC_TETHERING_APP_CLASSID,      /**< it uses in user space logic
344                                           for counting tethering traffic */
345         STC_FOREGROUND_APP_CLASSID,     /* it will used for special cgroup,
346                                            blocked cgroup */
347         STC_BACKGROUND_APP_CLASSID,
348         STC_TOTAL_DATACALL_CLASSID,
349         STC_TOTAL_WIFI_CLASSID,
350         STC_TOTAL_BLUETOOTH_CLASSID,
351         STC_NETWORK_RESTRICTION_APP_CLASSID,
352         STC_RESERVED_CLASSID_MAX,
353 };
354
355 enum stc_counter_state {
356         STC_DEFAULT_STATE = 0,
357         STC_FORCIBLY_FLUSH_STATE = 1 << 1,
358         STC_FORCIBLY_QUIT_STATE = 1 << 2,
359         STC_NET_BLOCKED_STATE = 1 << 3,
360         STC_CHECK_QUOTA = 1 << 4,
361         STC_UPDATE_REQUESTED = 1 << 5,
362 };
363
364 #endif /* __STC_MANAGER_UTIL_H__ */