ia64/xen-unstable

view tools/misc/miniterm/miniterm.c @ 7537:26fc51079f5f

Remove a non-portable and unused error.h, and use signal.h not
sys/signal.h (in tools/misc).
author kaf24@firebug.cl.cam.ac.uk
date Thu Oct 27 17:16:48 2005 +0100 (2005-10-27)
parents cfee4c4a8ed6
children ab85c20d33e5
line source
1 /******************************************************************************
2 * miniterm.c
3 *
4 * Adapted from the example program distributed with the Linux Programmer's
5 * Guide (LPG). This has been robustified and tweaked to work as a debugging
6 * terminal for Xen-based machines.
7 *
8 * Modifications are released under GPL and copyright (c) 2003, K A Fraser
9 * The original copyright message and license is fully intact below.
10 */
12 /*
13 * AUTHOR: Sven Goldt (goldt@math.tu-berlin.de)
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 */
27 #include <termios.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <signal.h>
33 #include <sys/types.h>
34 #include <sys/wait.h>
36 #define DEFAULT_BAUDRATE 115200
37 #define DEFAULT_SERDEVICE "/dev/ttyS0"
38 #define ENDMINITERM 2 /* ctrl-b to quit miniterm */
40 volatile int stop = 0;
42 void child_handler(int s)
43 {
44 stop = 1;
45 }
47 int cook_baud(int baud)
48 {
49 int cooked_baud = 0;
50 switch ( baud )
51 {
52 case 50: cooked_baud = B50; break;
53 case 75: cooked_baud = B75; break;
54 case 110: cooked_baud = B110; break;
55 case 134: cooked_baud = B134; break;
56 case 150: cooked_baud = B150; break;
57 case 200: cooked_baud = B200; break;
58 case 300: cooked_baud = B300; break;
59 case 600: cooked_baud = B600; break;
60 case 1200: cooked_baud = B1200; break;
61 case 1800: cooked_baud = B1800; break;
62 case 2400: cooked_baud = B2400; break;
63 case 4800: cooked_baud = B4800; break;
64 case 9600: cooked_baud = B9600; break;
65 case 19200: cooked_baud = B19200; break;
66 case 38400: cooked_baud = B38400; break;
67 case 57600: cooked_baud = B57600; break;
68 case 115200: cooked_baud = B115200; break;
69 }
70 return cooked_baud;
71 }
73 int main(int argc, char **argv)
74 {
75 int fd, c, cooked_baud = cook_baud(DEFAULT_BAUDRATE);
76 char *sername = DEFAULT_SERDEVICE;
77 struct termios oldsertio, newsertio, oldstdtio, newstdtio;
78 struct sigaction sa;
80 while ( --argc != 0 )
81 {
82 char *p = argv[argc];
83 if ( *p++ != '-' )
84 goto usage;
85 if ( *p == 'b' )
86 {
87 p++;
88 if ( (cooked_baud = cook_baud(atoi(p))) == 0 )
89 {
90 fprintf(stderr, "Bad baud rate '%d'\n", atoi(p));
91 goto usage;
92 }
93 }
94 else if ( *p == 'd' )
95 {
96 sername = ++p;
97 if ( *sername == '\0' )
98 goto usage;
99 }
100 else
101 goto usage;
102 }
104 /* Not a controlling tty: CTRL-C shouldn't kill us. */
105 fd = open(sername, O_RDWR | O_NOCTTY);
106 if ( fd < 0 )
107 {
108 perror(sername);
109 exit(-1);
110 }
112 tcgetattr(fd, &oldsertio); /* save current modem settings */
114 /*
115 * 8 data, no parity, 1 stop bit. Ignore modem control lines. Enable
116 * receive. Set appropriate baud rate. NO HARDWARE FLOW CONTROL!
117 */
118 newsertio.c_cflag = cooked_baud | CS8 | CLOCAL | CREAD;
120 /* Raw input. Ignore errors and breaks. */
121 newsertio.c_iflag = IGNBRK | IGNPAR;
123 /* Raw output. */
124 newsertio.c_oflag = 0;
126 /* No echo and no signals. */
127 newsertio.c_lflag = 0;
129 /* blocking read until 1 char arrives */
130 newsertio.c_cc[VMIN]=1;
131 newsertio.c_cc[VTIME]=0;
133 /* now clean the modem line and activate the settings for modem */
134 tcflush(fd, TCIFLUSH);
135 tcsetattr(fd,TCSANOW,&newsertio);
137 /* next stop echo and buffering for stdin */
138 tcgetattr(0,&oldstdtio);
139 tcgetattr(0,&newstdtio); /* get working stdtio */
140 newstdtio.c_lflag &= ~(ICANON | ECHO);
141 tcsetattr(0,TCSANOW,&newstdtio);
143 /* Terminal settings done: now enter the main I/O loops. */
144 switch ( fork() )
145 {
146 case 0:
147 close(1); /* stdout not needed */
148 for ( c = getchar(); c != ENDMINITERM ; c = getchar() )
149 write(fd,&c,1);
150 tcsetattr(fd,TCSANOW,&oldsertio);
151 tcsetattr(0,TCSANOW,&oldstdtio);
152 close(fd);
153 exit(0); /* will send a SIGCHLD to the parent */
154 break;
155 case -1:
156 perror("fork");
157 tcsetattr(fd,TCSANOW,&oldsertio);
158 close(fd);
159 exit(-1);
160 default:
161 printf("** ctrl-b quits miniterm **\n");
162 close(0); /* stdin not needed */
163 sa.sa_handler = child_handler;
164 sa.sa_flags = 0;
165 sigaction(SIGCHLD,&sa,NULL); /* handle dying child */
166 while ( !stop )
167 {
168 read(fd,&c,1); /* modem */
169 write(1,&c,1); /* stdout */
170 }
171 wait(NULL); /* wait for child to die or it will become a zombie */
172 break;
173 }
175 return 0;
177 usage:
178 printf("miniterm [-b<baudrate>] [-d<devicename>]\n");
179 printf("Default baud rate: %d\n", DEFAULT_BAUDRATE);
180 printf("Default device: %s\n", DEFAULT_SERDEVICE);
181 return 1;
182 }