- better portability check with HAVE_SIGACTION

- fix segfault when doing rig_set_trn(POLL->OFF->POLL)
- implement remove_trn_rig()/remove_trn_poll_rig() for rig_set_trn(TRN_OFF)


git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2956 7ae35d74-ebe9-4afe-98af-79ac388436b8
Hamlib-1.2.12
Stéphane Fillod, F8CFE 2010-08-21 11:37:58 +00:00
rodzic ea20e4ff9e
commit b818045a0a
3 zmienionych plików z 85 dodań i 44 usunięć

Wyświetl plik

@ -158,7 +158,7 @@ AC_CHECK_LIB(syslog,syslog) # OS/2 needs this
dnl Checks for library functions. dnl Checks for library functions.
AC_CHECK_FUNCS([atexit snprintf select memmove memset]) AC_CHECK_FUNCS([atexit snprintf select memmove memset])
AC_CHECK_FUNCS([strcasecmp strchr strdup strerror strrchr strstr strtol]) AC_CHECK_FUNCS([strcasecmp strchr strdup strerror strrchr strstr strtol])
AC_CHECK_FUNCS([cfmakeraw setitimer ioctl]) AC_CHECK_FUNCS([cfmakeraw setitimer ioctl sigaction])
AC_FUNC_ALLOCA AC_FUNC_ALLOCA
#AC_FUNC_MALLOC #AC_FUNC_MALLOC
AC_FUNC_VPRINTF AC_FUNC_VPRINTF

Wyświetl plik

@ -66,6 +66,9 @@
#define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !(r)->state.comm_state) #define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !(r)->state.comm_state)
#ifdef HAVE_SIGACTION
static struct sigaction hamlib_trn_oldact, hamlib_trn_poll_oldact;
#ifdef HAVE_SIGINFO_T #ifdef HAVE_SIGINFO_T
static RETSIGTYPE sa_sigioaction(int signum, siginfo_t *si, void *data); static RETSIGTYPE sa_sigioaction(int signum, siginfo_t *si, void *data);
static RETSIGTYPE sa_sigalrmaction(int signum, siginfo_t *si, void *data); static RETSIGTYPE sa_sigalrmaction(int signum, siginfo_t *si, void *data);
@ -73,9 +76,10 @@ static RETSIGTYPE sa_sigalrmaction(int signum, siginfo_t *si, void *data);
static RETSIGTYPE sa_sigiohandler(int signum); static RETSIGTYPE sa_sigiohandler(int signum);
static RETSIGTYPE sa_sigalrmhandler(int signum); static RETSIGTYPE sa_sigalrmhandler(int signum);
#endif #endif
#endif
/* This one should be in an include file */ /* This one should be in an include file */
int foreach_opened_rig(int (*cfunc)(RIG *, rig_ptr_t),rig_ptr_t data); extern int foreach_opened_rig(int (*cfunc)(RIG *, rig_ptr_t),rig_ptr_t data);
/* /*
* add_trn_rig * add_trn_rig
@ -84,13 +88,15 @@ int foreach_opened_rig(int (*cfunc)(RIG *, rig_ptr_t),rig_ptr_t data);
*/ */
int add_trn_rig(RIG *rig) int add_trn_rig(RIG *rig)
{ {
#ifndef WIN32 #ifdef HAVE_SIGACTION
struct sigaction act; struct sigaction act;
int status; int status;
/* /*
* FIXME: multiple open will register several time SIGIO hndlr * FIXME: multiple open will register several time SIGIO hndlr
*/ */
memset(&act, 0, sizeof(act));
#ifdef HAVE_SIGINFO_T #ifdef HAVE_SIGINFO_T
act.sa_sigaction = sa_sigioaction; act.sa_sigaction = sa_sigioaction;
#else #else
@ -100,33 +106,33 @@ int add_trn_rig(RIG *rig)
sigemptyset(&act.sa_mask); sigemptyset(&act.sa_mask);
#if defined(HAVE_SIGINFO_T) && defined(SA_SIGINFO) #if defined(HAVE_SIGINFO_T) && defined(SA_SIGINFO)
act.sa_flags = SA_SIGINFO; act.sa_flags = SA_SIGINFO|SA_RESTART;
#else #else
act.sa_flags = 0; act.sa_flags = SA_RESTART;
#endif #endif
status = sigaction(SIGIO, &act, NULL); status = sigaction(SIGIO, &act, &hamlib_trn_oldact);
if (status < 0) if (status < 0)
rig_debug(RIG_DEBUG_ERR,"rig_open sigaction failed: %s\n", rig_debug(RIG_DEBUG_ERR,"%s: sigaction failed: %s\n",
strerror(errno)); __func__, strerror(errno));
status = fcntl(rig->state.rigport.fd, F_SETOWN, getpid()); status = fcntl(rig->state.rigport.fd, F_SETOWN, getpid());
if (status < 0) if (status < 0)
rig_debug(RIG_DEBUG_ERR,"rig_open fcntl SETOWN failed: %s\n", rig_debug(RIG_DEBUG_ERR,"%s: fcntl SETOWN failed: %s\n",
strerror(errno)); __func__, strerror(errno));
#if defined(HAVE_SIGINFO_T) && defined(O_ASYNC) #if defined(HAVE_SIGINFO_T) && defined(O_ASYNC)
#ifdef F_SETSIG #ifdef F_SETSIG
status = fcntl(rig->state.rigport.fd, F_SETSIG, SIGIO); status = fcntl(rig->state.rigport.fd, F_SETSIG, SIGIO);
if (status < 0) if (status < 0)
rig_debug(RIG_DEBUG_ERR,"rig_open fcntl SETSIG failed: %s\n", rig_debug(RIG_DEBUG_ERR,"%s: fcntl SETSIG failed: %s\n",
strerror(errno)); __func__, strerror(errno));
#endif #endif
status = fcntl(rig->state.rigport.fd, F_SETFL, O_ASYNC); status = fcntl(rig->state.rigport.fd, F_SETFL, O_ASYNC);
if (status < 0) if (status < 0)
rig_debug(RIG_DEBUG_ERR,"rig_open fcntl SETASYNC failed: %s\n", rig_debug(RIG_DEBUG_ERR,"%s: fcntl SETASYNC failed: %s\n",
strerror(errno)); __func__, strerror(errno));
#else #else
return -RIG_ENIMPL; return -RIG_ENIMPL;
#endif #endif
@ -135,31 +141,67 @@ int add_trn_rig(RIG *rig)
#else #else
return -RIG_ENIMPL; return -RIG_ENIMPL;
#endif /* !WIN32 */ #endif /* !HAVE_SIGACTION */
} }
/*
* remove_trn_rig
* not exported in Hamlib API.
* Assumes rig->caps->transceive == RIG_TRN_RIG
*/
int remove_trn_rig(RIG *rig)
{
#ifdef HAVE_SIGACTION
int status;
/* assert(rig->caps->transceive == RIG_TRN_RIG); */
#if defined(HAVE_SIGINFO_T) && defined(O_ASYNC)
status = fcntl(rig->state.rigport.fd, F_SETFL, 0);
if (status < 0)
rig_debug(RIG_DEBUG_ERR,"%s: fcntl SETASYNC failed: %s\n",
__func__, strerror(errno));
#endif
status = sigaction(SIGIO, &hamlib_trn_oldact, NULL);
if (status < 0)
rig_debug(RIG_DEBUG_ERR,"%s: sigaction failed: %s\n",
__func__, strerror(errno));
return RIG_OK;
#else
return -RIG_ENIMPL;
#endif /* !HAVE_SIGACTION */
}
#ifdef HAVE_SIGACTION
/* /*
* add_trn_poll_rig * add_trn_poll_rig
* not exported in Hamlib API. * not exported in Hamlib API.
*/ */
int add_trn_poll_rig(RIG *rig) static int add_trn_poll_rig(RIG *rig)
{ {
#ifndef WIN32 #ifdef HAVE_SIGACTION
struct sigaction act; struct sigaction act;
int status; int status;
/* /*
* FIXME: multiple open will register several time SIGIO hndlr * FIXME: multiple open will register several time SIGALRM hndlr
*/ */
memset(&act, 0, sizeof(act));
#ifdef HAVE_SIGINFO_T #ifdef HAVE_SIGINFO_T
act.sa_sigaction = sa_sigalrmaction; act.sa_sigaction = sa_sigalrmaction;
#else #else
act.sa_handler = sa_sigalrmhandler; act.sa_handler = sa_sigalrmhandler;
#endif #endif
act.sa_flags = SA_RESTART;
sigemptyset(&act.sa_mask); sigemptyset(&act.sa_mask);
status = sigaction(SIGALRM, &act, NULL); status = sigaction(SIGALRM, &act, &hamlib_trn_poll_oldact);
if (status < 0) if (status < 0)
rig_debug(RIG_DEBUG_ERR,"%s sigaction failed: %s\n", rig_debug(RIG_DEBUG_ERR,"%s sigaction failed: %s\n",
__func__, __func__,
@ -169,33 +211,29 @@ int add_trn_poll_rig(RIG *rig)
#else #else
return -RIG_ENIMPL; return -RIG_ENIMPL;
#endif /* !WIN32 */ #endif /* !HAVE_SIGINFO */
} }
/* /*
* remove_trn_poll_rig * remove_trn_poll_rig
* not exported in Hamlib API. * not exported in Hamlib API.
*/ */
int remove_trn_poll_rig(RIG *rig) static int remove_trn_poll_rig(RIG *rig)
{ {
#ifdef HAVE_SIGINFO
int status;
status = sigaction(SIGALRM, &hamlib_trn_poll_oldact, NULL);
if (status < 0)
rig_debug(RIG_DEBUG_ERR,"%s sigaction failed: %s\n",
__func__,
strerror(errno));
return RIG_OK;
#else
return -RIG_ENIMPL; return -RIG_ENIMPL;
} #endif /* !HAVE_SIGINFO */
/*
* remove_trn_rig
* not exported in Hamlib API.
* Assumes rig->caps->transceive == RIG_TRN_RIG
*/
int remove_trn_rig(RIG *rig)
{
if (rig->caps->transceive == RIG_TRN_RIG)
return -RIG_ENIMPL;
if (rig->state.transceive == RIG_TRN_POLL)
return remove_trn_poll_rig(rig);
return -RIG_EINVAL;
} }
@ -294,7 +332,8 @@ static int search_rig_and_poll(RIG *rig, rig_ptr_t data)
retval = rig->caps->get_freq(rig, RIG_VFO_CURR, &freq); retval = rig->caps->get_freq(rig, RIG_VFO_CURR, &freq);
if (retval == RIG_OK) { if (retval == RIG_OK) {
if (freq != rs->current_freq) { if (freq != rs->current_freq) {
rig->callbacks.freq_event(rig, RIG_VFO_CURR, freq, rig->callbacks.freq_arg); rig->callbacks.freq_event(rig, RIG_VFO_CURR,
freq, rig->callbacks.freq_arg);
} }
rs->current_freq = freq; rs->current_freq = freq;
} }
@ -366,12 +405,14 @@ static RETSIGTYPE sa_sigalrmaction(int signum, siginfo_t *si, rig_ptr_t data)
static RETSIGTYPE sa_sigalrmhandler(int signum) static RETSIGTYPE sa_sigalrmhandler(int signum)
{ {
rig_debug(RIG_DEBUG_TRACE, "sa_sigalrmaction entered\n"); rig_debug(RIG_DEBUG_TRACE, "sa_sigalrmhandler entered\n");
foreach_opened_rig(search_rig_and_poll, NULL); foreach_opened_rig(search_rig_and_poll, NULL);
} }
#endif #endif /* !HAVE_SIGINFO_T */
#endif /* HAVE_SIGINFO */
#endif /* !DOC_HIDDEN */ #endif /* !DOC_HIDDEN */
@ -600,7 +641,7 @@ int HAMLIB_API rig_set_trn(RIG *rig, int trn)
rig_debug(RIG_DEBUG_ERR, "%s: setitimer: %s\n", rig_debug(RIG_DEBUG_ERR, "%s: setitimer: %s\n",
__func__, __func__,
strerror(errno)); strerror(errno));
remove_trn_rig(rig); remove_trn_poll_rig(rig);
return -RIG_EINTERNAL; return -RIG_EINTERNAL;
} }
#else #else
@ -612,7 +653,7 @@ int HAMLIB_API rig_set_trn(RIG *rig, int trn)
if (rig->state.transceive == RIG_TRN_POLL) { if (rig->state.transceive == RIG_TRN_POLL) {
#ifdef HAVE_SETITIMER #ifdef HAVE_SETITIMER
retcode = remove_trn_rig(rig); retcode = remove_trn_poll_rig(rig);
value.it_value.tv_sec = 0; value.it_value.tv_sec = 0;
value.it_value.tv_usec = 0; value.it_value.tv_usec = 0;

Wyświetl plik

@ -587,7 +587,7 @@ int HAMLIB_API rig_close(RIG *rig)
return -RIG_EINVAL; return -RIG_EINVAL;
if (rs->transceive != RIG_TRN_OFF) { if (rs->transceive != RIG_TRN_OFF) {
remove_trn_rig(rig); rig_set_trn(rig, RIG_TRN_OFF);
} }
/* /*