Add timestamps to saved filenames, fix daemon()

This commit is contained in:
Edward Emelianov 2017-02-18 17:34:57 +03:00
parent f6f0bd6f0f
commit d123815433
10 changed files with 73 additions and 50 deletions

View File

@ -2,16 +2,18 @@
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
LDFLAGS += -lm -pthread LDFLAGS += -lm -pthread
SRCS := $(wildcard *.c) SRCS := $(wildcard *.c)
DEFINES := $(DEF) -D_XOPEN_SOURCE=1111 #GCC_GE_4_9_3 := $(shell g++ -dumpversion | gawk '{print $$1>=4.9.3?"1":"0"}')
DEFINES += -DEBUG DEFINES := $(DEF) -D_XOPEN_SOURCE=1111
#OBJDIR := mk #ifeq ($(GCC_GE_4_9_3),1)
CFLAGS += -O2 -Wall -Werror -Wextra -Wno-trampolines -std=gnu99 DEFINES += -D_DEFAULT_SOURCE
#OBJS := $(addprefix $(OBJDIR)/, $(SRCS:%.c=%.o)) #else
#DEPS := $(OBJS:.o=.d) # DEFINES += -D_BSD_SOURCE
#endif
#DEFINES += -DEBUG
CFLAGS += -Wall -Wextra -O2 -std=gnu99
CC = gcc CC = gcc
all : sbig340 daemon client all : sbig340 daemon client
# $(OBJDIR)
sbig340 : $(SRCS) sbig340 : $(SRCS)
@echo -e "\t\tLD sbig340" @echo -e "\t\tLD sbig340"
@ -25,27 +27,11 @@ client : $(SRCS)
@echo -e "\t\tLD client" @echo -e "\t\tLD client"
$(CC) -DCLIENT $(CFLAGS) $(DEFINES) $(LDFLAGS) $(shell pkg-config --libs cfitsio) -ltiff $(SRCS) -o client $(CC) -DCLIENT $(CFLAGS) $(DEFINES) $(LDFLAGS) $(shell pkg-config --libs cfitsio) -ltiff $(SRCS) -o client
#$(OBJDIR): clean:
# mkdir $(OBJDIR) @echo -e "\t\tCLEAN"
@rm -f sbig340 daemon client
#ifneq ($(MAKECMDGOALS),clean)
#-include $(DEPS)
#endif
#$(OBJDIR)/%.o: %.c
# @echo -e "\t\tCC $<"
# $(CC) -MD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
#clean:
# @echo -e "\t\tCLEAN"
# @rm -f $(OBJS) $(DEPS)
# @rmdir $(OBJDIR) 2>/dev/null || true
#xclean: clean
# @rm -f $(PROGRAM)
gentags: gentags:
CFLAGS="$(CFLAGS) $(DEFINES)" geany -g $(PROGRAM).c.tags *[hc] 2>/dev/null CFLAGS="$(CFLAGS) $(DEFINES)" geany -g $(PROGRAM).c.tags *[hc] 2>/dev/null
.PHONY: gentags .PHONY: gentags clean
#clean xclean

View File

@ -53,8 +53,10 @@ glob_pars const Gdefault = {
.imformat = NULL, .imformat = NULL,
.imstoretype = NULL, .imstoretype = NULL,
.outpfname = "output.tiff", .outpfname = "output.tiff",
.hostname = "localhost", .hostname = NULL,
.port = "4444" .port = "4444",
.once = 0,
.timestamp = 0,
}; };
/* /*
@ -93,6 +95,8 @@ myoption cmdlnopts[] = {
#if defined DAEMON || defined CLIENT #if defined DAEMON || defined CLIENT
#ifndef DAEMON #ifndef DAEMON
{"hostname",NEED_ARG, NULL, 'H', arg_string, APTR(&G.hostname), _("hostname to connect (default: localhost)")}, {"hostname",NEED_ARG, NULL, 'H', arg_string, APTR(&G.hostname), _("hostname to connect (default: localhost)")},
{"once", NO_ARGS, NULL, '1', arg_int, APTR(&G.once), _("run client just once")},
{"timestamp",NO_ARGS, NULL, 't', arg_int, APTR(&G.timestamp), _("add timestamp to filename")},
#endif #endif
{"port", NEED_ARG, NULL, 'p', arg_string, APTR(&G.port), _("port to connect (default: 4444)")}, {"port", NEED_ARG, NULL, 'p', arg_string, APTR(&G.port), _("port to connect (default: 4444)")},
#endif #endif

View File

@ -35,6 +35,8 @@ typedef struct{
int rest_pars_num; // number of rest parameters int rest_pars_num; // number of rest parameters
heater_cmd heater; // turn heater on/off/leave unchanged heater_cmd heater; // turn heater on/off/leave unchanged
int splist; // list speeds available int splist; // list speeds available
int once; // run once (client)
int timestamp; // add timestamp
int newspeed; // change speed int newspeed; // change speed
int speed; // connect @ this speed int speed; // connect @ this speed
char *shutter_cmd; // shutter command: 'o' for open, 'c' for close, 'k' for de-energize char *shutter_cmd; // shutter command: 'o' for open, 'c' for close, 'k' for de-energize

View File

@ -25,10 +25,12 @@
#include "imfunctions.h" #include "imfunctions.h"
#include "term.h" #include "term.h"
#include <strings.h> // strncasecmp #include <strings.h> // strncasecmp
#include <tiffio.h> // save tiff
#include <math.h> // sqrt #include <math.h> // sqrt
#include <time.h> // time, gmtime etc #include <time.h> // time, gmtime etc
#ifndef DAEMON
#include <fitsio.h> // save fits #include <fitsio.h> // save fits
#include <tiffio.h> // save tiff
#endif
#include <libgen.h> // basename #include <libgen.h> // basename
#include <sys/stat.h> // utimensat #include <sys/stat.h> // utimensat
#include <fcntl.h> // AT_... #include <fcntl.h> // AT_...
@ -38,7 +40,8 @@ double exp_calculated = -1.; // optimal exposition, calculated in histogram save
* 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!
*/ */
#ifndef DAEMON
#include <time.h>
void modifytimestamp(char *filename, imstorage *img){ void modifytimestamp(char *filename, imstorage *img){
if(!filename) return; if(!filename) return;
struct timespec times[2]; struct timespec times[2];
@ -58,9 +61,19 @@ void modifytimestamp(char *filename, imstorage *img){
* make filename for given name, suffix and storage type * make filename for given name, suffix and storage type
* @return filename or NULL if can't create it * @return filename or NULL if can't create it
*/ */
static char *make_filename(const char *outfile, const char *suff, store_type st){ static char *make_filename(imstorage *img, const char *suff){
struct stat filestat; struct stat filestat;
static char buff[FILENAME_MAX]; static char buff[FILENAME_MAX];
store_type st = img->st;
char fnbuf[FILENAME_MAX], *outfile = img->imname;
if(img->timestamp){
struct tm *stm = localtime(&img->exposetime);
// add timestamp as YYYY-MM-DD_hh:mm:ss
snprintf(fnbuf, FILENAME_MAX, "%s_%04d-%02d-%02d_%02d:%02d:%02d", outfile,
1900+stm->tm_year, 1+stm->tm_mon, stm->tm_mday,
stm->tm_hour, stm->tm_min, stm->tm_sec);
outfile = fnbuf;
}
if(st == STORE_NORMAL || st == STORE_REWRITE){ if(st == STORE_NORMAL || st == STORE_REWRITE){
snprintf(buff, FILENAME_MAX, "%s.%s", outfile, suff); snprintf(buff, FILENAME_MAX, "%s.%s", outfile, suff);
if(stat(buff, &filestat)){ if(stat(buff, &filestat)){
@ -143,18 +156,20 @@ imstorage *chk_storeimg(char *filename, char* store, char *format){
#define FMTSZ (3) #define FMTSZ (3)
image_format formats[FMTSZ] = {FORMAT_FITS, FORMAT_TIFF, FORMAT_RAW}; image_format formats[FMTSZ] = {FORMAT_FITS, FORMAT_TIFF, FORMAT_RAW};
const char *suffixes[FMTSZ] = {SUFFIX_FITS, SUFFIX_TIFF, SUFFIX_RAW}; const char *suffixes[FMTSZ] = {SUFFIX_FITS, SUFFIX_TIFF, SUFFIX_RAW};
for(size_t i = 0; i < FMTSZ; ++i){
if(!(formats[i] & fmt)) continue;
if(!make_filename(nm, suffixes[i], st)){
WARNX(_("Can't create output file (is it exists?)"));
free(nm);
return NULL;
}
}
imstorage *ist = MALLOC(imstorage, 1); imstorage *ist = MALLOC(imstorage, 1);
ist->st = st; ist->st = st;
ist->imformat = fmt; ist->imformat = fmt;
ist->imname = strdup(nm); ist->imname = strdup(nm);
for(size_t i = 0; i < FMTSZ; ++i){
if(!(formats[i] & fmt)) continue;
if(!make_filename(ist, suffixes[i])){
WARNX(_("Can't create output file (is it exists?)"));
free(nm);
free(ist->imname);
free(ist);
return NULL;
}
}
return ist; return ist;
} }
@ -165,7 +180,7 @@ imstorage *chk_storeimg(char *filename, char* store, char *format){
int writetiff(imstorage *img){ int writetiff(imstorage *img){
int H = img->H, W = img->W, y; int H = img->H, W = img->W, y;
uint16_t *data = img->imdata; uint16_t *data = img->imdata;
char *name = make_filename(img->imname, SUFFIX_TIFF, img->st); char *name = make_filename(img, SUFFIX_TIFF);
TIFF *image = NULL; TIFF *image = NULL;
if(!name || !(image = TIFFOpen(name, "w"))){ if(!name || !(image = TIFFOpen(name, "w"))){
WARN("Can't save tiff file"); WARN("Can't save tiff file");
@ -195,6 +210,7 @@ int writetiff(imstorage *img){
modifytimestamp(name, img); modifytimestamp(name, img);
return 0; return 0;
} }
#endif
/** /**
* Calculate image statistics: print it on screen and save for `writefits` * Calculate image statistics: print it on screen and save for `writefits`
@ -243,6 +259,7 @@ void print_stat(imstorage *img){
printf("At 3sigma: Noverload = %ld, avr = %.3f, std = %.3f\n", Noverld, avr, std); printf("At 3sigma: Noverload = %ld, avr = %.3f, std = %.3f\n", Noverld, avr, std);
} }
#ifndef DAEMON
#define TRYFITS(f, ...) \ #define TRYFITS(f, ...) \
do{ int status = 0; \ do{ int status = 0; \
f(__VA_ARGS__, &status); \ f(__VA_ARGS__, &status); \
@ -260,7 +277,7 @@ int writefits(imstorage *img){
long naxes[2] = {img->W, img->H}; long naxes[2] = {img->W, img->H};
char buf[80]; char buf[80];
fitsfile *fp; fitsfile *fp;
char *filename = make_filename(img->imname, SUFFIX_FITS, img->st); char *filename = make_filename(img, SUFFIX_FITS);
TRYFITS(fits_create_file, &fp, filename); TRYFITS(fits_create_file, &fp, filename);
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes); TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
// FILE / Input file original name // FILE / Input file original name
@ -293,9 +310,9 @@ int writefits(imstorage *img){
WRITEKEY(TSTRING, "IMAGETYP", buf, "Image type"); WRITEKEY(TSTRING, "IMAGETYP", buf, "Image type");
// DATAMAX, DATAMIN / Max,min pixel value // DATAMAX, DATAMIN / Max,min pixel value
uint16_t val = UINT16_MAX; uint16_t val = UINT16_MAX;
WRITEKEY(TUSHORT, "DATAMAX", &val, "Max pixel value"); WRITEKEY(TUSHORT, "DATAMAX", &val, "Max possible pixel value");
val = 0; val = 0;
WRITEKEY(TUSHORT, "DATAMIN", &val, "Min pixel value"); WRITEKEY(TUSHORT, "DATAMIN", &val, "Min possible pixel value");
// statistical values // statistical values
WRITEKEY(TUSHORT, "STATMAX", &glob_max, "Max pixel value"); WRITEKEY(TUSHORT, "STATMAX", &glob_max, "Max pixel value");
WRITEKEY(TUSHORT, "STATMIN", &glob_min, "Min pixel value"); WRITEKEY(TUSHORT, "STATMIN", &glob_min, "Min pixel value");
@ -335,6 +352,7 @@ int writefits(imstorage *img){
green(_("Image %s saved\n"), filename); green(_("Image %s saved\n"), filename);
return 0; return 0;
} }
#endif
#ifndef CLIENT #ifndef CLIENT
/** /**
@ -406,8 +424,9 @@ int save_histo(FILE *f, imstorage *img){
return 0; return 0;
} }
#ifndef DAEMON
int writedump(imstorage *img){ int writedump(imstorage *img){
char *name = make_filename(img->imname, SUFFIX_RAW, img->st); char *name = make_filename(img, SUFFIX_RAW);
if(!name) return 1; if(!name) return 1;
int f = open(name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); int f = open(name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if(f){ if(f){
@ -423,7 +442,7 @@ int writedump(imstorage *img){
return 3; return 3;
} }
modifytimestamp(name, img); modifytimestamp(name, img);
name = make_filename(img->imname, "histogram.txt", img->st); name = make_filename(img, "histogram.txt");
if(!name) return 4; if(!name) return 4;
FILE *h = fopen(name, "w"); FILE *h = fopen(name, "w");
if(!h) return 5; if(!h) return 5;
@ -466,3 +485,4 @@ int store_image(imstorage *img){
} }
return status; return status;
} }
#endif

View File

@ -66,6 +66,8 @@ typedef struct{
size_t W, H; // image size size_t W, H; // image size
uint16_t *imdata; // image data itself uint16_t *imdata; // image data itself
time_t exposetime; // time of exposition start time_t exposetime; // time of exposition start
int timestamp; // add timestamp to filename
int once; // get only one image
} imstorage; } imstorage;
extern double exp_calculated; extern double exp_calculated;

4
main.c
View File

@ -111,6 +111,10 @@ int main(int argc, char **argv){
run_terminal(); // non-echo terminal mode run_terminal(); // non-echo terminal mode
} }
#endif // !defined DAEMON && !defined CLIENT #endif // !defined DAEMON && !defined CLIENT
#ifdef CLIENT
img->once = G->once;
img->timestamp = G->timestamp;
#endif
#if defined CLIENT || defined DAEMON #if defined CLIENT || defined DAEMON
daemonize(img, G->hostname, G->port); daemonize(img, G->hostname, G->port);
#endif #endif

View File

@ -31,6 +31,9 @@
#include <pthread.h> #include <pthread.h>
#include <limits.h> // INT_xxx #include <limits.h> // INT_xxx
#include <signal.h> // pthread_kill #include <signal.h> // pthread_kill
#include <unistd.h> // daemon
#include <sys/wait.h> // wait
#include <sys/prctl.h> //prctl
#define BUFLEN (10240) #define BUFLEN (10240)
#define BUFLEN10 (1048576) #define BUFLEN10 (1048576)
@ -396,6 +399,7 @@ static void client_(imstorage *img, int sock){
if(store_image(img)) if(store_image(img))
WARNX(_("Error storing image")); WARNX(_("Error storing image"));
} }
if(img->once) break;
} }
} }
#endif #endif
@ -405,8 +409,9 @@ static void client_(imstorage *img, int sock){
*/ */
void daemonize(imstorage *img, char *hostname, char *port){ void daemonize(imstorage *img, char *hostname, char *port){
FNAME(); FNAME();
green("Daemonize\n");
#ifndef EBUG #ifndef EBUG
if(!img->once){
green("Daemonize\n");
if(daemon(1, 0)){ if(daemon(1, 0)){
ERR("daemon()"); ERR("daemon()");
} }
@ -421,7 +426,7 @@ void daemonize(imstorage *img, char *hostname, char *port){
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;

2
term.h
View File

@ -41,7 +41,7 @@ typedef enum{
} heater_cmd; } heater_cmd;
// terminal timeout (seconds) // terminal timeout (seconds)
#define WAIT_TMOUT (0.1) #define WAIT_TMOUT (0.2)
// timeout waitint 'D' // timeout waitint 'D'
#define EXP_DONE_TMOUT (5.0) #define EXP_DONE_TMOUT (5.0)
// dataportion transfer timeout // dataportion transfer timeout

View File

@ -333,7 +333,7 @@ size_t read_tty(uint8_t *buff, size_t length){
int retval; int retval;
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(comfd, &rfds); FD_SET(comfd, &rfds);
tv.tv_sec = 0; tv.tv_usec = 50000; // wait for 50ms tv.tv_sec = 0; tv.tv_usec = 500000; // wait for 500ms max
retval = select(comfd + 1, &rfds, NULL, NULL, &tv); retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
if (!retval) return 0; if (!retval) return 0;
if(FD_ISSET(comfd, &rfds)){ if(FD_ISSET(comfd, &rfds)){