/*************************************************************************** * system.c * * Copyright 2009 - Steffen Pohle * steffen@gulpe.de ****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "system.h" #include "map.h" #include "osmroute.h" #include #include #include #include #if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__) #include #include #endif time_t starttime; /******************************************* * * comparsion between doubles and floats */ int cmpf (float f1, float f2) { return fabs(f1-f2) <= FLT_EPSILON; }; int cmpd (double d1, double d2) { return fabs(d1-d2) < DBL_EPSILON; }; #if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__) int execcall (struct s_execcall *p, char *prg, char **argv) { if (p->used) return 0; if ((p->pid = fork ()) < 0) { printf ("%s:%d syscall fork error: %s\n", __FILE__, __LINE__, strerror (errno)); return 0; } else if (p->pid == 0) { // child // if (execvp(prg, argv) < 0) { printf ("%s:%d syscall execvp error:%s\n", __FILE__, __LINE__, strerror (errno)); errorexit (-1); } } /* parent */ p->used = 1; return 1; }; int execwait (struct s_execcall *p) { pid_t ptmp; int status; if (p->used == 0) return -1; ptmp = waitpid (p->pid, &status, WNOHANG); if (ptmp == p->pid) { if (WIFEXITED (status)) { p->used = 0; return 1; } } else if (ptmp == -1) { p->used = 0; return 1; } return -2; }; #endif #ifndef ANDROID void d_printf (char *fmt,...) { va_list args; char text1[1024]; char text2[1024]; char fn[LEN_FILENAME]; int f; #if defined(__MINGW32CE__) || defined(_WIN32_WCE) // return; #endif va_start (args, fmt); vsnprintf (text1, 1024, fmt, args); va_end (args); text1[1023] = 0; text2[1023] = 0; snprintf (fn, LEN_FILENAME, "%slogfile.txt", cfg.logpath); snprintf (text2, 1024, "%-6d %s", (int)(time(NULL) - starttime), text1); #ifndef COSMROUTE fprintf (stderr, "%s\n", text2); #endif f = open (fn, O_RDWR | O_CREAT, 0644); if (f) { lseek (f, 0, SEEK_END); write (f, text2, strlen (text2)); #if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__) && !defined(ANDROID) write (f, "\n", 1); #else write (f, "\n\r", 2); #endif close (f); } }; #endif void d_print_init() { int i; char **strings; char fn[LEN_FILENAME]; snprintf (fn, LEN_FILENAME, "%slogfile.txt", cfg.logpath); starttime = time (NULL); unlink (fn); d_printf (""); d_printf ("************************************************************"); d_printf ("* Starting *"); d_printf ("************************************************************"); d_printf ("size of datatypes in bytes - should be on all systems the same"); d_printf (" type : size "); d_printf ("----------------+------"); d_printf ("float : %d", sizeof (float)); d_printf ("char : %d", sizeof (char)); d_printf ("uint16_t : %d", sizeof (uint16_t)); d_printf ("uint32_t : %d", sizeof (uint32_t)); d_printf ("uint64_t : %d", sizeof (uint64_t)); d_printf ("size of datatypes in bytes - can be different"); d_printf (" type : size "); d_printf ("----------------+------"); d_printf ("long long int : %d", sizeof (long long int)); d_printf ("long int : %d", sizeof (long int)); d_printf ("int : %d INT_MIN:%d, INT_MAX:%d", sizeof (int), INT_MIN, INT_MAX); d_printf ("short int : %d", sizeof (short int)); d_printf ("\nTest for Backtraces:"); strings = get_backtrace (&i); if (i < 1 || strings == NULL) d_printf ("seems not to work\n"); else { d_printf ("works: %s\n", strings[2]); free (strings); } }; #define D_PRINT_COL 16 void d_print_data (char *data, int len) { int i, j; int val; char txt1 [256] = {0}; char txt2 [256] = {0}; char left [256] = {0}; char right [256] = {0}; d_printf ("memdump: len:%d", len); for (i = 0; i < len; i++) { val = data[i] & 0x00FF; sprintf (txt1, "%2x ", val); if (data[i] >= ' ' && data[i] <= '~') sprintf (txt2, "%c", data[i]); else sprintf (txt2, "."); strncat (left, txt1, 256); strncat (right, txt2, 256); if ((i%D_PRINT_COL)==D_PRINT_COL-1 || i == len-1) { sprintf (txt1, " "); sprintf (txt2, " "); for (j = i%D_PRINT_COL; j != 0 && j < D_PRINT_COL; j++) { strncat (left, txt1, 256); strncat (right, txt2, 256); } d_printf (" |%s | %s |", left, right); memset (left, 0x0, 256); memset (right, 0x0, 256); } } }; unsigned long long int getticks () { static unsigned long long int ticks = 0; if (ticks > (unsigned long long int)(ticks+1)) { d_printf ("%s:%d ticks+1 < ticks", __FILE__, __LINE__); errorexit (-1); } return ++ticks; }; #define SIZE 100 void errorexit (int nr) { #if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__) && !defined(ANDROID) int j, nptrs; void *buffer[SIZE]; char **strings; nptrs = backtrace(buffer, SIZE); d_printf("****************** backtrace: (needs to be linked with -Wl,--export-dynamic)"); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) * would produce similar output to the following: */ strings = (char **) backtrace_symbols(buffer, nptrs); if (strings == NULL) { d_printf ("backtrace_symbols: %s", strerror(errno)); exit(EXIT_FAILURE); } for (j = 0; j < nptrs; j++) d_printf("%s", strings[j]); free(strings); #endif exit (nr); }; void d_print_backtrace () { #if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__) && !defined(ANDROID) int j, nptrs; void *buffer[SIZE]; char **strings; nptrs = backtrace(buffer, SIZE); d_printf("****************** backtrace: (needs to be linked with -Wl,--export-dynamic)"); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) * would produce similar output to the following: */ strings = (char **) backtrace_symbols(buffer, nptrs); if (strings == NULL) { d_printf (" backtrace_symbols: %s", strerror(errno)); exit(EXIT_FAILURE); } for (j = 0; j < nptrs; j++) d_printf(" %s", strings[j]); free(strings); #endif }; char **get_backtrace (int *cnt) { #if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__) && !defined(ANDROID) void *buffer[SIZE]; char **strings; *cnt = backtrace(buffer, SIZE); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) * would produce similar output to the following: */ strings = (char **) backtrace_symbols(buffer, *cnt); if (strings == NULL) { d_printf ("backtrace_symbols: %s", strerror(errno)); exit(EXIT_FAILURE); } return strings; #else return NULL; #endif }; /* * copy data to the givin address and return increased pointer */ char *mempush (void *mem, void *source, int size) { memcpy (mem, source, size); return mem+size; }; char *mempop (void *mem, void *dest, int size) { memcpy (dest, mem, size); return mem+size; }; char *memstrpop (void *mem, void *dest, int *size) { uint8_t *m = mem, *d = dest; void *mout; while (*m != 0) { *d = *m; d++; m++; } *d = *m; m++; mout = m; *size = mout - mem; return (char*)m; }; #if !defined(ANDROID) void memswap (void *mem1, void *mem2, int size) { char data[32]; if (size > 32) { d_printf ("memswap maximum memory size of 32 bytes overrun size:%d", size); errorexit (-1); } memcpy (data, mem2, size); memcpy (mem2, mem1, size); memcpy (mem1, data, size); }; #endif int file_exist (char *fn) { struct stat fs; if (stat(fn, &fs) != 0) return 0; return 1; }; int dir_exist (char *fn) { struct stat fs; if (stat(fn, &fs) == 0) { if (S_ISDIR(fs.st_mode)) return 1; } return 0; } void d_print_stat () { #if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__) && !defined(ANDROID) struct rusage usage; d_printf ("getrusage:"); if (getrusage(RUSAGE_SELF, &usage) == 0) { // d_printf ("ru_utime : %6ld user CPU time used", usage.ru_utime); // d_printf ("ru_stime : %6ld system CPU time used", usage.ru_stime); d_printf ("ru_maxrss : %6ld maximum resident set size", usage.ru_maxrss); // d_printf ("ru_ixrss : %6ld integral shared memory size", usage.ru_ixrss); // d_printf ("ru_idrss : %6ld integral unshared data size", usage.ru_idrss); // d_printf ("ru_isrss : %6ld integral unshared stack size", usage.ru_isrss); d_printf ("ru_minflt : %6ld page reclaims (soft page faults)", usage.ru_minflt); d_printf ("ru_majflt : %6ld page faults (hard page faults)", usage.ru_majflt); d_printf ("ru_nswap : %6ld swaps", usage.ru_nswap); d_printf ("ru_inblock : %6ld block input operations", usage.ru_inblock); d_printf ("ru_oublock : %6ld block output operations", usage.ru_oublock); // d_printf ("ru_msgsnd : %6ld IPC messages sent", usage.ru_msgsnd); // d_printf ("ru_msgrcv : %6ld IPC messages received", usage.ru_msgrcv); // d_printf ("ru_nsignals: %6ld signals received", usage.ru_nsignals); d_printf ("ru_nvcsw : %6ld voluntary context switches", usage.ru_nvcsw); d_printf ("ru_nivcsw : %6ld involuntary context switches", usage.ru_nivcsw); } else d_printf ("getrusage error."); #else d_printf ("getrusage not implemented in windows.."); #endif } char _flags2text_[255] = ""; char* flags2text (int f, char *text) { int i; int c; char *fn1; char *fn2; fn1 = text; memset (_flags2text_, 0x0, 255); snprintf (_flags2text_, 250, "%d:", f); for (c = 1; (c < 0xFFFF && fn1 != NULL); c *= 2) { fn2 = strchr (fn1, '\n'); if (fn2 == NULL) i = strlen (fn1); else i = fn2-fn1; if (f & c) { if (c > 1) { _flags2text_[strlen(_flags2text_)+1] = 0; _flags2text_[strlen(_flags2text_)] = ','; } strncpy (_flags2text_+strlen(_flags2text_), fn1, i); } if (fn2 != NULL) fn2 += 1; fn1 = fn2; } return _flags2text_; }