56 va_start(args, format);
58 vsnprintf(str,
sizeof str, format, args);
60 fprintf(stderr,
"%s", str);
71 if (!computer_name || len == 0)
return FALSE;
72 memset(computer_name, 0, len);
75 DWORD bufCharCount = (DWORD)len;
76 if (GetComputerName(infoBuf, &bufCharCount)) {
77 memcpy(computer_name, infoBuf, len);
79 strncpy(computer_name,
"Unknown_Host_Name", len - 1);
80 computer_name[len - 1] =
'\0';
84 if (gethostname(computer_name, len) == -1) {
86 strncpy(computer_name,
"Unknown_Host_Name", len - 1);
87 computer_name[len - 1] =
'\0';
102 if ((file = fopen(filename,
"r")) != NULL) {
114 char strbuf[PATH_MAX] =
"";
118 unsigned long int bytes = GetModuleFileName(NULL, strbuf, PATH_MAX);
121 return strdup(dirname(strbuf));
124 char procbuf[PATH_MAX] =
"";
126 snprintf(procbuf, PATH_MAX,
"/proc/%d/exe", (
int)getpid());
128 snprintf(procbuf, PATH_MAX,
"/proc/%d/path/a.out", (
int)getpid());
130 ssize_t bytes = MIN(readlink(procbuf, strbuf, PATH_MAX), PATH_MAX - 1);
133 strbuf[bytes] =
'\0';
134 return strdup(dirname(strbuf));
137 fprintf(stderr,
"%s", strerror(error));
146 char strbuf[PATH_MAX] =
"";
149 unsigned long int bytes = GetModuleFileName(NULL, strbuf, PATH_MAX);
152 return strdup(basename(strbuf));
155 char procbuf[PATH_MAX] =
"";
157 snprintf(procbuf, PATH_MAX,
"/proc/%d/exe", (
int)getpid());
159 snprintf(procbuf, PATH_MAX,
"/proc/%d/path/a.out", (
int)getpid());
161 ssize_t bytes = MIN(readlink(procbuf, strbuf, PATH_MAX), PATH_MAX - 1);
164 strbuf[bytes] =
'\0';
165 return strdup(basename(strbuf));
168 fprintf(stderr,
"%s", strerror(error));
180int n_popen(
char* cmd,
size_t read_buf_size,
void** nstr_output,
int* ret) {
183 if (read_buf_size > INT_MAX) {
184 n_log(
LOG_ERR,
"read_buf_size buffer size is too large for fgets (%zu>%d)", read_buf_size, INT_MAX);
187 if (read_buf_size > 65536) {
188 n_log(
LOG_ERR,
"read_buf_size %zu exceeds safe stack limit", read_buf_size);
196 char read_buf[read_buf_size];
198 fp = popen(cmd,
"r");
201 n_log(
LOG_ERR,
"popen( %s ) returned NULL , %s (%d)", cmd, strerror(err), err);
205 while (fgets(read_buf, (
int)read_buf_size, fp) != NULL) {
206 size_t length = strlen(read_buf);
207 if (length > 0 && read_buf[length - 1] ==
'\n') {
208 read_buf[length - 1] =
'\0';
215 n_log(
LOG_ERR,
"pclose( %s ) returned -1 , %s (%d)", cmd, strerror(err), err);
219 if (ret) (*ret) = WEXITSTATUS(status);
221 (*nstr_output) = output_pointer;
233#if defined(_WIN32) || defined(__MINGW32__) || defined(__windows__)
234 LPCH env_block = GetEnvironmentStrings();
235 if (!env_block)
return;
236 for (LPCH var = env_block; *var !=
'\0'; var += strlen(var) + 1) {
237 n_log(loglevel,
"env: %s", var);
239 FreeEnvironmentStrings(env_block);
241 extern char** environ;
242 for (
char** env = environ; *env != NULL; env++) {
243 n_log(loglevel,
"env: %s", *env);
255 int saved_errno = errno;
257 while (waitpid(-1, NULL, WNOHANG) > 0);
270 sigemptyset(&sa.sa_mask);
271 sa.sa_flags = SA_RESTART;
272 if (sigaction(SIGCHLD, &sa, NULL) == -1) {
300 n_log(
LOG_ERR,
"Error: unable to fork child: %s", strerror(error));
313 n_log(
LOG_ERR,
"Error: unable to set session leader with setsid(): %s", strerror(error));
322 signal(SIGCHLD, SIG_IGN);
335 n_log(
LOG_ERR,
"Error: unable to double fork child: %s", strerror(error));
351 if (chdir(
"/") < 0) {
353 n_log(
LOG_ERR,
"couldn't chdir() to '/': %s", strerror(error));
360 for (
int x = 3; x < sysconf(_SC_OPEN_MAX); x++) {
367 int fd = open(
"/dev/null", O_RDWR, 0);
369 dup2(fd, STDIN_FILENO);
370 dup2(fd, STDOUT_FILENO);
371 dup2(fd, STDERR_FILENO);
376 n_log(
LOG_ERR,
"Failed to open /dev/null: %s", strerror(errno));
390pid_t
system_nb(
const char* command,
int* infp,
int* outfp) {
393 int p_stdin[2] = {-1, -1};
394 int p_stdout[2] = {-1, -1};
398 if (pipe(p_stdin) != 0)
402 if (pipe(p_stdout) != 0) {
432 dup2(p_stdout[1], 1);
434 execlp(
"sh",
"sh",
"-c", command, (
char*)NULL);
437 n_log(
LOG_ERR,
"%s:%d: exec failed: %s", __FILE__, __LINE__, strerror(error));
467 while ((arg = va_arg(args,
int))) {
488 while ((i > 0) && (path[i] !=
'.') && (path[i] !=
'/') && (path[i] !=
'\\')) {
491 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.