Some code cleanup

This commit is contained in:
Igor Socec 2016-11-19 13:46:26 +01:00
parent c17e696566
commit b934bb120c
11 changed files with 122 additions and 112 deletions

View file

@ -51,7 +51,7 @@ int client_read(client_t *client)
} }
/* handle special telnet characters coming from the client */ /* handle special telnet characters coming from the client */
telnet_handle_client_read(client->data, &len); telnet_filter_client_read(client->data, &len);
/* grab current time and store it as client's last activity */ /* grab current time and store it as client's last activity */
client->last_active = time(NULL); client->last_active = time(NULL);
@ -64,7 +64,7 @@ int client_write(client_t *client, char *databuf, int datalen)
int len; int len;
/* handle special telnet characters to display them correctly on client */ /* handle special telnet characters to display them correctly on client */
//telnet_handle_client_write(databuf, &datalen); //telnet_filter_client_write(databuf, &datalen);
//TODO let's print received bytes during development phase... //TODO let's print received bytes during development phase...
if (debug_messages) if (debug_messages)
@ -119,7 +119,7 @@ int client_wait_line(client_t *client)
{ {
return -1; return -1;
} }
/* we don't want empty data so stop on \r or \n */ /* we don't want empty data so ignore data starting with \r or \n */
if ( (client->data[0] == '\r') || (client->data[0] == '\n') ) if ( (client->data[0] == '\r') || (client->data[0] == '\n') )
{ {
client->data[0] = '\0'; client->data[0] = '\0';
@ -133,10 +133,10 @@ int client_wait_line(client_t *client)
int client_ask_username(client_t *client) int client_ask_username(client_t *client)
{ {
int i; int i;
char msg[DATABUF_LEN]; char msg[BUFFER_LEN];
/* show username request to the client */ /* show username request to the client */
snprintf(msg, DATABUF_LEN, snprintf(msg, BUFFER_LEN,
"\nPlease provide a username to identify yourself to" "\nPlease provide a username to identify yourself to"
"other users (max %d characters):\n", USERNAME_LEN); "other users (max %d characters):\n", USERNAME_LEN);
client_write(client, msg, strlen(msg)); client_write(client, msg, strlen(msg));
@ -160,7 +160,7 @@ int client_ask_username(client_t *client)
} }
/* show welcome message to client */ /* show welcome message to client */
snprintf(msg, DATABUF_LEN, snprintf(msg, BUFFER_LEN,
"\nWelcome %s!\n\n", client->username); "\nWelcome %s!\n\n", client->username);
client_write(client, msg, strlen(msg)); client_write(client, msg, strlen(msg));

View file

@ -1,7 +1,7 @@
#pragma once
/* Handles communication with a client. */ /* Handles communication with a client. */
#pragma once
#include <common.h> #include <common.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -12,9 +12,9 @@ typedef struct
int socket; /* client socket */ int socket; /* client socket */
struct sockaddr_in address; /* client address information */ struct sockaddr_in address; /* client address information */
char ip_string[INET_ADDRSTRLEN]; /* client IP address as a string */ char ip_string[INET_ADDRSTRLEN]; /* client IP address as a string */
time_t last_active; /* time of client's last activity in seconds from Epoch */ time_t last_active; /* time of client's last activity */
char username[USERNAME_LEN]; /* username for human identification */ char username[USERNAME_LEN]; /* username for human identification */
char data[DATABUF_LEN]; /* buffer for data received from client */ char data[BUFFER_LEN]; /* buffer for received data */
} client_t; } client_t;
/** /**
@ -48,7 +48,7 @@ int client_write(client_t *client, char *databuf, int datalen);
* *
* Returns: * Returns:
* - 0 on success * - 0 on success
* - negative value if error occurred * - negative value if an error occurred
*/ */
int client_wait_line(client_t *client); int client_wait_line(client_t *client);
@ -58,6 +58,6 @@ int client_wait_line(client_t *client);
* *
* Returns: * Returns:
* - 0 on success * - 0 on success
* - negative value if error occurred * - negative value if an error occurred
*/ */
int client_ask_username(client_t *client); int client_ask_username(client_t *client);

View file

@ -1,3 +1,5 @@
/* Common header file reused within the project */
#pragma once #pragma once
#include <stdio.h> #include <stdio.h>
@ -8,17 +10,20 @@
#include <time.h> #include <time.h>
#include <fcntl.h> #include <fcntl.h>
#define DATABUF_LEN 128 /* ========================================================================== */
#define TIMESTAMP_FORMAT "%Y-%m-%dT%H:%M:%S" /* ISO 8601 */ #define BUFFER_LEN 128 /* length of a data buffer */
#define TIMESTAMP_LEN 20+1 /* calculated according to the timestamp format */
/* ========================================================================== */
/* Global variables used throughout the application. */
int debug_messages; /* if > 0 debug messages will be printed */ int debug_messages; /* if > 0 debug messages will be printed */
/* Global functions used throughout the application. */ /* ========================================================================== */
#define TIMESTAMP_FORMAT "%Y-%m-%dT%H:%M:%S" /* follow ISO 8601 format */
#define TIMESTAMP_LEN 20+1 /* size of the timestamp format above */
/** /**
* Converts time in seconds from Epoch to a conveniently formatted string. * Converts time in "seconds from Epoch" to a conveniently formatted string.
*/ */
void time2string(time_t time, char* timestamp); void time2string(time_t time, char* timestamp);

View file

@ -4,15 +4,16 @@
* communication with a specific TTY device. * communication with a specific TTY device.
*/ */
#include "moxerver.h" #include <moxerver.h>
#include "parser.h" #include <parser.h>
#include <signal.h> /* handling quit signals */ #include <signal.h> /* handling quit signals */
#include <pthread.h> #include <pthread.h>
#define NAME "moxerver" #define NAME "moxerver"
/* Prints help message. */ /* Prints help message. */
static void usage() { static void usage()
{
//TODO maybe some styling should be done //TODO maybe some styling should be done
fprintf(stderr, "Usage: %s -p tcp_port [-t tty_path] [-d] [-h]\n", NAME); fprintf(stderr, "Usage: %s -p tcp_port [-t tty_path] [-d] [-h]\n", NAME);
fprintf(stderr, "\t-t\ttty dev path (if not specified %s needs to be defined)\n", CONFILE); fprintf(stderr, "\t-t\ttty dev path (if not specified %s needs to be defined)\n", CONFILE);
@ -21,44 +22,55 @@ static void usage() {
} }
/* Performs cleanup and exit. */ /* Performs cleanup and exit. */
void cleanup(int exit_code) { void cleanup(int exit_code)
{
// TODO: maybe pthread_kill() should be used for threads and cleanup there
fprintf(stderr, "[%s] cleanup and exit with %d\n", NAME, exit_code); fprintf(stderr, "[%s] cleanup and exit with %d\n", NAME, exit_code);
/* close client */ /* close the client */
if (client.socket != -1) { if (client.socket != -1)
{
client_close(&client); client_close(&client);
} }
/* close tty device */ /* close the tty device */
if (tty_dev.fd != -1)
{
tty_close(&tty_dev); tty_close(&tty_dev);
/* close server */ }
/* close the server */
server_close(&server); server_close(&server);
/* exit */ /* exit */
exit(exit_code); exit(exit_code);
} }
/* Handles received quit signals, use it for all quit signals of interest. */ /* Handles received quit signals, use it for all quit signals of interest. */
void quit_handler(int signum) { void quit_handler(int signum)
{
/* perform cleanup and exit with 0 */ /* perform cleanup and exit with 0 */
fprintf(stderr, "[%s] received signal %d\n", NAME, signum); fprintf(stderr, "[%s] received signal %d\n", NAME, signum);
cleanup(0); cleanup(0);
} }
/* Parse handler function, used to configure serial port */ /* Parse handler function, used to configure serial port */
int parse_handler(void *user, const char *section, const char *name, const char *value) { int parse_handler(void *user, const char *section, const char *name, const char *value)
{
//printf("[%s] section = %s, name = %s, value = %s\n", __func__, section, name, value); //printf("[%s] section = %s, name = %s, value = %s\n", __func__, section, name, value);
if (!strcmp(name, "speed") && (unsigned int)atoi(section) == server.port) { if (!strcmp(name, "speed") && (unsigned int)atoi(section) == server.port)
{
fprintf(stderr, "[%s] setting %s speed for port %s\n", __func__, value, section); fprintf(stderr, "[%s] setting %s speed for port %s\n", __func__, value, section);
if (cfsetispeed(&(tty_dev.ttyset), baud_to_speed(atoi(value))) < 0 || if (cfsetispeed(&(tty_dev.ttyset), baud_to_speed(atoi(value))) < 0 ||
cfsetospeed(&(tty_dev.ttyset), baud_to_speed(atoi(value))) < 0) { cfsetospeed(&(tty_dev.ttyset), baud_to_speed(atoi(value))) < 0)
{
fprintf(stderr, "[%s] error configuring tty device speed\n", NAME); fprintf(stderr, "[%s] error configuring tty device speed\n", NAME);
return -1; return -1;
} }
} }
if (!strcmp(name, "dev") && (unsigned int)atoi(section) == server.port) if (!strcmp(name, "dev") && (unsigned int)atoi(section) == server.port)
{
strcpy(tty_dev.path, value); strcpy(tty_dev.path, value);
}
return 1; return 1;
} }
@ -70,7 +82,7 @@ void time2string(time_t time, char* timestamp)
void* thread_new_client_connection(void *args) void* thread_new_client_connection(void *args)
{ {
char msg[DATABUF_LEN]; char msg[BUFFER_LEN];
char timestamp[TIMESTAMP_LEN]; char timestamp[TIMESTAMP_LEN];
client_t temp_client; client_t temp_client;
@ -211,9 +223,9 @@ void* thread_client_data(void *args)
continue; continue;
} }
/* put client in "character" mode */ /* put client in "character" mode */
char msg[TELNET_MSG_SIZE_CHARMODE]; char msg[TELNET_MSG_LEN_CHARMODE];
telnet_message_set_character_mode(msg); telnet_message_set_character_mode(msg);
client_write(&client, msg, TELNET_MSG_SIZE_CHARMODE); client_write(&client, msg, TELNET_MSG_LEN_CHARMODE);
} }
/* setup parameters for select() */ /* setup parameters for select() */
@ -326,8 +338,8 @@ int main(int argc, char *argv[]) {
break; break;
/* get tty device path, default config used */ /* get tty device path, default config used */
case 't': case 't':
if ((strnlen(optarg, DEV_PATH) == 0) || if ((strnlen(optarg, TTY_DEV_PATH_LEN) == 0) ||
(strnlen(optarg, DEV_PATH) > (DEV_PATH - 1))) { (strnlen(optarg, TTY_DEV_PATH_LEN) > (TTY_DEV_PATH_LEN - 1))) {
fprintf(stderr, "[%s] error: tty path was not specified\n\n", NAME); fprintf(stderr, "[%s] error: tty path was not specified\n\n", NAME);
usage(); usage();
return -1; return -1;
@ -393,9 +405,10 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
/* start thread function (in this thread) that handles client data */
thread_client_data(NULL); thread_client_data(NULL);
/* unexpected break from while() loop */ /* unexpected break from client data loop */
fprintf(stderr, "[%s] unexpected condition\n", NAME); fprintf(stderr, "[%s] unexpected condition\n", NAME);
/* cleanup and exit with -1 */ /* cleanup and exit with -1 */
cleanup(-1); cleanup(-1);

View file

@ -9,12 +9,12 @@
#define CONFILE "moxanix.cfg" #define CONFILE "moxanix.cfg"
#define SERVER_WAIT_TIMEOUT 2 /* seconds for select() timeout in server loop */ #define SERVER_WAIT_TIMEOUT 2 /* seconds for select() timeout in server loop */
#define TTY_WAIT_TIMEOUT 5 /* seconds for select() timeout in server loop */ #define TTY_WAIT_TIMEOUT 5 /* seconds for select() timeout in tty loop */
/* Global variables used throughout the application. */ /* Global variables used throughout the application. */
server_t server; /* main server structure */ server_t server; /* main server */
client_t client; /* connected client structure */ //TODO working with only 1 client, this can be expanded into a list client_t client; /* connected client */ //TODO working with only 1 client, this can be expanded into a list
client_t new_client; /* client structure for new client request */ client_t new_client; /* reserved for a new client request */
tty_t tty_dev; /* connected tty device */ tty_t tty_dev; /* connected tty device */
typedef struct typedef struct

View file

@ -9,7 +9,7 @@ int server_setup(server_t *server, unsigned int port)
/* set up server address information */ /* set up server address information */
server->address.sin_family = AF_INET; /* use IPv4 address family */ server->address.sin_family = AF_INET; /* use IPv4 address family */
server->address.sin_port = htons(port); /* set up port number, htons is for using network byte order */ server->address.sin_port = htons(port); /* set up port number (htons for network byte order) */
server->address.sin_addr.s_addr = INADDR_ANY; /* use local address */ server->address.sin_addr.s_addr = INADDR_ANY; /* use local address */
/* create stream socket using TCP */ /* create stream socket using TCP */
@ -50,7 +50,7 @@ int server_setup(server_t *server, unsigned int port)
/* save server port number */ /* save server port number */
server->port = port; server->port = port;
fprintf(stderr,"[%s] assigned port %u\n", __func__, server->port); //ntohs(server->address.sin_port) fprintf(stderr,"[%s] assigned port %u\n", __func__, server->port); // ntohs(server->address.sin_port)
/* listen for a client connection, allow some connections in queue */ /* listen for a client connection, allow some connections in queue */
if (listen(server->socket, 1) == -1) if (listen(server->socket, 1) == -1)
@ -99,7 +99,7 @@ int server_accept(server_t *server, client_t *accepted_client)
return -errno; return -errno;
} }
/* get client IP address as human a readable string */ /* get client IP address as a human readable string */
inet_ntop(accepted_client->address.sin_family, inet_ntop(accepted_client->address.sin_family,
&accepted_client->address.sin_addr.s_addr, &accepted_client->address.sin_addr.s_addr,
accepted_client->ip_string, INET_ADDRSTRLEN); accepted_client->ip_string, INET_ADDRSTRLEN);

View file

@ -1,7 +1,7 @@
#pragma once
/* Handles server operation. */ /* Handles server operation. */
#pragma once
#include <common.h> #include <common.h>
#include <client.h> #include <client.h>
@ -9,7 +9,7 @@ typedef struct
{ {
int socket; /* server socket */ int socket; /* server socket */
struct sockaddr_in address; /* server address information */ struct sockaddr_in address; /* server address information */
unsigned int port; /* server port in host byte order, practical reference */ unsigned int port; /* server port in host byte order */
} server_t; } server_t;
/** /**

View file

@ -85,10 +85,10 @@ void telnet_message_set_character_mode(char *databuf)
//TODO Do we verify client response? What do we do if the response is not how we expected? //TODO Do we verify client response? What do we do if the response is not how we expected?
} }
void telnet_handle_client_read(char *databuf, int *datalen) void telnet_filter_client_read(char *databuf, int *datalen)
{ {
int i; int i;
char newdata[DATABUF_LEN]; char newdata[BUFFER_LEN];
int newlen = 0; int newlen = 0;
/* process data using a new buffer */ /* process data using a new buffer */
@ -115,10 +115,10 @@ void telnet_handle_client_read(char *databuf, int *datalen)
*datalen = newlen; *datalen = newlen;
} }
void telnet_handle_client_write(char *databuf, int *datalen) void telnet_filter_client_write(char *databuf, int *datalen)
{ {
int i; int i;
char newdata[DATABUF_LEN]; // TODO: maybe use realloc, this is risky char newdata[BUFFER_LEN]; // TODO: maybe use realloc, this is risky
int newlen = 0; int newlen = 0;
/* process data using a new buffer */ /* process data using a new buffer */

View file

@ -1,15 +1,15 @@
#pragma once
/* Handles details related to telnet protocol. */ /* Handles details related to telnet protocol. */
#pragma once
#include <common.h> #include <common.h>
#define TELNET_MSG_SIZE_CHARMODE 9 #define TELNET_MSG_LEN_CHARMODE 9
/** /**
* Creates a telnet protocol message that tells client to go into "character" * Creates a telnet protocol message that tells client to go into "character"
* mode. The passed data buffer must be big enough to hold the message payload * mode. The passed data buffer must be big enough to hold the message payload
* with the size defined by TELNET_MSG_SIZE_CHARMODE. * with the size defined by TELNET_MSG_LEN_CHARMODE.
* Operates directly on the passed data buffer. * Operates directly on the passed data buffer.
*/ */
void telnet_message_set_character_mode(char *databuf); void telnet_message_set_character_mode(char *databuf);
@ -19,11 +19,11 @@ void telnet_message_set_character_mode(char *databuf);
* client. Used to filter out the handshake commands of telnet protocol. * client. Used to filter out the handshake commands of telnet protocol.
* Operates directly on the passed data buffer and modifies the payload length. * Operates directly on the passed data buffer and modifies the payload length.
*/ */
void telnet_handle_client_read(char *databuf, int *datalen); void telnet_filter_client_read(char *databuf, int *datalen);
/** /**
* Handles special characters in the data buffer before sending them to the * Handles special characters in the data buffer before sending them to the
* client. Used to correctly echo the characters to the telnet client. * client. Used to correctly echo the characters to the telnet client.
* Operates directly on the passed data buffer and modifies the payload length. * Operates directly on the passed data buffer and modifies the payload length.
*/ */
void telnet_handle_client_write(char *databuf, int *datalen); void telnet_filter_client_write(char *databuf, int *datalen);

41
tty.c
View file

@ -1,32 +1,26 @@
#include <tty.h> #include <tty.h>
#define NAME "tty" #define NAME "tty"
#define TTY_DEF_BAUD_RATE B115200 #define TTY_DEFAULT_BAUDRATE B115200
int tty_open(tty_t *tty_dev) int tty_open(tty_t *tty_dev)
{ {
int fd; /* open tty device to get the file descriptor */
// PROPOSAL: tty_dev->fd = open (tty_dev->path, O_RDWR | O_NOCTTY | O_SYNC);
// open tty device to get file descriptor @tty_dev.fd if (tty_dev->fd < 0)
// setup tty device parameters @tty_dev.ttyset
// apply settings by calling tcsetattr(fd, ttyset)
// on success copy path to @tty_dev.path
if ((fd = open (tty_dev->path, O_RDWR | O_NOCTTY | O_SYNC)) < 0)
{ {
tty_dev->fd = -1;
return -errno; return -errno;
} }
else
{
tty_dev->fd = fd;
}
/* store default termios setitngs */ /* store default termios settings */
if (tcgetattr(tty_dev->fd, &(tty_dev->ttysetdef))) if (tcgetattr(tty_dev->fd, &(tty_dev->ttysetold)))
{ {
fprintf(stderr, "[%s] error reading device default config\n" fprintf(stderr, "[%s] error reading device default config\n"
"\t\t-> default config will not be restored upon exit", __func__); "\t\t-> default config will not be restored upon exit", __func__);
} }
/* set tty device parameters */
tty_dev->ttyset.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | tty_dev->ttyset.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR |
PARMRK | INPCK | ISTRIP | IXON); PARMRK | INPCK | ISTRIP | IXON);
tty_dev->ttyset.c_oflag &= ~(OCRNL | ONLCR | ONLRET | tty_dev->ttyset.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
@ -37,20 +31,21 @@ int tty_open(tty_t *tty_dev)
tty_dev->ttyset.c_cc[VMIN] = 1; tty_dev->ttyset.c_cc[VMIN] = 1;
tty_dev->ttyset.c_cc[VTIME] = 5; tty_dev->ttyset.c_cc[VTIME] = 5;
/* if speed is set to B0 (e.g. cfg file is not provided), default values are used */ /* if speed is set to B0 (e.g. cfg file not provided), use default values */
if (cfgetispeed(&(tty_dev->ttyset)) == baud_to_speed(0) && if (cfgetispeed(&(tty_dev->ttyset)) == baud_to_speed(0) &&
cfsetispeed(&(tty_dev->ttyset), TTY_DEF_BAUD_RATE) < 0) cfsetispeed(&(tty_dev->ttyset), TTY_DEFAULT_BAUDRATE) < 0)
{ {
fprintf(stderr, "[%s] error configuring tty device speed\n", __func__); fprintf(stderr, "[%s] error configuring tty device speed\n", __func__);
return -errno; return -errno;
} }
if (cfgetospeed(&(tty_dev->ttyset)) == baud_to_speed(0) && if (cfgetospeed(&(tty_dev->ttyset)) == baud_to_speed(0) &&
cfsetospeed(&(tty_dev->ttyset), TTY_DEF_BAUD_RATE) < 0) cfsetospeed(&(tty_dev->ttyset), TTY_DEFAULT_BAUDRATE) < 0)
{ {
fprintf(stderr, "[%s] error configuring tty device speed\n", __func__); fprintf(stderr, "[%s] error configuring tty device speed\n", __func__);
return -errno; return -errno;
} }
/* apply tty device settings */
if (tcsetattr(tty_dev->fd, TCSANOW, &(tty_dev->ttyset)) < 0) if (tcsetattr(tty_dev->fd, TCSANOW, &(tty_dev->ttyset)) < 0)
{ {
fprintf(stderr, "[%s] error configuring tty device\n", __func__); fprintf(stderr, "[%s] error configuring tty device\n", __func__);
@ -67,7 +62,7 @@ int tty_close(tty_t *tty_dev)
fprintf(stderr, "[%s] closing tty device \n", __func__); fprintf(stderr, "[%s] closing tty device \n", __func__);
if (tcsetattr(fd, TCSANOW, &(tty_dev->ttysetdef)) < 0) if (tcsetattr(fd, TCSANOW, &(tty_dev->ttysetold)) < 0)
{ {
fprintf(stderr, "[%s] error restoring tty device default config\n", __func__); fprintf(stderr, "[%s] error restoring tty device default config\n", __func__);
return -errno; return -errno;
@ -81,19 +76,11 @@ int tty_close(tty_t *tty_dev)
return 0; return 0;
} }
int tty_reconfigure(tty_t *tty_dev, struct termios newttyset)
{
// not sure how to organize this:
// 1. parameters in external termios struct, copied @tty_dev.ttyset, applied with tcsetattr()
// 2. parameters directly @tty_dev.ttyset, applied with tcsetattr()
return 0;
}
int tty_read(tty_t *tty_dev) int tty_read(tty_t *tty_dev)
{ {
int len; int len;
len = read(tty_dev->fd, tty_dev->data, DATABUF_LEN); len = read(tty_dev->fd, tty_dev->data, BUFFER_LEN);
if (len == -1) if (len == -1)
{ {
fprintf(stderr, "[%s:%d] error %d: %s\n", __func__, __LINE__, fprintf(stderr, "[%s:%d] error %d: %s\n", __func__, __LINE__,

39
tty.h
View file

@ -1,43 +1,48 @@
#pragma once
/* Handles communication with a tty device. */ /* Handles communication with a tty device. */
#pragma once
#include <common.h> #include <common.h>
#include <client.h> #include <client.h>
#include <termios.h> #include <termios.h>
#define DEV_PATH 128 #define TTY_DEV_PATH_LEN 128
typedef struct typedef struct
{ {
int fd; /* tty file descriptor */ int fd; /* tty device file descriptor */
struct termios ttysetdef; /* default tty termios settings */ struct termios ttysetold; /* previous termios settings */
struct termios ttyset; /* tty termios settings */ struct termios ttyset; /* current termios settings */
char path[DEV_PATH]; /* tty device path */ char path[TTY_DEV_PATH_LEN]; /* tty device path */
char data[DATABUF_LEN]; /* buffer for data received from tty */ char data[BUFFER_LEN]; /* buffer for received data */
} tty_t; } tty_t;
/** /**
* Opens the tty device and configures it. * Opens the tty device and configures it.
* The old device settings are saved.
*
* Returns:
* - 0 on success
* - negative errno value if an error occurred
*/ */
int tty_open(tty_t *tty_dev); int tty_open(tty_t *tty_dev);
/** /**
* Closes the tty device. * Closes the tty device connection.
* Also applies the old device settings.
*
* Returns:
* - 0 on success
* - negative errno value if an error occurred
*/ */
int tty_close(tty_t *tty_dev); int tty_close(tty_t *tty_dev);
/**
* Reconfigures the tty device.
*/
int tty_reconfigure(tty_t *tty_dev, struct termios newttyset);
/** /**
* Reads incoming data from tty device to tty data buffer. * Reads incoming data from tty device to tty data buffer.
* *
* Returns: * Returns:
* - number of read bytes on success, * - number of read bytes on success,
* - negative errno value set by an error while readin * - negative errno value set by an error while reading
*/ */
int tty_read(tty_t *tty_dev); int tty_read(tty_t *tty_dev);
@ -51,8 +56,8 @@ int tty_read(tty_t *tty_dev);
int tty_write(tty_t *tty_dev, char *databuf, int datalen); int tty_write(tty_t *tty_dev, char *databuf, int datalen);
/** /**
* Converts POSIX speed_t to a baud rate. The values of the * Converts POSIX speed_t to a baud rate.
* constants for speed_t are not themselves portable. * The values of the constants for speed_t are not themselves portable.
*/ */
int speed_to_baud(speed_t speed); int speed_to_baud(speed_t speed);