Add more detailed rig communication status to rig_state and multicast state data packets. Handle SIGINT and SIGTERM in a consistent way in both rigctl and rigctld.

pull/1415/head
Mikael Nousiainen 2023-11-06 00:42:02 +02:00
rodzic 3107a060f0
commit 43d1fbb323
12 zmienionych plików z 291 dodań i 29 usunięć

Wyświetl plik

@ -2577,6 +2577,15 @@ struct multicast_s
//#endif //#endif
}; };
typedef unsigned int rig_comm_status_t;
#define RIG_COMM_STATUS_OK 0x00
#define RIG_COMM_STATUS_CONNECTING 0x01
#define RIG_COMM_STATUS_DISCONNECTED 0x02
#define RIG_COMM_STATUS_TERMINATED 0x03
#define RIG_COMM_STATUS_WARNING 0x04
#define RIG_COMM_STATUS_ERROR 0x05
/** /**
* \brief Rig state containing live data and customized fields. * \brief Rig state containing live data and customized fields.
* *
@ -2766,6 +2775,8 @@ struct rig_state {
int multicast_cmd_port; /*!< Multicast command server UDP port for sending commands to rig */ int multicast_cmd_port; /*!< Multicast command server UDP port for sending commands to rig */
volatile int multicast_receiver_run; volatile int multicast_receiver_run;
void *multicast_receiver_priv_data; void *multicast_receiver_priv_data;
rig_comm_status_t comm_status; /*!< Detailed rig control status */
char device_id[HAMLIB_RIGNAMSIZ];
}; };
/** /**
@ -3710,6 +3721,7 @@ extern HAMLIB_EXPORT(const char *) rig_strscan(scan_t scan);
extern HAMLIB_EXPORT(const char *) rig_strstatus(enum rig_status_e status); extern HAMLIB_EXPORT(const char *) rig_strstatus(enum rig_status_e status);
extern HAMLIB_EXPORT(const char *) rig_strmtype(chan_type_t mtype); extern HAMLIB_EXPORT(const char *) rig_strmtype(chan_type_t mtype);
extern HAMLIB_EXPORT(const char *) rig_strspectrummode(enum rig_spectrum_mode_e mode); extern HAMLIB_EXPORT(const char *) rig_strspectrummode(enum rig_spectrum_mode_e mode);
extern HAMLIB_EXPORT(const char *) rig_strcommstatus(rig_comm_status_t vfo);
extern HAMLIB_EXPORT(rmode_t) rig_parse_mode(const char *s); extern HAMLIB_EXPORT(rmode_t) rig_parse_mode(const char *s);
extern HAMLIB_EXPORT(vfo_t) rig_parse_vfo(const char *s); extern HAMLIB_EXPORT(vfo_t) rig_parse_vfo(const char *s);

Wyświetl plik

@ -89,6 +89,11 @@ static const struct confparams frontend_cfg_params[] =
"The tx/rx range list name", "The tx/rx range list name",
"Default", RIG_CONF_STRING "Default", RIG_CONF_STRING
}, },
{
TOK_DEVICE_ID, "device_id", "Device ID",
"User-specified device ID for multicast state data and commands",
"", RIG_CONF_STRING,
},
{ {
TOK_VFO_COMP, "vfo_comp", "VFO compensation", TOK_VFO_COMP, "vfo_comp", "VFO compensation",
@ -627,6 +632,10 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val)
strncpy(rs->dcdport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); strncpy(rs->dcdport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1);
break; break;
case TOK_DEVICE_ID:
strncpy(rs->device_id, val, HAMLIB_RIGNAMSIZ - 1);
break;
case TOK_VFO_COMP: case TOK_VFO_COMP:
rs->vfo_comp = atof(val); rs->vfo_comp = atof(val);
@ -989,6 +998,10 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len)
strcpy(val, s); strcpy(val, s);
break; break;
case TOK_DEVICE_ID:
SNPRINTF(val, val_len, "%s", rs->device_id);
break;
case TOK_VFO_COMP: case TOK_VFO_COMP:
SNPRINTF(val, val_len, "%f", rs->vfo_comp); SNPRINTF(val, val_len, "%f", rs->vfo_comp);
break; break;
@ -1149,6 +1162,22 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len)
SNPRINTF(val, val_len, "%d", rs->rigport.timeout_retry); SNPRINTF(val, val_len, "%d", rs->rigport.timeout_retry);
break; break;
case TOK_MULTICAST_DATA_ADDR:
SNPRINTF(val, val_len, "%s", rs->multicast_data_addr);
break;
case TOK_MULTICAST_DATA_PORT:
SNPRINTF(val, val_len, "%d", rs->multicast_data_port);
break;
case TOK_MULTICAST_CMD_ADDR:
SNPRINTF(val, val_len, "%s", rs->multicast_cmd_addr);
break;
case TOK_MULTICAST_CMD_PORT:
SNPRINTF(val, val_len, "%d", rs->multicast_cmd_port);
break;
default: default:
return -RIG_EINVAL; return -RIG_EINVAL;
} }

Wyświetl plik

@ -64,8 +64,6 @@ typedef struct rig_poll_routine_priv_data_s
rig_poll_routine_args args; rig_poll_routine_args args;
} rig_poll_routine_priv_data; } rig_poll_routine_priv_data;
// TODO: Where to start/stop rig poll routine?
void *rig_poll_routine(void *arg) void *rig_poll_routine(void *arg)
{ {
rig_poll_routine_args *args = (rig_poll_routine_args *)arg; rig_poll_routine_args *args = (rig_poll_routine_args *)arg;
@ -93,6 +91,8 @@ void *rig_poll_routine(void *arg)
update_occurred = 0; update_occurred = 0;
network_publish_rig_poll_data(rig);
while (rs->poll_routine_thread_run) while (rs->poll_routine_thread_run)
{ {
if (rig->state.cache.freqMainA != freq_main_a) if (rig->state.cache.freqMainA != freq_main_a)
@ -351,6 +351,8 @@ void *rig_poll_routine(void *arg)
} }
} }
network_publish_rig_poll_data(rig);
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping rig poll routine thread\n", rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping rig poll routine thread\n",
__FILE__, __FILE__,
__LINE__); __LINE__);
@ -408,6 +410,8 @@ int rig_poll_routine_start(RIG *rig)
RETURNFUNC(-RIG_EINTERNAL); RETURNFUNC(-RIG_EINTERNAL);
} }
network_publish_rig_poll_data(rig);
RETURNFUNC(RIG_OK); RETURNFUNC(RIG_OK);
} }
@ -453,6 +457,8 @@ int rig_poll_routine_stop(RIG *rig)
poll_routine_priv->thread_id = 0; poll_routine_priv->thread_id = 0;
} }
network_publish_rig_poll_data(rig);
free(rs->poll_routine_priv_data); free(rs->poll_routine_priv_data);
rs->poll_routine_priv_data = NULL; rs->poll_routine_priv_data = NULL;

Wyświetl plik

@ -2707,6 +2707,42 @@ const char *HAMLIB_API rig_get_caps_cptr(rig_model_t rig_model,
} }
} }
static const struct
{
rig_comm_status_t status;
const char *str;
} comm_status_str[] =
{
{ RIG_COMM_STATUS_OK, "OK" },
{ RIG_COMM_STATUS_CONNECTING, "CONNECTING" },
{ RIG_COMM_STATUS_DISCONNECTED, "DISCONNECTED" },
{ RIG_COMM_STATUS_TERMINATED, "TERMINATIED" },
{ RIG_COMM_STATUS_WARNING, "WARNING" },
{ RIG_COMM_STATUS_ERROR, "ERROR" },
{ 0xffffffff, "" },
};
/**
* \brief Convert enum RIG_COMM_STATUS... to alpha string
* \param vfo RIG_COMM_STATUS_...
* \return alpha string
*/
const char *HAMLIB_API rig_strcommstatus(rig_comm_status_t status)
{
int i;
for (i = 0; comm_status_str[i].str[0] != '\0'; i++)
{
if (status == comm_status_str[i].status)
{
return comm_status_str[i].str;
}
}
return "";
}
void errmsg(int err, char *s, const char *func, const char *file, int line) void errmsg(int err, char *s, const char *func, const char *file, int line)
{ {
rig_debug(RIG_DEBUG_ERR, "%s(%s:%d): %s: %s\b", __func__, file, line, s, rig_debug(RIG_DEBUG_ERR, "%s(%s:%d): %s: %s\b", __func__, file, line, s,

Wyświetl plik

@ -921,6 +921,8 @@ void *multicast_publisher(void *arg)
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting multicast publisher\n", __FILE__, rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting multicast publisher\n", __FILE__,
__LINE__); __LINE__);
snapshot_init();
memset(&dest_addr, 0, sizeof(dest_addr)); memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.sin_family = AF_INET; dest_addr.sin_family = AF_INET;
dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr); dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr);

Wyświetl plik

@ -34,6 +34,7 @@ void network_flush(hamlib_port_t *rp);
int network_publish_rig_poll_data(RIG *rig); int network_publish_rig_poll_data(RIG *rig);
int network_publish_rig_transceive_data(RIG *rig); int network_publish_rig_transceive_data(RIG *rig);
int network_publish_rig_spectrum_data(RIG *rig, struct rig_spectrum_line *line); int network_publish_rig_spectrum_data(RIG *rig, struct rig_spectrum_line *line);
int network_publish_rig_status_change(RIG *rig, int32_t status);
HAMLIB_EXPORT(int) network_multicast_publisher_start(RIG *rig, const char *multicast_addr, int multicast_port, enum multicast_item_e items); HAMLIB_EXPORT(int) network_multicast_publisher_start(RIG *rig, const char *multicast_addr, int multicast_port, enum multicast_item_e items);
HAMLIB_EXPORT(int) network_multicast_publisher_stop(RIG *rig); HAMLIB_EXPORT(int) network_multicast_publisher_stop(RIG *rig);
HAMLIB_EXPORT(int) network_multicast_receiver_start(RIG *rig, const char *multicast_addr, int multicast_port); HAMLIB_EXPORT(int) network_multicast_receiver_start(RIG *rig, const char *multicast_addr, int multicast_port);

Wyświetl plik

@ -593,6 +593,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model)
#if defined(HAVE_PTHREAD) #if defined(HAVE_PTHREAD)
rs->rigport.asyncio = 0; rs->rigport.asyncio = 0;
#endif #endif
rig->state.comm_status = RIG_COMM_STATUS_CONNECTING;
rs->tuner_control_pathname = DEFAULT_TUNER_CONTROL_PATHNAME; rs->tuner_control_pathname = DEFAULT_TUNER_CONTROL_PATHNAME;
@ -1046,6 +1047,8 @@ int HAMLIB_API rig_open(RIG *rig)
RETURNFUNC2(-RIG_EINVAL); RETURNFUNC2(-RIG_EINVAL);
} }
rs->comm_status = RIG_COMM_STATUS_CONNECTING;
rs->rigport.fd = -1; rs->rigport.fd = -1;
if (rs->rigport.type.rig == RIG_PORT_SERIAL) if (rs->rigport.type.rig == RIG_PORT_SERIAL)
@ -1094,6 +1097,7 @@ int HAMLIB_API rig_open(RIG *rig)
rig_debug(RIG_DEBUG_VERBOSE, "%s: rs->comm_state==0?=%d\n", __func__, rig_debug(RIG_DEBUG_VERBOSE, "%s: rs->comm_state==0?=%d\n", __func__,
rs->comm_state); rs->comm_state);
rs->comm_state = 0; rs->comm_state = 0;
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
RETURNFUNC2(status); RETURNFUNC2(status);
} }
@ -1312,6 +1316,7 @@ int HAMLIB_API rig_open(RIG *rig)
if (status < 0) if (status < 0)
{ {
port_close(&rs->rigport, rs->rigport.type.rig); port_close(&rs->rigport, rs->rigport.type.rig);
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
RETURNFUNC2(status); RETURNFUNC2(status);
} }
@ -1320,11 +1325,10 @@ int HAMLIB_API rig_open(RIG *rig)
if (status < 0) if (status < 0)
{ {
port_close(&rs->rigport, rs->rigport.type.rig); port_close(&rs->rigport, rs->rigport.type.rig);
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
RETURNFUNC2(status); RETURNFUNC2(status);
} }
add_opened_rig(rig);
rs->comm_state = 1; rs->comm_state = 1;
rig_debug(RIG_DEBUG_VERBOSE, "%s: %p rs->comm_state==1?=%d\n", __func__, rig_debug(RIG_DEBUG_VERBOSE, "%s: %p rs->comm_state==1?=%d\n", __func__,
&rs->comm_state, &rs->comm_state,
@ -1377,6 +1381,7 @@ int HAMLIB_API rig_open(RIG *rig)
port_close(&rs->rigport, rs->rigport.type.rig); port_close(&rs->rigport, rs->rigport.type.rig);
memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated));
rs->comm_state = 0; rs->comm_state = 0;
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
RETURNFUNC2(status); RETURNFUNC2(status);
} }
} }
@ -1518,6 +1523,10 @@ int HAMLIB_API rig_open(RIG *rig)
// we will consider this non-fatal for now // we will consider this non-fatal for now
} }
rig->state.comm_status = RIG_COMM_STATUS_OK;
add_opened_rig(rig);
RETURNFUNC2(RIG_OK); RETURNFUNC2(RIG_OK);
} }
@ -1557,6 +1566,10 @@ int HAMLIB_API rig_close(RIG *rig)
RETURNFUNC(-RIG_EINVAL); RETURNFUNC(-RIG_EINVAL);
} }
remove_opened_rig(rig);
rig->state.comm_status = RIG_COMM_STATUS_DISCONNECTED;
morse_data_handler_stop(rig); morse_data_handler_stop(rig);
async_data_handler_stop(rig); async_data_handler_stop(rig);
rig_poll_routine_stop(rig); rig_poll_routine_stop(rig);
@ -1676,8 +1689,6 @@ int HAMLIB_API rig_close(RIG *rig)
port_close(&rs->rigport, rs->rigport.type.rig); port_close(&rs->rigport, rs->rigport.type.rig);
remove_opened_rig(rig);
// zero split so it will allow it to be set again on open for rigctld // zero split so it will allow it to be set again on open for rigctld
rig->state.cache.split = 0; rig->state.cache.split = 0;
rs->comm_state = 0; rs->comm_state = 0;

Wyświetl plik

@ -15,35 +15,21 @@
#define SPECTRUM_MODE_FIXED "FIXED" #define SPECTRUM_MODE_FIXED "FIXED"
#define SPECTRUM_MODE_CENTER "CENTER" #define SPECTRUM_MODE_CENTER "CENTER"
char snapshot_data_pid[20];
static int snapshot_serialize_rig(cJSON *rig_node, RIG *rig) static int snapshot_serialize_rig(cJSON *rig_node, RIG *rig)
{ {
cJSON *node; cJSON *node;
char buf[1024]; char buf[1024];
#if 0
// TODO: need to assign rig an ID, e.g. from command line
snprintf(buf, sizeof(buf), "%s:%s:%d", rig->caps->model_name,
rig->state.rigport.pathname, getpid());
node = cJSON_AddStringToObject(rig_node, "id", buf);
if (node == NULL)
{
goto error;
}
#else
cJSON *id_node = cJSON_CreateObject(); cJSON *id_node = cJSON_CreateObject();
cJSON_AddStringToObject(id_node, "model", rig->caps->model_name); cJSON_AddStringToObject(id_node, "model", rig->caps->model_name);
cJSON_AddStringToObject(id_node, "endpoint", rig->state.rigport.pathname); cJSON_AddStringToObject(id_node, "endpoint", rig->state.rigport.pathname);
char pid[16]; cJSON_AddStringToObject(id_node, "process", snapshot_data_pid);
sprintf(pid,"%d",getpid()); cJSON_AddStringToObject(id_node, "deviceId", rig->state.device_id);
cJSON_AddStringToObject(id_node, "process", pid);
cJSON_AddItemToObject(rig_node, "id", id_node); cJSON_AddItemToObject(rig_node, "id", id_node);
#endif
// TODO: what kind of status should this reflect? node = cJSON_AddStringToObject(rig_node, "status", rig_strcommstatus(rig->state.comm_status));
node = cJSON_AddStringToObject(rig_node, "status",
rig->state.comm_state ? "OK" : "CLOSED");
if (node == NULL) if (node == NULL)
{ {
@ -330,6 +316,11 @@ error:
RETURNFUNC2(-RIG_EINTERNAL); RETURNFUNC2(-RIG_EINTERNAL);
} }
void snapshot_init()
{
snprintf(snapshot_data_pid, sizeof(snapshot_data_pid), "%d", getpid());
}
int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig, int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig,
struct rig_spectrum_line *spectrum_line) struct rig_spectrum_line *spectrum_line)
{ {

Wyświetl plik

@ -1,6 +1,7 @@
#ifndef _SNAPSHOT_DATA_H #ifndef _SNAPSHOT_DATA_H
#define _SNAPSHOT_DATA_H #define _SNAPSHOT_DATA_H
void snapshot_init();
int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig, struct rig_spectrum_line *spectrum_line); int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig, struct rig_spectrum_line *spectrum_line);
#endif #endif

Wyświetl plik

@ -98,6 +98,7 @@
/** \brief Number of retries permitted in case of read timeouts */ /** \brief Number of retries permitted in case of read timeouts */
#define TOK_TIMEOUT_RETRY TOKEN_FRONTEND(39) #define TOK_TIMEOUT_RETRY TOKEN_FRONTEND(39)
#define TOK_POST_PTT_DELAY TOKEN_FRONTEND(40) #define TOK_POST_PTT_DELAY TOKEN_FRONTEND(40)
#define TOK_DEVICE_ID TOKEN_FRONTEND(41)
/* /*
* rig specific tokens * rig specific tokens

Wyświetl plik

@ -30,6 +30,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <getopt.h> #include <getopt.h>
#include <signal.h>
#ifdef HAVE_LIBREADLINE #ifdef HAVE_LIBREADLINE
# if defined(HAVE_READLINE_READLINE_H) # if defined(HAVE_READLINE_READLINE_H)
@ -113,11 +114,86 @@ static struct option long_options[] =
extern char rig_resp_sep; extern char rig_resp_sep;
extern powerstat_t rig_powerstat; extern powerstat_t rig_powerstat;
static RIG *my_rig; /* handle to rig (instance) */
#ifdef HAVE_SIG_ATOMIC_T
static sig_atomic_t volatile ctrl_c = 0;
#else
static int volatile ctrl_c = 0;
#endif
#define MAXCONFLEN 2048 #define MAXCONFLEN 2048
#ifdef WIN32
static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__);
switch (fdwCtrlType)
{
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
ctrl_c = 1;
return TRUE;
default:
return FALSE;
}
}
#else
static void signal_handler(int sig)
{
switch (sig)
{
case SIGINT:
case SIGTERM:
fprintf(stderr, "\nTerminating application, caught signal %d\n", sig);
// Close stdin to stop reading input
fclose(stdin);
ctrl_c = 1;
break;
default:
/* do nothing */
break;
}
}
#endif
static void handle_error(enum rig_debug_level_e lvl, const char *msg)
{
int e;
#ifdef __MINGW32__
LPVOID lpMsgBuf;
lpMsgBuf = (LPVOID)"Unknown error";
e = WSAGetLastError();
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, e,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
// Default language
(LPTSTR)&lpMsgBuf, 0, NULL))
{
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf);
LocalFree(lpMsgBuf);
}
else
{
rig_debug(lvl, "%s: Network error %d\n", msg, e);
}
#else
e = errno;
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e));
#endif
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
RIG *my_rig; /* handle to rig (instance) */
rig_model_t my_model = RIG_MODEL_DUMMY; rig_model_t my_model = RIG_MODEL_DUMMY;
int retcode; /* generic return code from functions */ int retcode; /* generic return code from functions */
@ -151,6 +227,9 @@ int main(int argc, char *argv[])
char rigstartup[1024]; char rigstartup[1024];
char vbuf[1024]; char vbuf[1024];
rig_powerstat = RIG_POWER_ON; // defaults to power on rig_powerstat = RIG_POWER_ON; // defaults to power on
#if HAVE_SIGACTION
struct sigaction act;
#endif
int err = setvbuf(stderr, vbuf, _IOFBF, sizeof(vbuf)); int err = setvbuf(stderr, vbuf, _IOFBF, sizeof(vbuf));
@ -648,6 +727,77 @@ int main(int argc, char *argv[])
#endif /* HAVE_LIBREADLINE */ #endif /* HAVE_LIBREADLINE */
int rig_opened = 1; // our rig is already open int rig_opened = 1; // our rig is already open
#if HAVE_SIGACTION
#ifdef SIGPIPE
/* Ignore SIGPIPE as we will handle it at the write()/send() calls
that will consequently fail with EPIPE. All child threads will
inherit this disposition which is what we want. */
memset(&act, 0, sizeof act);
act.sa_handler = SIG_IGN;
act.sa_flags = SA_RESTART;
if (sigaction(SIGPIPE, &act, NULL))
{
handle_error(RIG_DEBUG_ERR, "sigaction SIGPIPE");
}
#endif
#ifdef SIGINT
memset(&act, 0, sizeof act);
act.sa_handler = signal_handler;
if (sigaction(SIGINT, &act, NULL))
{
handle_error(RIG_DEBUG_ERR, "sigaction SIGINT");
}
#endif
#ifdef SIGTERM
memset(&act, 0, sizeof act);
act.sa_handler = signal_handler;
if (sigaction(SIGTERM, &act, NULL))
{
handle_error(RIG_DEBUG_ERR, "sigaction SIGTERM");
}
#endif
#elif defined (WIN32)
if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
{
handle_error(RIG_DEBUG_ERR, "SetConsoleCtrlHandler");
}
#elif HAVE_SIGNAL
#ifdef SIGPIPE
if (SIG_ERR == signal(SIGPIPE, SIG_IGN))
{
handle_error(RIG_DEBUG_ERR, "signal SIGPIPE");
}
#endif
#ifdef SIGINT
if (SIG_ERR == signal(SIGINT, signal_handler))
{
handle_error(RIG_DEBUG_ERR, "signal SIGINT");
}
#endif
#ifdef SIGTERM
if (SIG_ERR == signal(SIGTERM, signal_handler))
{
handle_error(RIG_DEBUG_ERR, "signal SIGTERM");
}
#endif
#endif
do do
{ {
if (!rig_opened) if (!rig_opened)
@ -695,7 +845,7 @@ int main(int argc, char *argv[])
while (retry-- > 0 && retcode != RIG_OK); while (retry-- > 0 && retcode != RIG_OK);
} }
} }
while (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode)); while (!ctrl_c && (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode)));
if (interactive && prompt) if (interactive && prompt)
{ {

Wyświetl plik

@ -136,9 +136,9 @@ static volatile int rig_opened = 0;
static int verbose; static int verbose;
#ifdef HAVE_SIG_ATOMIC_T #ifdef HAVE_SIG_ATOMIC_T
static sig_atomic_t volatile ctrl_c; static sig_atomic_t volatile ctrl_c = 0;
#else #else
static int volatile ctrl_c; static int volatile ctrl_c = 0;
#endif #endif
const char *portno = "4532"; const char *portno = "4532";
@ -196,6 +196,10 @@ static void signal_handler(int sig)
switch (sig) switch (sig)
{ {
case SIGINT: case SIGINT:
case SIGTERM:
fprintf(stderr, "\nTerminating application, caught signal %d\n", sig);
// Close stdin to stop reading input
fclose(stdin);
ctrl_c = 1; ctrl_c = 1;
break; break;
@ -949,6 +953,16 @@ int main(int argc, char *argv[])
handle_error(RIG_DEBUG_ERR, "sigaction SIGINT"); handle_error(RIG_DEBUG_ERR, "sigaction SIGINT");
} }
#endif
#ifdef SIGTERM
memset(&act, 0, sizeof act);
act.sa_handler = signal_handler;
if (sigaction(SIGTERM, &act, NULL))
{
handle_error(RIG_DEBUG_ERR, "sigaction SIGTERM");
}
#endif #endif
#elif defined (WIN32) #elif defined (WIN32)
@ -973,6 +987,14 @@ int main(int argc, char *argv[])
handle_error(RIG_DEBUG_ERR, "signal SIGINT"); handle_error(RIG_DEBUG_ERR, "signal SIGINT");
} }
#endif
#ifdef SIGTERM
if (SIG_ERR == signal(SIGTERM, signal_handler))
{
handle_error(RIG_DEBUG_ERR, "signal SIGTERM");
}
#endif #endif
#endif #endif