aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c100
-rw-r--r--src/main.h4
-rw-r--r--src/misc.c57
-rw-r--r--src/misc.h18
-rw-r--r--src/modem.c108
-rw-r--r--src/modem.h4
6 files changed, 214 insertions, 77 deletions
diff --git a/src/main.c b/src/main.c
index 5831c1a..26bd354 100644
--- a/src/main.c
+++ b/src/main.c
@@ -76,42 +76,92 @@ struct prog_params parse_args(int argc, char* argv[])
void handle_connection(int _socket, struct sockaddr_in _addr, int argc, char* argv[])
{
pid_t pid = fork();
- if( pid > 0 )
- {
+ if( pid != 0 ) {
close(_socket);
return;
}
- else if ( pid < 0 )
+
+ int in[2];
+ int out[2];
+
+ //1: write, 0: read
+ if(pipe(in) == -1)
+ return;
+
+ if(pipe(out) == -1)
+ return;
+
+ pid = fork_run(in[0], out[1], out[1], argc, argv);
+ if (pid < 0)
return;
- //This is here for later
- //This should handle a premature closed socket from client to not create unused processes
- pid = fork();
- if(pid > 0)
- {
- close(_socket);
- //Instead of waiting for pid, check if process is running AND socket is still open
- wait(0);
- exit(0);
- }
- else if(pid < 0)
- exit(1);
+ /*pid = fork();
- //Redirect STDIO to socket
- dup2(_socket, STDIN_FILENO);
- dup2(_socket, STDOUT_FILENO);
- dup2(_socket, STDERR_FILENO);
+ if(pid == 0) {//child
+ close (in[1]);
+ close (out[0]);
+
+ dup2 (in[0], STDIN_FILENO);
+ dup2 (out[1], STDOUT_FILENO);
+ dup2 (out[1], STDERR_FILENO);
- char* arv[argc + 1];
+ char* arv[argc + 1];
- for(int i = 0; i < argc; i++)
- arv[i] = argv[i];
+ for(int i = 0; i < argc; i++)
+ arv[i] = argv[i];
- arv[argc] = NULL;
+ arv[argc] = NULL;
- execv(argv[0], arv);
+ execv(argv[0], arv);
+
+ printf("EXEC ERROR %i: %s\r\n", errno, strerror(errno));
+ exit(1);
+ }
+ else if (pid < 0) {
+ return;
+ }*/
+
+ const int buffsize = 128;
+ char buff[ buffsize ];
+
+ //close unused pipes
+ close (in[0]);
+ close (out[1]);
+
+ //setup poll to listen for input
+ struct pollfd fds[2];
+ fds[0].fd = out[0];
+ fds[0].events = POLLIN;
+ fds[1].fd = _socket;
+ fds[1].events = POLLIN;
+
+ printf("Forked with PID %i\n", pid);
+
+ while(1)
+ {
+ int ret = poll (fds, 2, 100);
+ if ( fds[0].revents & POLLIN ) {
+ const int cnt = read (out[0], buff, buffsize);
+ if(try_write(_socket, buff, cnt, 100)) {
+ printf("Consecutive write errors while writing to socket.\n");
+ break;
+ }
+ }
+ if ( fds[1].revents & POLLIN ) {
+ const int cnt = read (_socket, buff, buffsize);
+ if(try_write(in[1], buff, cnt, 100)) {
+ printf("Consecutive write errors while writing to STDIN.\n");
+ break;
+ }
+ }
+
+ //TODO check socket active check. though somewhat handled by try_write()
+
+ if(kill(pid,0)) //Check if child is still alive, if not return.
+ break;
+ }
- PRINT_ERROR("EXEC failed");
+ printf("Connection closed.\n");
close(_socket);
exit(1);
diff --git a/src/main.h b/src/main.h
index a599ae2..7a6153e 100644
--- a/src/main.h
+++ b/src/main.h
@@ -5,6 +5,8 @@
* License: MIT
*/
+#pragma once
+
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
@@ -18,6 +20,8 @@
#include <signal.h>
#include <arpa/inet.h>
+#include "misc.h"
+
#define _DEF_MAX_BACKLOG 20
#define _DEF_PORT 23
#define _DEF_IP 0
diff --git a/src/misc.c b/src/misc.c
new file mode 100644
index 0000000..c2803a6
--- /dev/null
+++ b/src/misc.c
@@ -0,0 +1,57 @@
+/*
+ * misc.c
+ * (c) 2019, Jonas Gunz, jonasgunz.de
+ * <Description>
+ * <License>
+*/
+
+#include "misc.h"
+
+pid_t fork_run(int _stdin, int _stdout, int _stderr, int argc, char* argv[])
+{
+ pid_t pid = fork();
+
+ if(pid == 0) {//child
+ dup2 (_stdin, STDIN_FILENO);
+ dup2 (_stdout, STDOUT_FILENO);
+ dup2 (_stderr, STDERR_FILENO);
+
+ char* arv[argc + 1];
+
+ for(int i = 0; i < argc; i++)
+ arv[i] = argv[i];
+
+ arv[argc] = NULL;
+
+ execv(argv[0], arv);
+
+ printf("EXEC ERROR %i: %s\r\n", errno, strerror(errno));
+ exit(1);
+ }
+ else {
+ return pid;
+ }
+}
+
+
+int try_write(int _fd, char *_buff, int _size, int _retry)
+{
+ if( _size <= 0)
+ return 0;
+
+ int written = 0;
+ int cntr = 0;
+
+ while (written != _size) {
+ int ret = write ( _fd, _buff + written, _size - written);
+
+ if(ret < 0)
+ return 1;
+ else
+ written += ret;
+
+ if(++cntr > _retry)
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/misc.h b/src/misc.h
new file mode 100644
index 0000000..49a3384
--- /dev/null
+++ b/src/misc.h
@@ -0,0 +1,18 @@
+/*
+ * misc.h
+ * (c) 2019, Jonas Gunz, jonasgunz.de
+ * <Description>
+ * <License>
+*/
+
+#pragma once
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+int try_write(int _fd, char *_buff, int _size, int _retry);
+
+pid_t fork_run(int _stdin, int _stdout, int _stderr, int argc, char* argv[]);
diff --git a/src/modem.c b/src/modem.c
index a5644a7..0776bed 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -24,7 +24,7 @@ int modem_accept_wait(int fd)
modem_command(fd, _AT_MUTE, 1000);
modem_command(fd, _AT_RESET_ON_DTR, 1000);
-#ifdef _MODEM_WAIT_RING //DONT wait for ring
+#ifdef _MODEM_WAIT_RING
while ( 1 ) { //wait for RING
ret = poll(&fds, 1, 2000); //poll in 2s interval
usleep(5000);
@@ -44,7 +44,7 @@ int modem_accept_wait(int fd)
cnt = 0;
while(1)
{
- ret = poll(&fds, 1, 60000); //Connection timeout 1 minute
+ ret = poll(&fds, 1, timeout); //Connection timeout 1 minute
usleep(5000); //Wait for data
if(!ret)
break;
@@ -121,9 +121,9 @@ int modem_run(int fd, int argc, char* argv[])
if(pipe(out) == -1)
return 1;
- pid_t pid = fork();
+ pid_t pid = fork_run(in[0], out[1], out[1], argc, argv);//fork();
- if(pid == 0) {//child
+/* if(pid == 0) {//child
close (in[1]);
close (out[0]);
@@ -142,60 +142,66 @@ int modem_run(int fd, int argc, char* argv[])
printf("EXEC ERROR %i: %s\r\n", errno, strerror(errno));
exit(1);
- }
- else if (pid < 0) {//error
+ }*/
+ if (pid < 0) {//error
return 2;
}
- else {//parent
- int buffsize = 128;
- char buff[ buffsize ];
-
- close (in[0]);
- close (out[1]);
-
- //setup poll to listen for input
- struct pollfd fds[2];
- fds[0].fd = out[0];
- fds[0].events = POLLIN;
- fds[1].fd = fd;
- fds[1].events = POLLIN;
-
- printf("Forked with PID %i\n", pid);
-
- while(1)
- {
- int ret = poll (fds, 2, 100);
- usleep(5000); //Wait for data to fully come in, helps prevent truncation of status returns which helps with parsing
- if ( fds[0].revents & POLLIN ) {
- int cnt = read (out[0], buff, buffsize);
- if(cnt) {
- //replace +++ to not trigger modem command mode
- char *str = strstr(buff, "+++");
- if(str)
- str[1] = '*';
-
- write(fd, buff, cnt);
+
+ int buffsize = 128;
+ char buff[ buffsize ];
+
+ close (in[0]);
+ close (out[1]);
+
+ //setup poll to listen for input
+ struct pollfd fds[2];
+ fds[0].fd = out[0];
+ fds[0].events = POLLIN;
+ fds[1].fd = fd;
+ fds[1].events = POLLIN;
+
+ printf("Forked with PID %i\n", pid);
+
+ while(1)
+ {
+ int ret = poll (fds, 2, 100);
+ usleep(5000); //Wait for data to fully come in, helps prevent truncation of status returns which helps with parsing
+ if ( fds[0].revents & POLLIN ) {
+ int cnt = read (out[0], buff, buffsize);
+ if(cnt) {
+ //replace +++ to not trigger modem command mode
+ char *str = strstr(buff, "+++");
+ if(str)
+ str[1] = '*';
+
+ if(try_write(fd, buff, cnt, 100)) {
+ printf("Consecutive write errors while writing to serial device.\n");
+ break;
}
}
- if ( fds[1].revents & POLLIN ) {
- int cnt = read (fd, buff, buffsize);
- if(cnt) {
- //search for modem error message
- char *str = strstr(buff, "NO CARRIER");
- if(str){ //Exit if message found
- kill(pid,SIGTERM);
- break;
- }
- write(in[1], buff, cnt);
+ }
+ if ( fds[1].revents & POLLIN ) {
+ int cnt = read (fd, buff, buffsize);
+ if(cnt) {
+ //search for modem error message
+ char *str = strstr(buff, "NO CARRIER");
+ if(str){ //Exit if message found
+ kill(pid,SIGTERM);
+ break;
}
- }
- if(kill(pid,0)) //Check if child is still alive, if not return.
- break;
+ if(try_write(in[1], buff, cnt, 100)) {
+ printf("Consecutive write errors while writing to STDIN.\n");
+ break;
+ }
+ }
}
- printf("Connection closed.\n");
- close(fd); //Auto closes connection
- return 0;
+ if(kill(pid,0)) //Check if child is still alive, if not return.
+ break;
}
+
+ printf("Connection closed.\n");
+ close(fd); //Auto closes connection
+ return 0;
}
diff --git a/src/modem.h b/src/modem.h
index 246018d..e5aea4e 100644
--- a/src/modem.h
+++ b/src/modem.h
@@ -11,10 +11,12 @@
#include <signal.h>
#include <errno.h>
+#include "misc.h"
+
#define _AT "AT\r\n"
#define _AT_ANSWER "ATA\r\n"
#define _AT_ECHO_OFF "ATE0\r\n"
-#define _AT_ECHO_ON "ATE1\r\n\”"
+#define _AT_ECHO_ON "ATE1\r\n"
#define _AT_HANGUP "ATH\r\n"
#define _AT_CMD_MODE "+++\r\n"
#define _AT_MUTE "ATM0\r\n"