4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * This is a new line.c, which consists of line.c and culine.c
37 static struct sg_spds
{
86 GLOBAL
int linebaudrate
; /* for speedup hook in pk1.c */
87 #endif /* PKSPEEDUP */
88 static int Saved_line
; /* was savline() successful? */
89 static int Saved_termios
; /* was termios saved? */
91 Oddflag
= 0, /* Default is no parity */
92 Evenflag
= 0, /* Default is no parity */
93 Duplex
= 1, /* Default is full duplex */
94 Terminal
= 0, /* Default is no terminal */
95 term_8bit
= -1, /* Default to terminal setting or 8 bit */
96 line_8bit
= -1; /* Default is same as terminal */
98 static char *P_PARITY
= "Parity option error\r\n";
102 static struct termio Savettyb
;
103 static struct termios Savettybs
;
105 * set speed/echo/mode...
106 * tty -> terminal name
110 * if spwant == 0, speed is untouched
111 * type is unused, but needed for compatibility
118 fixline(tty
, spwant
, type
)
119 int tty
, spwant
, type
;
121 register struct sg_spds
*ps
;
123 struct termios ttbufs
;
125 int i
, istermios
, ospeed
;
127 DEBUG(6, "fixline(%d, ", tty
);
128 DEBUG(6, "%d)\n", spwant
);
129 if ((istermios
= (*Ioctl
)(tty
, TCGETS
, &ttbufs
)) < 0) {
130 if ((*Ioctl
)(tty
, TCGETA
, &ttbuf
) != 0) {
133 ttbufs
.c_lflag
= ttbuf
.c_lflag
;
134 ttbufs
.c_oflag
= ttbuf
.c_oflag
;
135 ttbufs
.c_iflag
= ttbuf
.c_iflag
;
136 ttbufs
.c_cflag
= ttbuf
.c_cflag
;
137 for (i
= 0; i
< NCC
; i
++)
138 ttbufs
.c_cc
[i
] = ttbuf
.c_cc
[i
];
142 for (ps
= spds
; ps
->sp_val
; ps
++)
143 if (ps
->sp_val
== spwant
) {
148 DEBUG(5, "speed (%d) not supported\n", spwant
);
149 ASSERT(speed
>= 0, "BAD SPEED", "", spwant
);
150 ttbufs
.c_cflag
&= 0xffff0000;
151 cfsetospeed(&ttbufs
, speed
);
152 } else { /* determine the current speed setting */
153 ospeed
= cfgetospeed(&ttbufs
);
154 ttbufs
.c_cflag
&= 0xffff0000;
155 cfsetospeed(&ttbufs
, ospeed
);
156 for (ps
= spds
; ps
->sp_val
; ps
++)
157 if (ps
->sp_name
== ospeed
) {
163 * In order to prevent attempts at split speed, all baud rate
164 * bitfields should be cleared. Thus cfsetispeed is used to
165 * set the speed to zero.
167 (void) cfsetispeed(&ttbufs
, 0);
168 ttbufs
.c_iflag
&= 0xffff0000;
169 ttbufs
.c_oflag
&= 0xffff0000;
170 ttbufs
.c_lflag
&= 0xffff0000;
172 linebaudrate
= spwant
;
173 #endif /* PKSPEEDUP */
176 /* CLOCAL may cause problems on pdp11s with DHs */
177 if (type
== D_DIRECT
) {
178 DEBUG(4, "fixline - direct\n%s", "");
179 ttbufs
.c_cflag
|= CLOCAL
;
181 #endif /* NO_MODEM_CTRL */
182 ttbufs
.c_cflag
&= ~CLOCAL
;
184 if (!EQUALS(Progname
, "uucico")) {
186 /* set attributes associated with -h, -t, -e, and -o options */
188 ttbufs
.c_iflag
= (IGNPAR
| IGNBRK
| IXON
| IXOFF
);
189 ttbufs
.c_cc
[VEOF
] = '\1';
190 ttbufs
.c_cflag
|= (CREAD
| (speed
? HUPCL
: 0));
193 ttbufs
.c_cflag
|= CS8
;
194 ttbufs
.c_iflag
&= ~ISTRIP
;
196 if (Evenflag
) { /* even parity -e */
197 ttbufs
.c_cflag
&= ~PARODD
;
198 } else if (Oddflag
) { /* odd parity -o */
199 ttbufs
.c_cflag
|= PARODD
;
201 ttbufs
.c_cflag
|= CS7
|PARENB
;
202 ttbufs
.c_iflag
|= ISTRIP
;
205 if (!Duplex
) /* half duplex -h */
206 ttbufs
.c_iflag
&= ~(IXON
| IXOFF
);
207 if (Terminal
) /* -t */
208 ttbufs
.c_oflag
|= (OPOST
| ONLCR
);
210 } else { /* non-uucico */
211 ttbufs
.c_cflag
|= (CS8
| CREAD
| (speed
? HUPCL
: 0));
212 ttbufs
.c_cc
[VMIN
] = HEADERSIZE
;
213 ttbufs
.c_cc
[VTIME
] = 1;
217 ttbuf
.c_lflag
= ttbufs
.c_lflag
;
218 ttbuf
.c_oflag
= ttbufs
.c_oflag
;
219 ttbuf
.c_iflag
= ttbufs
.c_iflag
;
220 ttbuf
.c_cflag
= ttbufs
.c_cflag
;
221 for (i
= 0; i
< NCC
; i
++)
222 ttbuf
.c_cc
[i
] = ttbufs
.c_cc
[i
];
223 ASSERT((*Ioctl
)(tty
, TCSETAW
, &ttbuf
) >= 0,
224 "RETURN FROM fixline ioctl", "", errno
);
226 ASSERT((*Ioctl
)(tty
, TCSETSW
, &ttbufs
) >= 0,
227 "RETURN FROM fixline ioctl", "", errno
);
237 if ((*Ioctl
)(dcf
, TCGETA
, &ttbuf
) != 0)
239 if (!(ttbuf
.c_cflag
& HUPCL
)) {
240 ttbuf
.c_cflag
|= HUPCL
;
241 (void) (*Ioctl
)(dcf
, TCSETAW
, &ttbuf
);
250 (void) (*Ioctl
)(fn
, TCSBRK
, 0);
255 * optimize line setting for sending or receiving files
263 static struct termio tbuf
;
264 static struct termios tbufs
;
265 int i
, vtime
, istermios
, ospeed
;
267 DEBUG(2, "setline - %c\n", type
);
269 if ((istermios
= (*Ioctl
)(Ifn
, TCGETS
, &tbufs
)) < 0) {
270 if ((*Ioctl
)(Ifn
, TCGETA
, &tbuf
) != 0) {
273 tbufs
.c_lflag
= tbuf
.c_lflag
;
274 tbufs
.c_oflag
= tbuf
.c_oflag
;
275 tbufs
.c_iflag
= tbuf
.c_iflag
;
276 tbufs
.c_cflag
= tbuf
.c_cflag
;
277 for (i
= 0; i
< NCC
; i
++)
278 tbufs
.c_cc
[i
] = tbuf
.c_cc
[i
];
283 ospeed
= cfgetospeed(&tbufs
);
313 if (tbufs
.c_cc
[VMIN
] != packsize
||
314 tbufs
.c_cc
[VTIME
] != vtime
) {
315 tbufs
.c_cc
[VMIN
] = packsize
;
316 tbufs
.c_cc
[VTIME
] = vtime
;
318 tbuf
.c_lflag
= tbufs
.c_lflag
;
319 tbuf
.c_oflag
= tbufs
.c_oflag
;
320 tbuf
.c_iflag
= tbufs
.c_iflag
;
321 tbuf
.c_cflag
= tbufs
.c_cflag
;
322 for (i
= 0; i
< NCC
; i
++)
323 tbuf
.c_cc
[i
] = tbufs
.c_cc
[i
];
324 if ((*Ioctl
)(Ifn
, TCSETAW
, &tbuf
) != 0)
325 DEBUG(4, "setline Ioctl failed errno=%d\n",
328 if ((*Ioctl
)(Ifn
, TCSETSW
, &tbufs
) != 0)
330 "setline Ioctl failed errno=%d\n",
338 if (tbufs
.c_cc
[VMIN
] != HEADERSIZE
) {
339 tbufs
.c_cc
[VMIN
] = HEADERSIZE
;
341 tbuf
.c_lflag
= tbufs
.c_lflag
;
342 tbuf
.c_oflag
= tbufs
.c_oflag
;
343 tbuf
.c_iflag
= tbufs
.c_iflag
;
344 tbuf
.c_cflag
= tbufs
.c_cflag
;
345 for (i
= 0; i
< NCC
; i
++)
346 tbuf
.c_cc
[i
] = tbufs
.c_cc
[i
];
347 if ((*Ioctl
)(Ifn
, TCSETAW
, &tbuf
) != 0)
349 "setline Ioctl failed errno=%d\n",
352 if ((*Ioctl
)(Ifn
, TCSETSW
, &tbufs
) != 0)
354 "setline Ioctl failed errno=%d\n",
365 if ((Saved_termios
= (*Ioctl
)(0, TCGETS
, &Savettybs
)) < 0) {
366 if ((*Ioctl
)(0, TCGETA
, &Savettyb
) != 0) {
371 (Savettyb
.c_cflag
& ~CS8
) | CS7
| PARENB
;
372 Savettyb
.c_oflag
|= OPOST
;
373 Savettyb
.c_lflag
|= (ISIG
|ICANON
|ECHO
);
377 Savettybs
.c_cflag
= (Savettybs
.c_cflag
& ~CS8
) | CS7
| PARENB
;
378 Savettybs
.c_oflag
|= OPOST
;
379 Savettybs
.c_lflag
|= (ISIG
|ICANON
|ECHO
);
387 * sytfixline(tty, spwant) set speed/echo/mode...
394 sytfixline(tty
, spwant
)
398 struct termios ttbufs
;
401 int i
, ret
, istermios
;
403 if ((istermios
= (*Ioctl
)(tty
, TCGETS
, &ttbufs
)) < 0) {
404 if ((*Ioctl
)(tty
, TCGETA
, &ttbuf
) != 0) {
407 ttbufs
.c_lflag
= ttbuf
.c_lflag
;
408 ttbufs
.c_oflag
= ttbuf
.c_oflag
;
409 ttbufs
.c_iflag
= ttbuf
.c_iflag
;
410 ttbufs
.c_cflag
= ttbuf
.c_cflag
;
411 for (i
= 0; i
< NCC
; i
++)
412 ttbufs
.c_cc
[i
] = ttbuf
.c_cc
[i
];
415 for (ps
= spds
; ps
->sp_val
>= 0; ps
++)
416 if (ps
->sp_val
== spwant
)
418 DEBUG(4, "sytfixline - speed= %d\n", speed
);
419 ASSERT(speed
>= 0, "BAD SPEED", "", spwant
);
420 ttbufs
.c_iflag
&= 0xffff0000;
421 ttbufs
.c_oflag
&= 0xffff0000;
422 ttbufs
.c_lflag
&= 0xffff0000;
423 ttbufs
.c_cflag
&= 0xffff0000;
424 cfsetospeed(&ttbufs
, speed
);
425 ttbufs
.c_cflag
|= (CS8
|CLOCAL
);
426 ttbufs
.c_cc
[VMIN
] = 6;
427 ttbufs
.c_cc
[VTIME
] = 1;
429 ttbuf
.c_lflag
= ttbufs
.c_lflag
;
430 ttbuf
.c_oflag
= ttbufs
.c_oflag
;
431 ttbuf
.c_iflag
= ttbufs
.c_iflag
;
432 ttbuf
.c_cflag
= ttbufs
.c_cflag
;
433 for (i
= 0; i
< NCC
; i
++)
434 ttbuf
.c_cc
[i
] = ttbufs
.c_cc
[i
];
435 ret
= (*Ioctl
)(tty
, TCSETAW
, &ttbuf
);
437 ret
= (*Ioctl
)(tty
, TCSETAWS
&ttbufs
);
438 ASSERT(ret
>= 0, "RETURN FROM sytfixline", "", ret
);
448 if ((*Ioctl
)(tty
, TCGETA
, &ttbuf
) != 0)
450 ttbuf
.c_cflag
&= ~CLOCAL
;
451 ttbuf
.c_cflag
|= CREAD
|HUPCL
;
452 ret
= (*Ioctl
)(tty
, TCSETAW
, &ttbuf
);
453 ASSERT(ret
>= 0, "RETURN FROM sytfix2line", "", ret
);
461 if (Saved_line
== TRUE
) {
462 if (Saved_termios
< 0)
463 return ((*Ioctl
)(0, TCSETAW
, &Savettyb
));
465 return ((*Ioctl
)(0, TCSETSW
, &Savettybs
));
470 #else /* !ATTSVTTY */
472 static struct sgttyb Savettyb
;
475 * fixline(tty, spwant, type) set speed/echo/mode...
478 * if spwant == 0, speed is untouched
479 * type is unused, but needed for compatibility
486 fixline(tty
, spwant
, type
)
487 int tty
, spwant
, type
;
493 DEBUG(6, "fixline(%d, ", tty
);
494 DEBUG(6, "%d)\n", spwant
);
496 if ((*Ioctl
)(tty
, TIOCGETP
, &ttbuf
) != 0)
499 for (ps
= spds
; ps
->sp_val
; ps
++)
500 if (ps
->sp_val
== spwant
) {
504 ASSERT(speed
>= 0, "BAD SPEED", "", spwant
);
505 ttbuf
.sg_ispeed
= ttbuf
.sg_ospeed
= speed
;
507 for (ps
= spds
; ps
->sp_val
; ps
++)
508 if (ps
->sp_name
== ttbuf
.sg_ispeed
) {
512 ASSERT(spwant
>= 0, "BAD SPEED", "", ttbuf
.sg_ispeed
);
514 ttbuf
.sg_flags
= (ANYP
| RAW
);
516 linebaudrate
= spwant
;
517 #endif /* PKSPEEDUP */
518 (void) (*Ioctl
)(tty
, TIOCSETP
, &ttbuf
);
519 (void) (*Ioctl
)(tty
, TIOCHPCL
, STBNULL
);
520 (void) (*Ioctl
)(tty
, TIOCEXCL
, STBNULL
);
528 (void) (*Ioctl
)(dcf
, TIOCHPCL
, STBNULL
);
532 * genbrk send a break
541 (void) (*Ioctl
)(fn
, TIOCSBRK
, 0);
543 nap(HZ
/10); /* 0.1 second break */
544 (void) (*Ioctl
)(fn
, TIOCCBRK
, 0);
550 * V7 and RT aren't smart enough for this -- linebaudrate is the best
560 if ((*Ioctl
)(0, TIOCGETP
, &Savettyb
) != 0)
564 Savettyb
.sg_flags
|= ECHO
;
565 Savettyb
.sg_flags
&= ~RAW
;
573 if (Saved_line
== TRUE
)
574 return ((*Ioctl
)(0, TIOCSETP
, &Savettyb
));