mirror of
https://github.com/eddyem/BTA_utils.git
synced 2025-12-06 10:45:14 +03:00
added pre-alpha of Stellarium control
This commit is contained in:
parent
448d576e7c
commit
bbb7e03c84
22
Stellarium_control/Makefile
Normal file
22
Stellarium_control/Makefile
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
PROGRAM = stellariumdaemon
|
||||||
|
LDFLAGS =
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
CC = gcc
|
||||||
|
DEFINES = -D_XOPEN_SOURCE=1111 -DEBUG
|
||||||
|
CXX = gcc
|
||||||
|
CFLAGS = -Wall -Werror -Wextra $(DEFINES)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
all : $(PROGRAM)
|
||||||
|
$(PROGRAM) : $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(PROGRAM)
|
||||||
|
|
||||||
|
# some addition dependencies
|
||||||
|
# %.o: %.c
|
||||||
|
# $(CC) $(LDFLAGS) $(CFLAGS) $< -o $@
|
||||||
|
#$(SRCS) : %.c : %.h $(INDEPENDENT_HEADERS)
|
||||||
|
# @touch $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
/bin/rm -f *.o *~
|
||||||
|
depend:
|
||||||
|
$(CXX) -MM $(CXX.SRCS)
|
||||||
2
Stellarium_control/Readme
Normal file
2
Stellarium_control/Readme
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Alpha version: no real control at all, just emulation
|
||||||
|
|
||||||
141
Stellarium_control/daemon.c
Normal file
141
Stellarium_control/daemon.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* daemon.c - functions for running in background like a daemon
|
||||||
|
*
|
||||||
|
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PROC_BASE "/proc"
|
||||||
|
|
||||||
|
#include <stdio.h> // printf, fopen, ...
|
||||||
|
#include <unistd.h> // getpid
|
||||||
|
#include <stdio.h> // perror
|
||||||
|
#include <sys/types.h> // opendir
|
||||||
|
#include <dirent.h> // opendir
|
||||||
|
#include <sys/stat.h> // stat
|
||||||
|
#include <fcntl.h> // fcntl
|
||||||
|
#include <stdlib.h> // exit
|
||||||
|
#include <string.h> // memset
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read process name from /proc/PID/cmdline
|
||||||
|
* @param pid - PID of interesting process
|
||||||
|
* @return filename or NULL if not found
|
||||||
|
* don't use this function twice for different names without copying
|
||||||
|
* its returning by strdup, because `name` contains in static array
|
||||||
|
*/
|
||||||
|
char *readname(pid_t pid){
|
||||||
|
static char name[256];
|
||||||
|
char *pp = name, byte, path[256];
|
||||||
|
FILE *file;
|
||||||
|
int cntr = 0;
|
||||||
|
size_t sz;
|
||||||
|
snprintf (path, 255, PROC_BASE "/%d/cmdline", pid);
|
||||||
|
file = fopen(path, "r");
|
||||||
|
if(!file) return NULL; // there's no such file
|
||||||
|
do{ // read basename
|
||||||
|
sz = fread(&byte, 1, 1, file);
|
||||||
|
if(sz != 1) break;
|
||||||
|
if(byte != '/') *pp++ = byte;
|
||||||
|
else{
|
||||||
|
pp = name;
|
||||||
|
cntr = 0;
|
||||||
|
}
|
||||||
|
}while(byte && cntr++ < 255);
|
||||||
|
name[cntr] = 0;
|
||||||
|
fclose(file);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iffound_default(pid_t pid){
|
||||||
|
fprintf(stderr, "\nFound running process (pid=%d), exit.\n", pid);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check wether there is a same running process
|
||||||
|
* exit if there is a running process or error
|
||||||
|
* Checking have 3 steps:
|
||||||
|
* 1) lock executable file
|
||||||
|
* 2) check pidfile (if you run a copy?)
|
||||||
|
* 3) check /proc for executables with the same name (no/wrong pidfile)
|
||||||
|
* @param argv - argument of main() or NULL for non-locking, call this function before getopt()
|
||||||
|
* @param pidfilename - name of pidfile or NULL if none
|
||||||
|
* @param iffound - action to run if file found or NULL for exit(0)
|
||||||
|
*/
|
||||||
|
void check4running(char **argv, char *pidfilename, void (*iffound)(pid_t pid)){
|
||||||
|
DIR *dir;
|
||||||
|
FILE *pidfile, *fself;
|
||||||
|
struct dirent *de;
|
||||||
|
struct stat s_buf;
|
||||||
|
pid_t pid = 0, self;
|
||||||
|
struct flock fl;
|
||||||
|
char *name, *myname;
|
||||||
|
if(!iffound) iffound = iffound_default;
|
||||||
|
if(argv){ // block self
|
||||||
|
fself = fopen(argv[0], "r"); // open self binary to lock
|
||||||
|
memset(&fl, 0, sizeof(struct flock));
|
||||||
|
fl.l_type = F_WRLCK;
|
||||||
|
if(fcntl(fileno(fself), F_GETLK, &fl) == -1){ // check locking
|
||||||
|
perror("fcntl");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if(fl.l_type != F_UNLCK){ // file is locking - exit
|
||||||
|
printf("Found locker, PID = %d!\n", fl.l_pid);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fl.l_type = F_RDLCK;
|
||||||
|
if(fcntl(fileno(fself), F_SETLKW, &fl) == -1){
|
||||||
|
perror("fcntl");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self = getpid(); // get self PID
|
||||||
|
if(!(dir = opendir(PROC_BASE))){ // open /proc directory
|
||||||
|
perror(PROC_BASE);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if(!(name = readname(self))){ // error reading self name
|
||||||
|
perror("Can't read self name");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
myname = strdup(name);
|
||||||
|
if(pidfilename && stat(pidfilename, &s_buf) == 0){ // pidfile exists
|
||||||
|
pidfile = fopen(pidfilename, "r");
|
||||||
|
if(pidfile){
|
||||||
|
if(fscanf(pidfile, "%d", &pid) > 0){ // read PID of (possibly) running process
|
||||||
|
if((name = readname(pid)) && strncmp(name, myname, 255) == 0)
|
||||||
|
iffound(pid);
|
||||||
|
}
|
||||||
|
fclose(pidfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// There is no pidfile or it consists a wrong record
|
||||||
|
while((de = readdir(dir))){ // scan /proc
|
||||||
|
if(!(pid = (pid_t)atoi(de->d_name)) || pid == self) // pass non-PID files and self
|
||||||
|
continue;
|
||||||
|
if((name = readname(pid)) && strncmp(name, myname, 255) == 0)
|
||||||
|
iffound(pid);
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
if(pidfilename){
|
||||||
|
pidfile = fopen(pidfilename, "w");
|
||||||
|
fprintf(pidfile, "%d\n", self); // write self PID to pidfile
|
||||||
|
fclose(pidfile);
|
||||||
|
}
|
||||||
|
free(myname);
|
||||||
|
}
|
||||||
376
Stellarium_control/main.c
Normal file
376
Stellarium_control/main.c
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
* main.c
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#define _BSD_SOURCE
|
||||||
|
#include <endian.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
// for pthread_kill
|
||||||
|
//#define _XOPEN_SOURCE 666
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
|
// daemon.c
|
||||||
|
extern void check4running(char **argv, char *pidfilename, void (*iffound)(pid_t pid));
|
||||||
|
|
||||||
|
// Max amount of connections
|
||||||
|
#define BACKLOG (1)
|
||||||
|
|
||||||
|
#define PORT ("10000")
|
||||||
|
#define BUFLEN (1024)
|
||||||
|
|
||||||
|
static uint8_t buff[BUFLEN+1];
|
||||||
|
|
||||||
|
//glob_pars *Global_parameters = NULL;
|
||||||
|
|
||||||
|
static volatile int global_quit = 0;
|
||||||
|
// quit by signal
|
||||||
|
static void signals(int sig){
|
||||||
|
DBG("Get signal %d, quit.\n", sig);
|
||||||
|
global_quit = 1;
|
||||||
|
sleep(1);
|
||||||
|
exit(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
// search a first word after needle without spaces
|
||||||
|
char* stringscan(char *str, char *needle){
|
||||||
|
char *a, *e;
|
||||||
|
char *end = str + strlen(str);
|
||||||
|
a = strstr(str, needle);
|
||||||
|
if(!a) return NULL;
|
||||||
|
a += strlen(needle);
|
||||||
|
while (a < end && (*a == ' ' || *a == '\r' || *a == '\t')) a++;
|
||||||
|
if(a >= end) return NULL;
|
||||||
|
e = strchr(a, ' ');
|
||||||
|
if(e) *e = 0;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data to user
|
||||||
|
* @param data - data to send
|
||||||
|
* @param dlen - data length
|
||||||
|
* @param sockfd - socket fd for sending data
|
||||||
|
*/
|
||||||
|
void send_data(uint8_t *data, size_t dlen, int sockfd){
|
||||||
|
/*char buf[1024];
|
||||||
|
if(!strip){
|
||||||
|
if(imtype == IMTYPE_RAW)
|
||||||
|
L = snprintf(buf, 255, "%s\n%dx%d\n", imsuffixes[imtype], w, h);
|
||||||
|
else
|
||||||
|
L = snprintf(buf, 255, "%s\n%zd\n", imsuffixes[imtype], buflen);
|
||||||
|
}else{
|
||||||
|
L = snprintf(buf, 1023, "HTTP/2.0 200 OK\r\nContent-type: image/%s\r\n"
|
||||||
|
"Content-Length: %zd\r\n\r\n", mimetypes[imtype], buflen);
|
||||||
|
}
|
||||||
|
buff = MALLOC(uint8_t, L + buflen);
|
||||||
|
memcpy(buff, buf, L);
|
||||||
|
memcpy(buff+L, imagedata, buflen);
|
||||||
|
FREE(imagedata);
|
||||||
|
buflen += L;*/
|
||||||
|
size_t sent = write(sockfd, data, dlen);
|
||||||
|
if(sent != dlen) WARN("write()");
|
||||||
|
//FREE(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
//read: 0x14 0x0 0x0 0x0 0x5b 0x5a 0x2e 0xc6 0x8c 0x23 0x5 0x0 0x23 0x9 0xe5 0xaf 0x23 0x2e 0x34 0xed
|
||||||
|
// command: goto 16h29 24.45 -26d25 55.62
|
||||||
|
/*
|
||||||
|
LITTLE-ENDIAN!!!
|
||||||
|
from client:
|
||||||
|
LENGTH (2 bytes, integer): length of the message
|
||||||
|
TYPE (2 bytes, integer): 0
|
||||||
|
TIME (8 bytes, integer): current time on the server computer in microseconds
|
||||||
|
since 1970.01.01 UT. Currently unused.
|
||||||
|
RA (4 bytes, unsigned integer): right ascension of the telescope (J2000)
|
||||||
|
a value of 0x100000000 = 0x0 means 24h=0h,
|
||||||
|
a value of 0x80000000 means 12h
|
||||||
|
DEC (4 bytes, signed integer): declination of the telescope (J2000)
|
||||||
|
a value of -0x40000000 means -90degrees,
|
||||||
|
a value of 0x0 means 0degrees,
|
||||||
|
a value of 0x40000000 means 90degrees
|
||||||
|
|
||||||
|
to client:
|
||||||
|
LENGTH (2 bytes, integer): length of the message
|
||||||
|
TYPE (2 bytes, integer): 0
|
||||||
|
TIME (8 bytes, integer): current time on the server computer in microseconds
|
||||||
|
since 1970.01.01 UT. Currently unused.
|
||||||
|
RA (4 bytes, unsigned integer): right ascension of the telescope (J2000)
|
||||||
|
a value of 0x100000000 = 0x0 means 24h=0h,
|
||||||
|
a value of 0x80000000 means 12h
|
||||||
|
DEC (4 bytes, signed integer): declination of the telescope (J2000)
|
||||||
|
a value of -0x40000000 means -90degrees,
|
||||||
|
a value of 0x0 means 0degrees,
|
||||||
|
a value of 0x40000000 means 90degrees
|
||||||
|
STATUS (4 bytes, signed integer): status of the telescope, currently unused.
|
||||||
|
status=0 means ok, status<0 means some error
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEG2DEC(degr) ((int32_t)(degr / 90. * ((double)0x40000000)))
|
||||||
|
#define HRS2RA(hrs) ((uint32_t)(hrs / 12. * ((double)0x80000000)))
|
||||||
|
#define DEC2DEG(i32) (((double)i32)*90./((double)0x40000000))
|
||||||
|
#define RA2HRS(u32) (((double)u32)*12. /((double)0x80000000))
|
||||||
|
|
||||||
|
typedef struct __attribute__((__packed__)){
|
||||||
|
uint16_t len;
|
||||||
|
uint16_t type;
|
||||||
|
uint64_t time;
|
||||||
|
uint32_t ra;
|
||||||
|
int32_t dec;
|
||||||
|
} indata;
|
||||||
|
|
||||||
|
typedef struct __attribute__((__packed__)){
|
||||||
|
uint16_t len;
|
||||||
|
uint16_t type;
|
||||||
|
uint64_t time;
|
||||||
|
uint32_t ra;
|
||||||
|
int32_t dec;
|
||||||
|
int32_t status;
|
||||||
|
} outdata;
|
||||||
|
|
||||||
|
static double tagRA = -1., tagDec = -100.;
|
||||||
|
|
||||||
|
void proc_data(uint8_t *data, ssize_t len){
|
||||||
|
FNAME();
|
||||||
|
if(len != sizeof(indata)){
|
||||||
|
WARN("Bad data size: got %zd instead of %zd!", len, sizeof(indata));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
indata *dat = (indata*)data;
|
||||||
|
uint16_t L, T;
|
||||||
|
uint64_t tim;
|
||||||
|
uint32_t ra;
|
||||||
|
int32_t dec;
|
||||||
|
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||||
|
L = le16toh(dat->len); T = le16toh(dat->type);
|
||||||
|
tim = le64toh(dat->time);
|
||||||
|
ra = le32toh(dat->ra);
|
||||||
|
dec = (int32_t)le32toh((uint32_t)dat->dec);
|
||||||
|
#else
|
||||||
|
L = dat->len; T = dat->type;
|
||||||
|
tim = dat->time;
|
||||||
|
ra = dat->ra; dec = dat->dec;
|
||||||
|
#endif
|
||||||
|
WARN("got message with len %u & type %u", L, T);
|
||||||
|
tagRA = RA2HRS(ra); tagDec = DEC2DEG(dec);
|
||||||
|
WARN("RA: %u (%g), DEC: %d (%g)", ra, tagRA,
|
||||||
|
dec, tagDec);
|
||||||
|
time_t z = time(NULL);
|
||||||
|
time_t tm = (time_t)(tim/1000000);
|
||||||
|
WARN("time: %ju (local: %ju)", (uintmax_t)tm, (uintmax_t)z);
|
||||||
|
WARN("time: %zd -- %s local: %s", tim, ctime(&tm), ctime(&z));
|
||||||
|
/* memmove(buff, data, sizeof(indata));
|
||||||
|
outdata *dout = (outdata*) buff;
|
||||||
|
dout->ra = 0; dout->dec = 0x40000000;
|
||||||
|
dout->status = 0;
|
||||||
|
send_data(data, sizeof(outdata), sock);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* main socket service procedure
|
||||||
|
*/
|
||||||
|
void handle_socket(int sock){
|
||||||
|
FNAME();
|
||||||
|
if(global_quit) return;
|
||||||
|
ssize_t readed;
|
||||||
|
outdata dout;
|
||||||
|
uint32_t oldra;
|
||||||
|
int32_t olddec;
|
||||||
|
dout.len = sizeof(outdata);
|
||||||
|
dout.type = 0;
|
||||||
|
dout.status = 0;
|
||||||
|
dout.ra = (tagRA < -0.1) ? 0 : HRS2RA(tagRA);
|
||||||
|
dout.dec = (tagDec < -91.) ? DEG2DEC(80.) : DEG2DEC(tagDec);
|
||||||
|
oldra = dout.ra; olddec = dout.dec;
|
||||||
|
while(!global_quit){
|
||||||
|
//dout.ra += 0xF5555555;
|
||||||
|
if(tagRA < -0.1) dout.ra += HRS2RA(0.33);
|
||||||
|
else dout.ra = HRS2RA(tagRA);
|
||||||
|
if(tagDec > -91.) dout.dec = DEG2DEC(tagDec);
|
||||||
|
if(dout.ra != oldra || dout.dec != olddec){
|
||||||
|
send_data((uint8_t*)&dout, sizeof(outdata), sock);
|
||||||
|
DBG("sent ra = %g (%g), dec = %g (%g)", RA2HRS(dout.ra), tagRA, DEC2DEG(dout.dec), tagDec);
|
||||||
|
oldra = (dout.ra+oldra)/2; olddec = (dout.dec+olddec)/2;
|
||||||
|
}
|
||||||
|
fd_set readfds;
|
||||||
|
struct timeval timeout;
|
||||||
|
FD_ZERO(&readfds);
|
||||||
|
FD_SET(sock, &readfds);
|
||||||
|
timeout.tv_sec = 1; // wait not more than 1 second
|
||||||
|
timeout.tv_usec = 0;//100000;
|
||||||
|
int sel = select(sock + 1 , &readfds , NULL , NULL , &timeout);
|
||||||
|
if(sel < 0){
|
||||||
|
if(errno != EINTR)
|
||||||
|
WARN("select()");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!(FD_ISSET(sock, &readfds))) continue;
|
||||||
|
// fill incoming buffer
|
||||||
|
readed = read(sock, buff, BUFLEN);
|
||||||
|
DBG("read %zd", readed);
|
||||||
|
if(readed <= 0){ // error or disconnect
|
||||||
|
DBG("Nothing to read from fd %d (ret: %zd)", sock, readed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/**************************************
|
||||||
|
* DO SOMETHING WITH DATA *
|
||||||
|
**************************************/
|
||||||
|
proc_data(buff, readed);
|
||||||
|
//send_data(...);
|
||||||
|
}
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void main_proc(){
|
||||||
|
int sock;
|
||||||
|
struct addrinfo hints, *res, *p;
|
||||||
|
int reuseaddr = 1;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
if(getaddrinfo(NULL, PORT, &hints, &res) != 0){
|
||||||
|
ERR("getaddrinfo");
|
||||||
|
}
|
||||||
|
struct sockaddr_in *ia = (struct sockaddr_in*)res->ai_addr;
|
||||||
|
char str[INET_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET, &(ia->sin_addr), str, INET_ADDRSTRLEN);
|
||||||
|
DBG("port: %u, addr: %s\n", ntohs(ia->sin_port), str);
|
||||||
|
// loop through all the results and bind to the first we can
|
||||||
|
for(p = res; p != NULL; p = p->ai_next){
|
||||||
|
if((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
|
||||||
|
WARN("socket");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1){
|
||||||
|
ERR("setsockopt");
|
||||||
|
}
|
||||||
|
if(bind(sock, p->ai_addr, p->ai_addrlen) == -1){
|
||||||
|
close(sock);
|
||||||
|
WARN("bind");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break; // if we get here, we have a successfull connection
|
||||||
|
}
|
||||||
|
if(p == NULL){
|
||||||
|
// looped off the end of the list with no successful bind
|
||||||
|
ERRX("failed to bind socket");
|
||||||
|
}
|
||||||
|
// Listen
|
||||||
|
if(listen(sock, BACKLOG) == -1){
|
||||||
|
ERR("listen");
|
||||||
|
}
|
||||||
|
freeaddrinfo(res);
|
||||||
|
// Main loop
|
||||||
|
while(!global_quit){
|
||||||
|
// fd_set readfds;
|
||||||
|
// struct timeval timeout;
|
||||||
|
socklen_t size = sizeof(struct sockaddr_in);
|
||||||
|
struct sockaddr_in their_addr;
|
||||||
|
int newsock;
|
||||||
|
/* FD_ZERO(&readfds);
|
||||||
|
FD_SET(sock, &readfds);
|
||||||
|
timeout.tv_sec = 0; // wait not more than 10 milliseconds
|
||||||
|
timeout.tv_usec = 10000;
|
||||||
|
int sel = select(sock + 1 , &readfds , NULL , NULL , &timeout);
|
||||||
|
if(sel < 0){
|
||||||
|
if(errno != EINTR)
|
||||||
|
WARN("select()");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!(FD_ISSET(sock, &readfds))) continue;*/
|
||||||
|
// DBG("accept");
|
||||||
|
newsock = accept(sock, (struct sockaddr*)&their_addr, &size);
|
||||||
|
// printf("got addr %ul\n", their_addr.sin_addr.s_addr);
|
||||||
|
if(newsock <= 0){
|
||||||
|
WARN("accept()");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pid_t pid = fork();
|
||||||
|
if(pid < 0)
|
||||||
|
ERR("ERROR on fork");
|
||||||
|
if(pid == 0){
|
||||||
|
close(sock);
|
||||||
|
handle_socket(newsock);
|
||||||
|
exit(0);
|
||||||
|
}else
|
||||||
|
close(newsock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for thread ends before closing videodev
|
||||||
|
// pthread_join(readout_thread, NULL);
|
||||||
|
// pthread_mutex_unlock(&readout_mutex);
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(_U_ int argc, char **argv){
|
||||||
|
// setup coloured output
|
||||||
|
initial_setup();
|
||||||
|
check4running(argv, NULL, NULL);
|
||||||
|
// Global_parameters = parce_args(argc, argv);
|
||||||
|
// assert(Global_parameters != NULL);
|
||||||
|
|
||||||
|
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 // daemonize only in release mode
|
||||||
|
if(!Global_parameters->nodaemon){
|
||||||
|
if(daemon(1, 0)){
|
||||||
|
perror("daemon()");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // EBUG
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
while(1){
|
||||||
|
pid_t childpid = fork();
|
||||||
|
if(childpid){
|
||||||
|
DBG("Created child with PID %d\n", childpid);
|
||||||
|
wait(NULL);
|
||||||
|
printf("Child %d died\n", childpid);
|
||||||
|
}else{
|
||||||
|
prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies
|
||||||
|
main_proc();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
main_proc();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
42
Stellarium_control/main.h
Normal file
42
Stellarium_control/main.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* main.h
|
||||||
|
*
|
||||||
|
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef __MAIN_H__
|
||||||
|
#define __MAIN_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "cmdlnopts.h"
|
||||||
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
|
// global parameters
|
||||||
|
extern glob_pars *Global_parameters;
|
||||||
|
|
||||||
|
#endif // __MAIN_H__
|
||||||
316
Stellarium_control/usefull_macros.c
Normal file
316
Stellarium_control/usefull_macros.c
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
/*
|
||||||
|
* usefull_macros.h - a set of usefull functions: memory, color etc
|
||||||
|
*
|
||||||
|
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
/**
|
||||||
|
* function for different purposes that need to know time intervals
|
||||||
|
* @return double value: time in seconds
|
||||||
|
*/
|
||||||
|
double dtime(){
|
||||||
|
double t;
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
t = tv.tv_sec + ((double)tv.tv_usec)/1e6;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
* Coloured terminal
|
||||||
|
\******************************************************************************/
|
||||||
|
int globErr = 0; // errno for WARN/ERR
|
||||||
|
|
||||||
|
// pointers to coloured output printf
|
||||||
|
int (*red)(const char *fmt, ...);
|
||||||
|
int (*green)(const char *fmt, ...);
|
||||||
|
int (*_WARN)(const char *fmt, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* format red / green messages
|
||||||
|
* name: r_pr_, g_pr_
|
||||||
|
* @param fmt ... - printf-like format
|
||||||
|
* @return number of printed symbols
|
||||||
|
*/
|
||||||
|
int r_pr_(const char *fmt, ...){
|
||||||
|
va_list ar; int i;
|
||||||
|
printf(RED);
|
||||||
|
va_start(ar, fmt);
|
||||||
|
i = vprintf(fmt, ar);
|
||||||
|
va_end(ar);
|
||||||
|
printf(OLDCOLOR);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
int g_pr_(const char *fmt, ...){
|
||||||
|
va_list ar; int i;
|
||||||
|
printf(GREEN);
|
||||||
|
va_start(ar, fmt);
|
||||||
|
i = vprintf(fmt, ar);
|
||||||
|
va_end(ar);
|
||||||
|
printf(OLDCOLOR);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* print red error/warning messages (if output is a tty)
|
||||||
|
* @param fmt ... - printf-like format
|
||||||
|
* @return number of printed symbols
|
||||||
|
*/
|
||||||
|
int r_WARN(const char *fmt, ...){
|
||||||
|
va_list ar; int i = 1;
|
||||||
|
fprintf(stderr, RED);
|
||||||
|
va_start(ar, fmt);
|
||||||
|
if(globErr){
|
||||||
|
errno = globErr;
|
||||||
|
vwarn(fmt, ar);
|
||||||
|
errno = 0;
|
||||||
|
globErr = 0;
|
||||||
|
}else
|
||||||
|
i = vfprintf(stderr, fmt, ar);
|
||||||
|
va_end(ar);
|
||||||
|
i++;
|
||||||
|
fprintf(stderr, OLDCOLOR "\n");
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char stars[] = "****************************************";
|
||||||
|
/*
|
||||||
|
* notty variants of coloured printf
|
||||||
|
* name: s_WARN, r_pr_notty
|
||||||
|
* @param fmt ... - printf-like format
|
||||||
|
* @return number of printed symbols
|
||||||
|
*/
|
||||||
|
int s_WARN(const char *fmt, ...){
|
||||||
|
va_list ar; int i;
|
||||||
|
i = fprintf(stderr, "\n%s\n", stars);
|
||||||
|
va_start(ar, fmt);
|
||||||
|
if(globErr){
|
||||||
|
errno = globErr;
|
||||||
|
vwarn(fmt, ar);
|
||||||
|
errno = 0;
|
||||||
|
globErr = 0;
|
||||||
|
}else
|
||||||
|
i = +vfprintf(stderr, fmt, ar);
|
||||||
|
va_end(ar);
|
||||||
|
i += fprintf(stderr, "\n%s\n", stars);
|
||||||
|
i += fprintf(stderr, "\n");
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
int r_pr_notty(const char *fmt, ...){
|
||||||
|
va_list ar; int i;
|
||||||
|
i = printf("\n%s\n", stars);
|
||||||
|
va_start(ar, fmt);
|
||||||
|
i += vprintf(fmt, ar);
|
||||||
|
va_end(ar);
|
||||||
|
i += printf("\n%s\n", stars);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run this function in the beginning of main() to setup locale & coloured output
|
||||||
|
*/
|
||||||
|
void initial_setup(){
|
||||||
|
// setup coloured output
|
||||||
|
if(isatty(STDOUT_FILENO)){ // make color output in tty
|
||||||
|
red = r_pr_; green = g_pr_;
|
||||||
|
}else{ // no colors in case of pipe
|
||||||
|
red = r_pr_notty; green = printf;
|
||||||
|
}
|
||||||
|
if(isatty(STDERR_FILENO)) _WARN = r_WARN;
|
||||||
|
else _WARN = s_WARN;
|
||||||
|
// Setup locale
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
setlocale(LC_NUMERIC, "C");
|
||||||
|
#ifdef GETTEXT_PACKAGE
|
||||||
|
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
||||||
|
textdomain(GETTEXT_PACKAGE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
* Memory
|
||||||
|
\******************************************************************************/
|
||||||
|
/*
|
||||||
|
* safe memory allocation for macro ALLOC
|
||||||
|
* @param N - number of elements to allocate
|
||||||
|
* @param S - size of single element (typically sizeof)
|
||||||
|
* @return pointer to allocated memory area
|
||||||
|
*/
|
||||||
|
void *my_alloc(size_t N, size_t S){
|
||||||
|
void *p = calloc(N, S);
|
||||||
|
if(!p) ERR("malloc");
|
||||||
|
//assert(p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Mmap file to a memory area
|
||||||
|
*
|
||||||
|
* @param filename (i) - name of file to mmap
|
||||||
|
* @return stuct with mmap'ed file or die
|
||||||
|
*/
|
||||||
|
mmapbuf *My_mmap(char *filename){
|
||||||
|
int fd;
|
||||||
|
char *ptr;
|
||||||
|
size_t Mlen;
|
||||||
|
struct stat statbuf;
|
||||||
|
if(!filename) ERRX(_("No filename given!"));
|
||||||
|
if((fd = open(filename, O_RDONLY)) < 0)
|
||||||
|
ERR(_("Can't open %s for reading"), filename);
|
||||||
|
if(fstat (fd, &statbuf) < 0)
|
||||||
|
ERR(_("Can't stat %s"), filename);
|
||||||
|
Mlen = statbuf.st_size;
|
||||||
|
if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
|
||||||
|
ERR(_("Mmap error for input"));
|
||||||
|
if(close(fd)) ERR(_("Can't close mmap'ed file"));
|
||||||
|
mmapbuf *ret = MALLOC(mmapbuf, 1);
|
||||||
|
ret->data = ptr;
|
||||||
|
ret->len = Mlen;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void My_munmap(mmapbuf *b){
|
||||||
|
if(munmap(b->data, b->len))
|
||||||
|
ERR(_("Can't munmap"));
|
||||||
|
FREE(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
* Terminal in no-echo mode
|
||||||
|
\******************************************************************************/
|
||||||
|
struct termios oldt, newt; // terminal flags
|
||||||
|
// run on exit:
|
||||||
|
/*
|
||||||
|
void quit(int sig){
|
||||||
|
//...
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // return terminal to previous state
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// initial setup:
|
||||||
|
void setup_con(){
|
||||||
|
tcgetattr(STDIN_FILENO, &oldt);
|
||||||
|
newt = oldt;
|
||||||
|
newt.c_lflag &= ~(ICANON | ECHO);
|
||||||
|
if(tcsetattr(STDIN_FILENO, TCSANOW, &newt) < 0){
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||||
|
exit(-2); //quit?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read character from console without echo
|
||||||
|
* @return char readed
|
||||||
|
*/
|
||||||
|
int read_console(){
|
||||||
|
int rb;
|
||||||
|
struct timeval tv;
|
||||||
|
int retval;
|
||||||
|
fd_set rfds;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(STDIN_FILENO, &rfds);
|
||||||
|
tv.tv_sec = 0; tv.tv_usec = 10000;
|
||||||
|
retval = select(1, &rfds, NULL, NULL, &tv);
|
||||||
|
if(!retval) rb = 0;
|
||||||
|
else {
|
||||||
|
if(FD_ISSET(STDIN_FILENO, &rfds)) rb = getchar();
|
||||||
|
else rb = 0;
|
||||||
|
}
|
||||||
|
return rb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getchar() without echo
|
||||||
|
* wait until at least one character pressed
|
||||||
|
* @return character readed
|
||||||
|
*/
|
||||||
|
int mygetchar(){ // аналог getchar() без необходимости жать Enter
|
||||||
|
int ret;
|
||||||
|
do ret = read_console();
|
||||||
|
while(ret == 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
* TTY with select()
|
||||||
|
\******************************************************************************/
|
||||||
|
struct termio oldtty, tty; // TTY flags
|
||||||
|
char *comdev; // TTY device name
|
||||||
|
int comfd; // TTY fd
|
||||||
|
// run on exit:
|
||||||
|
/*
|
||||||
|
void quit(int ex_stat){
|
||||||
|
ioctl(comfd, TCSANOW, &oldtty ); // return TTY to previous state
|
||||||
|
close(comfd);
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#ifndef BAUD_RATE
|
||||||
|
#define BAUD_RATE B9600
|
||||||
|
#endif
|
||||||
|
// init:
|
||||||
|
void tty_init(){
|
||||||
|
printf("\nOpen port...\n");
|
||||||
|
if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){
|
||||||
|
fprintf(stderr,"Can't use port %s\n",comdev);
|
||||||
|
ioctl(comfd, TCSANOW, &oldtty); // return TTY to previous state
|
||||||
|
close(comfd);
|
||||||
|
exit(1); // quit?
|
||||||
|
}
|
||||||
|
printf(" OK\nGet current settings...\n");
|
||||||
|
if(ioctl(comfd,TCGETA,&oldtty) < 0) exit(-1); // Get settings
|
||||||
|
tty = oldtty;
|
||||||
|
tty.c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG)
|
||||||
|
tty.c_oflag = 0;
|
||||||
|
tty.c_cflag = BAUD_RATE|CS8|CREAD|CLOCAL; // 9.6k, 8N1, RW, ignore line ctrl
|
||||||
|
tty.c_cc[VMIN] = 0; // non-canonical mode
|
||||||
|
tty.c_cc[VTIME] = 5;
|
||||||
|
if(ioctl(comfd,TCSETA,&tty) < 0) exit(-1); // set new mode
|
||||||
|
printf(" OK\n");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Read data from TTY
|
||||||
|
* @param buff (o) - buffer for data read
|
||||||
|
* @param length - buffer len
|
||||||
|
* @return amount of readed bytes
|
||||||
|
*/
|
||||||
|
size_t read_tty(uint8_t *buff, size_t length){
|
||||||
|
ssize_t L = 0;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
int retval;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(comfd, &rfds);
|
||||||
|
tv.tv_sec = 0; tv.tv_usec = 50000; // wait for 50ms
|
||||||
|
retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if (!retval) return 0;
|
||||||
|
if(FD_ISSET(comfd, &rfds)){
|
||||||
|
if((L = read(comfd, buff, length)) < 1) return 0;
|
||||||
|
}
|
||||||
|
return (size_t)L;
|
||||||
|
}
|
||||||
106
Stellarium_control/usefull_macros.h
Normal file
106
Stellarium_control/usefull_macros.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* usefull_macros.h - a set of usefull macros: memory, color etc
|
||||||
|
*
|
||||||
|
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __USEFULL_MACROS_H__
|
||||||
|
#define __USEFULL_MACROS_H__
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <termio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GETTEXT
|
||||||
|
*/
|
||||||
|
#define _(String) gettext(String)
|
||||||
|
#define gettext_noop(String) String
|
||||||
|
#define N_(String) gettext_noop(String)
|
||||||
|
|
||||||
|
// unused arguments with -Wall -Werror
|
||||||
|
#define _U_ __attribute__((__unused__))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Coloured messages output
|
||||||
|
*/
|
||||||
|
#define RED "\033[1;31;40m"
|
||||||
|
#define GREEN "\033[1;32;40m"
|
||||||
|
#define OLDCOLOR "\033[0;0;0m"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ERROR/WARNING messages
|
||||||
|
*/
|
||||||
|
extern int globErr;
|
||||||
|
#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); exit(-1);}while(0)
|
||||||
|
#define ERRX(...) do{globErr=0; _WARN(__VA_ARGS__); exit(-1);}while(0)
|
||||||
|
#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0)
|
||||||
|
#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print function name, debug messages
|
||||||
|
* debug mode, -DEBUG
|
||||||
|
*/
|
||||||
|
#ifdef EBUG
|
||||||
|
#define FNAME() fprintf(stderr, "\n%s (%s, line %d)\n", __func__, __FILE__, __LINE__)
|
||||||
|
#define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); \
|
||||||
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
|
fprintf(stderr, "\n");} while(0)
|
||||||
|
#else
|
||||||
|
#define FNAME() do{}while(0)
|
||||||
|
#define DBG(...) do{}while(0)
|
||||||
|
#endif //EBUG
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Memory allocation
|
||||||
|
*/
|
||||||
|
#define ALLOC(type, var, size) type * var = ((type *)my_alloc(size, sizeof(type)))
|
||||||
|
#define MALLOC(type, size) ((type *)my_alloc(size, sizeof(type)))
|
||||||
|
#define FREE(ptr) do{free(ptr); ptr = NULL;}while(0)
|
||||||
|
|
||||||
|
// functions for color output in tty & no-color in pipes
|
||||||
|
extern int (*red)(const char *fmt, ...);
|
||||||
|
extern int (*_WARN)(const char *fmt, ...);
|
||||||
|
extern int (*green)(const char *fmt, ...);
|
||||||
|
void * my_alloc(size_t N, size_t S);
|
||||||
|
void initial_setup();
|
||||||
|
|
||||||
|
// mmap file
|
||||||
|
typedef struct{
|
||||||
|
char *data;
|
||||||
|
size_t len;
|
||||||
|
} mmapbuf;
|
||||||
|
mmapbuf *My_mmap(char *filename);
|
||||||
|
void My_munmap(mmapbuf *b);
|
||||||
|
|
||||||
|
#endif // __USEFULL_MACROS_H__
|
||||||
Loading…
x
Reference in New Issue
Block a user