force to new usefull_macros lib

This commit is contained in:
2025-06-23 16:35:29 +03:00
parent db2c0e2d9c
commit 89815e8981
28 changed files with 1717 additions and 88 deletions

View File

@@ -1,24 +1,44 @@
# run `make DEF=...` to add extra defines
PROGRAM := weatherdaemon
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all -pthread
LDFLAGS += -flto `pkg-config --libs usefull_macros` -lm
PROGRAM := weatherdaemonN
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
LDFLAGS += -lusefull_macros -lm
SRCS := $(wildcard *.c)
DEFINES := $(DEF) -D_GNU_SOURCE -D_XOPEN_SOURCE=1111
#DEFINES += -DEBUG
OBJDIR := mk
CFLAGS += `pkg-config --cflags usefull_macros` -O3 -Wall -Werror -Wextra -Wno-trampolines -flto
CFLAGS += -O2 -Wall -Wextra -Wno-trampolines
OBJS := $(addprefix $(OBJDIR)/, $(SRCS:%.c=%.o))
DEPS := $(OBJS:.o=.d)
TARGFILE := $(OBJDIR)/TARGET
CC = gcc
all : $(OBJDIR) $(PROGRAM)
ifeq ($(shell test -e $(TARGFILE) && echo -n yes),yes)
TARGET := $(file < $(TARGFILE))
else
TARGET := RELEASE
endif
$(PROGRAM) : $(OBJS)
ifeq ($(TARGET), DEBUG)
.DEFAULT_GOAL := debug
endif
release: CFLAGS += -flto
release: LDFLAGS += -flto
release: $(PROGRAM)
debug: CFLAGS += -DEBUG -Werror
debug: TARGET := DEBUG
debug: $(PROGRAM)
$(TARGFILE): $(OBJDIR)
@echo -e "\t\tTARGET: $(TARGET)"
@echo "$(TARGET)" > $(TARGFILE)
$(PROGRAM) : $(TARGFILE) $(OBJS)
@echo -e "\t\tLD $(PROGRAM)"
$(CC) $(OBJS) $(LDFLAGS) -o $(PROGRAM)
$(CC) $(LDFLAGS) $(OBJS) -o $(PROGRAM)
$(OBJDIR):
mkdir $(OBJDIR)
@mkdir $(OBJDIR)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
@@ -30,13 +50,9 @@ $(OBJDIR)/%.o: %.c
clean:
@echo -e "\t\tCLEAN"
@rm -f $(OBJS) $(DEPS)
@rmdir $(OBJDIR) 2>/dev/null || true
@rm -rf $(OBJDIR) 2>/dev/null || true
xclean: clean
@rm -f $(PROGRAM)
gentags:
CFLAGS="$(CFLAGS) $(DEFINES)" geany -g $(PROGRAM).c.tags *[hc] 2>/dev/null
.PHONY: gentags clean xclean
.PHONY: clean xclean

View File

@@ -18,9 +18,7 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <math.h>
#include <usefull_macros.h>
#include "cmdlnopts.h"
@@ -28,7 +26,6 @@
* here are global parameters initialisation
*/
int help;
static glob_pars G;
// default values for Gdefault & help
#define DEFAULT_PORT "12345"
@@ -36,7 +33,7 @@ static glob_pars G;
// DEFAULTS
// default global parameters
glob_pars const Gdefault = {
static glob_pars G = {
.device = NULL,
.port = DEFAULT_PORT,
.logfile = NULL,
@@ -52,7 +49,7 @@ glob_pars const Gdefault = {
* Define command line options by filling structure:
* name has_arg flag val type argptr help
*/
myoption cmdlnopts[] = {
sl_option_t cmdlnopts[] = {
// common options
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
{"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("serial device name (default: none)")},
@@ -73,19 +70,15 @@ myoption cmdlnopts[] = {
* @return allocated structure with global parameters
*/
glob_pars *parse_args(int argc, char **argv){
int i;
void *ptr;
ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr);
// format of help: "Usage: progname [args]\n"
change_helpstring("Usage: %s [args]\n\n\tWhere args are:\n");
sl_helpstring("Usage: %s [args]\n\n\tWhere args are:\n");
// parse arguments
parseargs(&argc, &argv, cmdlnopts);
if(help) showhelp(-1, cmdlnopts);
sl_parseargs(&argc, &argv, cmdlnopts);
if(help) sl_showhelp(-1, cmdlnopts);
if(argc > 0){
G.rest_pars_num = argc;
G.rest_pars = calloc(argc, sizeof(char*));
for (i = 0; i < argc; i++)
G.rest_pars[i] = strdup(argv[i]);
printf("Ignore flags:\n");
for(int i = 0; i < argc; i++)
printf("\t%s\n", argv[i]);
}
return &G;
}

View File

@@ -16,11 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __CMDLNOPTS_H__
#define __CMDLNOPTS_H__
/*
* here are some typedef's for global data
@@ -41,4 +38,4 @@ typedef struct{
glob_pars *parse_args(int argc, char **argv);
#endif // __CMDLNOPTS_H__

View File

@@ -27,38 +27,30 @@
#include "socket.h"
#include "term.h"
glob_pars *GP;
void signals(int signo){
restore_console();
stop_tty();
LOGERR("exit with status %d", signo);
exit(signo);
}
int main(int argc, char **argv){
initial_setup();
signal(SIGTERM, signals); // kill (-15) - quit
signal(SIGHUP, SIG_IGN); // hup - ignore
signal(SIGINT, signals); // ctrl+C - quit
signal(SIGQUIT, signals); // ctrl+\ - quit
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
#ifndef EBUG
sl_init();
char *self = strdup(argv[0]);
#endif
GP = parse_args(argc, argv);
glob_pars *GP = parse_args(argc, argv);
sl_check4running(self, GP->pidfile);
if(GP->logfile){
sl_loglevel lvl = LOGLEVEL_ERR;
sl_loglevel_e lvl = LOGLEVEL_ERR;
for(; GP->verb && lvl < LOGLEVEL_ANY; --GP->verb) ++lvl;
DBG("Loglevel: %d", lvl);
if(!OPENLOG(GP->logfile, lvl, 1)) ERRX("Can't open log file");
LOGERR("Started");
}
#ifndef EBUG
if(daemon(1, 0)){
ERR("daemon()");
}
check4running(self, GP->pidfile);
signal(SIGTERM, signals); // kill (-15) - quit
signal(SIGHUP, SIG_IGN); // hup - ignore
signal(SIGINT, signals); // ctrl+C - quit
signal(SIGQUIT, signals); // ctrl+\ - quit
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
while(1){ // guard for dead processes
pid_t childpid = fork();
if(childpid){
@@ -75,14 +67,16 @@ int main(int argc, char **argv){
}
#endif
if(GP->device) if(!try_connect(GP->device, GP->tty_speed)){
LOGERR("Can't connect to device");
ERRX("Can't connect to device");
}
if(!GP->device && !GP->emul){
LOGERR("Need serial device name or emulation flag");
ERRX("Need serial device name or emulation flag");
}
if(!try_connect(GP->device, GP->tty_speed, GP->emul)){
LOGERR("Can't connect to device");
ERRX("Can't connect to device");
}
daemonize(GP->port);
return 0;
}

View File

@@ -28,7 +28,6 @@
#include <unistd.h> // daemon
#include <usefull_macros.h>
#include "cmdlnopts.h" // glob_pars
#include "socket.h"
#include "stat.h"
#include "term.h"
@@ -38,8 +37,6 @@
// Max amount of connections
#define BACKLOG (30)
extern glob_pars *GP;
static weather_t lastweather = {0};
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static weatherstat_t wstat;
@@ -72,7 +69,7 @@ static int send_data(int sock, int webquery, format_t format){
if(format == FORMAT_CURDFULL){ // full format
Len = snprintf(databuf, BUFSIZ,
"Wind=%.1f%sDir=%.1f%sPressure=%.1f%sTemperature=%.1f%sHumidity=%.1f%s"
"Rain=%.1f%sTime=%.3f%s",
"Rain=%.1f%sTime=%.1f%s",
lastweather.windspeed, eol, lastweather.winddir, eol, lastweather.pressure, eol,
lastweather.temperature, eol, lastweather.humidity, eol, lastweather.rainfall, eol,
lastweather.tmeasure, eol
@@ -117,6 +114,7 @@ static int send_data(int sock, int webquery, format_t format){
PRSTAT(tmeasure, "Time");
Len += snprintf(ptr, l, "%s", eol);
#undef PRSTAT
#undef COMMA
}else{
Len = snprintf(databuf, BUFSIZ, "Error!");
}
@@ -247,6 +245,7 @@ static int handle_socket(int sock){
// main socket server
static void *server(void *asock){
FNAME();
LOGMSG("server()");
int sock = *((int*)asock);
if(listen(sock, BACKLOG) == -1){
@@ -307,6 +306,7 @@ static void *server(void *asock){
// poll last weather data
static void *weatherpolling(_U_ void *notused){
FNAME();
while(1){
weather_t w;
if(getlastweather(&w) && 0 == pthread_mutex_lock(&mutex)){
@@ -321,6 +321,7 @@ static void *weatherpolling(_U_ void *notused){
// data gathering & socket management
static void daemon_(int sock){
DBG("sock=%d", sock);
if(sock < 0) return;
pthread_t sock_thread, parser_thread;
if(pthread_create(&sock_thread, NULL, server, (void*) &sock)){

View File

@@ -17,8 +17,6 @@
*/
#pragma once
#ifndef __SOCKET_H__
#define __SOCKET_H__
// time interval for data polling (seconds)
#define T_INTERVAL (10.)
@@ -29,4 +27,3 @@
void daemonize(char *port);
#endif // __SOCKET_H__

View File

@@ -29,8 +29,8 @@
#define BUFLEN (4096)
static TTY_descr *ttydescr = NULL;
extern glob_pars *GP;
static sl_tty_t *ttydescr = NULL;
static int emulate = FALSE;
static char buf[BUFLEN];
static const char *emultemplate = "0R0,S=1.9,D=217.2,P=787.7,T=10.8,H=69.0,R=31.0,Ri=0.0,Rs=Y";
@@ -41,7 +41,7 @@ static const char *emultemplate = "0R0,S=1.9,D=217.2,P=787.7,T=10.8,H=69.0,R=31.
*/
static char *read_string(){
//static int done = 0;
if(GP->emul){
if(emulate){
strncpy(buf, emultemplate, BUFLEN);
return buf;
}
@@ -49,16 +49,16 @@ static char *read_string(){
size_t r = 0, l;
int LL = BUFLEN - 1;
char *ptr = buf;
double d0 = dtime();
double d0 = sl_dtime();
do{
if((l = read_tty(ttydescr))){
if((l = sl_tty_read(ttydescr))){
strncpy(ptr, ttydescr->buf, LL);
r += l; LL -= l; ptr += l;
//DBG("l=%zd, r=%zd, LL=%d", l, r, LL);
d0 = dtime();
d0 = sl_dtime();
if(r > 2 && ptr[-1] == '\n') break;
}
}while(dtime() - d0 < WAIT_TMOUT && LL);
}while(sl_dtime() - d0 < WAIT_TMOUT && LL);
if(r){
//buf[r] = 0;
//DBG("buf: %s", buf);
@@ -71,20 +71,25 @@ static char *read_string(){
* Try to connect to `device` at baudrate speed
* @return 1 if OK
*/
int try_connect(char *device, int baudrate){
if(!device) return 0;
int try_connect(char *device, int baudrate, int emul){
if(emul){
emulate = TRUE;
DBG("Emulation mode");
return TRUE;
}
if(!device) return FALSE;
fflush(stdout);
ttydescr = new_tty(device, baudrate, 1024);
if(ttydescr) ttydescr = tty_open(ttydescr, 1); // exclusive open
if(!ttydescr) return 0;
while(read_tty(ttydescr)); // clear rbuf
ttydescr = sl_tty_new(device, baudrate, 1024);
if(ttydescr) ttydescr = sl_tty_open(ttydescr, 1); // exclusive open
if(!ttydescr) return FALSE;
while(sl_tty_read(ttydescr)); // clear rbuf
LOGMSG("Connected to %s", device);
return 1;
return TRUE;
}
// stop polling thread and close tty
void stop_tty(){
if(ttydescr) close_tty(&ttydescr);
if(ttydescr) sl_tty_close(&ttydescr);
}
static weather_t lastweather;
@@ -120,7 +125,7 @@ static int parseans(char *str, weather_t *w){
str += el->parlen;
char *endptr;
*el->weatherpar = strtod(str, &endptr);
DBG("found par: %s, val=%g", el->parname, *el->weatherpar);
//DBG("found par: %s, val=%g", el->parname, *el->weatherpar);
if(endptr == str){
DBG("Wrong double value");
*el->weatherpar = 0.;
@@ -133,19 +138,19 @@ static int parseans(char *str, weather_t *w){
str = strchr(str, ',');
//DBG("next=%s", str);
}while(str && *str);
lastweather.tmeasure = dtime();
lastweather.tmeasure = sl_dtime();
if(w) memcpy(w, &lastweather, sizeof(weather_t));
return TRUE;
}
// get weather measurements; return FALSE if something failed
int getlastweather(weather_t *w){
if(!GP->emul){
if(write_tty(ttydescr->comfd, "!0R0\r\n", 6))
if(!emulate){
if(sl_tty_write(ttydescr->comfd, "!0R0\r\n", 6))
return FALSE;
}
double t0 = dtime();
while(dtime() - t0 < T_POLLING_TMOUT){
double t0 = sl_dtime();
while(sl_dtime() - t0 < T_POLLING_TMOUT){
char *r = NULL;
if((r = read_string())){ // parse new data
//DBG("got %s", r);

View File

@@ -17,8 +17,6 @@
*/
#pragma once
#ifndef __TERM_H__
#define __TERM_H__
#include <usefull_macros.h>
@@ -39,8 +37,7 @@ typedef struct{
double tmeasure; // UNIX-time of last measure
} weather_t;
int try_connect(char *device, int baudrate);
int try_connect(char *device, int baudrate, int emul);
int getlastweather(weather_t *w);
void stop_tty();
#endif // __TERM_H__