Nilorea Library
C utilities for networking, threading, graphics
n_common.c
Go to the documentation of this file.
1
8#include "nilorea/n_common.h"
9#include "nilorea/n_log.h"
10#include "nilorea/n_str.h"
11
12#include <limits.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <libgen.h>
16
17#ifdef __windows__
18#include <windows.h>
19#else
20#include <errno.h>
21#include <strings.h>
22#include <unistd.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <sys/wait.h>
27#ifdef __linux__
28#include <string.h>
29#include <linux/limits.h>
30#include <unistd.h>
31#endif
32#endif
33
38void n_abort( char const *format, ... )
39{
40 char str[1024] = "" ;
41 va_list args;
42 va_start(args, format);
43
44 vsnprintf(str, sizeof str, format, args);
45 va_end(args);
46 fprintf(stderr, "%s", str);
47 exit(1);
48}
49
50
51
58int get_computer_name( char *computer_name , size_t len )
59{
60 memset(computer_name, 0, len);
61#ifdef WIN32
62 TCHAR infoBuf[len];
63 DWORD bufCharCount = len;
64 if( GetComputerName( infoBuf, &bufCharCount ) )
65 {
66 memcpy( computer_name , infoBuf , len );
67 }
68 else
69 {
70 strcpy(computer_name, "Unknown_Host_Name");
71 return FALSE ;
72 }
73#else
74 if( gethostname(computer_name, len) == -1 )
75 {
76 int error = errno ;
77 strcpy(computer_name, "Unknown_Host_Name");
78 n_log( LOG_ERR , "%s on gethostname !" , strerror( error ) );
79 return FALSE ;
80 }
81#endif
82 return TRUE ;
83} /* get_computer_name */
84
85
86
92int file_exist( const char *filename )
93{
94 FILE *file = NULL ;
95 if( ( file = fopen( filename, "r" ) ) != NULL )
96 {
97 fclose(file);
98 return 1 ;
99 }
100 return 0;
101} /* file_exist */
102
103
104
109char *get_prog_dir( void )
110{
111 char strbuf[ PATH_MAX ] = "" ;
112
113 int error = 0 ;
114#ifdef __windows__
115 unsigned long int bytes = GetModuleFileName( NULL, strbuf, PATH_MAX );
116 error = errno ;
117 if(bytes != 0)
118 {
119 return strdup( dirname(strbuf ) );
120 }
121#else
122 char procbuf[ PATH_MAX ] = "" ;
123#ifdef __linux__
124 sprintf( procbuf, "/proc/%d/exe", (int)getpid() );
125#elif defined __sun
126 sprintf( procbuf, "/proc/%d/path/a.out", (int)getpid() );
127#endif
128 int bytes = MIN( readlink( procbuf, strbuf, PATH_MAX ), PATH_MAX - 1 );
129 error = errno ;
130 if( bytes >= 0 )
131 {
132 strbuf[ bytes ] = '\0';
133 return strdup( dirname( strbuf ) );
134 }
135#endif
136 fprintf( stderr, "%s", strerror( error ) );
137 return NULL ;
138} /* get_prog_dir */
139
140
145char *get_prog_name( void )
146{
147 char strbuf[ PATH_MAX ] = "" ;
148 int error = 0 ;
149#ifdef __windows__
150 unsigned long int bytes = GetModuleFileName( NULL, strbuf, PATH_MAX );
151 error = errno ;
152 if(bytes != 0)
153 {
154 return strdup( basename(strbuf ) );
155 }
156#else
157 char procbuf[ PATH_MAX ] = "" ;
158#ifdef __linux__
159 sprintf( procbuf, "/proc/%d/exe", (int)getpid() );
160#elif defined __sun
161 sprintf( procbuf, "/proc/%d/path/a.out", (int)getpid() );
162#endif
163 int bytes = MIN( readlink( procbuf, strbuf, PATH_MAX ), PATH_MAX - 1 );
164 error = errno ;
165 if( bytes >= 0 )
166 {
167 strbuf[ bytes ] = '\0';
168 return strdup( basename( strbuf ) );
169 }
170#endif
171 fprintf( stderr, "%s", strerror( error ) );
172 return NULL ;
173} /* get_prog_dir */
174
175
176
185int n_popen( char *cmd, int read_buf_size, void **nstr_output, int *ret )
186{
187 __n_assert( cmd, return FALSE );
188
189 N_STR *output_pointer = new_nstr( read_buf_size + 1 );
190
191 FILE *fp = NULL ;
192 int status = 0 ;
193 char read_buf[ read_buf_size ] ;
194
195 fp = popen( cmd, "r" );
196 int err = errno ;
197 if (fp == NULL)
198 {
199 n_log( LOG_ERR, "popen( %s ) returned NULL , %s (%d)", cmd, strerror( err ), err );
200 return FALSE ;
201 }
202
203 int length = 0 ;
204 while( fgets( read_buf, read_buf_size, fp ) != NULL )
205 {
206 length = strlen( read_buf );
207 if( read_buf[ length - 1 ] == '\n' )
208 {
209 read_buf[ length - 1 ] = '\0' ;
210 }
211 nstrprintf_cat( output_pointer, "%s", read_buf );
212 }
213 status = pclose( fp );
214 err = errno ;
215 if( status == -1 )
216 {
217 n_log( LOG_ERR, "pclose( %s ) returned -1 , %s (%d)", cmd, strerror( err ), err );
218 if( WIFEXITED( status ) )
219 {
220 n_log( LOG_ERR, "Child exited with RC=%d", WEXITSTATUS( status ) );
221 (*ret) = WEXITSTATUS( status );
222 }
223 return FALSE ;
224 }
225 (*ret) = WEXITSTATUS( status );
226 (*nstr_output) = output_pointer ;
227 return TRUE ;
228} /* n_popen( ... ) */
229
230
231#ifndef __windows__
236int n_daemonize( void )
237{
238 /* Fork off the parent process */
239 pid_t pid = fork();
240 if( pid < 0 )
241 {
242 n_log( LOG_ERR, "Error: unable to fork child: %s", strerror( errno ) );
243 exit( 1 );
244 }
245 if( pid > 0 )
246 {
247 n_log( LOG_NOTICE, "Child started successfuly !" );
248 exit( 0 );
249 }
250 /* Close all open file descriptors */
251 for(int x = 0 ; x < sysconf( _SC_OPEN_MAX ) ; x++ )
252 {
253 close(x);
254 }
255 int fd = open("/dev/null",O_RDWR, 0);
256 if (fd != -1)
257 {
258 dup2 (fd, STDIN_FILENO);
259 dup2 (fd, STDOUT_FILENO);
260 dup2 (fd, STDERR_FILENO);
261 if (fd > 2)
262 {
263 close (fd);
264 }
265 }
266 else
267 {
268 n_log( LOG_ERR, "Failed to open /dev/null" );
269 }
270
271 /* On success: The child process becomes session leader */
272 if( setsid() < 0 )
273 {
274 n_log( LOG_ERR, "Error: unable to set session leader with setsid(): %s", strerror( errno ) );
275 exit( 1 );
276 }
277 else
278 {
279 n_log( LOG_NOTICE, "Session leader set !" );
280 }
281
282 return TRUE ;
283} /* n_daemonize(...) */
284
285
293pid_t system_nb(const char * command, int * infp, int * outfp)
294{
295 __n_assert( command, return -1 );
296
297 int p_stdin[2] = { -1, -1 };
298 int p_stdout[2] = { -1, -1 };
299 pid_t pid = -1 ;
300
301 if( pipe( p_stdin ) == -1 )
302 {
303 n_log( LOG_ERR, "Couldn't pipe stdin for command %s", command );
304 return -1;
305 }
306 if (pipe(p_stdout) == -1)
307 {
308 close(p_stdin[0]);
309 close(p_stdin[1]);
310 n_log( LOG_ERR, "Couldn't pipe stdout for command %s", command );
311 return -1;
312 }
313
314 pid = fork();
315 if (pid < 0)
316 {
317 close(p_stdin[0]);
318 close(p_stdin[1]);
319 close(p_stdout[0]);
320 close(p_stdout[1]);
321 n_log( LOG_ERR, "Couldn't fork command %s", command );
322 return pid;
323 }
324 else if (pid == 0)
325 {
326 close(p_stdin[1]);
327 dup2(p_stdin[0], 0);
328 close(p_stdout[0]);
329 dup2(p_stdout[1], 1);
330 dup2( open("/dev/null", O_RDONLY), 2);
331
333 for(int i = 3 ; i < sysconf( _SC_OPEN_MAX ) ; i++ )
334 {
335 close(i);
336 }
337 setsid();
338 execl("/bin/sh", "sh", "-c", command, (char *)NULL);
339 _exit(1);
340 }
341
342 close( p_stdin[0] );
343 close( p_stdout[1] );
344 if( infp == NULL)
345 {
346 close(p_stdin[1]);
347 }
348 else
349 {
350 *infp = p_stdin[1];
351 }
352 if (outfp == NULL)
353 {
354 close(p_stdout[0]);
355 }
356 else
357 {
358 *outfp = p_stdout[0];
359 }
360
361 return pid;
362} /* system_nb */
363
364#endif /* ifndef __windows__ */
365
371void N_HIDE_STR(char *buf, ...)
372{
373 size_t it = 0;
374 va_list args;
375
376 va_start (args, buf);
377
378 char arg = '\0' ;
379
380 while((arg = va_arg(args, int)))
381 {
382 buf[ it ] = arg ;
383 it ++ ;
384 }
385 buf[ it ] = '\0' ;
386 va_end (args);
387} /* N_HIDE_STR */
388
394char *n_get_file_extension( char path[])
395{
396 char *result = NULL ;
397 int i, n;
398
399 __n_assert(path , return "" );
400
401 n = strlen(path);
402 i = n - 1;
403 while ((i > 0) && (path[i] != '.') && (path[i] != '/') && (path[i] != '\\')) {
404 i--;
405 }
406 if ((i > 0) && (i < n - 1) && (path[i] == '.') && (path[i - 1] != '/') && (path[i - 1] != '\\')) {
407 result = path + i;
408 } else {
409 result = path + n;
410 }
411 return result;
412}
char * get_prog_name(void)
get current program name
Definition: n_common.c:145
void N_HIDE_STR(char *buf,...)
store a hidden version of a string
Definition: n_common.c:371
#define __n_assert(__ptr, __ret)
macro to assert things
Definition: n_common.h:276
int get_computer_name(char *computer_name, size_t len)
abort program with a text
Definition: n_common.c:58
pid_t system_nb(const char *command, int *infp, int *outfp)
Non blocking system call.
Definition: n_common.c:293
char * n_get_file_extension(char path[])
get extension of path+filename
Definition: n_common.c:394
int n_popen(char *cmd, int read_buf_size, void **nstr_output, int *ret)
launch a command abd return output and status
Definition: n_common.c:185
char * get_prog_dir(void)
get current program running directory
Definition: n_common.c:109
void n_abort(char const *format,...)
abort program with a text
Definition: n_common.c:38
int n_daemonize(void)
Daemonize program.
Definition: n_common.c:236
int file_exist(const char *filename)
test if file exist and if it's readable
Definition: n_common.c:92
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition: n_log.h:74
#define LOG_ERR
error conditions
Definition: n_log.h:58
#define LOG_NOTICE
normal but significant condition
Definition: n_log.h:62
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
Definition: n_str.c:215
#define nstrprintf_cat(__nstr_var,...)
Macro to quickly allocate and sprintf and cat to a N_STR *.
Definition: n_str.h:117
A box including a string and his lenght.
Definition: n_str.h:173
Common headers and low-level hugly functions & define.
Generic log system.
N_STR and string function declaration.