mirror of
https://github.com/eddyem/snippets_library.git
synced 2025-12-06 10:45:10 +03:00
Add ringbuffer to start adding sockets
This commit is contained in:
parent
e77fddc3b8
commit
54e88cfd92
2
daemon.c
2
daemon.c
@ -66,7 +66,6 @@ char *sl_getPSname(pid_t pid){
|
|||||||
* Redefine this function for user action
|
* Redefine this function for user action
|
||||||
*/
|
*/
|
||||||
void WEAK sl_iffound_deflt(pid_t pid){
|
void WEAK sl_iffound_deflt(pid_t pid){
|
||||||
/// \nОбнаружен одноименный процесс (pid=%d), выход.\n
|
|
||||||
fprintf(stderr, _("\nFound running process (pid=%d), exit.\n"), pid);
|
fprintf(stderr, _("\nFound running process (pid=%d), exit.\n"), pid);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
@ -139,7 +138,6 @@ void sl_check4running(char *selfname, char *pidfilename){
|
|||||||
free(myname);
|
free(myname);
|
||||||
if(pidfilename){
|
if(pidfilename){
|
||||||
pidfile = fopen(pidfilename, "w");
|
pidfile = fopen(pidfilename, "w");
|
||||||
/// Не могу открыть PID файл
|
|
||||||
if(!pidfile) ERR(_("Can't open PID file"));
|
if(!pidfile) ERR(_("Can't open PID file"));
|
||||||
fprintf(pidfile, "%d\n", self); // write self PID to pidfile
|
fprintf(pidfile, "%d\n", self); // write self PID to pidfile
|
||||||
fclose(pidfile);
|
fclose(pidfile);
|
||||||
|
|||||||
@ -10,3 +10,5 @@ add_executable(helloworld helloworld.c)
|
|||||||
add_executable(options options.c cmdlnopts.c)
|
add_executable(options options.c cmdlnopts.c)
|
||||||
add_executable(fifo fifo.c)
|
add_executable(fifo fifo.c)
|
||||||
add_executable(conffile conffile.c)
|
add_executable(conffile conffile.c)
|
||||||
|
add_executable(clientserver clientserver.c)
|
||||||
|
add_executable(ringbuffer ringbuffer.c)
|
||||||
|
|||||||
46
examples/__template.c
Normal file
46
examples/__template.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2024 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int help;
|
||||||
|
int verbose;
|
||||||
|
char *logfile;
|
||||||
|
} parameters;
|
||||||
|
|
||||||
|
static parameters G = {0};
|
||||||
|
|
||||||
|
static sl_option_t cmdlnopts[] = {
|
||||||
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"},
|
||||||
|
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose), "verbose level (each -v adds 1)"},
|
||||||
|
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), "log file name"},
|
||||||
|
end_option
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
sl_init();
|
||||||
|
sl_parseargs(&argc, &argv, cmdlnopts);
|
||||||
|
if(G.help) sl_showhelp(-1, cmdlnopts);
|
||||||
|
sl_loglevel_e lvl = G.verbose + LOGLEVEL_ERR;
|
||||||
|
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
||||||
|
if(G.logfile) OPENLOG(G.logfile, lvl, 1);
|
||||||
|
LOGMSG("hello");
|
||||||
|
LOGERRADD("additional to err");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
46
examples/clientserver.c
Normal file
46
examples/clientserver.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2024 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int help;
|
||||||
|
int verbose;
|
||||||
|
char *logfile;
|
||||||
|
} parameters;
|
||||||
|
|
||||||
|
static parameters G = {0};
|
||||||
|
|
||||||
|
static sl_option_t cmdlnopts[] = {
|
||||||
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"},
|
||||||
|
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose), "verbose level (each -v adds 1)"},
|
||||||
|
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), "log file name"},
|
||||||
|
end_option
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
sl_init();
|
||||||
|
sl_parseargs(&argc, &argv, cmdlnopts);
|
||||||
|
if(G.help) sl_showhelp(-1, cmdlnopts);
|
||||||
|
sl_loglevel_e lvl = G.verbose + LOGLEVEL_ERR;
|
||||||
|
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
||||||
|
if(G.logfile) OPENLOG(G.logfile, lvl, 1);
|
||||||
|
LOGMSG("hello");
|
||||||
|
LOGERRADD("additional to err");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
80
examples/ringbuffer.c
Normal file
80
examples/ringbuffer.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2024 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#define BUFS 128
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int help;
|
||||||
|
int verbose;
|
||||||
|
int size;
|
||||||
|
} parameters;
|
||||||
|
|
||||||
|
static parameters G = {
|
||||||
|
.size = 1024,
|
||||||
|
};
|
||||||
|
|
||||||
|
static sl_option_t cmdlnopts[] = {
|
||||||
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"},
|
||||||
|
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose), "verbose level (each -v adds 1)"},
|
||||||
|
{"bufsize", NEED_ARG, NULL, 's', arg_longlong,APTR(&G.size), "size of ring buffer"},
|
||||||
|
end_option
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
sl_init();
|
||||||
|
sl_parseargs(&argc, &argv, cmdlnopts);
|
||||||
|
if(G.help) sl_showhelp(-1, cmdlnopts);
|
||||||
|
sl_ringbuffer *b = sl_RB_new(G.size);
|
||||||
|
if(!b) return 1;
|
||||||
|
printf("Created ring buffer of %d bytes\n", G.size);
|
||||||
|
printf("Enter lines of text to fill it or type (get) to get one line from buffer\n");
|
||||||
|
ssize_t got = -1;
|
||||||
|
char buf[BUFS];
|
||||||
|
for(int nline = 1; ; ++nline){
|
||||||
|
printf("%4d > ", nline);
|
||||||
|
char *ln = NULL; size_t ls = 0;
|
||||||
|
got = getline(&ln, &ls, stdin);
|
||||||
|
if(got < 1){ FREE(ln); break; }
|
||||||
|
if(0 == strcmp(ln, "get\n")){
|
||||||
|
if(sl_RB_readline(b, buf, BUFS)){
|
||||||
|
printf("line: %s\n", buf);
|
||||||
|
nline -= 2;
|
||||||
|
}else --nline;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!sl_RB_writestr(b, ln)){
|
||||||
|
WARNX("Buffer overfull");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n This is all rest buffer data:\n");
|
||||||
|
for(int nline = 1; ; ++nline){
|
||||||
|
int r = sl_RB_readline(b, buf, BUFS);
|
||||||
|
if(r < 1){
|
||||||
|
if(r == -1) WARNX("Next string it too long");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("line %d: %s\n", nline, buf);
|
||||||
|
}
|
||||||
|
sl_RB_delete(&b);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
34
parseargs.c
34
parseargs.c
@ -50,7 +50,6 @@ void sl_helpstring(char *s){
|
|||||||
if(str[1] == 's') scount++; // increment "%s" counter
|
if(str[1] == 's') scount++; // increment "%s" counter
|
||||||
};
|
};
|
||||||
if(pcount > 1 || pcount != scount){ // amount of pcount and/or scount wrong
|
if(pcount > 1 || pcount != scount){ // amount of pcount and/or scount wrong
|
||||||
/// îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ
|
|
||||||
ERRX(_("Wrong helpstring!"));
|
ERRX(_("Wrong helpstring!"));
|
||||||
}
|
}
|
||||||
helpstring = s;
|
helpstring = s;
|
||||||
@ -80,7 +79,6 @@ static int myatoll(void *num, char *str, sl_argtype_e t){
|
|||||||
case arg_int:
|
case arg_int:
|
||||||
default:
|
default:
|
||||||
if(tmp < INT_MIN || tmp > INT_MAX){
|
if(tmp < INT_MIN || tmp > INT_MAX){
|
||||||
/// ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ
|
|
||||||
WARNX(_("Integer out of range"));
|
WARNX(_("Integer out of range"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -165,7 +163,6 @@ void *get_aptr(void *paptr, sl_argtype_e type){
|
|||||||
switch(type){
|
switch(type){
|
||||||
default:
|
default:
|
||||||
case arg_none:
|
case arg_none:
|
||||||
/// "îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÎÅÓËÏÌØËÏ ÐÁÒÁÍÅÔÒÏ× ÂÅÚ ÁÒÇÕÍÅÎÔÏ×!"
|
|
||||||
ERRX(_("Can't use multiple args with arg_none!"));
|
ERRX(_("Can't use multiple args with arg_none!"));
|
||||||
break;
|
break;
|
||||||
case arg_int:
|
case arg_int:
|
||||||
@ -286,24 +283,6 @@ void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
|||||||
DBG("%c(%d) = getopt_long(argc, argv, %s, long_options, &%d); optopt=%c(%d), errno=%d", opt, opt, short_options, optind, optopt, optopt, errno);
|
DBG("%c(%d) = getopt_long(argc, argv, %s, long_options, &%d); optopt=%c(%d), errno=%d", opt, opt, short_options, optind, optopt, optopt, errno);
|
||||||
if(optind < 0 ) optind = get_optind(opt, options); // find short option -> need to know index of long
|
if(optind < 0 ) optind = get_optind(opt, options); // find short option -> need to know index of long
|
||||||
// be careful with "-?" flag: all wrong or ambiguous flags will be interpreted as this!
|
// be careful with "-?" flag: all wrong or ambiguous flags will be interpreted as this!
|
||||||
/*
|
|
||||||
if(opt == '?'){ // real '?', wrong option or no argument when need
|
|
||||||
opt = optopt; // original short opt or 0 for wrong or long
|
|
||||||
if(opt == 0){ // '?' or wrong long
|
|
||||||
// there's no way to understand difference between real '-?' and unknown long flag
|
|
||||||
DBG("'?' or unknown parameter");
|
|
||||||
sl_showhelp(-1, options);
|
|
||||||
}else optind = get_optind(opt, options);
|
|
||||||
DBG("optind = %d", optind);
|
|
||||||
if(options[optind].has_arg == NEED_ARG || options[optind].has_arg == MULT_PAR)
|
|
||||||
sl_showhelp(optind, options); // need argument
|
|
||||||
}else{
|
|
||||||
// we should call functions get_optind / get_optindl for options where there's no long analog
|
|
||||||
if(opt < ' ') optind = get_optindl(&long_options[oindex], options);
|
|
||||||
else optind = get_optind(opt, options);
|
|
||||||
}
|
|
||||||
if(optind < 0) sl_showhelp(-1, options); // wrong argument
|
|
||||||
*/
|
|
||||||
DBG("index=%d", optind);
|
DBG("index=%d", optind);
|
||||||
opts = &options[optind];
|
opts = &options[optind];
|
||||||
DBG("Got option %s", opts->name);
|
DBG("Got option %s", opts->name);
|
||||||
@ -327,23 +306,23 @@ void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
|||||||
break;
|
break;
|
||||||
case arg_int:
|
case arg_int:
|
||||||
result = myatoll(aptr, optarg, arg_int);
|
result = myatoll(aptr, optarg, arg_int);
|
||||||
type = _("integer");
|
type = "integer";
|
||||||
break;
|
break;
|
||||||
case arg_longlong:
|
case arg_longlong:
|
||||||
result = myatoll(aptr, optarg, arg_longlong);
|
result = myatoll(aptr, optarg, arg_longlong);
|
||||||
type = _("long long");
|
type = "long long";
|
||||||
break;
|
break;
|
||||||
case arg_double:
|
case arg_double:
|
||||||
result = myatod(aptr, optarg, arg_double);
|
result = myatod(aptr, optarg, arg_double);
|
||||||
type = _("double");
|
type = "double";
|
||||||
break;
|
break;
|
||||||
case arg_float:
|
case arg_float:
|
||||||
result = myatod(aptr, optarg, arg_float);
|
result = myatod(aptr, optarg, arg_float);
|
||||||
type = _("float");
|
type = "float";
|
||||||
break;
|
break;
|
||||||
case arg_string:
|
case arg_string:
|
||||||
result = (*((void**)aptr) = (void*)strdup(optarg)) != NULL;
|
result = (*((void**)aptr) = (void*)strdup(optarg)) != NULL;
|
||||||
type = _("string");
|
type = "string";
|
||||||
break;
|
break;
|
||||||
case arg_function:
|
case arg_function:
|
||||||
result = ((sl_argfn_t)aptr)(optarg);
|
result = ((sl_argfn_t)aptr)(optarg);
|
||||||
@ -504,17 +483,14 @@ int sl_get_suboption(char *str, sl_suboption_t *opt){
|
|||||||
}
|
}
|
||||||
int idx = findsubopt(tok, opt);
|
int idx = findsubopt(tok, opt);
|
||||||
if(idx < 0){
|
if(idx < 0){
|
||||||
/// îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s
|
|
||||||
WARNX(_("Wrong parameter: %s"), tok);
|
WARNX(_("Wrong parameter: %s"), tok);
|
||||||
goto returning;
|
goto returning;
|
||||||
}
|
}
|
||||||
if(noarg && opt[idx].has_arg == NEED_ARG){
|
if(noarg && opt[idx].has_arg == NEED_ARG){
|
||||||
/// %s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!
|
|
||||||
WARNX(_("%s: need argument!"), tok);
|
WARNX(_("%s: need argument!"), tok);
|
||||||
goto returning;
|
goto returning;
|
||||||
}
|
}
|
||||||
if(!opt_setarg(opt, idx, val)){
|
if(!opt_setarg(opt, idx, val)){
|
||||||
/// îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\"
|
|
||||||
WARNX(_("Wrong argument \"%s\" of parameter \"%s\""), val, tok);
|
WARNX(_("Wrong argument \"%s\" of parameter \"%s\""), val, tok);
|
||||||
goto returning;
|
goto returning;
|
||||||
}
|
}
|
||||||
|
|||||||
256
ringbuffer.c
Normal file
256
ringbuffer.c
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2024 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_new - create ringbuffer with `size` bytes
|
||||||
|
* @param size - RB size
|
||||||
|
* @return RB
|
||||||
|
*/
|
||||||
|
sl_ringbuffer *sl_RB_new(size_t size){
|
||||||
|
sl_ringbuffer *b = MALLOC(sl_ringbuffer, 1);
|
||||||
|
b->data = MALLOC(uint8_t, size);
|
||||||
|
pthread_mutex_init(&b->busy, NULL);
|
||||||
|
b->head = b->tail = 0;
|
||||||
|
b->length = size;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_delete - free ringbuffer
|
||||||
|
* @param b - buffer to free
|
||||||
|
*/
|
||||||
|
void sl_RB_delete(sl_ringbuffer **b){
|
||||||
|
if(!b || !*b) return;
|
||||||
|
sl_ringbuffer *bptr = *b;
|
||||||
|
pthread_mutex_lock(&bptr->busy);
|
||||||
|
FREE(bptr->data);
|
||||||
|
*b = 0;
|
||||||
|
pthread_mutex_unlock(&bptr->busy);
|
||||||
|
FREE(bptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief datalen - amount of bytes in buffer
|
||||||
|
* @param b - buffer
|
||||||
|
* @return N
|
||||||
|
*/
|
||||||
|
static size_t datalen(sl_ringbuffer *b){
|
||||||
|
if(b->tail >= b->head) return (b->tail - b->head);
|
||||||
|
else return (b->length - b->head + b->tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
// datalen but with blocking of RB
|
||||||
|
size_t sl_RB_datalen(sl_ringbuffer *b){
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
size_t l = datalen(b);
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief hasbyte - check if RB have given byte
|
||||||
|
* @param b - rb
|
||||||
|
* @param byte - what to find
|
||||||
|
* @return index of byte or -1 if not found or no data
|
||||||
|
*/
|
||||||
|
static ssize_t hasbyte(sl_ringbuffer *b, uint8_t byte){
|
||||||
|
if(b->head == b->tail) return -1; // no data in buffer
|
||||||
|
size_t startidx = b->head;
|
||||||
|
if(b->head > b->tail){
|
||||||
|
for(size_t found = b->head; found < b->length; ++found)
|
||||||
|
if(b->data[found] == byte) return found;
|
||||||
|
startidx = 0;
|
||||||
|
}
|
||||||
|
for(size_t found = startidx; found < b->tail; ++found)
|
||||||
|
if(b->data[found] == byte) return found;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasbyte with block
|
||||||
|
ssize_t sl_RB_hasbyte(sl_ringbuffer *b, uint8_t byte){
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
size_t idx = hasbyte(b, byte);
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
// increment head or tail
|
||||||
|
inline void incr(sl_ringbuffer *b, volatile size_t *what, size_t n){
|
||||||
|
*what += n;
|
||||||
|
if(*what >= b->length) *what -= b->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t rbread(sl_ringbuffer *b, uint8_t *s, size_t len){
|
||||||
|
size_t l = datalen(b);
|
||||||
|
if(!l) return 0;
|
||||||
|
if(l > len) l = len;
|
||||||
|
size_t _1st = b->length - b->head;
|
||||||
|
if(_1st > l) _1st = l;
|
||||||
|
if(_1st > len) _1st = len;
|
||||||
|
memcpy(s, b->data + b->head, _1st);
|
||||||
|
if(_1st < len && l > _1st){
|
||||||
|
memcpy(s+_1st, b->data, l - _1st);
|
||||||
|
incr(b, &b->head, l);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
incr(b, &b->head, _1st);
|
||||||
|
return _1st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_read - read data from rb
|
||||||
|
* @param b - rb
|
||||||
|
* @param s - buffer for data
|
||||||
|
* @param len - length of `s`
|
||||||
|
* @return amount of bytes read
|
||||||
|
*/
|
||||||
|
size_t sl_RB_read(sl_ringbuffer *b, uint8_t *s, size_t len){
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
size_t got = rbread(b, s, len);
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_readto - read until meet byte `byte`
|
||||||
|
* @param b - rb
|
||||||
|
* @param byte - byte to find
|
||||||
|
* @param s - receiver
|
||||||
|
* @param len - length of `s`
|
||||||
|
* @return amount of bytes read or -1 if `s` have insufficient size
|
||||||
|
*/
|
||||||
|
ssize_t sl_RB_readto(sl_ringbuffer *b, uint8_t byte, uint8_t *s, size_t len){
|
||||||
|
ssize_t got = 0;
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
ssize_t idx = hasbyte(b, byte);
|
||||||
|
if(idx < 0) goto ret;
|
||||||
|
size_t partlen = idx + 1 - b->head;
|
||||||
|
// now calculate length of new data portion
|
||||||
|
if((size_t)idx < b->head) partlen += b->length;
|
||||||
|
if(partlen > len) got = -1;
|
||||||
|
else got = rbread(b, s, partlen);
|
||||||
|
ret:
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_readline - read string of text ends with '\n'
|
||||||
|
* @param b - rb
|
||||||
|
* @param s - string buffer
|
||||||
|
* @param len - length of `s`
|
||||||
|
* @return amount of characters read or -1 if buffer too small
|
||||||
|
* !!! this function changes '\n' to 0 in `s`; `len` should include trailing '\0' too
|
||||||
|
*/
|
||||||
|
ssize_t sl_RB_readline(sl_ringbuffer *b, char *s, size_t len){
|
||||||
|
ssize_t got = 0;
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
ssize_t idx = hasbyte(b, '\n');
|
||||||
|
if(idx < 0) goto ret;
|
||||||
|
size_t partlen = idx + 1 - b->head;
|
||||||
|
// now calculate length of new data portion
|
||||||
|
if((size_t)idx < b->head) partlen += b->length;
|
||||||
|
if(partlen > len) got = -1;
|
||||||
|
else{
|
||||||
|
got = rbread(b, (uint8_t*)s, partlen);
|
||||||
|
s[partlen - 1] = 0; // substitute '\n' with trailing zero
|
||||||
|
}
|
||||||
|
ret:
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_putbyte - put one byte into rb
|
||||||
|
* @param b - rb
|
||||||
|
* @param byte - data byte
|
||||||
|
* @return FALSE if there's no place for `byte` in `b`
|
||||||
|
*/
|
||||||
|
int sl_RB_putbyte(sl_ringbuffer *b, uint8_t byte){
|
||||||
|
int rtn = FALSE;
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
size_t s = datalen(b);
|
||||||
|
if(b->length == s + 1) goto ret;
|
||||||
|
b->data[b->tail] = byte;
|
||||||
|
incr(b, &b->tail, 1);
|
||||||
|
rtn = TRUE;
|
||||||
|
ret:
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_write - write data to buffer
|
||||||
|
* @param b - buffer
|
||||||
|
* @param str - data
|
||||||
|
* @param len - data length
|
||||||
|
* @return amount of bytes wrote (can be less than `len`)
|
||||||
|
*/
|
||||||
|
size_t sl_RB_write(sl_ringbuffer *b, const uint8_t *str, size_t len){
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
size_t r = b->length - 1 - datalen(b); // rest length
|
||||||
|
if(len > r) len = r;
|
||||||
|
if(!len){ r = 0; goto ret; }
|
||||||
|
size_t _1st = b->length - b->tail;
|
||||||
|
if(_1st > len) _1st = len;
|
||||||
|
memcpy(b->data + b->tail, str, _1st);
|
||||||
|
if(_1st < len){ // add another piece from start
|
||||||
|
memcpy(b->data, str+_1st, len-_1st);
|
||||||
|
}
|
||||||
|
incr(b, &b->tail, len);
|
||||||
|
ret:
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_clearbuf - reset buffer
|
||||||
|
* @param b - rb
|
||||||
|
*/
|
||||||
|
void sl_RB_clearbuf(sl_ringbuffer *b){
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
b->head = 0;
|
||||||
|
b->tail = 0;
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_RB_writestr - write FULL string `s` to buffer (without trailing zero!)
|
||||||
|
* @param b - rb
|
||||||
|
* @param s - string
|
||||||
|
* @return amount of bytes written (strlen of s) or 0
|
||||||
|
*/
|
||||||
|
size_t sl_RB_writestr(sl_ringbuffer *b, char *s){
|
||||||
|
size_t len = strlen(s);
|
||||||
|
pthread_mutex_lock(&b->busy);
|
||||||
|
size_t r = b->length - 1 - datalen(b); // rest length
|
||||||
|
if(len > r){ len = 0; goto ret; } // insufficient space - don't even try to write a part
|
||||||
|
size_t _1st = b->length - b->tail;
|
||||||
|
if(_1st > len) _1st = len;
|
||||||
|
memcpy(b->data + b->tail, s, _1st);
|
||||||
|
if(_1st < len){ // add another piece from start
|
||||||
|
memcpy(b->data, s+_1st, len-_1st);
|
||||||
|
}
|
||||||
|
incr(b, &b->tail, len);
|
||||||
|
ret:
|
||||||
|
pthread_mutex_unlock(&b->busy);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
20
socket.c
Normal file
20
socket.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2024 Edward V. Emelianov <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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
6
term.c
6
term.c
@ -99,12 +99,10 @@ tcflag_t sl_tty_convspd(int speed){
|
|||||||
static int tty_init(sl_tty_t *descr){
|
static int tty_init(sl_tty_t *descr){
|
||||||
// |O_NONBLOCK ?
|
// |O_NONBLOCK ?
|
||||||
if ((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
|
if ((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
|
||||||
/// Не могу использовать порт %s
|
|
||||||
WARN(_("Can't use port %s"), descr->portname);
|
WARN(_("Can't use port %s"), descr->portname);
|
||||||
return globErr ? globErr : 1;
|
return globErr ? globErr : 1;
|
||||||
}
|
}
|
||||||
if(tcgetattr(descr->comfd, &descr->oldtty) < 0){ // Get settings
|
if(tcgetattr(descr->comfd, &descr->oldtty) < 0){ // Get settings
|
||||||
/// Не могу получить действующие настройки порта
|
|
||||||
WARN(_("Can't get old TTY settings"));
|
WARN(_("Can't get old TTY settings"));
|
||||||
return globErr ? globErr : 1;
|
return globErr ? globErr : 1;
|
||||||
}
|
}
|
||||||
@ -116,14 +114,12 @@ static int tty_init(sl_tty_t *descr){
|
|||||||
descr->tty.c_cc[VMIN] = 0; // non-canonical mode
|
descr->tty.c_cc[VMIN] = 0; // non-canonical mode
|
||||||
descr->tty.c_cc[VTIME] = 5;
|
descr->tty.c_cc[VTIME] = 5;
|
||||||
if(tcsetattr(descr->comfd, TCSANOW, &descr->tty) < 0){
|
if(tcsetattr(descr->comfd, TCSANOW, &descr->tty) < 0){
|
||||||
/// Не могу сменить настройки порта
|
|
||||||
WARN(_("Can't apply new TTY settings"));
|
WARN(_("Can't apply new TTY settings"));
|
||||||
return globErr ? globErr : 1;
|
return globErr ? globErr : 1;
|
||||||
}
|
}
|
||||||
// make exclusive open
|
// make exclusive open
|
||||||
if(descr->exclusive){
|
if(descr->exclusive){
|
||||||
if(ioctl(descr->comfd, TIOCEXCL)){
|
if(ioctl(descr->comfd, TIOCEXCL)){
|
||||||
/// Не могу сделать порт эксклюзивным
|
|
||||||
WARN(_("Can't do exclusive open"));
|
WARN(_("Can't do exclusive open"));
|
||||||
}}
|
}}
|
||||||
return 0;
|
return 0;
|
||||||
@ -159,7 +155,6 @@ sl_tty_t *sl_tty_new(char *comdev, int speed, size_t bufsz){
|
|||||||
descr->baudrate = spd;
|
descr->baudrate = spd;
|
||||||
descr->speed = speed;
|
descr->speed = speed;
|
||||||
if(!descr->portname){
|
if(!descr->portname){
|
||||||
/// Отсутствует имя порта
|
|
||||||
WARNX(_("Port name is missing"));
|
WARNX(_("Port name is missing"));
|
||||||
}else{
|
}else{
|
||||||
if(bufsz){
|
if(bufsz){
|
||||||
@ -252,7 +247,6 @@ int sl_tty_read(sl_tty_t *d){
|
|||||||
int sl_tty_write(int comfd, const char *buff, size_t length){
|
int sl_tty_write(int comfd, const char *buff, size_t length){
|
||||||
ssize_t L = write(comfd, buff, length);
|
ssize_t L = write(comfd, buff, length);
|
||||||
if((size_t)L != length){
|
if((size_t)L != length){
|
||||||
/// "Ошибка записи!"
|
|
||||||
WARN("Write error");
|
WARN("Write error");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
6
term2.c
6
term2.c
@ -99,12 +99,10 @@ static int tty_init(sl_tty_t *descr){
|
|||||||
tcflag_t flags;
|
tcflag_t flags;
|
||||||
if(!parse_format(descr->format, &flags)) return 1;
|
if(!parse_format(descr->format, &flags)) return 1;
|
||||||
if((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
|
if((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
|
||||||
/// Не могу использовать порт %s
|
|
||||||
WARN(_("Can't use port %s"), descr->portname);
|
WARN(_("Can't use port %s"), descr->portname);
|
||||||
return globErr ? globErr : 1;
|
return globErr ? globErr : 1;
|
||||||
}
|
}
|
||||||
if(ioctl(descr->comfd, TCGETS2, &descr->oldtty)){ // Get settings
|
if(ioctl(descr->comfd, TCGETS2, &descr->oldtty)){ // Get settings
|
||||||
/// Не могу получить действующие настройки порта
|
|
||||||
WARN(_("Can't get old TTY settings"));
|
WARN(_("Can't get old TTY settings"));
|
||||||
return globErr ? globErr : 1;
|
return globErr ? globErr : 1;
|
||||||
}
|
}
|
||||||
@ -118,7 +116,6 @@ static int tty_init(sl_tty_t *descr){
|
|||||||
descr->tty.c_cc[VMIN] = 0; // non-canonical mode
|
descr->tty.c_cc[VMIN] = 0; // non-canonical mode
|
||||||
descr->tty.c_cc[VTIME] = 5;
|
descr->tty.c_cc[VTIME] = 5;
|
||||||
if(ioctl(descr->comfd, TCSETS2, &descr->tty)){
|
if(ioctl(descr->comfd, TCSETS2, &descr->tty)){
|
||||||
/// Не могу сменить настройки порта
|
|
||||||
WARN(_("Can't apply new TTY settings"));
|
WARN(_("Can't apply new TTY settings"));
|
||||||
return globErr ? globErr : 1;
|
return globErr ? globErr : 1;
|
||||||
}
|
}
|
||||||
@ -130,7 +127,6 @@ static int tty_init(sl_tty_t *descr){
|
|||||||
// make exclusive open
|
// make exclusive open
|
||||||
if(descr->exclusive){
|
if(descr->exclusive){
|
||||||
if(ioctl(descr->comfd, TIOCEXCL)){
|
if(ioctl(descr->comfd, TIOCEXCL)){
|
||||||
/// Не могу сделать порт эксклюзивным
|
|
||||||
WARN(_("Can't do exclusive open"));
|
WARN(_("Can't do exclusive open"));
|
||||||
}}
|
}}
|
||||||
return 0;
|
return 0;
|
||||||
@ -163,7 +159,6 @@ sl_tty_t *sl_tty_new(char *comdev, int speed, size_t bufsz){
|
|||||||
descr->portname = strdup(comdev);
|
descr->portname = strdup(comdev);
|
||||||
descr->speed = speed;
|
descr->speed = speed;
|
||||||
if(!descr->portname){
|
if(!descr->portname){
|
||||||
/// Отсутствует имя порта
|
|
||||||
WARNX(_("Port name is missing"));
|
WARNX(_("Port name is missing"));
|
||||||
}else{
|
}else{
|
||||||
if(bufsz){
|
if(bufsz){
|
||||||
@ -256,7 +251,6 @@ int sl_tty_read(sl_tty_t *d){
|
|||||||
int sl_tty_write(int comfd, const char *buff, size_t length){
|
int sl_tty_write(int comfd, const char *buff, size_t length){
|
||||||
ssize_t L = write(comfd, buff, length);
|
ssize_t L = write(comfd, buff, length);
|
||||||
if((size_t)L != length){
|
if((size_t)L != length){
|
||||||
/// "Ошибка записи!"
|
|
||||||
WARN("Write error");
|
WARN("Write error");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -191,12 +191,10 @@ long sl_random_seed(){
|
|||||||
int fd = open("/dev/random", O_RDONLY);
|
int fd = open("/dev/random", O_RDONLY);
|
||||||
do{
|
do{
|
||||||
if(-1 == fd){
|
if(-1 == fd){
|
||||||
/// Не могу открыть /dev/random
|
|
||||||
WARN(_("Can't open /dev/random"));
|
WARN(_("Can't open /dev/random"));
|
||||||
fail = 1; break;
|
fail = 1; break;
|
||||||
}
|
}
|
||||||
if(sizeof(long) != read(fd, &r_ini, sizeof(long))){
|
if(sizeof(long) != read(fd, &r_ini, sizeof(long))){
|
||||||
/// Не могу прочесть /dev/random
|
|
||||||
WARN(_("Can't read /dev/random"));
|
WARN(_("Can't read /dev/random"));
|
||||||
fail = 1;
|
fail = 1;
|
||||||
}
|
}
|
||||||
@ -247,29 +245,24 @@ sl_mmapbuf_t *sl_mmap(char *filename){
|
|||||||
size_t Mlen;
|
size_t Mlen;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
if(!filename){
|
if(!filename){
|
||||||
/// Не задано имя файла!
|
|
||||||
WARNX(_("No filename given!"));
|
WARNX(_("No filename given!"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if((fd = open(filename, O_RDONLY)) < 0){
|
if((fd = open(filename, O_RDONLY)) < 0){
|
||||||
/// Не могу открыть %s для чтения
|
|
||||||
WARN(_("Can't open %s for reading"), filename);
|
WARN(_("Can't open %s for reading"), filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(fstat (fd, &statbuf) < 0){
|
if(fstat (fd, &statbuf) < 0){
|
||||||
/// Не могу выполнить stat %s
|
|
||||||
WARN(_("Can't stat %s"), filename);
|
WARN(_("Can't stat %s"), filename);
|
||||||
close(fd);
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Mlen = statbuf.st_size;
|
Mlen = statbuf.st_size;
|
||||||
if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED){
|
if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED){
|
||||||
/// Ошибка mmap
|
|
||||||
WARN(_("Mmap error for input"));
|
WARN(_("Mmap error for input"));
|
||||||
close(fd);
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/// Не могу закрыть mmap'нутый файл
|
|
||||||
if(close(fd)) WARN(_("Can't close mmap'ed file"));
|
if(close(fd)) WARN(_("Can't close mmap'ed file"));
|
||||||
sl_mmapbuf_t *ret = MALLOC(sl_mmapbuf_t, 1);
|
sl_mmapbuf_t *ret = MALLOC(sl_mmapbuf_t, 1);
|
||||||
ret->data = ptr;
|
ret->data = ptr;
|
||||||
@ -283,7 +276,6 @@ sl_mmapbuf_t *sl_mmap(char *filename){
|
|||||||
*/
|
*/
|
||||||
void sl_munmap(sl_mmapbuf_t *b){
|
void sl_munmap(sl_mmapbuf_t *b){
|
||||||
if(munmap(b->data, b->len)){
|
if(munmap(b->data, b->len)){
|
||||||
/// Не могу munmap
|
|
||||||
ERR(_("Can't munmap"));
|
ERR(_("Can't munmap"));
|
||||||
}
|
}
|
||||||
FREE(b);
|
FREE(b);
|
||||||
@ -352,7 +344,6 @@ void sl_setup_con(){
|
|||||||
#else
|
#else
|
||||||
if(tcsetattr(STDIN_FILENO, TCSANOW, &newt) < 0){
|
if(tcsetattr(STDIN_FILENO, TCSANOW, &newt) < 0){
|
||||||
#endif
|
#endif
|
||||||
/// Не могу настроить консоль
|
|
||||||
WARN(_("Can't setup console"));
|
WARN(_("Can't setup console"));
|
||||||
#ifndef SL_USE_OLD_TTY
|
#ifndef SL_USE_OLD_TTY
|
||||||
ioctl(STDIN_FILENO, TCSETS2, &oldt);
|
ioctl(STDIN_FILENO, TCSETS2, &oldt);
|
||||||
@ -409,7 +400,6 @@ int sl_str2d(double *num, const char *str){
|
|||||||
if(!str) return FALSE;
|
if(!str) return FALSE;
|
||||||
res = strtod(str, &endptr);
|
res = strtod(str, &endptr);
|
||||||
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
||||||
/// "Неправильный формат числа double '%s'"
|
|
||||||
WARNX(_("Wrong double number format '%s'"), str);
|
WARNX(_("Wrong double number format '%s'"), str);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -423,8 +413,7 @@ int sl_str2ll(long long *num, const char *str){
|
|||||||
if(!str) return FALSE;
|
if(!str) return FALSE;
|
||||||
res = strtoll(str, &endptr, 0);
|
res = strtoll(str, &endptr, 0);
|
||||||
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
||||||
/// "Неправильный формат числа double!"
|
WARNX(_("Wrong integer number format '%s'"));
|
||||||
WARNX(_("Wrong number format!"));
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(num) *num = res;
|
if(num) *num = res;
|
||||||
|
|||||||
@ -377,3 +377,65 @@ typedef struct{
|
|||||||
int sl_get_keyval(const char *pair, char key[SL_KEY_LEN], char value[SL_VAL_LEN]);
|
int sl_get_keyval(const char *pair, char key[SL_KEY_LEN], char value[SL_VAL_LEN]);
|
||||||
char *sl_print_opts(sl_option_t *opt, int showall);
|
char *sl_print_opts(sl_option_t *opt, int showall);
|
||||||
int sl_conf_readopts(const char *filename, sl_option_t *options);
|
int sl_conf_readopts(const char *filename, sl_option_t *options);
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
The original ringbuffer.h
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
// ring buffer for string or binary data
|
||||||
|
typedef struct{
|
||||||
|
uint8_t *data; // data buffer
|
||||||
|
size_t length; // its length
|
||||||
|
size_t head; // head index
|
||||||
|
size_t tail; // tail index
|
||||||
|
pthread_mutex_t busy; // mutex of buffer activity
|
||||||
|
} sl_ringbuffer;
|
||||||
|
|
||||||
|
sl_ringbuffer *sl_RB_new(size_t size);
|
||||||
|
void sl_RB_delete(sl_ringbuffer **b);
|
||||||
|
size_t sl_RB_read(sl_ringbuffer *b, uint8_t *s, size_t len);
|
||||||
|
ssize_t sl_RB_readto(sl_ringbuffer *b, uint8_t byte, uint8_t *s, size_t len);
|
||||||
|
ssize_t sl_RB_hasbyte(sl_ringbuffer *b, uint8_t byte);
|
||||||
|
int sl_RB_putbyte(sl_ringbuffer *b, uint8_t byte);
|
||||||
|
size_t sl_RB_write(sl_ringbuffer *b, const uint8_t *str, size_t len);
|
||||||
|
size_t sl_RB_datalen(sl_ringbuffer *b);
|
||||||
|
void sl_RB_clearbuf(sl_ringbuffer *b);
|
||||||
|
ssize_t sl_RB_readline(sl_ringbuffer *b, char *s, size_t len);
|
||||||
|
size_t sl_RB_writestr(sl_ringbuffer *b, char *s);
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
The original socket.h
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
// handler result: what to send to client
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
RESULT_OK, // all OK
|
||||||
|
RESULT_FAIL, // failed running command
|
||||||
|
RESULT_BADVAL, // bad value
|
||||||
|
RESULT_BADKEY, // bad (non-existant) key
|
||||||
|
RESULT_SILENCE, // send nothing to client (in case of handlers which sends data by themself)
|
||||||
|
RESULT_NUM // total amount of enum fields
|
||||||
|
} sl_hresult;
|
||||||
|
|
||||||
|
typedef sl_hresult (*sl_msghandler)(int fd, const char *key, const char *val);
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
sl_msghandler handler;
|
||||||
|
const char *key;
|
||||||
|
const char *help;
|
||||||
|
} sl_handleritem;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
SOCKT_UNIX, // UNIX socket
|
||||||
|
SOCKT_NETLOCAL, // INET socket but only for localhost
|
||||||
|
SOCKT_NET // true INET socket
|
||||||
|
} sl_socktype;
|
||||||
|
|
||||||
|
const char *sl_hresult2str(sl_hresult r);
|
||||||
|
int sl_start_socket(int isserver, int isnet, const char *path);
|
||||||
|
void sl_sendbinmessage(int fd, const uint8_t *msg, int l);
|
||||||
|
void sl_sendstrmessage(int fd, const char *msg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user