add fifo/lifo

This commit is contained in:
eddyem 2018-12-17 23:43:53 +03:00
parent bed730e245
commit e982f06ca1
13 changed files with 752 additions and 177 deletions

View File

@ -8,3 +8,4 @@ link_libraries(usefull_macros)
# exe list # exe list
add_executable(helloworld helloworld.c) add_executable(helloworld helloworld.c)
add_executable(options options.c cmdlnopts.c) add_executable(options options.c cmdlnopts.c)
add_executable(fifo fifo.c)

View File

@ -32,15 +32,15 @@
int help; int help;
glob_pars G; glob_pars G;
#define DEFAULT_COMDEV "/dev/ttyUSB0"
// default PID filename: // default PID filename:
#define DEFAULT_PIDFILE "/tmp/testcmdlnopts.pid" #define DEFAULT_PIDFILE "/tmp/testcmdlnopts.pid"
// DEFAULTS // DEFAULTS
// default global parameters // default global parameters
glob_pars const Gdefault = { glob_pars const Gdefault = {
.device = DEFAULT_COMDEV, .device = NULL,
.pidfile = DEFAULT_PIDFILE, .pidfile = DEFAULT_PIDFILE,
.speed = 9600,
.logfile = NULL // don't save logs .logfile = NULL // don't save logs
}; };
@ -51,7 +51,8 @@ glob_pars const Gdefault = {
myoption cmdlnopts[] = { myoption cmdlnopts[] = {
// common options // common options
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")}, {"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: " DEFAULT_COMDEV ")")}, {"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("serial device name")},
{"speed", NEED_ARG, NULL, 's', arg_int, APTR(&G.speed), _("serial device speed (default: 9600)")},
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")}, {"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")},
{"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")}, {"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
end_option end_option

View File

@ -30,6 +30,7 @@ typedef struct{
char *device; // serial device name char *device; // serial device name
char *pidfile; // name of PID file char *pidfile; // name of PID file
char *logfile; // logging to this file char *logfile; // logging to this file
int speed; // connection speed
int rest_pars_num; // number of rest parameters int rest_pars_num; // number of rest parameters
char** rest_pars; // the rest parameters: array of char* char** rest_pars; // the rest parameters: array of char*
} glob_pars; } glob_pars;

57
examples/fifo.c Normal file
View File

@ -0,0 +1,57 @@
/*
* This file is part of the usefull_macros project.
* Copyright 2018 Edward V. Emelianov <edward.emelianoff@gmail.com>, <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 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>
#include <stdio.h>
int main(int argc, char *argv[argc]) {
List *f = NULL;
printf("Available memory: %luMB\n", get_available_mem()/1024/1024);
//initial_setup(); - there's no need for this function if you don't use locale & don't want to have
// specific output in non-tty
if(argc == 1){
green("Usage:\n\t%s args - fill fifo with arguments\n", __progname);
return 1;
}
red("\n\nLIFO example\n");
for(int i = 1; i < argc; ++i){
if(!list_push(&f, argv[i])) ERR("Allocation error!");
green("push to list ");
printf("%s\n", argv[i]);
}
char *d;
printf("\n");
while(f){
d = list_pop(&f);
green("pull: ");
printf("%s\n", d);
}
red("\n\nFIFO example\n");
for(int i = 1; i < argc; ++i){
if(!list_push_tail(&f, argv[i])) ERR("Allocation error!");
green("push to list ");
printf("%s\n", argv[i]);
}
printf("\n");
while(f){
d = list_pop(&f);
green("pull: ");
printf("%s\n", d);
// after last usage we should FREE data, but here it is parameter of main()
}
return 0;
}

View File

@ -16,12 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <usefull_macros.h>
#include <signal.h> // signal #include <signal.h> // signal
#include <stdlib.h> // exit, free #include <stdlib.h> // exit, free
#include <stdio.h> // printf #include <stdio.h> // printf
#include <string.h> // strdup #include <string.h> // strdup
#include <unistd.h> // sleep #include <unistd.h> // sleep
#include <usefull_macros.h>
#include "cmdlnopts.h" #include "cmdlnopts.h"
/** /**
@ -34,15 +34,22 @@
* The `cmdlnopts.[hc]` are intrinsic files of this demo. * The `cmdlnopts.[hc]` are intrinsic files of this demo.
*/ */
TTY_descr *dev = NULL; // shoul be global to restore if die
glob_pars *GP = NULL; // for GP->pidfile need in `signals`
/** /**
* We REDEFINE the default WEAK function of signal processing * We REDEFINE the default WEAK function of signal processing
*/ */
void signals(int sig){ void signals(int sig){
signal(sig, SIG_IGN); if(sig){
restore_console(); signal(sig, SIG_IGN);
restore_tty(); DBG("Get signal %d, quit.\n", sig);
DBG("Get signal %d, quit.\n", sig); }
putlog("Exit with status %d", sig); putlog("Exit with status %d", sig);
if(GP->pidfile) // remove unnesessary PID file
unlink(GP->pidfile);
restore_console();
close_tty(&dev);
exit(sig); exit(sig);
} }
@ -53,7 +60,7 @@ void iffound_default(pid_t pid){
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
initial_setup(); initial_setup();
char *self = strdup(argv[0]); char *self = strdup(argv[0]);
glob_pars *GP = parse_args(argc, argv); GP = parse_args(argc, argv);
if(GP->rest_pars_num){ if(GP->rest_pars_num){
printf("%d extra options:\n", GP->rest_pars_num); printf("%d extra options:\n", GP->rest_pars_num);
for(int i = 0; i < GP->rest_pars_num; ++i) for(int i = 0; i < GP->rest_pars_num; ++i)
@ -69,13 +76,32 @@ int main(int argc, char *argv[]){
if(GP->logfile) openlogfile(GP->logfile); if(GP->logfile) openlogfile(GP->logfile);
setup_con(); setup_con();
putlog(("Start application...")); putlog(("Start application..."));
; // main stuff goes here if(GP->rest_pars_num){
green("Now I will sleep for 10 seconds. Do whatever you want.\n"); for(int i = 0; i < GP->rest_pars_num; ++i)
sleep(10); printf("Extra argument: %s\n", GP->rest_pars[i]);
; // clean everything }
if(GP->pidfile) // remove unnesessary PID file if(GP->device){
unlink(GP->pidfile); putlog("Try to open serial %s", GP->device);
restore_console(); dev = tty_open(GP->device, GP->speed, 256);
restore_tty(); if(!dev){
putlog("Can't open %s with speed %d. Exit.", GP->device, GP->speed);
signals(0);
}
}
// main stuff goes here
long seed = throw_random_seed();
green("Now I will sleep for 10 seconds. Do whatever you want. Random seed: %ld\n", seed);
double t0 = dtime();
while(dtime() - t0 < 10.){ // read data from port and print in into terminal
if(dev){
if(read_tty(dev)){
printf("Data from port: %s\n", dev->buf);
}
char ch = read_console();
if(ch) write_tty(dev->comfd, &ch, 1);
}
}
// clean everything
signals(0);
return 0; return 0;
} }

81
fifo_lifo.c Normal file
View File

@ -0,0 +1,81 @@
/*
* fifo_lifo.c - simple FIFO/LIFO
*
* 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"
/**
* @brief list_push_tail - push data into the tail of a stack (like FIFO)
* @param lst (io) - list
* @param v (i) - data to push
* @return pointer to just pused node or NULL in case of error
*/
List *list_push_tail(List **lst, void *v){
List *node;
if(!lst) return NULL;
if((node = MALLOC(List, 1)) == NULL)
return NULL; // allocation error
node->data = v; // insert data
if(!*lst){
*lst = node;
}else{
(*lst)->last->next = node;
}
(*lst)->last = node;
return node;
}
/**
* @brief list_push - push data into the head of a stack (like LIFO)
* @param lst (io) - list
* @param v (i) - data to push
* @return pointer to just pused node
*/
List *list_push(List **lst, void *v){
List *node;
if(!lst) return NULL;
if((node = MALLOC(List, 1)) == NULL)
return NULL; // allocation error
node->data = v; // insert data
if(!*lst){
*lst = node;
(*lst)->last = node;
return node;
}
node->next = *lst;
node->last = (*lst)->last;
*lst = node;
return node;
}
/**
* @brief list_pop - get data from head of list. Don't forget to FREE list data after `pop`
* @param lst (io) - list
* @return data from lst head
*/
void *list_pop(List **lst){
void *ret;
List *node = *lst;
if(!lst || !*lst) return NULL;
ret = (*lst)->data;
*lst = (*lst)->next;
FREE(node);
return ret;
}

155
locale/ru/messages.po Normal file
View File

@ -0,0 +1,155 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-12-09 01:49+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8bit\n"
#. / \nïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n
#: /Big/Data/C_sources/snippets_library/daemon.c:70
#, c-format
msgid ""
"\n"
"Found running process (pid=%d), exit.\n"
msgstr ""
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ PID ÆÁÊÌ
#: /Big/Data/C_sources/snippets_library/daemon.c:143
msgid "Can't open PID file"
msgstr ""
#. amount of pcount and/or scount wrong
#. / îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ
#: /Big/Data/C_sources/snippets_library/parseargs.c:54
msgid "Wrong helpstring!"
msgstr ""
#. / ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ
#: /Big/Data/C_sources/snippets_library/parseargs.c:84
msgid "Integer out of range"
msgstr ""
#. / îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s
#: /Big/Data/C_sources/snippets_library/parseargs.c:478
#, c-format
msgid "Wrong parameter: %s"
msgstr ""
#. / %s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!
#: /Big/Data/C_sources/snippets_library/parseargs.c:483
#, c-format
msgid "%s: argument needed!"
msgstr ""
#. / îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\"
#: /Big/Data/C_sources/snippets_library/parseargs.c:488
#, c-format
msgid "Wrong argument \"%s\" of parameter \"%s\""
msgstr ""
#: /Big/Data/C_sources/snippets_library/term.c:92
#, c-format
msgid "Wrong speed value: %d!"
msgstr ""
#. / îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s
#: /Big/Data/C_sources/snippets_library/term.c:105
#, c-format
msgid "Can't use port %s"
msgstr ""
#. Get settings
#. / îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
#: /Big/Data/C_sources/snippets_library/term.c:111
msgid "Can't get old TTY settings"
msgstr ""
#. / îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
#: /Big/Data/C_sources/snippets_library/term.c:123
msgid "Can't apply new TTY settings"
msgstr ""
#. / îÅ ÍÏÇÕ ÓÄÅÌÁÔØ ÐÏÒÔ ÜËÓËÌÀÚÉ×ÎÙÍ
#: /Big/Data/C_sources/snippets_library/term.c:129
msgid "Can't do exclusive open"
msgstr ""
#. / ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ
#: /Big/Data/C_sources/snippets_library/term.c:168
msgid "Port name is missing"
msgstr ""
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:184
msgid "Can't open /dev/random"
msgstr ""
#. / îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:189
msgid "Can't read /dev/random"
msgstr ""
#. / îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:232
msgid "No filename given!"
msgstr ""
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:237
#, c-format
msgid "Can't open %s for reading"
msgstr ""
#. / îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat %s
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:242
#, c-format
msgid "Can't stat %s"
msgstr ""
#. / ïÛÉÂËÁ mmap
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:249
msgid "Mmap error for input"
msgstr ""
#. / îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:254
msgid "Can't close mmap'ed file"
msgstr ""
#. / îÅ ÍÏÇÕ munmap
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:268
msgid "Can't munmap"
msgstr ""
#. / îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:299
msgid "Can't setup console"
msgstr ""
#. / îÅ ÚÁÄÁÎÏ ÉÍÑ ÌÏÇÆÁÊÌÁ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:374
msgid "Need filename for log file"
msgstr ""
#. / ðÒÏÂÕÀ ÏÔËÒÙÔØ ÌÏÇÆÁÊÌ %s × ÒÅÖÉÍÅ ÄÏÐÏÌÎÅÎÉÑ\n
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:378
#, c-format
msgid "Try to open log file %s in append mode\n"
msgstr ""
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÌÏÇÆÁÊÌ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:382
msgid "Can't open log file"
msgstr ""

View File

@ -7,7 +7,7 @@
msgid "" msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n" msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-12-07 02:52+0300\n" "POT-Creation-Date: 2018-12-09 01:49+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -30,87 +30,104 @@ msgstr "\n"
msgid "%s: argument needed!" msgid "%s: argument needed!"
msgstr "%s: необходим аргумент!" msgstr "%s: необходим аргумент!"
#. / îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
#: /Big/Data/C_sources/snippets_library/term.c:123
#, fuzzy
msgid "Can't apply new TTY settings"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÁÓÔÒÏÊËÉ"
#. / Не могу закрыть mmap'нутый файл #. / Не могу закрыть mmap'нутый файл
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:218 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:254
msgid "Can't close mmap'ed file" msgid "Can't close mmap'ed file"
msgstr "Не могу закрыть mmap'нутый файл" msgstr "Не могу закрыть mmap'нутый файл"
#. / îÅ ÍÏÇÕ ÐÅÒÅ×ÅÓÔÉ ÐÏÒÔ × ÜËÓËÌÀÚÉ×ÎÙÊ ÒÅÖÉÍ #. / îÅ ÍÏÇÕ ÓÄÅÌÁÔØ ÐÏÒÔ ÜËÓËÌÀÚÉ×ÎÙÍ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:352 #: /Big/Data/C_sources/snippets_library/term.c:129
msgid "Can't do exclusive open" msgid "Can't do exclusive open"
msgstr "Не могу перевести порт в эксклюзивный режим" msgstr "Не могу перевести порт в эксклюзивный режим"
#. Get settings #. Get settings
#. / îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ #. / îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:345 #: /Big/Data/C_sources/snippets_library/term.c:111
msgid "Can't get port settings" #, fuzzy
msgid "Can't get old TTY settings"
msgstr "Не могу получить настройки порта" msgstr "Не могу получить настройки порта"
#. / Не могу munmap #. / Не могу munmap
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:232 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:268
msgid "Can't munmap" msgid "Can't munmap"
msgstr "Не могу munmap" msgstr "Не могу munmap"
#. / Не могу открыть %s для чтения #. / Не могу открыть %s для чтения
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:201 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:237
#, c-format #, c-format
msgid "Can't open %s for reading" msgid "Can't open %s for reading"
msgstr "Не могу открыть %s для чтения" msgstr "Не могу открыть %s для чтения"
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:184
msgid "Can't open /dev/random"
msgstr ""
#. / Не могу открыть PID файл #. / Не могу открыть PID файл
#: /Big/Data/C_sources/snippets_library/daemon.c:143 #: /Big/Data/C_sources/snippets_library/daemon.c:143
msgid "Can't open PID file" msgid "Can't open PID file"
msgstr "Не могу открыть PID файл" msgstr "Не могу открыть PID файл"
#. / Не могу открыть логфайл #. / Не могу открыть логфайл
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:462 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:382
msgid "Can't open log file" msgid "Can't open log file"
msgstr "Не могу открыть логфайл" msgstr "Не могу открыть логфайл"
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÐÏÒÔ %s #. / îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:340 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:189
#, c-format msgid "Can't read /dev/random"
msgid "Can't open port %s" msgstr ""
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÐÏÒÔ %s"
#. / îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÁÓÔÒÏÊËÉ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:365
msgid "Can't set settings"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÁÓÔÒÏÊËÉ"
#. / Не могу настроить консоль #. / Не могу настроить консоль
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:263 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:299
msgid "Can't setup console" msgid "Can't setup console"
msgstr "Не могу настроить консоль" msgstr "Не могу настроить консоль"
#. / Не могу выполнить stat %s #. / Не могу выполнить stat %s
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:206 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:242
#, c-format #, c-format
msgid "Can't stat %s" msgid "Can't stat %s"
msgstr "Не могу выполнить stat %s" msgstr "Не могу выполнить stat %s"
#. / îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s
#: /Big/Data/C_sources/snippets_library/term.c:105
#, fuzzy, c-format
msgid "Can't use port %s"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÐÏÒÔ %s"
#. / Целое вне допустимого диапазона #. / Целое вне допустимого диапазона
#: /Big/Data/C_sources/snippets_library/parseargs.c:84 #: /Big/Data/C_sources/snippets_library/parseargs.c:84
msgid "Integer out of range" msgid "Integer out of range"
msgstr "Целое вне допустимого диапазона" msgstr "Целое вне допустимого диапазона"
#. / Ошибка mmap #. / Ошибка mmap
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:213 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:249
msgid "Mmap error for input" msgid "Mmap error for input"
msgstr "Ошибка mmap" msgstr "Ошибка mmap"
#. / Не задано имя логфайла #. / Не задано имя логфайла
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:454 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:374
msgid "Need filename for log file" msgid "Need filename for log file"
msgstr "Не задано имя логфайла" msgstr "Не задано имя логфайла"
#. / Не задано имя файла! #. / Не задано имя файла!
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:196 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:232
msgid "No filename given!" msgid "No filename given!"
msgstr "Не задано имя файла!" msgstr "Не задано имя файла!"
#. / ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ
#: /Big/Data/C_sources/snippets_library/term.c:168
msgid "Port name is missing"
msgstr ""
#. / Пробую открыть логфайл %s в режиме дополнения\n #. / Пробую открыть логфайл %s в режиме дополнения\n
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:458 #: /Big/Data/C_sources/snippets_library/usefull_macros.c:378
#, c-format #, c-format
msgid "Try to open log file %s in append mode\n" msgid "Try to open log file %s in append mode\n"
msgstr "Пробую открыть логфайл %s в режиме дополнения\n" msgstr "Пробую открыть логфайл %s в режиме дополнения\n"
@ -132,3 +149,8 @@ msgstr "
#, c-format #, c-format
msgid "Wrong parameter: %s" msgid "Wrong parameter: %s"
msgstr "Неправильный параметр: %s" msgstr "Неправильный параметр: %s"
#: /Big/Data/C_sources/snippets_library/term.c:92
#, c-format
msgid "Wrong speed value: %d!"
msgstr ""

232
term.c Normal file
View File

@ -0,0 +1,232 @@
/*
* client.c - simple terminal client
*
* 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 <unistd.h> // tcsetattr, close, read, write
#include <sys/ioctl.h> // ioctl
#include <stdio.h> // printf, getchar, fopen, perror
#include <stdlib.h> // exit, realloc
#include <sys/stat.h> // read
#include <fcntl.h> // read
#include <signal.h> // signal
#include <time.h> // time
#include <string.h> // memcpy
#include <stdint.h> // int types
#include <sys/time.h> // gettimeofday
#include <unistd.h> // usleep
#include "usefull_macros.h"
#define LOGBUFSZ (1024)
typedef struct {
int speed; // communication speed in bauds/s
int bspeed; // baudrate from termios.h
} spdtbl;
static int tty_init(TTY_descr *descr);
static spdtbl speeds[] = {
{50, B50},
{75, B75},
{110, B110},
{134, B134},
{150, B150},
{200, B200},
{300, B300},
{600, B600},
{1200, B1200},
{1800, B1800},
{2400, B2400},
{4800, B4800},
{9600, B9600},
{19200, B19200},
{38400, B38400},
{57600, B57600},
{115200, B115200},
{230400, B230400},
{460800, B460800},
{500000, B500000},
{576000, B576000},
{921600, B921600},
{1000000, B1000000},
{1152000, B1152000},
{1500000, B1500000},
{2000000, B2000000},
{2500000, B2500000},
{3000000, B3000000},
{3500000, B3500000},
{4000000, B4000000},
{0,0}
};
/**
* @brief conv_spd - test if `speed` is in .speed of `speeds` array
* @param speed - integer speed (bps)
* @return 0 if error, Bxxx if all OK
*/
int conv_spd(int speed){
spdtbl *spd = speeds;
int curspeed = 0;
do{
curspeed = spd->speed;
if(curspeed == speed)
return spd->bspeed;
++spd;
}while(curspeed);
WARNX(_("Wrong speed value: %d!"), speed);
return 0;
}
/**
* @brief tty_init - open & setup terminal
* @param descr (io) - port descriptor
* @return 0 if all OK or error code
*/
static int tty_init(TTY_descr *descr){
DBG("\nOpen port...");
if ((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){
/// îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s
WARN(_("Can't use port %s"), descr->portname);
return globErr ? globErr : 1;
}
DBG("OK\nGet current settings...");
if(ioctl(descr->comfd, TCGETA, &descr->oldtty) < 0){ // Get settings
/// îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
WARN(_("Can't get old TTY settings"));
return globErr ? globErr : 1;
}
descr->tty = descr->oldtty;
struct termios *tty = &descr->tty;
tty->c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG)
tty->c_oflag = 0;
tty->c_cflag = descr->baudrate|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(descr->comfd, TCSETA, &descr->tty) < 0){
/// îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
WARN(_("Can't apply new TTY settings"));
return globErr ? globErr : 1;
}
// make exclusive open
if(ioctl(descr->comfd, TIOCEXCL)){
/// îÅ ÍÏÇÕ ÓÄÅÌÁÔØ ÐÏÒÔ ÜËÓËÌÀÚÉ×ÎÙÍ
WARN(_("Can't do exclusive open"));
}
DBG("OK");
return 0;
}
/**
* @brief restore_tty - restore opened TTY to previous state and close it
*/
void close_tty(TTY_descr **descr){
if(descr == NULL || *descr == NULL) return;
TTY_descr *d = *descr;
FREE(d->portname);
FREE(d->buf);
if(d->comfd){
DBG("close file..");
ioctl(d->comfd, TCSANOW, &d->oldtty); // return TTY to previous state
close(d->comfd);
}
FREE(*descr);
DBG("done!\n");
}
/**
* @brief tty_open - init & open tty device
* @param port - TTY device filename
* @param speed - speed (number)
* @param bufsz - size of buffer for input data (or 0 if opened only to write)
* @return pointer to TTY structure if all OK
*/
TTY_descr *tty_open(char *port, int speed, size_t bufsz){
int spd = conv_spd(speed);
if(!spd) return NULL;
DBG("open %s with speed %d)", port, speed);
TTY_descr *descr = MALLOC(TTY_descr, 1);
descr->portname = strdup(port);
descr->baudrate = spd;
if(!descr->portname){
/// ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ
WARNX(_("Port name is missing"));
}else if(!tty_init(descr)){
if(bufsz){
descr->buf = MALLOC(char, bufsz+1);
descr->bufsz = bufsz;
DBG("allocate buffer with size %zd", bufsz);
}
return descr;
}
FREE(descr->portname);
FREE(descr);
return NULL;
}
/**
* @brief read_tty - read data from TTY with 10ms timeout
* @param buff (o) - buffer for data read
* @param length - buffer len
* @return amount of bytes read
*/
size_t read_tty(TTY_descr *d){
if(d->comfd < 0) return 0;
ssize_t L = 0, l;
size_t length = d->bufsz;
char *ptr = d->buf;
fd_set rfds;
struct timeval tv;
int retval;
do{
l = 0;
FD_ZERO(&rfds);
FD_SET(d->comfd, &rfds);
// wait for 10ms
tv.tv_sec = 0; tv.tv_usec = 10000;
retval = select(d->comfd + 1, &rfds, NULL, NULL, &tv);
if (!retval) break;
if(FD_ISSET(d->comfd, &rfds)){
if((l = read(d->comfd, ptr, length)) < 1){
return 0;
}
ptr += l; L += l;
length -= l;
}
}while(l);
d->buflen = L;
d->buf[L] = 0;
return (size_t)L;
}
/**
* @brief write_tty - write data to serial port
* @param buff (i) - data to write
* @param length - its length
* @return 0 if all OK
*/
int write_tty(int comfd, const char *buff, size_t length){
ssize_t L = write(comfd, buff, length);
if((size_t)L != length){
/// "ïÛÉÂËÁ ÚÁÐÉÓÉ!"
WARN("Write error");
return 1;
}
return 0;
}

34
term.h Normal file
View File

@ -0,0 +1,34 @@
/*
* term.h
*
* Copyright 2016 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 __TERM_H__
#define __TERM_H__
#include <termios.h> // tcsetattr, baudrates
void term_quit(int ex_stat);
int conv_spd(int speed);
void ttys_open(char **ports, int **speeds, int globspeed);
void set_comlogname(char* nm);
void set_charmode();
#endif // __TERM_H__

View File

@ -33,6 +33,7 @@
#include <time.h> #include <time.h>
#include <sys/types.h> #include <sys/types.h>
#include <linux/limits.h> // PATH_MAX #include <linux/limits.h> // PATH_MAX
#include <math.h> // floor
#include "usefull_macros.h" #include "usefull_macros.h"
@ -62,11 +63,6 @@ double dtime(){
\******************************************************************************/ \******************************************************************************/
int globErr = 0; // errno for WARN/ERR 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, ...);
/** /**
* @brief r_pr_, g_pr_ - format red / green messages * @brief r_pr_, g_pr_ - format red / green messages
* @param fmt ... - printf-like format * @param fmt ... - printf-like format
@ -112,6 +108,11 @@ int r_WARN(const char *fmt, ...){
return i; return i;
} }
// pointers to coloured output printf
int (*red)(const char *fmt, ...) = r_pr_;
int (*green)(const char *fmt, ...) = g_pr_;
int (*_WARN)(const char *fmt, ...) = r_WARN;
static const char stars[] = "****************************************"; static const char stars[] = "****************************************";
/** /**
* @brief s_WARN, r_pr_notty - notty variants of coloured printf * @brief s_WARN, r_pr_notty - notty variants of coloured printf
@ -165,6 +166,49 @@ void initial_setup(){
#endif #endif
} }
/******************************************************************************\
* Different things
\******************************************************************************/
/**
* @brief throw_random_seed - Generate a quasy-random number to initialize PRNG
* @return value for srand48
*/
long throw_random_seed(){
long r_ini;
int fail = 0;
int fd = open("/dev/random", O_RDONLY);
do{
if(-1 == fd){
/// îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random
WARN(_("Can't open /dev/random"));
fail = 1; break;
}
if(sizeof(long) != read(fd, &r_ini, sizeof(long))){
/// îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random
WARN(_("Can't read /dev/random"));
fail = 1;
}
close(fd);
}while(0);
if(fail){
double tt = dtime() * 1e6;
double mx = (double)LONG_MAX;
r_ini = (long)(tt - mx * floor(tt/mx));
}
return (r_ini);
}
/**
* @brief get_available_mem
* @return system available physical memory
*/
uint64_t get_available_mem(){
return sysconf(_SC_AVPHYS_PAGES) * (uint64_t) sysconf(_SC_PAGE_SIZE);
}
/******************************************************************************\ /******************************************************************************\
* Memory * Memory
\******************************************************************************/ \******************************************************************************/
@ -300,122 +344,6 @@ int mygetchar(){
return ret; return ret;
} }
/******************************************************************************\
* TTY with select()
* BE CAREFULL! These functions aren't thread-safe!
* BE CAREFULL! These functions are for one serial port only!
\******************************************************************************/
static struct termios oldtty, tty; // TTY flags
static int comfd = -1; // TTY fd
/**
* @brief restore_tty - restore port settings to previous
*/
void restore_tty(){
if(comfd == -1) return;
if(oldtty.c_cflag)
tcsetattr(comfd, TCSANOW, &oldtty); // return TTY to previous state
close(comfd);
comfd = -1;
}
/**
* @brief tty_init - init port with 8N1 in non-blocking RW mode
* @param comdev (i) - port device
* @param speed - communication speed
*/
void tty_init(char *comdev, tcflag_t speed){
if(comfd == -1){ // not opened
if(!comdev){
WARNX("comdev == NULL");
signals(11);
}
DBG("Open port...");
do{
comfd = open(comdev, O_RDWR|O_NOCTTY|O_NONBLOCK);
}while (comfd == -1 && errno == EINTR);
if(comfd < 0){
/// îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÐÏÒÔ %s
WARN(_("Can't open port %s"),comdev);
signals(2);
}
if(tcgetattr(comfd, &oldtty)){ // Get settings
/// îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
WARN(_("Can't get port settings"));
oldtty.c_cflag = 0;
}
DBG("Make exclusive");
// make exclusive open
if(ioctl(comfd, TIOCEXCL)){
/// îÅ ÍÏÇÕ ÐÅÒÅ×ÅÓÔÉ ÐÏÒÔ × ÜËÓËÌÀÚÉ×ÎÙÊ ÒÅÖÉÍ
WARN(_("Can't do exclusive open"));
close(comfd);
signals(2);
}
}
tty = oldtty;
tty.c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG)
tty.c_oflag = 0;
tty.c_cflag = speed|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){
/// îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÁÓÔÒÏÊËÉ
WARN(_("Can't set settings"));
signals(0);
}
DBG("OK");
}
/**
* @brief read_tty - read data from TTY with 10ms timeout
* @param buff (o) - buffer for data read
* @param length - buffer len
* @return amount of bytes read
*/
size_t read_tty(char *buff, size_t length){
if(comfd < 0) return 0;
ssize_t L = 0, l;
char *ptr = buff;
fd_set rfds;
struct timeval tv;
int retval;
do{
l = 0;
FD_ZERO(&rfds);
FD_SET(comfd, &rfds);
// wait for 10ms
tv.tv_sec = 0; tv.tv_usec = 10000;
retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
if (!retval) break;
if(FD_ISSET(comfd, &rfds)){
if((l = read(comfd, ptr, length)) < 1){
return 0;
}
ptr += l; L += l;
length -= l;
}
}while(l);
return (size_t)L;
}
/**
* @brief write_tty - write data to serial port
* @param buff (i) - data to write
* @param length - its length
* @return 0 if all OK
*/
int write_tty(const char *buff, size_t length){
ssize_t L = write(comfd, buff, length);
if((size_t)L != length){
/// "ïÛÉÂËÁ ÚÁÐÉÓÉ!"
WARN("Write error");
return 1;
}
return 0;
}
/** /**
* @brief str2double - safely convert data from string to double * @brief str2double - safely convert data from string to double
* @param num (o) - double number read from string * @param num (o) - double number read from string
@ -481,7 +409,10 @@ int putlog(const char *fmt, ...){
openlogfile(logname); openlogfile(logname);
if(!Flog) return 0; if(!Flog) return 0;
} }
int i = fprintf(Flog, "\n\t\t%s", ctime(&t_now)); //int i = fprintf(Flog, "%s\t\t", ctime(&t_now));
char buf[256];
strftime(buf, 255, "%Y/%m/%d %H:%M:%S", localtime(&t_now));
int i = fprintf(Flog, "%s\t\t", buf);
va_list ar; va_list ar;
va_start(ar, fmt); va_start(ar, fmt);
i = vfprintf(Flog, fmt, ar); i = vfprintf(Flog, fmt, ar);
@ -490,3 +421,4 @@ int putlog(const char *fmt, ...){
fflush(Flog); fflush(Flog);
return i; return i;
} }

View File

@ -23,10 +23,14 @@
#ifndef __USEFULL_MACROS_H__ #ifndef __USEFULL_MACROS_H__
#define __USEFULL_MACROS_H__ #define __USEFULL_MACROS_H__
#include <termios.h> // tcflag_t #include <stdbool.h> // bool
#include <stdbool.h> // bool #include <unistd.h> // pid_t
#include <unistd.h> // pid_t #include <errno.h> // errno
#include <errno.h> // errno #include <termios.h> // termios
#include <stdlib.h> // alloc, free
// just for different purposes
#include <limits.h>
#include <stdint.h>
#if defined GETTEXT #if defined GETTEXT
/* /*
@ -111,9 +115,9 @@ void WEAK signals(int sig);
double dtime(); double dtime();
// functions for color output in tty & no-color in pipes // functions for color output in tty & no-color in pipes
int (*red)(const char *fmt, ...); extern int (*red)(const char *fmt, ...);
int (*_WARN)(const char *fmt, ...); extern int (*_WARN)(const char *fmt, ...);
int (*green)(const char *fmt, ...); extern int (*green)(const char *fmt, ...);
// safe allocation // safe allocation
void * my_alloc(size_t N, size_t S); void * my_alloc(size_t N, size_t S);
// setup locales & other // setup locales & other
@ -133,11 +137,28 @@ void setup_con();
int read_console(); int read_console();
int mygetchar(); int mygetchar();
// serial port long throw_random_seed();
void restore_tty();
void tty_init(char *comdev, tcflag_t speed); uint64_t get_available_mem();
size_t read_tty(char *buff, size_t length);
int write_tty(const char *buff, size_t length); /******************************************************************************\
The original term.h
\******************************************************************************/
typedef struct {
char *portname; // device filename (should be freed before structure freeing)
int baudrate; // baudrate (B...)
struct termios oldtty; // TTY flags for previous port settings
struct termios tty; // TTY flags for current settings
int comfd; // TTY file descriptor
char *buf; // buffer for data read
int bufsz; // size of buf
int buflen; // length of data read into buf
} TTY_descr;
void close_tty(TTY_descr **descr);
TTY_descr *tty_open(char *comdev, int speed, size_t bufsz);
size_t read_tty(TTY_descr *descr);
int write_tty(int comfd, const char *buff, size_t length);
// convert string to double with checking // convert string to double with checking
int str2double(double *num, const char *str); int str2double(double *num, const char *str);
@ -252,3 +273,15 @@ void check4running(char *selfname, char *pidfilename);
// read name of process by its PID // read name of process by its PID
char *readPSname(pid_t pid); char *readPSname(pid_t pid);
#endif // __USEFULL_MACROS_H__ #endif // __USEFULL_MACROS_H__
/******************************************************************************\
The original fifo_lifo.h
\******************************************************************************/
typedef struct buff_node{
void *data;
struct buff_node *next, *last;
} List;
List *list_push_tail(List **lst, void *v);
List *list_push(List **lst, void *v);
void *list_pop(List **lst);