fix bug in socket.c

This commit is contained in:
eddyem 2017-04-17 17:04:27 +03:00
parent 695396383d
commit 99010c6f51
7 changed files with 99 additions and 27 deletions

View File

@ -24,7 +24,6 @@
#define __CMDLNOPTS_H__ #define __CMDLNOPTS_H__
#include "parseargs.h" #include "parseargs.h"
#include "term.h"
/* /*
* here are some typedef's for global data * here are some typedef's for global data

View File

@ -32,13 +32,12 @@
#include "usefull_macros.h" #include "usefull_macros.h"
#include "imfunctions.h" #include "imfunctions.h"
#include "term.h"
#include "socket.h" #include "socket.h"
/** /**
* All image-storing functions modify ctime of saved files to be the time of * All image-storing functions modify ctime of saved files to be the time of
* exposition start! * exposition start!
*/ *
void modifytimestamp(char *filename, time_t tv_sec){ void modifytimestamp(char *filename, time_t tv_sec){
if(!filename) return; if(!filename) return;
struct timespec times[2]; struct timespec times[2];
@ -46,7 +45,7 @@ void modifytimestamp(char *filename, time_t tv_sec){
times[0].tv_nsec = UTIME_OMIT; times[0].tv_nsec = UTIME_OMIT;
times[1].tv_sec = tv_sec; // change mtime times[1].tv_sec = tv_sec; // change mtime
if(utimensat(AT_FDCWD, filename, times, 0)) WARN(_("Can't change timestamp for %s"), filename); if(utimensat(AT_FDCWD, filename, times, 0)) WARN(_("Can't change timestamp for %s"), filename);
} }*/
/** /**
* Test if `name` is a fits file with 2D image * Test if `name` is a fits file with 2D image
@ -133,15 +132,22 @@ static void gotodir(char *relpath){ // create directory structure
* @return 1 if it's dark * @return 1 if it's dark
*/ */
int fits_is_dark(char *name){ int fits_is_dark(char *name){
int ret = 0;
mmapbuf *buf = My_mmap(name); mmapbuf *buf = My_mmap(name);
if(!buf) return 0; if(!buf) return 0;
char *key = memmem(buf->data, buf->len, "IMAGETYP", 8); char *key = memmem(buf->data, buf->len, "IMAGETYP", 8);
if(!key) return 0; if(!key) goto light;
if(buf->len - (key - buf->data) < 30) return 0; if(buf->len - (key - buf->data) < 30) goto light;
key += 9; key += 9;
char *dark = memmem(key, 20, "'dark", 5); char *dark = memmem(key, 20, "'dark", 5);
if(dark) return 1; if(dark){
return 0; DBG("DARK!");
ret = 1;
}
light:
My_munmap(buf);
DBG("LIGHT");
return ret;
} }
#define TRYFITS(f, ...) \ #define TRYFITS(f, ...) \
@ -244,7 +250,7 @@ ret:
status = 0; status = 0;
if(ofptr){ if(ofptr){
fits_close_file(ofptr, &status); fits_close_file(ofptr, &status);
modifytimestamp(newname, (time_t)modtm); //modifytimestamp(newname, (time_t)modtm);
} }
// as cfitsio removes old file instead of trunkate it, we need to refresh inotify every time! // as cfitsio removes old file instead of trunkate it, we need to refresh inotify every time!
if(chdir(oldwd)){ // return back to BD root directory if(chdir(oldwd)){ // return back to BD root directory

View File

@ -253,11 +253,9 @@ static void client_(char *FITSpath, int infd, int sock){
ssize_t len = read(infd, &buf, sizeof(buf)); ssize_t len = read(infd, &buf, sizeof(buf));
if (len == -1 && errno != EAGAIN){ if (len == -1 && errno != EAGAIN){
ERR("read"); ERR("read");
return;
}else{ }else{
DBG("file changed"); DBG("file changed");
usleep(100000); // wait a little for file changes usleep(100000); // wait a little for file changes
fds.fd = watch_fits(FITSpath);
if(dtime() - lastTstorage > minstoragetime){ if(dtime() - lastTstorage > minstoragetime){
DBG("lastT: %.2g, now: %.2g", lastTstorage, dtime()); DBG("lastT: %.2g, now: %.2g", lastTstorage, dtime());
lastTstorage = dtime(); lastTstorage = dtime();
@ -265,6 +263,7 @@ static void client_(char *FITSpath, int infd, int sock){
}else if(fits_is_dark(FITSpath)) // save darks nevertheless time }else if(fits_is_dark(FITSpath)) // save darks nevertheless time
store_fits(FITSpath, last_good_msrment); store_fits(FITSpath, last_good_msrment);
} }
fds.fd = watch_fits(FITSpath);
} }
} }
if(!waittoread(sock)) continue; if(!waittoread(sock)) continue;
@ -285,7 +284,7 @@ static void client_(char *FITSpath, int infd, int sock){
} }
rlc(offset); rlc(offset);
recvBuff[offset] = 0; recvBuff[offset] = 0;
DBG("read %zd bytes", offset); //DBG("read %zd bytes", offset);
parse_data(recvBuff, &last_good_msrment); parse_data(recvBuff, &last_good_msrment);
} }
} }
@ -305,7 +304,7 @@ void daemonize(glob_pars *G){
// run fork before socket opening to prevent daemon's death if there's no network // run fork before socket opening to prevent daemon's death if there's no network
#ifndef EBUG #ifndef EBUG
green("Daemonize\n"); green("Daemonize\n");
if(daemon(1, 0)){ if(daemon(1, 0))
ERR("daemon()"); ERR("daemon()");
while(1){ // guard for dead processes while(1){ // guard for dead processes
pid_t childpid = fork(); pid_t childpid = fork();
@ -318,7 +317,7 @@ void daemonize(glob_pars *G){
prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies
break; // go out to normal functional break; // go out to normal functional
} }
}} }
#endif #endif
int sock = -1; int sock = -1;
struct addrinfo hints, *res, *p; struct addrinfo hints, *res, *p;

8
main.c
View File

@ -37,7 +37,13 @@ int main(int argc, char **argv){
signal(SIGQUIT, signals); // ctrl+\ - quit signal(SIGQUIT, signals); // ctrl+\ - quit
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
glob_pars *G = parse_args(argc, argv); glob_pars *G = parse_args(argc, argv);
if(G->rest_pars_num)
openlogfile(G->rest_pars[0]);
#ifndef EBUG
if(daemon(1, 0)){
ERR("daemon()");
}
#endif
try_connect(G->device); try_connect(G->device);
if(check_sensor()) signals(15); // there's not Boltwood sensor connected if(check_sensor()) signals(15); // there's not Boltwood sensor connected
if(G->terminal) run_terminal(); if(G->terminal) run_terminal();

View File

@ -31,6 +31,7 @@
#include <unistd.h> // daemon #include <unistd.h> // daemon
#include <sys/wait.h> // wait #include <sys/wait.h> // wait
#include <sys/prctl.h> //prctl #include <sys/prctl.h> //prctl
#include <sys/syscall.h> // syscall
#define BUFLEN (10240) #define BUFLEN (10240)
#define BUFLEN10 (1048576) #define BUFLEN10 (1048576)
@ -142,6 +143,7 @@ char* stringscan(char *str, char *needle){
} }
void *handle_socket(void *asock){ void *handle_socket(void *asock){
putlog("handle_socket(): getpid: %d, pthread_self: %lu, tid: %lu",getpid(), pthread_self(), syscall(SYS_gettid));
FNAME(); FNAME();
int sock = *((int*)asock); int sock = *((int*)asock);
int webquery = 0; // whether query is web or regular int webquery = 0; // whether query is web or regular
@ -161,14 +163,23 @@ void *handle_socket(void *asock){
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
break; // end of transmission break; // end of transmission
} }
}else{ // some error
putlog("can't send data, some error occured");
pthread_mutex_unlock(&mutex);
break;
} }
} }
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
continue; continue;
} }
if(!(rd = read(sock, buff, BUFLEN-1))) continue; if(!(rd = read(sock, buff, BUFLEN-1))){
putlog("socket closed. Exit");
break;
}
putlog("client send %zd bytes", rd);
DBG("Got %zd bytes", rd); DBG("Got %zd bytes", rd);
if(rd < 0){ // error or disconnect if(rd < 0){ // error
putlog("some error occured");
DBG("Nothing to read from fd %d (ret: %zd)", sock, rd); DBG("Nothing to read from fd %d (ret: %zd)", sock, rd);
break; break;
} }
@ -187,13 +198,16 @@ void *handle_socket(void *asock){
} }
close(sock); close(sock);
//DBG("closed"); //DBG("closed");
putlog("socket closed, exit");
pthread_exit(NULL); pthread_exit(NULL);
return NULL; return NULL;
} }
void *server(void *asock){ void *server(void *asock){
putlog("server(): getpid: %d, pthread_self: %lu, tid: %lu",getpid(), pthread_self(), syscall(SYS_gettid));
int sock = *((int*)asock); int sock = *((int*)asock);
if(listen(sock, BACKLOG) == -1){ if(listen(sock, BACKLOG) == -1){
putlog("listen() failed");
WARN("listen"); WARN("listen");
return NULL; return NULL;
} }
@ -202,35 +216,48 @@ void *server(void *asock){
struct sockaddr_in their_addr; struct sockaddr_in their_addr;
int newsock; int newsock;
if(!waittoread(sock)) continue; if(!waittoread(sock)) continue;
red("Got connection\n");
newsock = accept(sock, (struct sockaddr*)&their_addr, &size); newsock = accept(sock, (struct sockaddr*)&their_addr, &size);
if(newsock <= 0){ if(newsock <= 0){
putlog("accept() failed");
WARN("accept()"); WARN("accept()");
continue; continue;
} }
struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&their_addr;
struct in_addr ipAddr = pV4Addr->sin_addr;
char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
putlog("get connection from %s", str);
red("Got connection from %s\n", str);
pthread_t handler_thread; pthread_t handler_thread;
if(pthread_create(&handler_thread, NULL, handle_socket, (void*) &newsock)) if(pthread_create(&handler_thread, NULL, handle_socket, (void*) &newsock)){
putlog("server(): pthread_create() failed");
WARN("pthread_create()"); WARN("pthread_create()");
else{ }else{
DBG("Thread created, detouch"); DBG("Thread created, detouch");
pthread_detach(handler_thread); // don't care about thread state pthread_detach(handler_thread); // don't care about thread state
} }
} }
putlog("server(): UNREACHABLE CODE REACHED!");
} }
static void daemon_(int sock){ static void daemon_(int sock){
FNAME(); FNAME();
if(sock < 0) return; if(sock < 0) return;
pthread_t sock_thread; pthread_t sock_thread;
if(pthread_create(&sock_thread, NULL, server, (void*) &sock)) if(pthread_create(&sock_thread, NULL, server, (void*) &sock)){
putlog("daemon_(): pthread_create() failed");
ERR("pthread_create()"); ERR("pthread_create()");
}
do{ do{
if(pthread_kill(sock_thread, 0) == ESRCH){ // died if(pthread_kill(sock_thread, 0) == ESRCH){ // died
WARNX("Sockets thread died"); WARNX("Sockets thread died");
putlog("Sockets thread died");
pthread_join(sock_thread, NULL); pthread_join(sock_thread, NULL);
if(pthread_create(&sock_thread, NULL, server, (void*) &sock)) if(pthread_create(&sock_thread, NULL, server, (void*) &sock)){
putlog("daemon_(): new pthread_create() failed");
ERR("pthread_create()"); ERR("pthread_create()");
} }
}
// get data // get data
boltwood_data b; boltwood_data b;
if(poll_sensor(&b) == 1){ if(poll_sensor(&b) == 1){
@ -241,6 +268,7 @@ static void daemon_(int sock){
} }
usleep(1000); // sleep a little or thread's won't be able to lock mutex usleep(1000); // sleep a little or thread's won't be able to lock mutex
}while(1); }while(1);
putlog("daemon_(): UNREACHABLE CODE REACHED!");
} }
/** /**
@ -249,15 +277,13 @@ static void daemon_(int sock){
void daemonize(char *port){ void daemonize(char *port){
FNAME(); FNAME();
#ifndef EBUG #ifndef EBUG
green("Daemonize\n");
if(daemon(1, 0)){
ERR("daemon()");
}
while(1){ // guard for dead processes while(1){ // guard for dead processes
pid_t childpid = fork(); pid_t childpid = fork();
if(childpid){ if(childpid){
putlog("create child with PID %d\n", childpid);
DBG("Created child with PID %d\n", childpid); DBG("Created child with PID %d\n", childpid);
wait(NULL); wait(NULL);
putlog("child %d died\n", childpid);
WARNX("Child %d died\n", childpid); WARNX("Child %d died\n", childpid);
sleep(1); sleep(1);
}else{ }else{
@ -297,12 +323,14 @@ void daemonize(char *port){
break; // if we get here, we have a successfull connection break; // if we get here, we have a successfull connection
} }
if(p == NULL){ if(p == NULL){
putlog("failed to bind socket");
// looped off the end of the list with no successful bind // looped off the end of the list with no successful bind
ERRX("failed to bind socket"); ERRX("failed to bind socket");
} }
freeaddrinfo(res); freeaddrinfo(res);
daemon_(sock); daemon_(sock);
close(sock); close(sock);
putlog("socket closed, exit");
signals(0); signals(0);
} }

View File

@ -20,6 +20,7 @@
*/ */
#include "usefull_macros.h" #include "usefull_macros.h"
#include <time.h>
/** /**
* function for different purposes that need to know time intervals * function for different purposes that need to know time intervals
@ -386,3 +387,34 @@ int str2double(double *num, const char *str){
if(num) *num = res; // you may run it like myatod(NULL, str) to test wether str is double number if(num) *num = res; // you may run it like myatod(NULL, str) to test wether str is double number
return TRUE; return TRUE;
} }
FILE *Flog = NULL; // log file descriptor
/**
* Try to open log file
* if failed show warning message
*/
void openlogfile(char *name){
if(!name){
WARNX(_("Need filename"));
return;
}
green(_("Try to open log file %s in append mode\n"), name);
if(!(Flog = fopen(name, "a")))
WARN(_("Can't open log file"));
}
/**
* Save message to log file
*/
int putlog(const char *fmt, ...){
if(!Flog) return 0;
time_t t_now = time(NULL);
int i = fprintf(Flog, "\n\t\t%s", ctime(&t_now));
va_list ar;
va_start(ar, fmt);
i = vfprintf(Flog, fmt, ar);
va_end(ar);
fprintf(Flog, "\n");
fflush(Flog);
return i;
}

View File

@ -135,4 +135,6 @@ int write_tty(uint8_t *buff, size_t length);
int str2double(double *num, const char *str); int str2double(double *num, const char *str);
void openlogfile(char *name);
int putlog(const char *fmt, ...);
#endif // __USEFULL_MACROS_H__ #endif // __USEFULL_MACROS_H__