1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* test_termios.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sben**** <sben****@*************> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2015/11/20 01:23:46 by sben**** #+# #+# */
/* Updated: 2015/11/20 02:10:19 by sben**** ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <signal.h>
#include <strings.h>
#include <errno.h>
#include <termios.h>
#define FTIO_BS 5
typedef struct s_ftio
{
int fd;
struct termios term;
struct termios cp;
} t_ftio;
t_ftio *ftio(void)
{
/*
* J'aime pas vraiment ça, mais pour les signaux j'ai pas vraiment le choix... (globale ou static)
* Entre la peste et le choléra :p
*/
static t_ftio ftio_settings;
return (&ftio_settings);
}
void ftio_error_handle(void)
{
/*
* Affichage de l'erreur en fonction d'errno à implementer
*/
exit(EXIT_FAILURE);
}
void ftio_init_term(void);
void ftio_sigcont_handle(int sig)
{
/*
* -Wall -Wextra // Ce test ne me sert qu'a cacher le warn gcc :/
*/
if (sig) // sig toujours > 0
ftio_init_term();
}
void ftio_signal_handle(void)
{
/*
* J'ai observé que l'arret du programme par Ctrl+(C|Z)
* remet de lui même la structure termios par defaut...
* Je ne comprend pas vraiment pourquoi.. ^^
*/
signal(SIGCONT, ftio_sigcont_handle);
}
void ftio_init_term(void)
{
ftio_signal_handle();
if (!isatty(ftio()->fd) || (tcgetattr(ftio()->fd, &ftio()->term) == -1))
ftio_error_handle();
ftio()->cp = ftio()->term;
ftio()->cp.c_lflag &= ~(ICANON | ECHO);
ftio()->cp.c_lflag |= ISIG;
ftio()->cp.c_cc[VTIME] = 0;
ftio()->cp.c_cc[VMIN] = 1;
if (tcsetattr(ftio()->fd, TCSADRAIN, &ftio()->cp) == -1)
ftio_error_handle();
}
void ftio_reset_term(void)
{
if (tcsetattr(ftio()->fd, TCSANOW, &ftio()->term) == -1)
ftio_error_handle();
bzero((void *)ftio(), sizeof(t_ftio));
}
int main(void)
{
char buf[FTIO_BS + 1];
int ret;
ftio()->fd = 0;
ftio_init_term();
while (42)
{
bzero((void *)buf, FTIO_BS + 1);
ret = read(ftio()->fd, buf, FTIO_BS);
if (ret < 0)
{
ftio_reset_term();
ftio_error_handle();
}
buf[ret] = 0;
/*
* Implementer ici l'automate et les actions à entreprendre
* selon son etat (et surtout son changement d'etat)
*/
/*
* Juste pour la demo, dans la version final,
* j'aimerai bien gerer les wchar_t // Mais la c'est pas le propos
*/
if (isprint(*buf))
write(ftio()->fd, buf, ret);
}
ftio_reset_term();
return (0);
} |
Partager