- Fix: avoid infinite loop on mulitcast read thread if no data to read

Pre-ci test passed

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4000 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
Cedric Roux
2013-06-25 09:05:02 +00:00
commit 56c66c09aa
4111 changed files with 2133103 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
File: Readme.txt
Author: Florian Kaltenberger
Date: 11.2.09
This directory contains configuration files and maps for gpsdrive. gpsdrive displays your position and position of others (which are connected to the friends server) on a map. see man gpsdrive and man friendsd2 for details.
Copy the maps directory to your ~/.gpsdrive directory or merge it with the existing directory iff you have already created other maps.
Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

@@ -0,0 +1,29 @@
top_Africa.jpg 1.82500 26.57917 24167707
top_Americas.jpg 4.25000 -91.50000 38529708
top_AsiaMiddleEast.jpg 34.33333 54.87500 17638272
top_AsiaEast.jpg 32.78333 139.37500 24646780
top_Australia.jpg -26.96667 134.12500 10990784
top_BritishIsles.jpg 54.54167 -4.20833 3135892
top_Europe.jpg 52.91667 12.41667 11823932
top_Germany.jpg 51.50833 11.05000 3909032
top_GPSWORLD.jpg 0.00000 0.00000 88067900
top_JapanKorea.jpg 38.45833 135.15833 5379458
top_NewZealand.jpg -40.85000 172.50000 4240306
top_NorthAmerica.jpg 39.96667 -95.52500 20982408
top_SouthAmerica.jpg -21.58333 -63.14583 21456356
top_WorldEast.jpg 12.40000 68.00000 43055416
expedia/map_98750_41.516_2.088.gif 41.51642 2.08774 98750
expedia/map_3950_41.516_2.087.gif 41.51642 2.08732 3950
expedia/map_47400_41.282_1.989.gif 41.28168 1.98933 47400
expedia/map_3950_41.282_1.989.gif 41.28160 1.98929 3950
expedia/map_98750_41.516_2.088.gif 41.51600 2.08802 98750
expedia/map_98750_41.516_2.088.gif 41.51597 2.08801 98750
expedia/map_3950_41.502_2.113.gif 41.50223 2.11301 3950
expedia/map_3950_41.501_2.111.gif 41.50111 2.11116 3950
expedia/map_3950_43.735_7.421.gif 43.73466 7.42114 3950
expedia/map_3950_43.883_7.355.gif 43.88309 7.35546 3950
expedia/map_27650000_43.847_7.448.gif 43.84667 7.44823 27650000
expedia/map_3950_43.912_7.516.gif 43.91186 7.51550 3950
expedia/map_3950_43.923_7.527.gif 43.92305 7.52726 3950
expedia/map_3950_43.735_7.421.gif 43.73466 7.42114 3950
expedia/map_3950_43.735_7.421.gif 43.73466 7.42114 3950
+8
View File
@@ -0,0 +1,8 @@
all: remserial
REMOBJ=remserial.o stty.o
remserial: $(REMOBJ)
$(CC) $(LDFLAGS) -o remserial $(REMOBJ)
clean:
rm -f remserial *.o
+150
View File
@@ -0,0 +1,150 @@
Remserial
---------
The remserial program acts as a communications bridge between a TCP/IP
network port and a Linux device such as a serial port. Any character-oriented
Linux /dev device will work.
The program can also use pseudo-ttys as the device. A pseudo-tty is like
a serial port in that it has a /dev entry that can be opened by a program
that expects a serial port device, except that instead of belonging to
a physical serial device, the data can be intercepted by another program.
The remserial program uses this to connect a network port to the
"master" (programming) side of the pseudo-tty allowing the device driver
(slave) side to be used by some program expecting a serial port. See example
3 below for details.
The program can operate as a server accepting network connections from
other machines, or as a client, connecting to remote machine that
is running the remserial program or some other program that accepts
a raw network connection. The network connection passes data as-is,
there is no control protocol over the network socket.
Multiple copies of the program can run on the same computer at the same
time assuming each is using a different network port and device.
Some examples:
1) Give access to a RS232 device over a network.
The computer with the serial port connected to the device (such as a
data aquisition device) runs the remserial program:
remserial -d -p 23000 -s "9600 raw" /dev/ttyS0 &
This starts the program in daemon mode so that it runs in the background,
it waits for connections on port 23000 and sets up the serial port
/dev/ttyS0 at 9600 baud. Network connections to port 23000 from any
machine can then read and write to the device attached to the serial port.
This can be started from /etc/rc.local or as an entry in /etc/inittab
or set up as a system service with a file in /etc/rc.init/.
2) Connect an RS232 device to a specified server.
The computer with the serial port connected to the device (such as a
data aquisition device) runs the remserial program:
remserial -d -r server-name -p 23000 -s "9600 raw" /dev/ttyS0 &
This would be used with case number 1 above creating an end-to-end serial
port connection. What goes in the serial port on one machine would come
out the serial port of the other machine. The ports could be running at
different baud rates or other serial port settings.
3) Connect a Linux program that needs a serial port to a remote serial port.
Some programs are written to communicate directly with a serial port such
as some data aquisition programs. The remserial program can use
pseudo-ttys to fool the program into thinking that it is talking to a
real serial port on the local machine:
remserial -d -r server-name -p 23000 -l /dev/remserial1 /dev/ptmx &
This creates a file called /dev/remserial1 which can be used by the
data aquisition application as its serial port. Any data sent or received
is passed to the remote server-name on port 23000 where a computer configured
in case number 1 above passes it to a real serial port.
The remserial program uses the special pseudo-tty master device /dev/ptmx
(see man ptmx) which creates a slave device that looks like a normal
serial port named /dev/pts/something. Unfortunately, the actual device
name created isn't consistent, so the remserial program creates a symbol
link from the device name specified with the -l option to the /dev/pts/
name that was created allowing the other application to be configured
with a consistent device name.
4) Server farm console control.
Assuming multiple Linux servers (such as web servers) are set up to have a
serial port as their console instead of a monitor/keyboard, their serial
ports could be connected to a control server using a multi-port serial board.
On the control server, a copy of remserial is run for each server:
remserial -d -p 23000 -s "115200 raw" /dev/ttyS0 &
remserial -d -p 23001 -s "115200 raw" /dev/ttyS1 &
remserial -d -p 23002 -s "115200 raw" /dev/ttyS2 &
remserial -d -p 23003 -s "115200 raw" /dev/ttyS3 &
etc.
From any computer on the local network, use a telnet program to connect
to the control server on the appropriate port:
telnet control-server-name 23002
This would connect through the associated serial port to the desired server's
console. This example would then give the user console access to the 3rd
server.
Careful scripting such as using the Linux "expect" program could allow
batches of commands to be run on each server.
Other Linux program useful with remserial
-----------------------------------------
- nc - The netcat program is similar to remserial except that it creates
connections between network ports and command line standard input and
output.
For example, with case number 1 above, the following command run on
another computer will send the contents of the named file out the
serial port used by the remserial program:
nc server-name 23000 <file-name
Similarily, the following command will store incoming serial data in a file
until the program is manually interrupted:
nc server-name 23000 >file-name
- telnet - The telnet program is normally used to log into a remote computer,
but when used with network ports other than number 23, it operates in a
raw data mode.
For example, with case number 1 above, the following command will allow
the user of the telnet program to see incoming serial port data and
type data on the keyboard to send to the serial port:
telnet server-name 23000
This is ideal for controlling the device connected to the serial port
if it has some sort of command line interface usable over the serial port.
remserial Usage:
---------------
remserial [-r machinename] [-p netport] [-s "stty params"] device
-r machinename The remote machine name to connect to. If not
specified, then this is the server side.
-p netport Specifiy IP port# (default 23000)
-s "stty params" If serial port, specify stty parameters, see man stty
-d Run as daemon programs
-x debuglevel Set debug level, 0 is default, 1,2 give more info
-l linkname If the device is /dev/ptmx, creates a symbolic link
to the corresponding slave pseudo-tty so that another
application has a static device name to use.
-m max-connections Maximum number of simultaneous client connections to allow
device Character oriented device node such as /dev/ttyS0.
+480
View File
@@ -0,0 +1,480 @@
/*
* remserial
* Copyright (C) 2000 Paul Davis, pdavis@lpccomp.bc.ca
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* This program acts as a bridge either between a socket(2) and a
* serial/parallel port or between a socket and a pseudo-tty.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
struct sockaddr_in addr,remoteaddr;
int sockfd = -1;
int server_port = 23000;
int client_port = 22999;
int debug = 0;
int devfd;
int *remotefd;
char *machinename = NULL;
char *sttyparms = NULL;
static char *sdevname = NULL;
char *linkname = NULL;
int isdaemon = 0;
fd_set fdsread,fdsreaduse;
struct hostent *remotehost;
extern char* ptsname(int fd);
int curConnects = 0;
void sighandler (int sig);
int connect_to (struct sockaddr_in *addr);
void usage (char *progname);
void link_slave (int fd);
int main(int argc, char *argv[])
{
int result;
extern char *optarg;
extern int optind;
int maxfd = -1;
char devbuf[512];
int devbytes;
int remoteaddrlen;
int c;
int waitlogged = 0;
int maxConnects = 1;
int writeonly = 0;
register int i;
while ( (c=getopt(argc,argv,"dl:m:p:r:s:wx:")) != EOF )
switch (c) {
case 'd':
isdaemon = 1;
break;
case 'l':
linkname = optarg;
break;
case 'x':
debug = atoi(optarg);
break;
case 'm':
maxConnects = atoi(optarg);
break;
case 'p':
server_port = atoi(optarg);
break;
case 'r':
machinename = optarg;
break;
case 's':
sttyparms = optarg;
break;
case 'w':
writeonly = 1;
break;
case '?':
usage(argv[0]);
exit(1);
}
sdevname = argv[optind];
remotefd = (int *) malloc (maxConnects * sizeof(int));
// struct group *getgrgid(gid_t gid);
printf("sdevname=%s,server_port=%d,stty=%s\n",sdevname,server_port,sttyparms);
openlog("remserial", LOG_PID, LOG_USER);
if (writeonly)
devfd = open(sdevname,O_WRONLY);
else
devfd = open(sdevname,O_RDWR);
if ( devfd == -1 ) {
syslog(LOG_ERR, "Open of %s failed: %m",sdevname);
printf("Open of %s failed: %m",sdevname);
exit(1);
}
if (linkname)
link_slave(devfd);
if ( sttyparms ) {
set_tty(devfd,sttyparms);
}
signal(SIGINT,sighandler);
signal(SIGHUP,sighandler);
signal(SIGTERM,sighandler);
if ( machinename ) {
//-----------------------------------------------------------------
// We are the client, Find the IP address for the remote machine
//-----------------------------------------------------------------
remotehost = gethostbyname(machinename);
if ( !remotehost ) {
syslog(LOG_ERR, "Couldn't determine address of %s", machinename );
exit(1);
}
/* Copy it into the addr structure */
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = 0;
//memcpy(&(addr.sin_addr),remotehost->h_addr_list[0], sizeof(struct in_addr));
//addr.sin_port = htons(server_port);
addr.sin_port = htons(0);
remotefd[curConnects] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if ( remotefd[curConnects] == -1 ) {
syslog(LOG_ERR, "Can't open socket: %m");
exit(1);
}
/* Set up to listen on the given port */
if( bind( remotefd[curConnects], (struct sockaddr*)(&addr), sizeof(struct sockaddr_in)) < 0 ) {
syslog(LOG_ERR, "Couldn't bind port %d, aborting: %m",client_port );
exit(1);
}
addr.sin_family = AF_INET;
memcpy(&(addr.sin_addr),remotehost->h_addr_list[0], sizeof(struct in_addr));
addr.sin_port = htons(server_port);
if (connect(remotefd[curConnects], (struct sockaddr*)(&addr), sizeof(struct sockaddr_in)) < 0 ) {
syslog(LOG_ERR, "Couldn't connect client socket to server socket, aborting: %m");
exit(1);
}
if ( debug>1 )
syslog(LOG_NOTICE,"Connected to remote UDP socket");
curConnects += 1;
} else {
//-------------------------------
// We are the server
//-------------------------------
/* Open the initial socket for communications */
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if ( sockfd == -1 ) {
syslog(LOG_ERR, "Can't open socket: %m");
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = 0;
addr.sin_port = htons(server_port);
/* Set up to listen on the given port */
if( bind( sockfd, (struct sockaddr*)(&addr),
sizeof(struct sockaddr_in)) < 0 ) {
syslog(LOG_ERR, "Couldn't bind port %d, aborting: %m",server_port );
exit(1);
}
if ( debug>1 )
syslog(LOG_NOTICE,"Bound port");
}
if ( isdaemon ) {
setsid();
close(0);
close(1);
close(2);
}
/* Set up the files/sockets for the select() call */
if ( sockfd != -1 ) {
FD_SET(sockfd,&fdsread);
if ( sockfd >= maxfd )
maxfd = sockfd + 1;
}
for (i=0 ; i<curConnects ; i++) {
FD_SET(remotefd[i],&fdsread);
if ( remotefd[i] >= maxfd )
maxfd = remotefd[i] + 1;
}
if (!writeonly) {
FD_SET(devfd,&fdsread);
if ( devfd >= maxfd )
maxfd = devfd + 1;
}
while (1) {
/* Wait for data from the listening socket, the device
or the remote connection */
fdsreaduse = fdsread;
if ( select(maxfd,&fdsreaduse,NULL,NULL,NULL) == -1 )
break;
/* Activity on the controlling socket, only on server */
if ( !machinename && FD_ISSET(sockfd,&fdsreaduse) ) {
remoteaddrlen = sizeof(struct sockaddr_in);
devbytes = recvfrom(sockfd, devbuf, 512, 0, (struct sockaddr *) &remoteaddr, &remoteaddrlen);
//if ( debug>1 && devbytes>0 )
if (debug>1) {
syslog(LOG_INFO,"Remote: %d bytes",devbytes);
}
printf("Socket Remote read: %d bytes\n",devbytes);
if ( devbytes == 0 ) {
} else if ( devfd != -1 ) {
if (connect(sockfd, (struct sockaddr*)(&remoteaddr), remoteaddrlen) < 0 ) {
syslog(LOG_ERR, "Couldn't connect server socket to client socket, aborting: %m");
exit(1);
}
// socket read/write
//remotefd[curConnects] = sockfd;
/* Write the data to the device */
result = write(devfd,devbuf,devbytes);
if (result < 0) {
printf("write(%d,devbuf,%d):%s", devfd, devbytes,strerror(result));
} else {
printf("Write to device returned %d", result);
}
fflush(NULL);
}
}
/* Data to read from the device */
if ( FD_ISSET(devfd,&fdsreaduse) ) {
devbytes = read(devfd,devbuf,512);
//if ( debug>1 && devbytes>0 )
if (debug>1) {
syslog(LOG_INFO,"Device: %d bytes",devbytes);
}
printf("Device: %d bytes", devbytes);
if ( devbytes <= 0 ) {
if ( debug>0 ) {
syslog(LOG_INFO,"%s closed",sdevname);
printf("%s closed",sdevname);
}
close(devfd);
FD_CLR(devfd,&fdsread);
while (1) {
devfd = open(sdevname,O_RDWR);
if ( devfd != -1 )
break;
syslog(LOG_ERR, "Open of %s failed: %m", sdevname);
if ( errno != EIO )
exit(1);
sleep(1);
}
if ( debug>0 )
syslog(LOG_INFO,"%s re-opened",sdevname);
if ( sttyparms )
set_tty(devfd,sttyparms);
if (linkname)
link_slave(devfd);
FD_SET(devfd,&fdsread);
if ( devfd >= maxfd )
maxfd = devfd + 1;
} else {
for (i=0 ; i<curConnects ; i++) {
result = write(remotefd[i],devbuf,devbytes);
if (result < 0) {
printf("write(remotefd[%d]=%d,devbuf,%d):%s", i, remotefd[i], devbytes, strerror(result));
} else {
printf("Write to remotefd[%d]=%d returned %d", i, remotefd[i], result);
}
fflush(NULL);
}
if ( !machinename) {
result = write(sockfd, devbuf,devbytes);
if (result < 0) {
printf("write(sockfd=%d,devbuf,%d):%s", sockfd, devbytes, strerror(result));
} else {
printf("Write to sockfd=%d returned %d", sockfd, result);
}
fflush(NULL);
}
}
}
/* Data to read from the remote system */
for (i=0 ; i<curConnects ; i++)
if (FD_ISSET(remotefd[i],&fdsreaduse) ) {
devbytes = read(remotefd[i],devbuf,512);
//if ( debug>1 && devbytes>0 )
if (debug>1) {
syslog(LOG_INFO,"Remote: %d bytes",devbytes);
}
printf("Remote: %d bytes",devbytes);
if ( devbytes == 0 ) {
/*register int j;
syslog(LOG_NOTICE,"Connection closed");
printf("Connection closed");
close(remotefd[i]);
FD_CLR(remotefd[i],&fdsread);
curConnects--;
for (j=i ; j<curConnects ; j++)
remotefd[j] = remotefd[j+1];
if ( machinename ) {
// Wait for the server again
remotefd[curConnects++] = connect_to(&addr);
FD_SET(remotefd[curConnects-1],&fdsread);
if ( remotefd[curConnects-1] >= maxfd )
maxfd = remotefd[curConnects-1] + 1;
}*/
}
else if ( devfd != -1 ) {
/* Write the data to the device */
result = write(devfd,devbuf,devbytes);
if (result < 0) {
printf("write(devfd=%d,devbuf,%d):%s", devfd, devbytes, strerror(result));
} else {
printf("Write to devfd=%d returned %d", devfd, result);
}
fflush(NULL);
}
}
}
close(sockfd);
for (i=0 ; i<curConnects ; i++)
close(remotefd[i]);
printf("End of program, normal exit\n");
}
void sighandler(int sig)
{
int i;
if ( sockfd != -1 )
close(sockfd);
for (i=0 ; i<curConnects ; i++)
close(remotefd[i]);
if ( devfd != -1 )
close(devfd);
if (linkname)
unlink(linkname);
syslog(LOG_ERR,"Terminating on signal %d",sig);
exit(0);
}
void link_slave(int fd)
{
char *slavename;
int status = grantpt(devfd);
if (status != -1)
status = unlockpt(devfd);
if (status != -1) {
slavename = ptsname(devfd);
if (slavename) {
// Safety first
unlink(linkname);
status = symlink(slavename, linkname);
}
else
status = -1;
}
if (status == -1) {
syslog(LOG_ERR, "Cannot create link for pseudo-tty: %m");
printf("Cannot create link for pseudo-tty: %m");
exit(1);
}
}
int
connect_to(struct sockaddr_in *addr)
{
int waitlogged = 0;
int stat;
extern int errno;
int sockfd;
if ( debug>0 ) {
unsigned long ip = ntohl(addr->sin_addr.s_addr);
syslog(LOG_NOTICE, "Trying to connect to %d.%d.%d.%d",
(int)(ip>>24)&0xff,
(int)(ip>>16)&0xff,
(int)(ip>>8)&0xff,
(int)(ip>>0)&0xff);
}
while (1) {
/* Open the socket for communications */
sockfd = socket(AF_INET, SOCK_STREAM, 6);
if ( sockfd == -1 ) {
syslog(LOG_ERR, "Can't open socket: %m");
exit(1);
}
/* Try to connect to the remote server,
if it fails, keep trying */
stat = connect(sockfd, (struct sockaddr*)addr,
sizeof(struct sockaddr_in));
if ( debug>1 )
if (stat == -1)
syslog(LOG_NOTICE, "Connect status %d, errno %d: %m\n", stat,errno);
else
syslog(LOG_NOTICE, "Connect status %d\n", stat);
if ( stat == 0 )
break;
/* Write a message to syslog once */
if ( ! waitlogged ) {
syslog(LOG_NOTICE, "Waiting for server on %s port %d: %m", machinename,server_port );
waitlogged = 1;
}
close(sockfd);
sleep(10);
}
if ( waitlogged || debug>0 )
syslog(LOG_NOTICE, "Connected to server %s port %d", machinename,server_port );
return sockfd;
}
void usage(char *progname) {
printf("Remserial version 1.3. Usage:\n");
printf("remserial [-r machinename] [-p netport] [-s \"stty params\"] [-m maxconnect] device\n\n");
printf("-r machinename The remote machine name to connect to. If not\n");
printf(" specified, then this is the server side.\n");
printf("-p netport Specifiy IP port# (default 23000)\n");
printf("-s \"stty params\" If serial port, specify stty parameters, see man stty\n");
printf("-m max-connections Maximum number of simultaneous client connections to allow\n");
printf("-d Run as a daemon program\n");
printf("-x debuglevel Set debug level, 0 is default, 1,2 give more info\n");
printf("-l linkname If the device name is a pseudo-tty, create a link to the slave\n");
printf("-w Only write to the device, no reading\n");
printf("device I/O device, either serial port or pseudo-tty master\n");
}
+249
View File
@@ -0,0 +1,249 @@
/*
* remserial
* Copyright (C) 2000 Paul Davis, pdavis@lpccomp.bc.ca
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#define CFLG 0
#define IFLG 1
#define OFLG 2
#define LFLG 3
#define RFLG 4
#define BFLG 5
extern int errno;
static struct sttyset {
char *name;
int which;
int mask;
int value;
} sttynames[] = {
{ "0", BFLG, 0, B0 },
{ "50", BFLG, 0, B50 },
{ "75", BFLG, 0, B75 },
{ "110", BFLG, 0, B110 },
{ "134", BFLG, 0, B134 },
{ "150", BFLG, 0, B150 },
{ "200", BFLG, 0, B200 },
{ "300", BFLG, 0, B300 },
{ "600", BFLG, 0, B600 },
{ "1200", BFLG, 0, B1200 },
{ "1800", BFLG, 0, B1800 },
{ "2400", BFLG, 0, B2400 },
{ "4800", BFLG, 0, B4800 },
{ "9600", BFLG, 0, B9600 },
{ "19200", BFLG, 0, B19200 },
{ "38400", BFLG, 0, B38400 },
#ifdef B57600
{ "57600", BFLG, 0, B57600 },
#endif
#ifdef B115200
{ "115200", BFLG, 0, B115200 },
#endif
#ifdef B230400
{ "230400", BFLG, 0, B230400 },
#endif
{ "cs7", CFLG, CSIZE, CS7 },
{ "cs8", CFLG, CSIZE, CS8 },
{ "cstopb", CFLG, CSTOPB, CSTOPB },
{ "cread", CFLG, CREAD, CREAD },
{ "parenb", CFLG, PARENB, PARENB },
{ "parodd", CFLG, PARODD, PARODD },
{ "hubcl", CFLG, HUPCL, HUPCL },
{ "clocal", CFLG, CLOCAL, CLOCAL },
#ifdef CRTSCTS
{ "crtscts", CFLG, CRTSCTS, CRTSCTS },
#endif
#ifdef ORTSFL
{ "ortsfl", CFLG, ORTSFL, ORTSFL },
#endif
#ifdef CTSFLOW
{ "ctsflow", CFLG, CTSFLOW, CTSFLOW },
#endif
#ifdef RTSFLOW
{ "rtsflow", CFLG, RTSFLOW, RTSFLOW },
#endif
{ "ignbrk", IFLG, IGNBRK, IGNBRK },
{ "brkint", IFLG, BRKINT, BRKINT },
{ "ignpar", IFLG, IGNPAR, IGNPAR },
{ "parmrk", IFLG, PARMRK, PARMRK },
{ "inpck", IFLG, INPCK, INPCK },
{ "istrip", IFLG, ISTRIP, ISTRIP },
{ "inlcr", IFLG, INLCR, INLCR },
{ "igncr", IFLG, IGNCR, IGNCR },
{ "icrnl", IFLG, ICRNL, ICRNL },
#ifdef IUCLC // Missing on OSX, FreeBSD
{ "iuclc", IFLG, IUCLC, IUCLC },
#endif
{ "ixon", IFLG, IXON, IXON },
{ "ixany", IFLG, IXANY, IXANY },
{ "ixoff", IFLG, IXOFF, IXOFF },
#ifdef IMAXBEL
{ "imaxbel", IFLG, IMAXBEL, IMAXBEL },
#endif
{ "opost", OFLG, OPOST, OPOST },
#ifdef ILCUC // Missing on OSX, FreeBSD
{ "olcuc", OFLG, OLCUC, OLCUC },
#endif
{ "onlcr", OFLG, ONLCR, ONLCR },
{ "ocrnl", OFLG, OCRNL, OCRNL },
{ "onocr", OFLG, ONOCR, ONOCR },
{ "onlret", OFLG, ONLRET, ONLRET },
{ "ofil", OFLG, OFILL, OFILL },
{ "ofdel", OFLG, OFDEL, OFDEL },
{ "nl0", OFLG, NLDLY, NL0 },
{ "nl1", OFLG, NLDLY, NL1 },
{ "cr0", OFLG, CRDLY, CR0 },
{ "cr1", OFLG, CRDLY, CR1 },
{ "cr2", OFLG, CRDLY, CR2 },
{ "cr3", OFLG, CRDLY, CR3 },
{ "tab0", OFLG, TABDLY, TAB0 },
{ "tab1", OFLG, TABDLY, TAB1 },
{ "tab2", OFLG, TABDLY, TAB2 },
{ "tab3", OFLG, TABDLY, TAB3 },
{ "bs0", OFLG, BSDLY, BS0 },
{ "bs1", OFLG, BSDLY, BS1 },
{ "vt0", OFLG, VTDLY, VT0 },
{ "vt1", OFLG, VTDLY, VT1 },
{ "ff0", OFLG, FFDLY, FF0 },
{ "ff1", OFLG, FFDLY, FF1 },
{ "isig", LFLG, ISIG, ISIG },
{ "icanon", LFLG, ICANON, ICANON },
#ifdef XCASE // Missing on OSX, FreeBSD
{ "xcase", LFLG, XCASE, XCASE },
#endif
{ "echo", LFLG, ECHO, ECHO },
{ "echoe", LFLG, ECHOE, ECHOE },
{ "echok", LFLG, ECHOK, ECHOK },
{ "echonl", LFLG, ECHONL, ECHONL },
{ "noflsh", LFLG, NOFLSH, NOFLSH },
{ "tostop", LFLG, TOSTOP, TOSTOP },
#ifdef ECHOCTL
{ "echoctl", LFLG, ECHOCTL, ECHOCTL },
#endif
#ifdef ECHOPRT
{ "echoprt", LFLG, ECHOPRT, ECHOPRT },
#endif
#ifdef ECHOKE
{ "echoke", LFLG, ECHOKE, ECHOKE },
#endif
#ifdef FLUSHO
{ "flusho", LFLG, FLUSHO, FLUSHO },
#endif
#ifdef PENDIN
{ "pendin", LFLG, PENDIN, PENDIN },
#endif
{ "iexten", LFLG, IEXTEN, IEXTEN },
#ifdef TOSTOP
{ "tostop", LFLG, TOSTOP, TOSTOP },
#endif
{ "raw", RFLG, 0, 0 },
{ NULL, 0, 0, 0 } };
static void
set_this_tty(struct termios *term,struct sttyset *p,int turnon)
{
/*
pdebug(5,"set_this_tty: setting %s on? %d\n",p->name,turnon);
*/
switch ( p->which ) {
case CFLG:
term->c_cflag &= ~(p->mask);
if ( turnon )
term->c_cflag |= p->value;
break;
case IFLG:
term->c_iflag &= ~(p->mask);
if ( turnon )
term->c_iflag |= p->value;
break;
case OFLG:
term->c_oflag &= ~(p->mask);
if ( turnon )
term->c_oflag |= p->value;
break;
case LFLG:
term->c_lflag &= ~(p->mask);
if ( turnon )
term->c_lflag |= p->value;
break;
case RFLG:
term->c_iflag = 0;
term->c_oflag = 0;
term->c_lflag = 0;
term->c_cc[VMIN] = 1;
term->c_cc[VTIME] = 0;
break;
case BFLG:
cfsetispeed(term, p->value);
cfsetospeed(term, p->value);
break;
}
}
int
set_tty(int fd,char *settings)
{
register char *p;
register char *s;
struct termios term;
register int i;
int mode;
/*
pdebug(4,"set_tty: fd %d settings %s\n",fd,settings);
*/
if ( tcgetattr(fd,&term) == -1 ) {
/*
pdebug(4,"set_tty: cannot get settings for fd %d, error %d\n",
fd,errno);
*/
return -1;
}
s = strdup(settings);
p = strtok(s," \t\n");
while (p) {
mode = 1;
if ( *p == '-' ) {
mode = 0;
p++;
}
for ( i=0 ; sttynames[i].name ; i++ ) {
if ( !strcmp(p,sttynames[i].name) ) {
set_this_tty(&term,&sttynames[i],mode);
break;
}
}
p = strtok(NULL," \t\n");
}
free(s);
if ( tcsetattr(fd,TCSANOW,&term) == -1 ) {
/*
pdebug(4,"set_tty: cannot get settings for fd %d error %d\n",
fd,errno);
*/
return -1;
}
else
return 0;
}