1 |
/* |
/* |
2 |
Copyright (C) 1995,96,97,98,99,2000,01 Free Software Foundation, Inc. |
Copyright (C) 1995,96,97,98,99,2000,01,02 Free Software Foundation, Inc. |
3 |
Written by Michael I. Bushnell, p/BSG. |
Written by Michael I. Bushnell, p/BSG. |
4 |
|
|
5 |
This file is part of the GNU Hurd. |
This file is part of the GNU Hurd. |
152 |
|
|
153 |
if (!(termflags & TTY_OPEN)) |
if (!(termflags & TTY_OPEN)) |
154 |
{ |
{ |
155 |
bzero (&termstate, sizeof termstate); |
memset (&termstate, 0, sizeof termstate); |
156 |
|
|
157 |
/* This is different from BSD: we don't turn on ISTRIP, |
/* This is different from BSD: we don't turn on ISTRIP, |
158 |
and we use CS8 rather than CS7|PARENB. */ |
and we use CS8 rather than CS7|PARENB. */ |
162 |
| ECHOE|ECHOKE|ECHOCTL); |
| ECHOE|ECHOKE|ECHOCTL); |
163 |
termstate.c_cflag |= CREAD | CS8 | HUPCL; |
termstate.c_cflag |= CREAD | CS8 | HUPCL; |
164 |
|
|
165 |
bcopy (ttydefchars, termstate.c_cc, NCCS); |
memcpy (termstate.c_cc, ttydefchars, NCCS); |
166 |
|
|
167 |
bzero (&window_size, sizeof window_size); |
memset (&window_size, 0, sizeof window_size); |
168 |
|
|
169 |
termflags |= NO_OWNER; |
termflags |= NO_OWNER; |
170 |
} |
} |
212 |
|
|
213 |
if (!err) |
if (!err) |
214 |
{ |
{ |
215 |
termflags |= TTY_OPEN; |
struct termios state = termstate; |
216 |
(*bottom->set_bits) (); |
err = (*bottom->set_bits) (&state); |
217 |
|
if (!err) |
218 |
|
{ |
219 |
|
termstate = state; |
220 |
|
termflags |= TTY_OPEN; |
221 |
|
} |
222 |
} |
} |
223 |
|
|
224 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
565 |
{ |
{ |
566 |
int i; |
int i; |
567 |
int cancel; |
int cancel; |
568 |
|
error_t err = 0; |
569 |
|
|
570 |
if (!cred) |
if (!cred) |
571 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
601 |
{ |
{ |
602 |
while (!qavail (outputq) && !cancel) |
while (!qavail (outputq) && !cancel) |
603 |
{ |
{ |
604 |
(*bottom->start_output) (); |
err = (*bottom->start_output) (); |
605 |
if (!qavail (outputq)) |
if (err) |
606 |
cancel = hurd_condition_wait (outputq->wait, &global_lock); |
cancel = 1; |
607 |
|
else |
608 |
|
{ |
609 |
|
if (!qavail (outputq)) |
610 |
|
cancel = hurd_condition_wait (outputq->wait, &global_lock); |
611 |
|
} |
612 |
} |
} |
613 |
if (cancel) |
if (cancel) |
614 |
break; |
break; |
618 |
|
|
619 |
*amt = i; |
*amt = i; |
620 |
|
|
621 |
(*bottom->start_output) (); |
if (!err && datalen) |
622 |
|
(*bottom->start_output) (); |
623 |
|
|
624 |
trivfs_set_mtime (termctl); |
trivfs_set_mtime (termctl); |
625 |
|
|
627 |
|
|
628 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
629 |
|
|
630 |
return ((cancel && datalen && !*amt) ? EINTR : 0); |
return ((cancel && datalen && !*amt) ? (err ?: EINTR) : 0); |
631 |
} |
} |
632 |
|
|
633 |
/* Called for user reads from the terminal. */ |
/* Called for user reads from the terminal. */ |
894 |
int *state) |
int *state) |
895 |
{ |
{ |
896 |
struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); |
struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); |
897 |
|
error_t err = 0; |
898 |
|
|
899 |
if (!cred) |
if (!cred) |
900 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
901 |
|
|
907 |
} |
} |
908 |
|
|
909 |
mutex_lock (&global_lock); |
mutex_lock (&global_lock); |
910 |
*state = (*bottom->mdmstate) (); |
err = (*bottom->mdmstate) (state); |
911 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
912 |
|
|
913 |
ports_port_deref (cred); |
ports_port_deref (cred); |
914 |
return 0; |
return err; |
915 |
} |
} |
916 |
|
|
917 |
/* TIOCMODS ioctl -- Set modem state */ |
/* TIOCMODS ioctl -- Set modem state */ |
936 |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
937 |
err = EBADF; |
err = EBADF; |
938 |
else |
else |
939 |
{ |
err = (*bottom->mdmctl) (MDMCTL_SET, state); |
|
(*bottom->mdmctl) (MDMCTL_SET, state); |
|
|
err = 0; |
|
|
} |
|
940 |
|
|
941 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
942 |
|
|
1012 |
int flags) |
int flags) |
1013 |
{ |
{ |
1014 |
struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); |
struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); |
1015 |
|
error_t err = 0; |
1016 |
|
|
|
error_t err; |
|
1017 |
if (!cred) |
if (!cred) |
1018 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
1019 |
|
|
1035 |
|
|
1036 |
if (flags & O_READ) |
if (flags & O_READ) |
1037 |
{ |
{ |
1038 |
clear_queue (inputq); |
err = (*bottom->notice_input_flushed) (); |
1039 |
(*bottom->notice_input_flushed) (); |
if (!err) |
1040 |
|
clear_queue (inputq); |
1041 |
} |
} |
1042 |
|
|
1043 |
if (flags & O_WRITE) |
if (!err && (flags & O_WRITE)) |
1044 |
drop_output (); |
err = drop_output (); |
|
|
|
|
err = 0; |
|
1045 |
} |
} |
1046 |
|
|
1047 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1073 |
modes[1] = termstate.c_oflag; |
modes[1] = termstate.c_oflag; |
1074 |
modes[2] = termstate.c_cflag; |
modes[2] = termstate.c_cflag; |
1075 |
modes[3] = termstate.c_lflag; |
modes[3] = termstate.c_lflag; |
1076 |
bcopy (termstate.c_cc, ccs, NCCS); |
memcpy (ccs, termstate.c_cc, NCCS); |
1077 |
speeds[0] = termstate.__ispeed; |
speeds[0] = termstate.__ispeed; |
1078 |
speeds[1] = termstate.__ospeed; |
speeds[1] = termstate.__ospeed; |
1079 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1094 |
struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); |
struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); |
1095 |
error_t err; |
error_t err; |
1096 |
int oldlflag; |
int oldlflag; |
1097 |
|
struct termios state; |
1098 |
|
|
1099 |
if (!cred) |
if (!cred) |
1100 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
1116 |
{ |
{ |
1117 |
if (cred->pi.class == pty_class) |
if (cred->pi.class == pty_class) |
1118 |
{ |
{ |
1119 |
|
err = (*bottom->abandon_physical_output) (); |
1120 |
|
if (err) |
1121 |
|
goto leave; |
1122 |
clear_queue (outputq); |
clear_queue (outputq); |
|
(*bottom->abandon_physical_output) (); |
|
1123 |
} |
} |
1124 |
|
|
1125 |
if (draino) |
if (draino) |
1126 |
{ |
{ |
1127 |
err = drain_output (); |
err = drain_output (); |
1128 |
if (err) |
if (err) |
1129 |
{ |
goto leave; |
|
mutex_unlock (&global_lock); |
|
|
ports_port_deref (cred); |
|
|
return err; |
|
|
} |
|
1130 |
} |
} |
1131 |
|
|
1132 |
if (flushi) |
if (flushi) |
1133 |
{ |
{ |
1134 |
|
err = (*bottom->notice_input_flushed) (); |
1135 |
|
if (err) |
1136 |
|
goto leave; |
1137 |
clear_queue (inputq); |
clear_queue (inputq); |
|
(*bottom->notice_input_flushed) (); |
|
1138 |
} |
} |
1139 |
|
|
1140 |
oldlflag = termstate.c_lflag; |
state = termstate; |
1141 |
termstate.c_iflag = modes[0]; |
state.c_iflag = modes[0]; |
1142 |
termstate.c_oflag = modes[1]; |
state.c_oflag = modes[1]; |
1143 |
termstate.c_cflag = modes[2]; |
state.c_cflag = modes[2]; |
1144 |
termstate.c_lflag = modes[3]; |
state.c_lflag = modes[3]; |
1145 |
bcopy (ccs, termstate.c_cc, NCCS); |
memcpy (state.c_cc, ccs, NCCS); |
1146 |
termstate.__ispeed = speeds[0]; |
state.__ispeed = speeds[0]; |
1147 |
termstate.__ospeed = speeds[1]; |
state.__ospeed = speeds[1]; |
1148 |
|
|
1149 |
if (external_processing) |
if (external_processing) |
1150 |
termstate.c_lflag |= EXTPROC; |
state.c_lflag |= EXTPROC; |
1151 |
else |
else |
1152 |
termstate.c_lflag &= ~EXTPROC; |
state.c_lflag &= ~EXTPROC; |
1153 |
|
|
1154 |
|
err = (*bottom->set_bits) (&state); |
1155 |
|
if (err) |
1156 |
|
goto leave; |
1157 |
|
|
1158 |
(*bottom->set_bits) (); |
oldlflag = termstate.c_lflag; |
1159 |
|
termstate = state; |
1160 |
|
|
1161 |
if (oldlflag & ICANON) |
if (oldlflag & ICANON) |
1162 |
{ |
{ |
1168 |
if (termstate.c_lflag & ICANON) |
if (termstate.c_lflag & ICANON) |
1169 |
rescan_inputq (); |
rescan_inputq (); |
1170 |
} |
} |
|
err = 0; |
|
1171 |
} |
} |
1172 |
|
|
1173 |
|
leave: |
1174 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
|
|
|
1175 |
ports_port_deref (cred); |
ports_port_deref (cred); |
1176 |
return err; |
return err; |
1177 |
} |
} |
1178 |
|
|
1179 |
|
|
|
|
|
1180 |
/* TIOCSETA -- Set termios state */ |
/* TIOCSETA -- Set termios state */ |
1181 |
kern_return_t |
kern_return_t |
1182 |
S_tioctl_tiocseta (io_t port, |
S_tioctl_tiocseta (io_t port, |
1368 |
int *bits) |
int *bits) |
1369 |
{ |
{ |
1370 |
struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); |
struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); |
1371 |
|
error_t err = 0; |
1372 |
|
|
1373 |
if (!cred) |
if (!cred) |
1374 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
1381 |
} |
} |
1382 |
|
|
1383 |
mutex_lock (&global_lock); |
mutex_lock (&global_lock); |
1384 |
*bits = (*bottom->mdmstate) (); |
err = (*bottom->mdmstate) (bits); |
1385 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1386 |
|
|
1387 |
ports_port_deref (cred); |
ports_port_deref (cred); |
1388 |
return 0; |
return err; |
1389 |
} |
} |
1390 |
|
|
1391 |
/* TIOCMSET -- Set all modem bits */ |
/* TIOCMSET -- Set all modem bits */ |
1410 |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
1411 |
err = EBADF; |
err = EBADF; |
1412 |
else |
else |
1413 |
{ |
err = (*bottom->mdmctl) (MDMCTL_SET, bits); |
|
(*bottom->mdmctl) (MDMCTL_SET, bits); |
|
|
err = 0; |
|
|
} |
|
1414 |
|
|
1415 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1416 |
ports_port_deref (cred); |
ports_port_deref (cred); |
1439 |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
1440 |
err = EBADF; |
err = EBADF; |
1441 |
else |
else |
1442 |
{ |
err = (*bottom->mdmctl) (MDMCTL_BIC, bits); |
|
(*bottom->mdmctl) (MDMCTL_BIC, bits); |
|
|
err = 0; |
|
|
} |
|
1443 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1444 |
|
|
1445 |
ports_port_deref (cred); |
ports_port_deref (cred); |
1469 |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
1470 |
err = EBADF; |
err = EBADF; |
1471 |
else |
else |
1472 |
{ |
err = (*bottom->mdmctl) (MDMCTL_BIS, bits); |
|
(*bottom->mdmctl) (MDMCTL_BIS, bits); |
|
|
err = 0; |
|
|
} |
|
1473 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1474 |
ports_port_deref (cred); |
ports_port_deref (cred); |
1475 |
return err; |
return err; |
1498 |
err = EBADF; |
err = EBADF; |
1499 |
else |
else |
1500 |
{ |
{ |
1501 |
|
int old_termflags = termflags; |
1502 |
|
|
1503 |
termflags &= ~USER_OUTPUT_SUSP; |
termflags &= ~USER_OUTPUT_SUSP; |
1504 |
(*bottom->start_output) (); |
err = (*bottom->start_output) (); |
1505 |
err = 0; |
if (err) |
1506 |
|
termflags = old_termflags; |
1507 |
} |
} |
1508 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1509 |
|
|
1533 |
err = EBADF; |
err = EBADF; |
1534 |
else |
else |
1535 |
{ |
{ |
1536 |
|
int old_termflags = termflags; |
1537 |
termflags |= USER_OUTPUT_SUSP; |
termflags |= USER_OUTPUT_SUSP; |
1538 |
(*bottom->suspend_physical_output) (); |
err = (*bottom->suspend_physical_output) (); |
1539 |
err = 0; |
if (err) |
1540 |
|
termflags = old_termflags; |
1541 |
} |
} |
1542 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1543 |
|
|
1701 |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
1702 |
err = EBADF; |
err = EBADF; |
1703 |
else |
else |
1704 |
{ |
err = (*bottom->mdmctl) (MDMCTL_BIC, TIOCM_DTR); |
|
(*bottom->mdmctl) (MDMCTL_BIC, TIOCM_DTR); |
|
|
err = 0; |
|
|
} |
|
1705 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1706 |
|
|
1707 |
ports_port_deref (cred); |
ports_port_deref (cred); |
1729 |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
1730 |
err = EBADF; |
err = EBADF; |
1731 |
else |
else |
1732 |
{ |
err = (*bottom->mdmctl) (MDMCTL_BIS, TIOCM_DTR); |
|
(*bottom->mdmctl) (MDMCTL_BIS, TIOCM_DTR); |
|
|
err = 0; |
|
|
} |
|
1733 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1734 |
|
|
1735 |
ports_port_deref (cred); |
ports_port_deref (cred); |
1757 |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
1758 |
err = EBADF; |
err = EBADF; |
1759 |
else |
else |
1760 |
{ |
err = (*bottom->clear_break) (); |
|
(*bottom->clear_break) (); |
|
|
err = 0; |
|
|
} |
|
1761 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1762 |
|
|
1763 |
ports_port_deref (cred); |
ports_port_deref (cred); |
1785 |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
if (!(cred->po->openmodes & (O_READ|O_WRITE))) |
1786 |
err = EBADF; |
err = EBADF; |
1787 |
else |
else |
1788 |
{ |
err = (*bottom->set_break) (); |
|
(*bottom->set_break) (); |
|
|
err = 0; |
|
|
} |
|
1789 |
mutex_unlock (&global_lock); |
mutex_unlock (&global_lock); |
1790 |
|
|
1791 |
ports_port_deref (cred); |
ports_port_deref (cred); |
2236 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
2237 |
|
|
2238 |
ports_port_deref (cred); |
ports_port_deref (cred); |
2239 |
if (bottom == &devio_bottom) |
*ttype = bottom->type; |
|
*ttype = TERM_ON_MACHDEV; |
|
|
else |
|
|
*ttype = TERM_ON_MASTERPTY; |
|
2240 |
return 0; |
return 0; |
2241 |
} |
} |
2242 |
|
|