55 va_start(args, format);
57 vsnprintf(str,
sizeof str, format, args);
59 fprintf(stderr,
"%s", str);
70 if (!computer_name || len == 0)
return FALSE;
71 memset(computer_name, 0, len);
74 DWORD bufCharCount = (DWORD)len;
75 if (GetComputerName(infoBuf, &bufCharCount)) {
76 memcpy(computer_name, infoBuf, len);
78 strncpy(computer_name,
"Unknown_Host_Name", len - 1);
79 computer_name[len - 1] =
'\0';
83 if (gethostname(computer_name, len) == -1) {
85 strncpy(computer_name,
"Unknown_Host_Name", len - 1);
86 computer_name[len - 1] =
'\0';
101 if ((file = fopen(filename,
"r")) != NULL) {
113 char strbuf[PATH_MAX] =
"";
117 unsigned long int bytes = GetModuleFileName(NULL, strbuf, PATH_MAX);
120 return strdup(dirname(strbuf));
123 char procbuf[PATH_MAX] =
"";
125 snprintf(procbuf, PATH_MAX,
"/proc/%d/exe", (
int)getpid());
127 snprintf(procbuf, PATH_MAX,
"/proc/%d/path/a.out", (
int)getpid());
129 ssize_t bytes = MIN(readlink(procbuf, strbuf, PATH_MAX), PATH_MAX - 1);
132 strbuf[bytes] =
'\0';
133 return strdup(dirname(strbuf));
136 fprintf(stderr,
"%s", strerror(error));
145 char strbuf[PATH_MAX] =
"";
148 unsigned long int bytes = GetModuleFileName(NULL, strbuf, PATH_MAX);
151 return strdup(basename(strbuf));
154 char procbuf[PATH_MAX] =
"";
156 snprintf(procbuf, PATH_MAX,
"/proc/%d/exe", (
int)getpid());
158 snprintf(procbuf, PATH_MAX,
"/proc/%d/path/a.out", (
int)getpid());
160 ssize_t bytes = MIN(readlink(procbuf, strbuf, PATH_MAX), PATH_MAX - 1);
163 strbuf[bytes] =
'\0';
164 return strdup(basename(strbuf));
167 fprintf(stderr,
"%s", strerror(error));
179int n_popen(
char* cmd,
size_t read_buf_size,
void** nstr_output,
int* ret) {
182 if (read_buf_size > INT_MAX) {
183 n_log(
LOG_ERR,
"read_buf_size buffer size is too large for fgets (%zu>%d)", read_buf_size, INT_MAX);
186 if (read_buf_size > 65536) {
187 n_log(
LOG_ERR,
"read_buf_size %zu exceeds safe stack limit", read_buf_size);
195 char read_buf[read_buf_size];
197 fp = popen(cmd,
"r");
200 n_log(
LOG_ERR,
"popen( %s ) returned NULL , %s (%d)", cmd, strerror(err), err);
204 while (fgets(read_buf, (
int)read_buf_size, fp) != NULL) {
205 size_t length = strlen(read_buf);
206 if (length > 0 && read_buf[length - 1] ==
'\n') {
207 read_buf[length - 1] =
'\0';
214 n_log(
LOG_ERR,
"pclose( %s ) returned -1 , %s (%d)", cmd, strerror(err), err);
218 if (ret) (*ret) = WEXITSTATUS(status);
220 (*nstr_output) = output_pointer;
232#if defined(_WIN32) || defined(__MINGW32__) || defined(__windows__)
233 LPCH env_block = GetEnvironmentStrings();
234 if (!env_block)
return;
235 for (LPCH var = env_block; *var !=
'\0'; var += strlen(var) + 1) {
236 n_log(loglevel,
"env: %s", var);
238 FreeEnvironmentStrings(env_block);
240 extern char** environ;
241 for (
char** env = environ; *env != NULL; env++) {
242 n_log(loglevel,
"env: %s", *env);
254 int saved_errno = errno;
256 while (waitpid(-1, NULL, WNOHANG) > 0);
269 sigemptyset(&sa.sa_mask);
270 sa.sa_flags = SA_RESTART;
271 if (sigaction(SIGCHLD, &sa, NULL) == -1) {
299 n_log(
LOG_ERR,
"Error: unable to fork child: %s", strerror(error));
312 n_log(
LOG_ERR,
"Error: unable to set session leader with setsid(): %s", strerror(error));
321 signal(SIGCHLD, SIG_IGN);
334 n_log(
LOG_ERR,
"Error: unable to double fork child: %s", strerror(error));
350 if (chdir(
"/") < 0) {
352 n_log(
LOG_ERR,
"couldn't chdir() to '/': %s", strerror(error));
359 for (
int x = 3; x < sysconf(_SC_OPEN_MAX); x++) {
366 int fd = open(
"/dev/null", O_RDWR, 0);
368 dup2(fd, STDIN_FILENO);
369 dup2(fd, STDOUT_FILENO);
370 dup2(fd, STDERR_FILENO);
375 n_log(
LOG_ERR,
"Failed to open /dev/null: %s", strerror(errno));
389pid_t
system_nb(
const char* command,
int* infp,
int* outfp) {
392 int p_stdin[2] = {-1, -1};
393 int p_stdout[2] = {-1, -1};
397 if (pipe(p_stdin) != 0)
401 if (pipe(p_stdout) != 0) {
431 dup2(p_stdout[1], 1);
433 execlp(
"sh",
"sh",
"-c", command, (
char*)NULL);
436 n_log(
LOG_ERR,
"%s:%d: exec failed: %s", __FILE__, __LINE__, strerror(error));
466 while ((arg = va_arg(args,
int))) {
487 while ((i > 0) && (path[i] !=
'.') && (path[i] !=
'/') && (path[i] !=
'\\')) {
490 if ((i > 0) && (i < n - 1) && (path[i] ==
'.') && (path[i - 1] !=
'/') && (path[i - 1] !=
'\\')) {
void log_environment(int loglevel)
log environment variables in syslog
#define N_DAEMON_NO_UMASK
daemonize flag: do not call umask( 0 )
char * get_prog_name(void)
get current program name
#define N_DAEMON_NO_DOUBLE_FORK
daemonize flag: do not double fork
void N_HIDE_STR(char *buf,...)
store a hidden version of a string
#define N_DAEMON_NO_SIGCHLD_IGN
daemonize flag: do not ignore SIGCHLD
#define N_DAEMON_NO_CHDIR
daemonize flag: do not call chdir("/")
#define __n_assert(__ptr, __ret)
macro to assert things
#define N_DAEMON_NO_CLOSE
daemonize flag: no descriptor close at all
#define N_DAEMON_NO_SIGCHLD_HANDLER
daemonize flag: do not use internal zombie SIGCHLD handler
#define N_DAEMON_NO_STD_REDIRECT
daemonize flag: just do not redirect stdin/out/err to /dev/null
int get_computer_name(char *computer_name, size_t len)
get the computer name
#define N_DAEMON_NO_SETSID
daemonize flag: do not call setsid
void sigchld_handler(int sig)
Handles SIGCHLD issues when forking.
pid_t system_nb(const char *command, int *infp, int *outfp)
Non blocking system call.
char * n_get_file_extension(char path[])
get extension of path+filename
char * get_prog_dir(void)
get current program running directory
int n_daemonize_ex(int mode)
Daemonize program.
void n_abort(char const *format,...)
abort program with a text
int sigchld_handler_installer()
install signal SIGCHLD handler to reap zombie processes
int n_daemonize(void)
Daemonize program.
int file_exist(const char *filename)
test if file exist and if it's readable
int n_popen(char *cmd, size_t read_buf_size, void **nstr_output, int *ret)
launch a command and return output and status
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
#define LOG_NOTICE
normal but significant condition
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
#define nstrprintf_cat(__nstr_var, __format,...)
Macro to quickly allocate and sprintf and cat to a N_STR.
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
A box including a string and his lenght.
Common headers and low-level functions & define.
N_STR and string function declaration.