From a882dbfaa2a878f9fb7c11e361e76e192ef27951 Mon Sep 17 00:00:00 2001 From: Jonas Gunz Date: Fri, 12 Jul 2019 00:54:27 +0200 Subject: Some refactoring --- src/main.c | 100 +++++++++++++++++++++++++++++++++++++++++-------------- src/main.h | 4 +++ src/misc.c | 57 ++++++++++++++++++++++++++++++++ src/misc.h | 18 ++++++++++ src/modem.c | 108 ++++++++++++++++++++++++++++++++---------------------------- src/modem.h | 4 ++- 6 files changed, 214 insertions(+), 77 deletions(-) create mode 100644 src/misc.c create mode 100644 src/misc.h 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 #include #include @@ -18,6 +20,8 @@ #include #include +#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 + * + * +*/ + +#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 + * + * +*/ + +#pragma once + +#include +#include +#include +#include +#include + +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 #include +#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" -- cgit v1.2.3