aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-07-16 17:34:05 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-07-16 17:34:05 +0200
commitcc9d637652875020e1a26874f15ff362938aa9e0 (patch)
treec620907b09b8926a2ea8888856b5cc154be0dc87
parent7cffb5df19cefd6169da43864737551d393abd91 (diff)
downloadcli-cc9d637652875020e1a26874f15ff362938aa9e0.zip
cli-cc9d637652875020e1a26874f15ff362938aa9e0.tar.bz2
Signal handling, code improvements.
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/cli.h15
-rw-r--r--src/main.c244
-rw-r--r--src/signal.c91
-rw-r--r--src/socket.c90
5 files changed, 317 insertions, 125 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f99ceed..61aeb77 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,6 +3,8 @@ add_subdirectory(error)
set(
SRC_FILES ${SRC_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/main.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/signal.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/socket.c
)
set(SRC_FILES ${SRC_FILES} PARENT_SCOPE)
diff --git a/src/cli.h b/src/cli.h
new file mode 100644
index 0000000..ca42f76
--- /dev/null
+++ b/src/cli.h
@@ -0,0 +1,15 @@
+#ifndef _JH_CLI_CLI_H_
+#define _JH_CLI_CLI_H_
+
+#include <stdio.h>
+
+int JH_cli_open_socket
+(
+ FILE * s [const restrict static 1],
+ const char socket_name [const restrict static 1]
+);
+
+int JH_cli_is_running (void);
+int JH_cli_set_signal_handlers (void);
+
+#endif
diff --git a/src/main.c b/src/main.c
index f8902b7..e80d1d8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,3 @@
-#include <sys/socket.h>
-#include <sys/un.h>
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -11,6 +8,8 @@
#include "pervasive.h"
+#include "./cli.h"
+
static void print_help (const char runnable [const restrict static 1])
{
printf
@@ -29,160 +28,139 @@ static void print_help (const char runnable [const restrict static 1])
);
}
-static int open_socket
+static int send_to_network
(
- FILE * s [const restrict static 1],
- const char socket_name [const restrict static 1]
+ FILE socket [const restrict static 1]
)
{
- int fd;
- struct sockaddr_un addr;
-
- const int old_errno = errno;
-
- errno = 0;
-
- if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- {
- JH_FATAL
- (
- stderr,
- "Unable to create socket: %s.",
- strerror(errno)
- );
-
- errno = old_errno;
-
- return -1;
- }
-
- errno = old_errno;
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path)-1);
-
- errno = 0;
-
- if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
- {
- JH_FATAL
- (
- stderr,
- "Unable to connect to address: %s.",
- strerror(errno)
- );
-
- errno = old_errno;
-
- close(fd);
-
- return -1;
- }
-
- errno = 0;
+ int data;
- *s = fdopen(fd, "w+");
-
- if (*s == (FILE *) NULL)
+ while (JH_cli_is_running())
{
- JH_FATAL
- (
- stderr,
- "Unable to open socket as a file: %s.",
- strerror(errno)
- );
+ data = fgetc(stdin);
- errno = old_errno;
+ if (data == EOF)
+ {
+ return -1;
+ }
+ else
+ {
+ if (fputc(data, socket) == EOF)
+ {
+ JH_S_FATAL(stderr, "Unable to write to socket.");
- close(fd);
+ return -2;
+ }
+ }
- return -1;
+ if (data == '\n')
+ {
+ return 0;
+ }
}
- errno = old_errno;
-
- return 0;
+ return -1;
}
-static void gateway
+static int receive_from_network
(
FILE socket [const restrict static 1]
)
{
- int is_sending;
- int data, data_prev, is_last_message;
+ int data;
+ int match_index;
- is_sending = 1;
+ match_index = 0;
- for (;;)
+ while (JH_cli_is_running())
{
- if (is_sending)
+ data = fgetc(socket);
+
+ if (data == EOF)
{
- data = fgetc(stdin);
+ JH_S_FATAL(stderr, "Unable to read from socket.");
- if (data == EOF)
- {
- return;
- }
- else
+ return -1;
+ }
+ else
+ {
+ if (fputc(data, stdout) == EOF)
{
- if (fputc(data, socket) == EOF)
- {
- JH_S_FATAL(stderr, "Unable to write to socket.");
-
- return;
- }
- }
+ /* ... seems like it wouldn't work. */
+ JH_S_FATAL(stderr, "Unable to write to stdout.");
- if (data == '\n')
- {
- is_sending = 0;
- data = 0;
- is_last_message = 0;
+ return -2;
}
}
- else
+
+ switch (match_index)
{
- data_prev = data;
- data = fgetc(socket);
+ case -1:
+ if (data == '\n')
+ {
+ match_index = 0;
+ }
+ break;
- if (data == EOF)
- {
- JH_S_FATAL(stderr, "Unable to read from socket.");
+ case 0:
+ if (data == '!')
+ {
+ match_index = 1;
+ }
+ else if (data == '\n')
+ {
+ match_index = 0;
+ }
+ else
+ {
+ match_index = -1;
+ }
+ break;
- return;
- }
- else
- {
- if (fputc(data, stdout) == EOF)
+ case 1:
+ if ((data == 'P') || (data == 'N'))
+ {
+ match_index = 2;
+ }
+ else if (data == '\n')
{
- /* ... seems like it wouldn't work. */
- JH_S_FATAL(stderr, "Unable to write to stdout.");
+ match_index = 0;
+ }
+ else
+ {
+ match_index = -1;
+ }
+ break;
- return;
+ case 2:
+ if (data == ' ')
+ {
+ match_index = 3;
}
- }
+ else if (data == '\n')
+ {
+ match_index = 0;
+ }
+ else
+ {
+ match_index = -1;
+ }
+ break;
- is_last_message =
- (
- is_last_message
- || (
- (data_prev == '!')
- && (
- (data == 'P')
- || (data == 'N')
- )
- // TODO: check for the ' '.
- )
- );
-
- if (is_last_message && (data == '\n'))
- {
- is_sending = 1;
- }
+ case 3:
+ if (data == '\n')
+ {
+ return 0;
+ }
+ else
+ {
+ match_index = -1;
+ }
+ break;
}
}
+
+ return -1;
}
int main (int const argc, const char * argv [const static argc])
@@ -196,12 +174,28 @@ int main (int const argc, const char * argv [const static argc])
return -1;
}
- if (open_socket(&socket, argv[1]) < 0)
+ if (JH_cli_set_signal_handlers() < 0)
{
return -1;
}
- gateway(socket);
+ if (JH_cli_open_socket(&socket, argv[1]) < 0)
+ {
+ return -1;
+ }
+
+ while (JH_cli_is_running())
+ {
+ if (send_to_network(socket) < 0)
+ {
+ break;
+ }
+
+ if (receive_from_network(socket) < 0)
+ {
+ break;
+ }
+ }
fclose(socket);
diff --git a/src/signal.c b/src/signal.c
new file mode 100644
index 0000000..eb9584e
--- /dev/null
+++ b/src/signal.c
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "error/error.h"
+
+#include "pervasive.h"
+
+#include "./cli.h"
+
+static volatile char JH_GATEWAY_IS_RUNNING = (char) 1;
+
+static void request_termination (int const signo)
+{
+ if ((signo == SIGINT) || (signo == SIGTERM))
+ {
+ JH_GATEWAY_IS_RUNNING = (char) 0;
+ }
+}
+
+int JH_cli_is_running (void)
+{
+ return (int) JH_GATEWAY_IS_RUNNING;
+}
+
+int JH_cli_set_signal_handlers (void)
+{
+ struct sigaction act;
+ const int old_errno = errno;
+
+ memset((void *) &act, 0, sizeof(struct sigaction));
+
+ act.sa_handler = request_termination;
+
+ errno = 0;
+
+ if (sigaction(SIGHUP, &act, (struct sigaction * restrict) NULL) == -1)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Could not set sigaction for SIGHUP (errno: %d): %s",
+ errno,
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ return -1;
+ }
+
+ errno = 0;
+
+ if (sigaction(SIGINT, &act, (struct sigaction * restrict) NULL) == -1)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Could not set sigaction for SIGINT (errno: %d): %s",
+ errno,
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ return -1;
+ }
+
+ act.sa_handler = SIG_IGN;
+
+ if (sigaction(SIGPIPE, &act, (struct sigaction * restrict) NULL) == -1)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Could not set sigaction for SIGPIPE (errno: %d): %s",
+ errno,
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ return -1;
+ }
+
+ errno = old_errno;
+
+ return 0;
+}
diff --git a/src/socket.c b/src/socket.c
new file mode 100644
index 0000000..343e1a3
--- /dev/null
+++ b/src/socket.c
@@ -0,0 +1,90 @@
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "error/error.h"
+
+#include "pervasive.h"
+
+#include "./cli.h"
+
+int JH_cli_open_socket
+(
+ FILE * s [const restrict static 1],
+ const char socket_name [const restrict static 1]
+)
+{
+ int fd;
+ struct sockaddr_un addr;
+
+ const int old_errno = errno;
+
+ errno = 0;
+
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Unable to create socket: %s.",
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ return -1;
+ }
+
+ errno = old_errno;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path)-1);
+
+ errno = 0;
+
+ if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Unable to connect to address: %s.",
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ close(fd);
+
+ return -1;
+ }
+
+ errno = 0;
+
+ *s = fdopen(fd, "w+");
+
+ if (*s == (FILE *) NULL)
+ {
+ JH_FATAL
+ (
+ stderr,
+ "Unable to open socket as a file: %s.",
+ strerror(errno)
+ );
+
+ errno = old_errno;
+
+ close(fd);
+
+ return -1;
+ }
+
+ errno = old_errno;
+
+ return 0;
+}