summaryrefslogtreecommitdiff
path: root/src/libsystem/libsystem.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystem/libsystem.h')
-rw-r--r--src/libsystem/libsystem.h955
1 files changed, 955 insertions, 0 deletions
diff --git a/src/libsystem/libsystem.h b/src/libsystem/libsystem.h
new file mode 100644
index 0000000..7819aa7
--- /dev/null
+++ b/src/libsystem/libsystem.h
@@ -0,0 +1,955 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * libsystem
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file libsystem.h
+ *
+ * system utility library
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Many functions have no effects except the return value and their
+ * return value depends only on the parameters and/or global
+ * variables. Such a function can be subject to common subexpression
+ * elimination and loop optimization just as an arithmetic operator
+ * would be. These functions should be declared with the attribute
+ * pure.
+ */
+#define _pure_ __attribute__ ((pure))
+
+/**
+ * The cleanup attribute runs a function when the variable goes out of
+ * scope. This attribute can only be applied to auto function scope
+ * variables; it may not be applied to parameters or variables with
+ * static storage duration. The function must take one parameter, a
+ * pointer to a type compatible with the variable. The return value of
+ * the function (if any) is ignored.
+ */
+#define _cleanup_(x) __attribute__((cleanup(x)))
+
+/**
+ * whitespaces such like space, tab or newlines
+ */
+#define WHITESPACE " \t\n\r"
+
+/**
+ * newlines
+ */
+#define NEWLINE "\n\r"
+
+/**
+ * single or double quotes
+ */
+#define QUOTES "\"\'"
+
+/**
+ * comment start specifiers such like sharp(#) or semicolon(;)
+ */
+#define COMMENTS "#;"
+
+/**
+ * @defgroup GCC_CLEANUP_ATT_GROUP gcc cleanup attribute
+ *
+ * @{
+ */
+
+static inline void __cleanup_free_func(void *p) {
+ free(*(void**) p);
+}
+
+static inline void __cleanup_close_func(int *fd) {
+ if (*fd >= 0)
+ close(*fd);
+}
+
+static inline void __cleanup_fclose_func(FILE **f) {
+ if (*f)
+ fclose(*f);
+}
+
+static inline void __cleanup_pclose_func(FILE **f) {
+ if (*f)
+ pclose(*f);
+}
+
+static inline void __cleanup_closedir_func(DIR **d) {
+ if (*d)
+ closedir(*d);
+}
+
+static inline const char *startswith(const char *s, const char *prefix) {
+ if (strncmp(s, prefix, strlen(prefix)) == 0)
+ return s + strlen(prefix);
+ return NULL;
+}
+
+static inline bool isempty(const char *p) {
+ return !p || !p[0];
+}
+
+/**
+ * Declare value with cleanup attribute. free() is called when is
+ * going out the scope.
+ */
+#define _cleanup_free_ _cleanup_(__cleanup_free_func)
+
+/**
+ * Declare value with cleanup attribute. close() is called when is
+ * going out the scope.
+ */
+#define _cleanup_close_ _cleanup_(__cleanup_close_func)
+
+/**
+ * Declare value with cleanup attribute. fclose() is called when is
+ * going out the scope.
+ */
+#define _cleanup_fclose_ _cleanup_(__cleanup_fclose_func)
+
+/**
+ * Declare value with cleanup attribute. pclose() is called when is
+ * going out the scope.
+ */
+#define _cleanup_pclose_ _cleanup_(__cleanup_pclose_func)
+
+/**
+ * Declare value with cleanup attribute. closedir() is called when is
+ * going out the scope.
+ */
+#define _cleanup_closedir_ _cleanup_(__cleanup_closedir_func)
+/**
+ * @}
+ */
+
+/**
+ * Allocate n number of size t memory.
+ */
+#define new(t, n) ((t*) malloc(sizeof(t) * (n)))
+
+/**
+ * Allocate n number of size t memory. And initialize to 0 all.
+ */
+#define new0(t, n) ((t*) calloc((n), sizeof(t)))
+
+/**
+ * Allocate n number memory.
+ */
+#define malloc0(n) (calloc((n), 1))
+
+/**
+ * @brief Parse boolean type string.
+ *
+ * @param v String to parse.
+ *
+ * @return TRUE on "1", 'y', 'Y', 't', 'T' and "on". FALSE on "0",
+ * 'n', 'N', 'f', 'F', "off".
+ */
+int parse_boolean(const char *v) _pure_;
+
+/**
+ * @brief Parse byte type string.
+ *
+ * @param b Byte string. This can be only digit number with byte unit
+ * "BKMG". B is byte, K is kilo byte, M is mega byte and G is gira
+ * byte. Byte is default.
+ * @param s Parsed byte size is filled.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int parse_bytes(const char *b, size_t *s) _pure_;
+
+/**
+ * @brief Parse percentage type string.
+ *
+ * @param string Percentage string to parse. Such like "70%".
+ * @param percent Parsed percentage size is filled.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int parse_percent(const char *string, size_t *percent) _pure_;
+
+/**
+ * @brief check the path string is started with '/'
+ *
+ * @param p a path to check
+ *
+ * @return true if p started with '/', otherwise false.
+ */
+bool path_is_absolute(const char *p);
+
+/**
+ * @brief Removes redundant inner and trailing slashes. Modifies the
+ * passed string in-place. For example, if "///foo//bar/" is given
+ * then the path will be changed as "/foo/bar"
+ *
+ * @param path a path to modify.
+ *
+ * @return modified path pointer. It maybe identical with given path.
+ */
+char *path_kill_slashes(char *path);
+
+/**
+ * Get element number of array.
+ */
+#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
+
+/**
+ * Iterate for each struct reference.
+ */
+#define FOREACH_STRUCT_REF(s, f, i) \
+ for ((i) = 0; s[(i)].f != NULL; (i)++)
+
+/**
+ * @brief Iterate for each directory entries exclude "." and "..".
+ */
+#define FOREACH_DIRENT(de, d, on_error) \
+ for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
+ if (!de) { \
+ if (errno > 0) { \
+ on_error; \
+ } \
+ break; \
+ } else if (streq(de->d_name, ".") || \
+ streq(de->d_name, "..")) \
+ continue; \
+ else
+
+/**
+ * @brief Check string is digit.
+ *
+ * @param s String to check.
+ * @param l Length to check.
+ *
+ * @return TRUE on all the characters are digit. FALSE on the others.
+ */
+bool is_number(const char *s, int l);
+
+/**
+ * @brief Run cp with given src, dst with option. Internally, directly
+ * calls /bin/cp with given arguments.
+ * @todo change direct calls of /bin/cp to c api.
+ *
+ * @param src source
+ * @param dst destination
+ * @param option cp option
+ * @param timeout_msec timeout milliseconds
+ *
+ * @return return exit code of /bin/cp or negative errno.
+ */
+int do_copy(const char *src, const char *dst, const char *option, int64_t timeout_msec);
+
+/**
+ * @brief Make a directory. If parent directories are also absent,
+ * make them also. Corresponding with "mkdir -p".
+ *
+ * @param path Path to make directory.
+ * @param mode The directory mode.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int do_mkdir(const char *path, mode_t mode);
+
+/**
+ * @brief Remove all elements in path recursivly.
+ *
+ * @param path Path to make directory.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int rmdir_recursive(const char *path);
+
+/**
+ * @defgroup FILE_READ_WRITE_GROUP File Read/Write utility
+ *
+ * @{
+ */
+
+/**
+ * file write flags
+ */
+enum file_write_flags {
+ /** Append line-end(\\n) at the end of file. In case of string
+ * write, if given string has already line-end characters
+ * then this flag has no effect. */
+ FILE_WRITE_NEWLINE_IF_NOT = 1 << 0,
+ /** Run fflush(3) after file write. */
+ FILE_WRITE_WITH_FFLUSH = 1 << 1,
+ /** Open file as append mode. */
+ FILE_WRITE_APPEND = 1 << 2,
+};
+
+/**
+ * @brief Write strings to FILE
+ *
+ * @param f File pointer.
+ * @param str Strings to write.
+ * @param flags Optional flags to write file. For
+ * ::FILE_WRITE_NEWLINE_IF_NOT, if str has already line-end,
+ * ::FILE_WRITE_NEWLINE_IF_NOT will has no effect. For detail, see
+ * ::file_write_flags.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int write_str_to_file(FILE *f, const char *str, enum file_write_flags flags);
+
+/**
+ * @brief Write strings to path.
+ *
+ * @param path File path.
+ * @param str Strings to write.
+ * @param flags Optional flags to write file. For
+ * ::FILE_WRITE_NEWLINE_IF_NOT, if str has already line-end,
+ * ::FILE_WRITE_NEWLINE_IF_NOT will has no effect. For detail, see
+ * ::file_write_flags.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int write_str_to_path(const char *path, const char *str, enum file_write_flags flags);
+
+/**
+ * @brief Write signed decimal integer to FILE.
+ *
+ * @param f File pointer.
+ * @param i Signed integer to write.
+ * @param flags Optional flags to write file. if
+ * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see
+ * ::file_write_flags.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int write_int32_to_file(FILE *f, int32_t i, enum file_write_flags flags);
+
+/**
+ * @brief Write signed decimal integer to path.
+ *
+ * @param path File path.
+ * @param i Signed integer to write.
+ * @param flags Optional flags to write file. if
+ * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see
+ * ::file_write_flags.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int write_int32_to_path(const char *path, int32_t i, enum file_write_flags flags);
+
+/**
+ * @brief Write unsigned decimal integer to FILE.
+ *
+ * @param f File pointer
+ * @param u Unsigned integer to write.
+ * @param flags Optional flags to write file. if
+ * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see
+ * ::file_write_flags.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int write_uint32_to_file(FILE *f, uint32_t u, enum file_write_flags flags);
+
+/**
+ * @brief Write unsigned decimal integer to path.
+ *
+ * @param path File path.
+ * @param u Unsigned integer to write.
+ * @param flags Optional flags to write file. if
+ * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see
+ * ::file_write_flags.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int write_uint32_to_path(const char *path, uint32_t u, enum file_write_flags flags);
+
+/**
+ * @brief Read the first line from FILE
+ *
+ * @param f File pointer.
+ * @param line Duplicated string line is filled. This value has to
+ * be free-ed by caller.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int read_one_line_from_file(FILE *f, char **line);
+
+/**
+ * @brief Read the first line from path
+ *
+ * @param path File path.
+ * @param line Duplicated string line is filled. This value has to
+ * be free-ed by caller.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int read_one_line_from_path(const char *path, char **line);
+
+/**
+ * @brief Read signed decimal integer from FILE.
+ *
+ * @param f File pointer.
+ * @param i signed int value pointer.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int read_int32_from_file(FILE *f, int32_t *i);
+
+/**
+ * @brief Read signed decimalinteger from path.
+ *
+ * @param path File path.
+ * @param i signed int value pointer.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int read_int32_from_path(const char *path, int32_t *i);
+
+/**
+ * @brief Read unsigned decimalinteger from FILE.
+ *
+ * @param f File pointer.
+ * @param u unsigned int value pointer.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int read_uint32_from_file(FILE *f, uint32_t *u);
+
+/**
+ * @brief Read unsigned decimal integer from path
+ *
+ * @param path File path.
+ * @param u unsigned int value pointer.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int read_uint32_from_path(const char *path, uint32_t *u);
+/**
+ * @}
+ */
+
+/**
+ * @defgroup STRING_GROUP String helper
+ *
+ * @{
+ */
+
+/**
+ * Compare two strings. TRUE on same, FALSE on others.
+ * Same with (strcmp((a),(b)) == 0)
+ */
+#define streq(a,b) (strcmp((a),(b)) == 0)
+/**
+ * Compare two strings for n length. TRUE on same, FALSE on others.
+ * Same with (strncmp((a), (b), (n)) == 0)
+ */
+#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
+
+/**
+ * Compare two strings. Similar to streq() but ignore case. TRUE on
+ * same, FALSE on others.
+ * Same with (strcasecmp((a),(b)) == 0)
+ */
+#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
+
+/**
+ * Compare two strings for n length. Similar to strneq() but ignore
+ * case. TRUE on same, FALSE on others.
+ * Same with (strcasecmp((a),(b)) == 0)
+ */
+#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
+
+/**
+ * Iterate string in strings which include null characters.
+ * For example,
+ *\code{.c}
+const char str[] = {
+ "foo\0"
+ "bar\0";
+};
+
+const char *s;
+
+NULSTR_FOREACH(s, str) {
+ // do something here
+}
+ *\endcode
+ */
+#define NULSTR_FOREACH(i, l) \
+ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
+
+/**
+ * @brief Like streq(), but tries to make sense of NULL pointers.
+ *
+ * @param a String.
+ * @param b String.
+ *
+ * @return TRUE on same, FALSE on the others.
+ */
+bool streq_ptr(const char *a, const char *b) _pure_;
+
+/**
+ * @brief Truncate line end characters.
+ *
+ * @param s String to truncate.
+ *
+ * @return Result string.
+ */
+char *truncate_nl(char *s);
+
+/**
+ * @brief Append suffix string to sting s with size b.
+ *
+ * @param s Ahead string.
+ * @param suffix The second string.
+ * @param b suffix size to append.
+ *
+ * @return Result string. This string has to be free-ed by caller.
+ */
+char *strnappend(const char *s, const char *suffix, size_t b);
+
+/**
+ * @brief Append suffix string to sting s.
+ *
+ * @param s Ahead string.
+ * @param suffix The second string.
+ *
+ * @return Result string. This string has to be free-ed by caller.
+ */
+char *strappend(const char *s, const char *suffix);
+
+/**
+ * @brief Drops trailing whitespaces.
+ *
+ * @param s String.
+ *
+ * @return The pointer to the first non-space character.
+ */
+char *strstrip(char *s);
+
+/**
+ * @brief duplicate string without leading and trailing whitespaces
+ *
+ * @param str a target string to duplicate
+ * @param ret newly allocated string is filled
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int strdup_strip(const char *str, char **ret);
+
+/**
+ * @brief duplicate string without leading and trailing whitespaces,
+ * duplicated string is not over given length len
+ *
+ * @param str a target string to duplicate
+ * @param len maxium length of duplicate
+ * @param ret newly allocated string is filled
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int strndup_strip(const char *str, size_t len, char **ret);
+
+/**
+ * @brief nulstr is similar to string list but each strings ends with
+ * null and the strings are put at one memory buffer. For example,
+ * "foo" and "bar" string can be represented "foo\0bar". This function
+ * check nulstr is containing the needle string.
+ *
+ * @param nulstr a nulstr
+ * @param needle a needle string to find
+ *
+ * @return true if the needle found, otherwise false.
+ */
+bool nulstr_contains(const char*nulstr, const char *needle);
+
+/**
+ * @brief check a string ends with postfix pattern
+ *
+ * @param s a string to check
+ * @param postfix postfix string
+ *
+ * @return if s is ended with postfix string the pointer of the
+ * string, matched pointer of s is returned. Otherwise NULL.
+ */
+char* endswith(const char *s, const char *postfix);
+
+/**
+ * @brief split a string into words. This api generally is not called
+ * directly, #FOREACH_WORD_SEPARATOR or #FOREACH_WORD are using
+ * this. If separator does not include quotes then quoted words are
+ * assumed as single word.
+ *
+ * @param c string to split
+ * @param l splitted word length
+ * @param separator separator strings such like #WHITESPACE
+ * @param state a state internally used
+ *
+ * @return a splitted current word pointer
+ */
+char *split(const char *c, size_t *l, const char *separator, char **state);
+
+/**
+ * @brief Iterate for each words. If separator does not include quotes
+ * then quoted words are assumed as single word.
+ *
+ * @param word Each word
+ * @param length Length of word
+ * @param s Target string
+ * @param separator Seperator string
+ * @param state Used only internal split().
+ */
+#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
+ for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); (word); (word) = split((s), &(length), (separator), &(state)))
+
+/**
+ * @brief Iterate for each words. (Seperators are WHITESPACES.) Quoted
+ * words are assumed as single word.
+ *
+ * @param word Each word
+ * @param length Length of word
+ * @param s Target string
+ * @param state Used only internal split().
+ */
+#define FOREACH_WORD(word, length, s, state) \
+ FOREACH_WORD_SEPARATOR(word, length, s, WHITESPACE, state)
+
+/**
+ * @brief Duplicate string and strip quotes from the string.
+ *
+ * @param str String to duplicate.
+ * @param quotes Quote characters to strip. Predefined #QUOTES can be
+ * used to specify quote and double quote.
+ *
+ * @return Result string. This value has to be free-ed by caller.
+ */
+char *strdup_unquote(const char *str, const char *quotes);
+/**
+ * @}
+ */
+
+/**
+ * @defgroup STRV_GROUP String List
+ *
+ * @{
+ */
+
+/**
+ * iterate for each elements of string list.
+ */
+#define FOREACH_STRV(s, l) \
+ for ((s) = (l); (s) && *(s); (s)++)
+
+/**
+ * @brief Split given string to string list with separator.
+ *
+ * @param str string to split as string list.
+ * @param strv Splitted string list is filled. This string list has to
+ * be free-ed.
+ * @param separator sperators to split the string.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int str_to_strv(const char *str, char ***strv, const char *separator);
+
+/**
+ * @brief Get elements of string list. #sizeof_strv() does not count
+ * end of list NULL. For example, for {"foo", "bar", NULL} string
+ * list, #sizeof_strv() returns 2.
+ *
+ * @param strv string list.
+ *
+ * @return number of string list.
+ */
+size_t sizeof_strv(char **strv);
+
+/**
+ * @brief Merge two string lists. If {"foo", "bar"} and {"baz", "qux"}
+ * are given, the result is {"foo", "bar", "baz", "quz"}.
+ *
+ * @param first The first string list.
+ * @param second The second string list.
+ * @param strv Merged string list.
+ * @param free_second If TRUE is given, the second string list will be
+ * free-ed. If FALSE, no action.
+ *
+ * @return number of string list.
+ */
+int strv_attach(char **first, char **second, char ***strv, bool free_second);
+
+/**
+ * @brief Free all given string list
+ *
+ * @param strv string list to free.
+ */
+void strv_free_full(char **strv);
+/**
+ * @}
+ */
+
+/**
+ * @brief Check given path is directory or not
+ *
+ * @param path path to check
+ *
+ * @return TRUE if path is directory, FALSE on others.
+ */
+bool isdir(const char *path);
+
+/**
+ * @brief Simple file create api similar to touch(1)
+ *
+ * @param path file path
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int touch(const char *path);
+
+/**
+ * @defgroup PROC_GROUP proc group
+ *
+ * @brief A set utility library for /proc. Some of library functions
+ * are only able to be successful root uid with security permissions.
+ *
+ * @{
+ */
+
+/**
+ * @brief Get string with operator from /proc/cmdline. If foo=bar is
+ * included in /proc/cmdline and want to get the bar, then:
+ * \code{.c}
+ char *buf;
+
+ cmdline_get_str(&buf, "foo=");
+ * \endcode
+ *
+ * @param buf The value string is filled to here. This value has to be
+ * free-ed by caller.
+ * @param op An operator string.
+ *
+ * @return Result string. This value has to be free-ed by caller.
+ */
+ssize_t cmdline_get_str(char **buf, const char *op);
+
+/**
+ * @brief Get PID of process.
+ *
+ * @param pname Process name.
+ *
+ * @return PID on successful find. If not found, 0 is returned. And
+ * -errno is returned on failure.
+ */
+int pid_of(const char *pname);
+
+/**
+ * @brief Check mount entry. Multiple matches of conditoin are able to
+ * be set with mnt_fsname, mnt_dir, mnt_type or mnt_opts. If multiple
+ * matches are given, return true if a entry satisfied all matches.
+ *
+ * \code{.c}
+// check cgroup is mounted
+if (is_mounted("cgroup", NULL, NULL, NULL))
+ printf("cgroup is mounted\n");
+
+// check /tmp is mounted
+if (is_mounted("tmpfs", "/tmp", NULL, NULL))
+ printf("/tmp is mounted\n");
+
+// check cgroup is mounted as cgroup2
+if (is_mounted("cgroup", "/sys/fs/cgroup", "cgroup2", NULL))
+ printf("cgroup is mounted as cgroup2\n");
+ * \endcode
+ *
+ * @param fsname find matched mount filesystem name
+ * @param dir find matched mount dir(path) name
+ * @param type find matched mount type name
+ * @param opts find matched mount option name
+ *
+ * @return true if matched mount entry found, otherwise false.
+ */
+bool mnt_is_mounted(const char *fsname, const char *dir, const char *type, const char *opts);
+/**
+ * @}
+ */
+
+/**
+ * @defgroup EXEC_GROUP exec group
+ *
+ * @brief fork() and exec() utility
+ * @{
+ */
+
+/**
+ * @brief Traditional fork() and exec() helper.
+ *
+ * @param argv array of pointers to null-terminated strings that
+ * represent the argument list available to the new program. The first
+ * argument should point to the filename associated with the file
+ * being executed. The array of pointers must be terminated by a NULL pointer.
+ * @param envp specify the environment of the executed program via the
+ * argument envp. The envp argument is an array of pointers to
+ * null-terminated strings and must be terminated by a NULL pointer.
+ * @param timeout_msec timeout millisecond to prevent infinite
+ * waiting. If negative is given, the parent will not wait the
+ * child. In other word, the parent will return immediately. If 0 is
+ * given, parent will wait the child infinitly. And if positive value
+ * is given parent will wait given milliseconds and expired return
+ * -1. If the child is exit within the tiemout millisecond return with
+ * child exit code.
+ *
+ * @return exit code of child. It is fully depend on the child
+ * process. If the child exit with 1 then this function also return 1.
+ * Negative errno on error. -ETIME on timer expired.
+ */
+int do_fork_exec(char *const argv[], char * const envp[], int64_t timeout_msec);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup TIME_UTIL_GROUP time util group
+ *
+ * @brief time utility libraries
+ * @{
+ */
+
+/** millisecond per second */
+#define MSEC_PER_SEC 1000ULL
+/** microsecond per second */
+#define USEC_PER_SEC ((uint64_t) 1000000ULL)
+/** microsecond per millisecond */
+#define USEC_PER_MSEC ((uint64_t) 1000ULL)
+/** nanosecond per second */
+#define NSEC_PER_SEC ((uint64_t) 1000000000ULL)
+/** nanosecond per microsecond */
+#define NSEC_PER_MSEC ((uint64_t) 1000000ULL)
+/** nanosecond per microsecond */
+#define NSEC_PER_USEC ((uint64_t) 1000ULL)
+
+/** microsecond per minute */
+#define USEC_PER_MINUTE ((uint64_t) (60ULL*USEC_PER_SEC))
+/** nanosecond per minute */
+#define NSEC_PER_MINUTE ((uint64_t) (60ULL*NSEC_PER_SEC))
+/** microsecond per hour */
+#define USEC_PER_HOUR ((uint64_t) (60ULL*USEC_PER_MINUTE))
+/** nanosecond per hour */
+#define NSEC_PER_HOUR ((uint64_t) (60ULL*NSEC_PER_MINUTE))
+/** microsecond per day */
+#define USEC_PER_DAY ((uint64_t) (24ULL*USEC_PER_HOUR))
+/** nanosecond per day */
+#define NSEC_PER_DAY ((uint64_t) (24ULL*NSEC_PER_HOUR))
+/** microsecond per week */
+#define USEC_PER_WEEK ((uint64_t) (7ULL*USEC_PER_DAY))
+/** nanosecond per week */
+#define NSEC_PER_WEEK ((uint64_t) (7ULL*NSEC_PER_DAY))
+/** microsecond per month */
+#define USEC_PER_MONTH ((uint64_t) (2629800ULL*USEC_PER_SEC))
+/** nanosecond per month */
+#define NSEC_PER_MONTH ((uint64_t) (2629800ULL*NSEC_PER_SEC))
+/** microsecond per year */
+#define USEC_PER_YEAR ((uint64_t) (31557600ULL*USEC_PER_SEC))
+/** nanosecond per year */
+#define NSEC_PER_YEAR ((uint64_t) (31557600ULL*NSEC_PER_SEC))
+
+/** frequently used time format string: 12:34 */
+#define HH_MM "%H:%M"
+/** frequently used time format string: 12:34:56 */
+#define HH_MM_SS "%H:%M:%S"
+
+/** frequently used time format string: 2015-01-23 */
+#define YYYY_MM_DD "%Y-%m-%d"
+/** frequently used time format string: 2015-01-23 12:34 */
+#define YYYY_MM_DD_HH_MM "%Y-%m-%d %H:%M"
+/** frequently used time format string: 2015-01-23 12:34:56 */
+#define YYYY_MM_DD_HH_MM_SS "%Y-%m-%d %H:%M:%S"
+/** frequently used time format string: 2015-01-23 12:34:56 KST */
+#define YYYY_MM_DD_HH_MM_SS_Z "%Y-%m-%d %H:%M:%S %Z"
+
+/** frequently used time format string: Fri 2015-01-23 */
+#define DOW_YYYY_MM_DD "%a %Y-%m-%d"
+/** frequently used time format string: Fri 2015-01-23 12:34 */
+#define DOW_YYYY_MM_DD_HH_MM "%a %Y-%m-%d %H:%M"
+/** frequently used time format string: Fri 2015-01-23 12:34:56 */
+#define DOW_YYYY_MM_DD_HH_MM_SS "%a %Y-%m-%d %H:%M:%S"
+/** frequently used time format string: Fri 2015-01-23 12:34:56 KST */
+#define DOW_YYYY_MM_DD_HH_MM_SS_Z "%a %Y-%m-%d %H:%M:%S %Z"
+
+/**
+ * @brief Convert time_t to given format time string.
+ *
+ * @param sec time second to convert
+ * @param format format string
+ * @param time string pointer to converted time is filled. On
+ * successful return, this value has to be free-ed by caller.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int sec_to_timestr(time_t sec, const char *format, char **time);
+
+/**
+ * @brief Convert time_t to \%a \%Y-\%m-\%d \%H:\%M:\%S \%Z format time string.
+ *
+ * @param sec time second to convert
+ * @param time string pointer to converted time is filled. On
+ * successful return, this value has to be free-ed by caller.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int sec_to_timestr_full(time_t sec, char **time);
+
+/**
+ * @brief Convert given format time string to time_t.
+ *
+ * @param format format string
+ * @param time time string to convert to time_t
+ * @param sec converted time_t
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int timestr_to_sec(const char *format, const char *time, time_t *sec);
+
+/**
+ * @brief Make struct timeval from millisecond
+ *
+ * @param msec millisecond to Convert
+ * @param tv struct timeval to be filled
+ */
+void msec_to_timeval(uint64_t msec, struct timeval *tv);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif