fixed bug with termio/termios

This commit is contained in:
eddyem 2019-03-12 10:06:31 +03:00
parent e982f06ca1
commit 53ec829cb7
13 changed files with 331 additions and 94 deletions

3
Snippets.config Normal file
View File

@ -0,0 +1,3 @@
// Add predefined macros for your project here. For example:
// #define THE_ANSWER 42
#define EBUG 1

1
Snippets.creator Normal file
View File

@ -0,0 +1 @@
[General]

170
Snippets.creator.user Normal file
View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.8.0, 2019-03-12T09:59:40. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{cf63021e-ef53-49b0-b03b-2f2570cdf3b6}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">1</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">2</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">false</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{91347f2c-5221-46a7-80b1-0a054ca02f79}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/eddy/Docs/SAO/C_diff/snippets_library</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">По умолчанию</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Установка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Конфигурация установки</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Особая программа</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">20</value>
</data>
<data>
<variable>Version</variable>
<value type="int">20</value>
</data>
</qtcreator>

14
Snippets.files Normal file
View File

@ -0,0 +1,14 @@
CMakeLists.txt
daemon.c
examples/CMakeLists.txt
examples/cmdlnopts.c
examples/cmdlnopts.h
examples/fifo.c
examples/helloworld.c
examples/options.c
fifo_lifo.c
parseargs.c
term.c
term.h
usefull_macros.c
usefull_macros.h

2
Snippets.includes Normal file
View File

@ -0,0 +1,2 @@
.
examples

View File

@ -29,15 +29,15 @@
/* /*
* here are global parameters initialisation * here are global parameters initialisation
*/ */
int help; static int help;
glob_pars G; static glob_pars G;
// 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 = { static glob_pars const Gdefault = {
.device = NULL, .device = NULL,
.pidfile = DEFAULT_PIDFILE, .pidfile = DEFAULT_PIDFILE,
.speed = 9600, .speed = 9600,
@ -48,13 +48,14 @@ glob_pars const Gdefault = {
* Define command line options by filling structure: * Define command line options by filling structure:
* name has_arg flag val type argptr help * name has_arg flag val type argptr help
*/ */
myoption cmdlnopts[] = { static 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")}, {"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)")}, {"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 ")")},
{"exclusive",NO_ARGS, NULL, 'e', arg_int, APTR(&G.exclusive), _("open serial device exclusively")},
end_option end_option
}; };

View File

@ -20,8 +20,8 @@
*/ */
#pragma once #pragma once
#ifndef __CMDLNOPTS_H__ #ifndef CMDLNOPTS_H__
#define __CMDLNOPTS_H__ #define CMDLNOPTS_H__
/* /*
* here are some typedef's for global data * here are some typedef's for global data
@ -32,9 +32,11 @@ typedef struct{
char *logfile; // logging to this file char *logfile; // logging to this file
int speed; // connection speed int speed; // connection speed
int rest_pars_num; // number of rest parameters int rest_pars_num; // number of rest parameters
int exclusive; // exclusive open port
char** rest_pars; // the rest parameters: array of char* char** rest_pars; // the rest parameters: array of char*
} glob_pars; } glob_pars;
glob_pars *parse_args(int argc, char **argv); glob_pars *parse_args(int argc, char **argv);
#endif // __CMDLNOPTS_H__
#endif // CMDLNOPTS_H__

View File

@ -18,6 +18,10 @@
#include <usefull_macros.h> #include <usefull_macros.h>
#include <stdio.h> #include <stdio.h>
/*
* Example of FIFO/LIFO usage
*/
int main(int argc, char *argv[argc]) { int main(int argc, char *argv[argc]) {
List *f = NULL; List *f = NULL;
printf("Available memory: %luMB\n", get_available_mem()/1024/1024); printf("Available memory: %luMB\n", get_available_mem()/1024/1024);

View File

@ -16,13 +16,27 @@
* 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 "cmdlnopts.h"
#include <signal.h> // signal #include <signal.h> // signal
#include <stdlib.h> // exit, free
#include <stdio.h> // printf #include <stdio.h> // printf
#include <stdlib.h> // exit, free
#include <string.h> // strdup #include <string.h> // strdup
#include <unistd.h> // sleep #include <unistd.h> // sleep
#include <usefull_macros.h> #include <usefull_macros.h>
#include "cmdlnopts.h"
#include <termios.h> // tcsetattr
#include <unistd.h> // tcsetattr, close, read, write
#include <sys/ioctl.h> // ioctl
#include <stdio.h> // printf, getchar, fopen, perror
#include <stdlib.h> // exit
#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
/** /**
* This is an example of usage: * This is an example of usage:
@ -34,8 +48,8 @@
* 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 static TTY_descr *dev = NULL; // shoul be global to restore if die
glob_pars *GP = NULL; // for GP->pidfile need in `signals` static 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
@ -82,23 +96,31 @@ int main(int argc, char *argv[]){
} }
if(GP->device){ if(GP->device){
putlog("Try to open serial %s", GP->device); putlog("Try to open serial %s", GP->device);
dev = tty_open(GP->device, GP->speed, 256); dev = new_tty(GP->device, GP->speed, 256);
if(dev) dev = tty_open(dev, GP->exclusive);
if(!dev){ if(!dev){
putlog("Can't open %s with speed %d. Exit.", GP->device, GP->speed); putlog("Can't open %s with speed %d. Exit.", GP->device, GP->speed);
signals(0); signals(0);
} }
} }
// main stuff goes here // main stuff goes here
long seed = throw_random_seed(); long seed = throw_random_seed();
green("Now I will sleep for 10 seconds. Do whatever you want. Random seed: %ld\n", seed); green("Now I will sleep for 10 seconds. Do whatever you want. Random seed: %ld\n", seed);
double t0 = dtime(); double t0 = dtime();
char b[2] = {0};
while(dtime() - t0 < 10.){ // read data from port and print in into terminal while(dtime() - t0 < 10.){ // read data from port and print in into terminal
if(dev){ if(dev){
if(read_tty(dev)){ if(read_tty(dev)){
printf("Data from port: %s\n", dev->buf); printf("Got %zd bytes from port: %s\n", dev->buflen, dev->buf);
t0 = dtime();
} }
char ch = read_console(); int r = read_console();
if(ch) write_tty(dev->comfd, &ch, 1); if(r < 1) continue;
t0 = dtime();
b[0] = (char) r;
printf("send to tty: %d (%c)\n", r, b[0]);
write_tty(dev->comfd, b, 1);
} }
} }
// clean everything // clean everything

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-09 01:49+0300\n" "POT-Creation-Date: 2019-03-12 09:53+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"
@ -17,7 +17,7 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#. / \nïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n #. / \nïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n
#: /Big/Data/C_sources/snippets_library/daemon.c:70 #: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:70
#, c-format #, c-format
msgid "\n" msgid "\n"
"Found running process (pid=%d), exit.\n" "Found running process (pid=%d), exit.\n"
@ -25,132 +25,118 @@ msgstr "\n"
"ïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n" "ïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n"
#. / %s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ! #. / %s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!
#: /Big/Data/C_sources/snippets_library/parseargs.c:483 #: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:483
#, c-format #, c-format
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:254 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:262
msgid "Can't close mmap'ed file" msgid "Can't close mmap'ed file"
msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ" msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
#. / îÅ ÍÏÇÕ ÓÄÅÌÁÔØ ÐÏÒÔ ÜËÓËÌÀÚÉ×ÎÙÍ #. / îÅ ÍÏÇÕ ÓÄÅÌÁÔØ ÐÏÒÔ ÜËÓËÌÀÚÉ×ÎÙÍ
#: /Big/Data/C_sources/snippets_library/term.c:129 #: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:129
msgid "Can't do exclusive open" msgid "Can't do exclusive open"
msgstr "îÅ ÍÏÇÕ ÐÅÒÅ×ÅÓÔÉ ÐÏÒÔ × ÜËÓËÌÀÚÉ×ÎÙÊ ÒÅÖÉÍ" msgstr "îÅ ÍÏÇÕ ÐÅÒÅ×ÅÓÔÉ ÐÏÒÔ × ÜËÓËÌÀÚÉ×ÎÙÊ ÒÅÖÉÍ"
#. Get settings
#. / îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
#: /Big/Data/C_sources/snippets_library/term.c:111
#, fuzzy
msgid "Can't get old TTY settings"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
#. / îÅ ÍÏÇÕ munmap #. / îÅ ÍÏÇÕ munmap
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:268 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:276
msgid "Can't munmap" msgid "Can't munmap"
msgstr "îÅ ÍÏÇÕ munmap" msgstr "îÅ ÍÏÇÕ munmap"
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ #. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:237 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:245
#, c-format #, c-format
msgid "Can't open %s for reading" msgid "Can't open %s for reading"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ" msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random #. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:184 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:184
msgid "Can't open /dev/random" msgid "Can't open /dev/random"
msgstr "" msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random"
#. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ PID ÆÁÊÌ #. / îÅ ÍÏÇÕ ÏÔËÒÙÔØ PID ÆÁÊÌ
#: /Big/Data/C_sources/snippets_library/daemon.c:143 #: /home/eddy/Docs/SAO/C_diff/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:382 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:390
msgid "Can't open log file" msgid "Can't open log file"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÌÏÇÆÁÊÌ" msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÌÏÇÆÁÊÌ"
#. / îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random #. / îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:189 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:189
msgid "Can't read /dev/random" msgid "Can't read /dev/random"
msgstr "" msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random"
#. / îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ #. / îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:299 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:307
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:242 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:250
#, 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 #: /home/eddy/Docs/SAO/C_diff/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:249 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:257
msgid "Mmap error for input" msgid "Mmap error for input"
msgstr "ïÛÉÂËÁ mmap" msgstr "ïÛÉÂËÁ mmap"
#. / îÅ ÚÁÄÁÎÏ ÉÍÑ ÌÏÇÆÁÊÌÁ #. / îÅ ÚÁÄÁÎÏ ÉÍÑ ÌÏÇÆÁÊÌÁ
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:374 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:382
msgid "Need filename for log file" msgid "Need filename for log file"
msgstr "îÅ ÚÁÄÁÎÏ ÉÍÑ ÌÏÇÆÁÊÌÁ" msgstr "îÅ ÚÁÄÁÎÏ ÉÍÑ ÌÏÇÆÁÊÌÁ"
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:176
msgid "Need non-zero buffer for TTY device"
msgstr "äÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÕÓÔÒÏÊÓÔ×Á ÔÒÅÂÕÅÔÓÑ ÂÕÆÅÒ ÎÅÎÕÌÅ×ÏÇÏ ÒÁÚÍÅÒÁ"
#. / îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ! #. / îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:232 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:240
msgid "No filename given!" msgid "No filename given!"
msgstr "îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!" msgstr "îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
#. / ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ #. / ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ
#: /Big/Data/C_sources/snippets_library/term.c:168 #: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:169
msgid "Port name is missing" msgid "Port name is missing"
msgstr "" msgstr "ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ"
#. / ðÒÏÂÕÀ ÏÔËÒÙÔØ ÌÏÇÆÁÊÌ %s × ÒÅÖÉÍÅ ÄÏÐÏÌÎÅÎÉÑ\n #. / ðÒÏÂÕÀ ÏÔËÒÙÔØ ÌÏÇÆÁÊÌ %s × ÒÅÖÉÍÅ ÄÏÐÏÌÎÅÎÉÑ\n
#: /Big/Data/C_sources/snippets_library/usefull_macros.c:378 #: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:386
#, 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"
#. / îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\" #. / îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\"
#: /Big/Data/C_sources/snippets_library/parseargs.c:488 #: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:488
#, c-format #, c-format
msgid "Wrong argument \"%s\" of parameter \"%s\"" msgid "Wrong argument \"%s\" of parameter \"%s\""
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\"" msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\""
#. amount of pcount and/or scount wrong #. amount of pcount and/or scount wrong
#. / îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ #. / îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ
#: /Big/Data/C_sources/snippets_library/parseargs.c:54 #: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:54
msgid "Wrong helpstring!" msgid "Wrong helpstring!"
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ" msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ"
#. / îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s #. / îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s
#: /Big/Data/C_sources/snippets_library/parseargs.c:478 #: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:478
#, 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 #: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:92
#, c-format #, c-format
msgid "Wrong speed value: %d!" msgid "Wrong speed value: %d!"
msgstr "" msgstr "îÅÐÒÁ×ÉÌØÎÏÅ ÚÎÁÞÅÎÉÅ ÓËÏÒÏÓÔÉ: %d!"

82
term.c
View File

@ -36,7 +36,7 @@
typedef struct { typedef struct {
int speed; // communication speed in bauds/s int speed; // communication speed in bauds/s
int bspeed; // baudrate from termios.h tcflag_t bspeed; // baudrate from termios.h
} spdtbl; } spdtbl;
static int tty_init(TTY_descr *descr); static int tty_init(TTY_descr *descr);
@ -80,7 +80,7 @@ static spdtbl speeds[] = {
* @param speed - integer speed (bps) * @param speed - integer speed (bps)
* @return 0 if error, Bxxx if all OK * @return 0 if error, Bxxx if all OK
*/ */
int conv_spd(int speed){ tcflag_t conv_spd(int speed){
spdtbl *spd = speeds; spdtbl *spd = speeds;
int curspeed = 0; int curspeed = 0;
do{ do{
@ -99,35 +99,35 @@ int conv_spd(int speed){
* @return 0 if all OK or error code * @return 0 if all OK or error code
*/ */
static int tty_init(TTY_descr *descr){ static int tty_init(TTY_descr *descr){
DBG("\nOpen port..."); DBG("\nOpen port..."); // |O_NONBLOCK
if ((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){ if ((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
/// îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s /// îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %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;
} }
DBG("OK\nGet current settings..."); DBG("OK\nGet current settings...");
if(ioctl(descr->comfd, TCGETA, &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;
} }
descr->tty = descr->oldtty; descr->tty = descr->oldtty;
struct termios *tty = &descr->tty; descr->tty.c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG)
tty->c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG) descr->tty.c_oflag = 0;
tty->c_oflag = 0; descr->tty.c_cflag = descr->baudrate|CS8|CREAD|CLOCAL; // 9.6k, 8N1, RW, ignore line ctrl
tty->c_cflag = descr->baudrate|CS8|CREAD|CLOCAL; // 9.6k, 8N1, RW, ignore line ctrl descr->tty.c_cc[VMIN] = 0; // non-canonical mode
tty->c_cc[VMIN] = 0; // non-canonical mode descr->tty.c_cc[VTIME] = 5;
tty->c_cc[VTIME] = 5; if(tcsetattr(descr->comfd, TCSANOW, &descr->tty) < 0){
if(ioctl(descr->comfd, TCSETA, &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(ioctl(descr->comfd, TIOCEXCL)){ if(ioctl(descr->comfd, TIOCEXCL)){
/// îÅ ÍÏÇÕ ÓÄÅÌÁÔØ ÐÏÒÔ ÜËÓËÌÀÚÉ×ÎÙÍ /// îÅ ÍÏÇÕ ÓÄÅÌÁÔØ ÐÏÒÔ ÜËÓËÌÀÚÉ×ÎÙÍ
WARN(_("Can't do exclusive open")); WARN(_("Can't do exclusive open"));
} }}
DBG("OK"); DBG("OK");
return 0; return 0;
} }
@ -138,47 +138,62 @@ static int tty_init(TTY_descr *descr){
void close_tty(TTY_descr **descr){ void close_tty(TTY_descr **descr){
if(descr == NULL || *descr == NULL) return; if(descr == NULL || *descr == NULL) return;
TTY_descr *d = *descr; TTY_descr *d = *descr;
FREE(d->portname);
FREE(d->buf);
if(d->comfd){ if(d->comfd){
DBG("close file.."); DBG("close file..");
ioctl(d->comfd, TCSANOW, &d->oldtty); // return TTY to previous state ioctl(d->comfd, TCSANOW, &d->oldtty); // return TTY to previous state
close(d->comfd); close(d->comfd);
} }
FREE(d->portname);
FREE(d->buf);
FREE(*descr); FREE(*descr);
DBG("done!\n"); DBG("done!\n");
} }
/** /**
* @brief tty_open - init & open tty device * @brief new_tty - create new TTY structure with partially filled fields
* @param port - TTY device filename * @param comdev - TTY device filename
* @param speed - speed (number) * @param speed - speed (number)
* @param bufsz - size of buffer for input data (or 0 if opened only to write) * @param bufsz - size of buffer for input data (or 0 if opened only to write)
* @return pointer to TTY structure if all OK * @return pointer to TTY structure if all OK
*/ */
TTY_descr *tty_open(char *port, int speed, size_t bufsz){ TTY_descr *new_tty(char *comdev, int speed, size_t bufsz){
int spd = conv_spd(speed); tcflag_t spd = conv_spd(speed);
if(!spd) return NULL; if(!spd) return NULL;
DBG("open %s with speed %d)", port, speed); DBG("create %s with speed %d and buffer size %zd", comdev, speed, bufsz);
TTY_descr *descr = MALLOC(TTY_descr, 1); TTY_descr *descr = MALLOC(TTY_descr, 1);
descr->portname = strdup(port); descr->portname = strdup(comdev);
descr->baudrate = spd; descr->baudrate = spd;
descr->speed = speed;
if(!descr->portname){ if(!descr->portname){
/// ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ /// ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ
WARNX(_("Port name is missing")); WARNX(_("Port name is missing"));
}else if(!tty_init(descr)){ }else{
if(bufsz){ if(bufsz){
descr->buf = MALLOC(char, bufsz+1); descr->buf = MALLOC(char, bufsz+1);
descr->bufsz = bufsz; descr->bufsz = bufsz;
DBG("allocate buffer with size %zd", bufsz); DBG("allocate buffer with size %zd", bufsz);
}
return descr; return descr;
}else WARNX(_("Need non-zero buffer for TTY device"));
} }
FREE(descr->portname); FREE(descr->portname);
FREE(descr); FREE(descr);
return NULL; return NULL;
} }
/**
* @brief tty_open - init & open tty device
* @param d - already filled structure (with new_tty or by hands)
* @param exclusive - == 1 to make exclusive open
* @return pointer to TTY structure if all OK
*/
TTY_descr *tty_open(TTY_descr *d, int exclusive){
DBG("open %s with speed %d%s", d->portname, d->speed, exclusive ? "" : " (exclusive)");
if(!d || !d->portname || !d->baudrate) return NULL;
if(exclusive) d->exclusive = TRUE;
else d->exclusive = FALSE;
if(tty_init(d)) return NULL;
return d;
}
/** /**
* @brief read_tty - read data from TTY with 10ms timeout * @brief read_tty - read data from TTY with 10ms timeout
@ -188,7 +203,8 @@ TTY_descr *tty_open(char *port, int speed, size_t bufsz){
*/ */
size_t read_tty(TTY_descr *d){ size_t read_tty(TTY_descr *d){
if(d->comfd < 0) return 0; if(d->comfd < 0) return 0;
ssize_t L = 0, l; size_t L = 0;
ssize_t l;
size_t length = d->bufsz; size_t length = d->bufsz;
char *ptr = d->buf; char *ptr = d->buf;
fd_set rfds; fd_set rfds;
@ -199,19 +215,30 @@ size_t read_tty(TTY_descr *d){
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(d->comfd, &rfds); FD_SET(d->comfd, &rfds);
// wait for 10ms // wait for 10ms
tv.tv_sec = 0; tv.tv_usec = 10000; tv.tv_sec = 0; tv.tv_usec = 50000;
retval = select(d->comfd + 1, &rfds, NULL, NULL, &tv); retval = select(d->comfd + 1, &rfds, NULL, NULL, &tv);
if (!retval) break; if (!retval) break;
if(FD_ISSET(d->comfd, &rfds)){ if(FD_ISSET(d->comfd, &rfds)){
if((l = read(d->comfd, ptr, length)) < 1){ if((l = read(d->comfd, ptr, length)) < 1){
return 0; break;
} }
#ifdef EBUG
char *s = ptr;
#endif
ptr += l; L += l; ptr += l; L += l;
#ifdef EBUG
*ptr = 0;
#endif
//DBG("got %zd bytes: %s\nBUF[%zd](%d): %s", l, s, L, d->bufsz, d->buf);
DBG("FD %d got %zd bytes: %s\nsym: %d, BUF[%zd](%zd): %s", d->comfd, l, s, (int)s[0], L, d->bufsz, d->buf);
length -= l; length -= l;
} }
}while(l); }while(l && length);
d->buflen = L; d->buflen = L;
d->buf[L] = 0; d->buf[L] = 0;
#ifdef EBUG
if(L) DBG("Got %zd bytes total: %s", d->buflen, d->buf);
#endif
return (size_t)L; return (size_t)L;
} }
@ -222,6 +249,7 @@ size_t read_tty(TTY_descr *d){
* @return 0 if all OK * @return 0 if all OK
*/ */
int write_tty(int comfd, const char *buff, size_t length){ int write_tty(int comfd, const char *buff, size_t length){
DBG("comfd: %d, buff: \"%s\", len: %zd", comfd, buff, 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){
/// "ïÛÉÂËÁ ÚÁÐÉÓÉ!" /// "ïÛÉÂËÁ ÚÁÐÉÓÉ!"

View File

@ -146,19 +146,23 @@ uint64_t get_available_mem();
\******************************************************************************/ \******************************************************************************/
typedef struct { typedef struct {
char *portname; // device filename (should be freed before structure freeing) char *portname; // device filename (should be freed before structure freeing)
int baudrate; // baudrate (B...) int speed; // baudrate in human-readable format
tcflag_t baudrate; // baudrate (B...)
struct termios oldtty; // TTY flags for previous port settings struct termios oldtty; // TTY flags for previous port settings
struct termios tty; // TTY flags for current settings struct termios tty; // TTY flags for current settings
int comfd; // TTY file descriptor int comfd; // TTY file descriptor
char *buf; // buffer for data read char *buf; // buffer for data read
int bufsz; // size of buf size_t bufsz; // size of buf
int buflen; // length of data read into buf size_t buflen; // length of data read into buf
bool exclusive; // should device be exclusive opened
} TTY_descr; } TTY_descr;
void close_tty(TTY_descr **descr); void close_tty(TTY_descr **descr);
TTY_descr *tty_open(char *comdev, int speed, size_t bufsz); TTY_descr *new_tty(char *comdev, int speed, size_t bufsz);
TTY_descr *tty_open(TTY_descr *d, int exclusive);
size_t read_tty(TTY_descr *descr); size_t read_tty(TTY_descr *descr);
int write_tty(int comfd, const char *buff, size_t length); int write_tty(int comfd, const char *buff, size_t length);
tcflag_t conv_spd(int speed);
// 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);