2008-03-13 14:14:44 +00:00
|
|
|
/*
|
2014-02-21 17:44:15 +00:00
|
|
|
* Copyright (C) 2008-2014 Tobias Brunner
|
2008-03-13 14:14:44 +00:00
|
|
|
* Copyright (C) 2005-2008 Martin Willi
|
|
|
|
* Hochschule fuer Technik Rapperswil
|
|
|
|
*
|
|
|
|
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2013-10-18 12:19:32 +00:00
|
|
|
#include "utils.h"
|
|
|
|
|
2008-03-13 14:14:44 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2008-08-28 07:47:55 +00:00
|
|
|
#include <unistd.h>
|
2011-06-07 15:16:01 +00:00
|
|
|
#include <inttypes.h>
|
2009-07-15 08:07:15 +00:00
|
|
|
#include <stdint.h>
|
2008-08-28 07:47:55 +00:00
|
|
|
#include <dirent.h>
|
2008-12-02 08:46:15 +00:00
|
|
|
#include <time.h>
|
2014-03-10 11:12:47 +00:00
|
|
|
#ifndef WIN32
|
|
|
|
# include <signal.h>
|
|
|
|
#endif
|
2008-03-13 14:14:44 +00:00
|
|
|
|
2014-05-28 10:17:15 +00:00
|
|
|
#include <library.h>
|
|
|
|
#include <utils/chunk.h>
|
|
|
|
#include <collections/enumerator.h>
|
2014-03-10 11:12:47 +00:00
|
|
|
#include <threading/mutex.h>
|
|
|
|
#include <threading/condvar.h>
|
2008-03-13 14:14:44 +00:00
|
|
|
|
2014-03-10 11:12:47 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Flag to indicate signaled wait_sigint()
|
|
|
|
*/
|
|
|
|
static bool sigint_signaled = FALSE;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Condvar to wait in wait_sigint()
|
|
|
|
*/
|
|
|
|
static condvar_t *sigint_cond;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mutex to check signaling()
|
|
|
|
*/
|
|
|
|
static mutex_t *sigint_mutex;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Control handler to catch ^C
|
|
|
|
*/
|
2014-06-05 11:10:43 +00:00
|
|
|
static BOOL WINAPI handler(DWORD dwCtrlType)
|
2014-03-10 11:12:47 +00:00
|
|
|
{
|
|
|
|
switch (dwCtrlType)
|
|
|
|
{
|
|
|
|
case CTRL_C_EVENT:
|
|
|
|
case CTRL_BREAK_EVENT:
|
|
|
|
case CTRL_CLOSE_EVENT:
|
|
|
|
sigint_mutex->lock(sigint_mutex);
|
|
|
|
sigint_signaled = TRUE;
|
|
|
|
sigint_cond->signal(sigint_cond);
|
|
|
|
sigint_mutex->unlock(sigint_mutex);
|
|
|
|
return TRUE;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Windows variant
|
|
|
|
*/
|
|
|
|
void wait_sigint()
|
|
|
|
{
|
|
|
|
SetConsoleCtrlHandler(handler, TRUE);
|
|
|
|
|
|
|
|
sigint_mutex = mutex_create(MUTEX_TYPE_DEFAULT);
|
|
|
|
sigint_cond = condvar_create(CONDVAR_TYPE_DEFAULT);
|
|
|
|
|
|
|
|
sigint_mutex->lock(sigint_mutex);
|
|
|
|
while (!sigint_signaled)
|
|
|
|
{
|
|
|
|
sigint_cond->wait(sigint_cond, sigint_mutex);
|
|
|
|
}
|
|
|
|
sigint_mutex->unlock(sigint_mutex);
|
|
|
|
|
|
|
|
sigint_mutex->destroy(sigint_mutex);
|
|
|
|
sigint_cond->destroy(sigint_cond);
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* !WIN32 */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unix variant
|
|
|
|
*/
|
|
|
|
void wait_sigint()
|
|
|
|
{
|
|
|
|
sigset_t set;
|
|
|
|
int sig;
|
|
|
|
|
|
|
|
sigemptyset(&set);
|
|
|
|
sigaddset(&set, SIGINT);
|
|
|
|
sigaddset(&set, SIGTERM);
|
|
|
|
|
|
|
|
sigprocmask(SIG_BLOCK, &set, NULL);
|
|
|
|
sigwait(&set, &sig);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2011-10-13 08:34:51 +00:00
|
|
|
#ifndef HAVE_CLOSEFROM
|
|
|
|
/**
|
|
|
|
* Described in header.
|
|
|
|
*/
|
|
|
|
void closefrom(int lowfd)
|
|
|
|
{
|
2011-10-13 09:10:05 +00:00
|
|
|
char fd_dir[PATH_MAX];
|
|
|
|
int maxfd, fd, len;
|
|
|
|
|
|
|
|
/* try to close only open file descriptors on Linux... */
|
|
|
|
len = snprintf(fd_dir, sizeof(fd_dir), "/proc/%u/fd", getpid());
|
2011-10-13 09:12:15 +00:00
|
|
|
if (len > 0 && len < sizeof(fd_dir) && access(fd_dir, F_OK) == 0)
|
2011-10-13 09:10:05 +00:00
|
|
|
{
|
|
|
|
enumerator_t *enumerator = enumerator_create_directory(fd_dir);
|
|
|
|
if (enumerator)
|
|
|
|
{
|
2011-10-13 12:34:34 +00:00
|
|
|
char *rel;
|
2011-10-13 09:10:05 +00:00
|
|
|
while (enumerator->enumerate(enumerator, &rel, NULL, NULL))
|
|
|
|
{
|
|
|
|
fd = atoi(rel);
|
|
|
|
if (fd >= lowfd)
|
|
|
|
{
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ...fall back to closing all fds otherwise */
|
2013-10-11 15:27:25 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
maxfd = _getmaxstdio();
|
|
|
|
#else
|
2011-10-13 08:34:51 +00:00
|
|
|
maxfd = (int)sysconf(_SC_OPEN_MAX);
|
2013-10-11 15:27:25 +00:00
|
|
|
#endif
|
2011-10-13 08:34:51 +00:00
|
|
|
if (maxfd < 0)
|
|
|
|
{
|
|
|
|
maxfd = 256;
|
|
|
|
}
|
|
|
|
for (fd = lowfd; fd < maxfd; fd++)
|
|
|
|
{
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* HAVE_CLOSEFROM */
|
|
|
|
|
2008-03-19 09:44:47 +00:00
|
|
|
/**
|
|
|
|
* return null
|
|
|
|
*/
|
|
|
|
void *return_null()
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-04-24 14:08:42 +00:00
|
|
|
/**
|
|
|
|
* returns TRUE
|
|
|
|
*/
|
|
|
|
bool return_true()
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns FALSE
|
|
|
|
*/
|
|
|
|
bool return_false()
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2008-04-17 11:22:37 +00:00
|
|
|
/**
|
|
|
|
* nop operation
|
|
|
|
*/
|
|
|
|
void nop()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-05-28 10:17:15 +00:00
|
|
|
/**
|
|
|
|
* See header
|
|
|
|
*/
|
|
|
|
void utils_init()
|
|
|
|
{
|
|
|
|
#ifdef WIN32
|
|
|
|
windows_init();
|
|
|
|
#endif
|
2015-04-15 13:48:17 +00:00
|
|
|
atomics_init();
|
2014-05-28 10:17:15 +00:00
|
|
|
strerror_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See header
|
|
|
|
*/
|
|
|
|
void utils_deinit()
|
|
|
|
{
|
|
|
|
#ifdef WIN32
|
|
|
|
windows_deinit();
|
|
|
|
#endif
|
2015-04-15 13:48:17 +00:00
|
|
|
atomics_deinit();
|
2014-05-28 10:17:15 +00:00
|
|
|
strerror_deinit();
|
|
|
|
}
|