2
2
The serial port communication routines for Unix.
4
Copyright (C) 1991, 1992, 1993, 1994, 1995 Ian Lance Taylor
4
Copyright (C) 1991, 1992, 1993, 1994, 1995, 2002 Ian Lance Taylor
6
6
This file is part of the Taylor UUCP package.
18
18
You should have received a copy of the GNU General Public License
19
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22
The author of the program may be contacted at ian@airs.com or
23
c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
22
The author of the program may be contacted at ian@airs.com.
29
const char serial_rcsid[] = "$Id: serial.c,v 1.65 1995/08/10 00:53:54 ian Rel $";
28
const char serial_rcsid[] = "$Id: serial.c,v 1.78 2002/03/05 19:10:42 ian Rel $";
32
31
#include "uudefs.h"
237
240
static boolean fsserial_lockfile P((boolean flok,
238
241
const struct sconnection *));
239
242
static boolean fsserial_lock P((struct sconnection *qconn,
243
boolean fin, boolean fuser));
241
244
static boolean fsserial_unlock P((struct sconnection *qconn));
242
245
static boolean fsserial_open P((struct sconnection *qconn, long ibaud,
243
boolean fwait, enum tclocal_setting tlocal));
246
boolean fwait, boolean fuser,
247
enum tclocal_setting tlocal));
244
248
static boolean fsstdin_open P((struct sconnection *qconn, long ibaud,
249
boolean fwait, boolean fuser));
246
250
static boolean fsmodem_open P((struct sconnection *qconn, long ibaud,
251
boolean fwait, boolean fuser));
248
252
static boolean fsdirect_open P((struct sconnection *qconn, long ibaud,
253
boolean fwait, boolean fuser));
250
254
static boolean fsblock P((struct ssysdep_conn *q, boolean fblock));
251
255
static boolean fsserial_close P((struct ssysdep_conn *q));
252
256
static boolean fsstdin_close P((struct sconnection *qconn,
729
733
open because we can't fail out if it is locked then. */
732
fsserial_lock (qconn, fin)
736
fsserial_lock (qconn, fin, fuser)
733
737
struct sconnection *qconn;
736
741
if (! fsserial_lockfile (TRUE, qconn))
750
757
iflag = iSunblock;
761
if (! fsuser_perms (&ieuid, &iegid))
763
(void) fsserial_lockfile (FALSE, qconn);
752
768
qsysdep->o = open (qsysdep->zdevice, O_RDWR | iflag);
753
769
if (qsysdep->o < 0)
763
779
if (qsysdep->o < 0)
785
(void) fsuucp_perms ((long) ieuid, (long) iegid);
766
787
ulog (LOG_ERROR, "open (%s): %s", qsysdep->zdevice,
789
(void) fsserial_lockfile (FALSE, qconn);
796
if (! fsuucp_perms ((long) ieuid, (long) iegid))
798
(void) close (qsysdep->o);
768
800
(void) fsserial_lockfile (FALSE, qconn);
940
1013
/* Open a serial line. This sets the terminal settings. We begin in
941
1014
seven bit mode and let the protocol change if necessary. If fwait
942
is FALSE we open the terminal in non-blocking mode. If flocal is
943
TRUE we set CLOCAL on the terminal when using termio[s]; this is
944
supposedly required on some versions of BSD/386. */
1015
is FALSE we open the terminal in non-blocking mode. If fuser is
1016
true we open the port using the user's permissions. The tlocal
1017
parameter indicates whether to set, clear, or ignore CLOCAL. */
947
fsserial_open (qconn, ibaud, fwait, tlocal)
1020
fsserial_open (qconn, ibaud, fwait, fuser, tlocal)
948
1021
struct sconnection *qconn;
951
1025
enum tclocal_setting tlocal;
953
1027
struct ssysdep_conn *q;
1111
(void) fsuucp_perms ((long) ieuid, (long) iegid);
1025
1112
ulog (LOG_ERROR, "open (%s): %s", q->zdevice,
1120
if (! fsuucp_perms ((long) ieuid, (long) iegid))
1031
1124
if (fcntl (q->o, F_SETFD, fcntl (q->o, F_GETFD, 0) | FD_CLOEXEC) < 0)
1033
1126
ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
1187
1283
q->ibaud = ibaud;
1192
1288
q->ibaud = (long) 1200;
1193
1289
for (i = 0; i < CBAUD_TABLE; i++)
1195
if (asSbaud_table[i].icode == ib)
1291
if (asSbaud_table[i].icode == ib
1292
&& asSbaud_table[i].ibaud != 0)
1197
1294
q->ibaud = asSbaud_table[i].ibaud;
1211
1308
call to fsblock. */
1214
fsstdin_open (qconn, ibaud, fwait)
1311
fsstdin_open (qconn, ibaud, fwait, fuser)
1215
1312
struct sconnection *qconn;
1219
1317
struct ssysdep_conn *q;
1226
if (! fsserial_open (qconn, ibaud, fwait, IGNORE_CLOCAL))
1324
if (! fsserial_open (qconn, ibaud, fwait, fuser, IGNORE_CLOCAL))
1228
1326
q->iwr_flags = fcntl (q->owr, F_GETFL, 0);
1229
1327
if (q->iwr_flags < 0)
1237
1335
/* Open a modem port. */
1240
fsmodem_open (qconn, ibaud, fwait)
1338
fsmodem_open (qconn, ibaud, fwait, fuser)
1241
1339
struct sconnection *qconn;
1245
1344
struct uuconf_modem_port *qm;
1248
1347
if (ibaud == (long) 0)
1249
1348
ibaud = qm->uuconf_ibaud;
1251
if (! fsserial_open (qconn, ibaud, fwait,
1350
if (! fsserial_open (qconn, ibaud, fwait, fuser,
1252
1351
fwait ? CLEAR_CLOCAL : SET_CLOCAL))
1267
1366
/* Open a direct port. */
1270
fsdirect_open (qconn, ibaud, fwait)
1369
fsdirect_open (qconn, ibaud, fwait, fuser)
1271
1370
struct sconnection *qconn;
1275
1375
struct uuconf_direct_port *qd;
1277
1377
qd = &qconn->qport->uuconf_u.uuconf_sdirect;
1278
1378
if (ibaud == (long) 0)
1279
1379
ibaud = qd->uuconf_ibaud;
1280
if (! fsserial_open (qconn, ibaud, fwait,
1380
if (! fsserial_open (qconn, ibaud, fwait, fuser,
1281
1381
qd->uuconf_fcarrier ? CLEAR_CLOCAL : SET_CLOCAL))
1334
1434
iwant = qs->iwr_flags | iSunblock;
1336
if (fcntl (qs->owr, F_SETFL, iwant) < 0)
1436
isys = fcntl (qs->owr, F_SETFL, iwant);
1338
/* We don't bother to fix up iSunblock here, since we
1340
ulog (LOG_ERROR, "fcntl: %s", strerror (errno));
1440
if (! fblock && iSunblock != O_NONBLOCK && errno == EINVAL)
1442
iSunblock = O_NONBLOCK;
1443
iwant = qs->iwr_flags | O_NONBLOCK;
1444
isys = fcntl (qs->owr, F_SETFL, iwant);
1449
ulog (LOG_ERROR, "fcntl: %s", strerror (errno));
1344
1454
qs->iwr_flags = iwant;
1406
1516
fsstdin_close (qconn, puuconf, qdialer, fsuccess)
1407
1517
struct sconnection *qconn;
1409
struct uuconf_dialer *qdialer;
1518
pointer puuconf ATTRIBUTE_UNUSED;
1519
struct uuconf_dialer *qdialer ATTRIBUTE_UNUSED;
1520
boolean fsuccess ATTRIBUTE_UNUSED;
1412
1522
struct ssysdep_conn *qsysdep;
1574
1684
fsdirect_close (qconn, puuconf, qdialer, fsuccess)
1575
1685
struct sconnection *qconn;
1577
struct uuconf_dialer *qdialer;
1686
pointer puuconf ATTRIBUTE_UNUSED;
1687
struct uuconf_dialer *qdialer ATTRIBUTE_UNUSED;
1688
boolean fsuccess ATTRIBUTE_UNUSED;
1580
1690
return fsserial_close ((struct ssysdep_conn *) qconn->psysdep);
1826
1936
/* Tell the port to use hardware flow control. There is no standard
1827
1937
mechanism for controlling this. This implementation supports
1828
CRTSCTS on SunOS, RTS/CTSFLOW on 386(ish) unix, CTSCD on the 3b1,
1829
CCTS_OFLOW/CRTS_IFLOW on BSDI, TXADDCD/TXDELCD on AIX, and IRTS on
1830
NCR Tower. If you know how to do it on other systems, please
1831
implement it and send me the patches. */
1938
CRTSCTS and CRTSXOFF on SunOS/Solaris, RTS/CTSFLOW on 386(ish)
1939
unix, CTSCD on the 3b1, CCTS_OFLOW/CRTS_IFLOW on BSDI,
1940
TXADDCD/TXDELCD on AIX, IRTS on NCR Tower, and TCGETX/TCSETX on
1941
HP/UX. If you know how to do it on other systems, please implement
1942
it and send me the patches. */
1834
1945
fsserial_hardflow (qconn, fhardflow)
1883
1994
q->snew.c_cflag |= CRTSCTS;
1884
1995
#endif /* defined (CRTSCTS) */
1997
q->snew.c_cflag |= CRTSXOFF;
1998
#endif /* defined (CRTSXOFF) */
1886
2000
q->snew.c_cflag |= CTSCD;
1887
2001
#endif /* defined (CTSCD) */
1898
2012
strerror (errno));
2015
#if HAVE_SYS_TERMIOX
2020
if (ioctl (q->o, TCGETX, &tx) < 0)
2023
"Can't enable hardware flow control: ioctl (TCGETX): %s",
2027
tx.x_hflag |= RTSXOFF | CTSXON;
2028
if (ioctl (q->o, TCSETX, &tx) < 0)
2031
"Can't enable hardware flow control: ioctl (TCSETX): %s",
2037
#endif /* HAVE_SYS_TERMIOX */
1901
2038
#endif /* ! HAVE_TXADDCD */
1916
2053
q->snew.c_cflag &=~ CRTSCTS;
1917
2054
#endif /* defined (CRTSCTS) */
2056
q->snew.c_cflag &=~ CRTSXOFF;
2057
#endif /* defined (CRTSXOFF) */
1919
2059
q->snew.c_cflag &=~ CTSCD;
1920
2060
#endif /* defined (CTSCD) */
1931
2071
strerror (errno));
2074
#if HAVE_SYS_TERMIOX
2079
if (ioctl (q->o, TCGETX, &tx) < 0)
2082
"Can't disable hardware flow control: ioctl (TCGETX): %s",
2086
tx.x_hflag &=~ (RTSXOFF | CTSXON);
2087
if (ioctl (q->o, TCSETX, &tx) < 0)
2090
"Can't disable hardware flow control: ioctl (TCSETX): %s",
2096
#endif /* HAVE_SYS_TERMIOX */
1934
2097
#endif /* ! HAVE_TXADDCD */
1936
2099
#endif /* HAVE_HARDFLOW */
2378
2541
csleepchars = MAX_INPUT - 10;
2382
isleep = (int) (((long) csleepchars * 10000L) / q->ibaud);
2385
isleep = 1000; /* I hope, a second is right... */
2388
2543
isleep = (int) (((long) csleepchars * 10000L) / q->ibaud);
2392
2546
if (isleep > 10)
2779
2933
#if HAVE_SELECT
2780
2934
struct timeval stime;
2784
2942
/* We didn't write any data. Call select. We use a timeout
2785
long enough for 1024 bytes to be sent.
2943
long enough for 1024 bytes to be sent. But we don't wait
2944
longer than the times it takes to receive cread bytes, in
2945
case our read buffer is small.
2786
2946
secs/kbyte == (1024 bytes/kbyte * 10 bits/byte) / baud bits/sec
2787
2947
usecs/kbyte == (((1024 bytes/kbyte * 1000000 usecs/sec)
2788
2948
/ baud bits/sec)
2789
2949
* 10 bits/byte)
2793
stime.tv_sec = (long) 10240 / q->ibaud;
2794
stime.tv_usec = ((((long) 1024000000 / q->ibaud) * (long) 10)
2954
unsigned long cwait;
2959
stime.tv_sec = (cwait * 10) / q->ibaud;
2960
stime.tv_usec = ((((cwait * 1000000) / q->ibaud) * 10)
2965
/* This is some sort of network connection. We can't
2966
estimate how long it will take to write data. It
2967
also doesn't matter as much, as most systems will
2968
buffer much more incoming network data than they will
2969
incoming serial data. Sleep for a second, although
2970
normally the select will return sonner because we can
2978
FD_SET (q->o, &smask);
2801
stime.tv_sec = (long) 10240 / q->ibaud;
2802
stime.tv_usec = ((((long) 1024000000 / q->ibaud) * (long) 10)
2808
2982
ulog (LOG_FATAL, "fsysdep_conn_io: File descriptors too large");
2810
2985
/* If we've received a signal, don't continue. */
2811
2986
if (FGOT_QUIT_SIGNAL ())
2816
2991
/* We don't bother to loop on EINTR. If we get a signal, we
2817
2992
just loop around and try the read and write again. */
2818
c = select (q->o + 1, (pointer) NULL, (pointer) &imask,
2993
c = select (q->o + 1, (pointer) NULL, (pointer) &smask,
2819
2994
(pointer) NULL, &stime);
2820
2995
if (c < 0 && errno == EINTR)
2872
3047
we don't need to use the catch stuff, since we know
2873
3048
that HAVE_RESTARTABLE_SYSCALLS is 0. */
2874
3049
usset_signal (SIGALRM, usalarm, TRUE, (boolean *) NULL);
2877
alarm ((int) ((long) 10240 / q->ibaud) + 1);
3051
alarm ((int) ((long) 10240 / q->ibaud) + 1);
2881
alarm ((int) ((long) 10240 / q->ibaud) + 1);
2884
3055
/* There is a race condition here: on a severely loaded
2885
3056
system, we could get the alarm before we start the