You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
418 lines
10 KiB
418 lines
10 KiB
/***************************************************************************
|
|
* 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 <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
#if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__)
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
#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_;
|
|
}
|
|
|