]>
git.proxmox.com Git - rustc.git/blob - vendor/libc/src/unix/solarish/compat.rs
1 // Common functions that are unfortunately missing on illumos and
2 // Solaris, but often needed by other crates.
7 const PTEM
: &[u8] = b
"ptem\0";
8 const LDTERM
: &[u8] = b
"ldterm\0";
10 pub unsafe fn cfmakeraw(termios
: *mut ::termios
) {
12 !(IMAXBEL
| IGNBRK
| BRKINT
| PARMRK
| ISTRIP
| INLCR
| IGNCR
| ICRNL
| IXON
);
13 (*termios
).c_oflag
&= !OPOST
;
14 (*termios
).c_lflag
&= !(ECHO
| ECHONL
| ICANON
| ISIG
| IEXTEN
);
15 (*termios
).c_cflag
&= !(CSIZE
| PARENB
);
16 (*termios
).c_cflag
|= CS8
;
18 // By default, most software expects a pending read to block until at
19 // least one byte becomes available. As per termio(7I), this requires
20 // setting the MIN and TIME parameters appropriately.
22 // As a somewhat unfortunate artefact of history, the MIN and TIME slots
23 // in the control character array overlap with the EOF and EOL slots used
24 // for canonical mode processing. Because the EOF character needs to be
25 // the ASCII EOT value (aka Control-D), it has the byte value 4. When
26 // switching to raw mode, this is interpreted as a MIN value of 4; i.e.,
27 // reads will block until at least four bytes have been input.
29 // Other platforms with a distinct MIN slot like Linux and FreeBSD appear
30 // to default to a MIN value of 1, so we'll force that value here:
31 (*termios
).c_cc
[VMIN
] = 1;
32 (*termios
).c_cc
[VTIME
] = 0;
35 pub unsafe fn cfsetspeed(termios
: *mut ::termios
, speed
: ::speed_t
) -> ::c_int
{
36 // Neither of these functions on illumos or Solaris actually ever
38 ::cfsetispeed(termios
, speed
);
39 ::cfsetospeed(termios
, speed
);
43 unsafe fn bail(fdm
: ::c_int
, fds
: ::c_int
) -> ::c_int
{
55 pub unsafe fn openpty(
57 asubord
: *mut ::c_int
,
59 termp
: *const termios
,
60 winp
: *const ::winsize
,
62 // Open the main pseudo-terminal device, making sure not to set it as the
63 // controlling terminal for this process:
64 let fdm
= ::posix_openpt(O_RDWR
| O_NOCTTY
);
69 // Set permissions and ownership on the subordinate device and unlock it:
70 if ::grantpt(fdm
) < 0 || ::unlockpt(fdm
) < 0 {
74 // Get the path name of the subordinate device:
75 let subordpath
= ::ptsname(fdm
);
76 if subordpath
.is_null() {
80 // Open the subordinate device without setting it as the controlling
81 // terminal for this process:
82 let fds
= ::open(subordpath
, O_RDWR
| O_NOCTTY
);
87 // Check if the STREAMS modules are already pushed:
88 let setup
= ::ioctl(fds
, I_FIND
, LDTERM
.as_ptr());
90 return bail(fdm
, fds
);
91 } else if setup
== 0 {
92 // The line discipline is not present, so push the appropriate STREAMS
93 // modules for the subordinate device:
94 if ::ioctl(fds
, I_PUSH
, PTEM
.as_ptr()) < 0 || ::ioctl(fds
, I_PUSH
, LDTERM
.as_ptr()) < 0 {
95 return bail(fdm
, fds
);
99 // If provided, set the terminal parameters:
100 if !termp
.is_null() && ::tcsetattr(fds
, TCSAFLUSH
, termp
) != 0 {
101 return bail(fdm
, fds
);
104 // If provided, set the window size:
105 if !winp
.is_null() && ::ioctl(fds
, TIOCSWINSZ
, winp
) < 0 {
106 return bail(fdm
, fds
);
109 // If the caller wants the name of the subordinate device, copy it out.
111 // Note that this is a terrible interface: there appears to be no standard
112 // upper bound on the copy length for this pointer. Nobody should pass
113 // anything but NULL here, preferring instead to use ptsname(3C) directly.
115 ::strcpy(name
, subordpath
);
123 pub unsafe fn forkpty(
126 termp
: *const termios
,
127 winp
: *const ::winsize
,
131 if openpty(amain
, &mut fds
, name
, termp
, winp
) != 0 {
137 return bail(*amain
, fds
);
139 // In the parent process, we close the subordinate device and return the
140 // process ID of the new child:
145 // The rest of this function executes in the child process.
147 // Close the main side of the pseudo-terminal pair:
150 // Use TIOCSCTTY to set the subordinate device as our controlling
151 // terminal. This will fail (with ENOTTY) if we are not the leader in
152 // our own session, so we call setsid() first. Finally, arrange for
153 // the pseudo-terminal to occupy the standard I/O descriptors.
155 || ::ioctl(fds
, TIOCSCTTY
, 0) < 0
156 || ::dup2(fds
, 0) < 0
157 || ::dup2(fds
, 1) < 0
158 || ::dup2(fds
, 2) < 0
160 // At this stage there are no particularly good ways to handle failure.
161 // Exit as abruptly as possible, using _exit() to avoid messing with any
162 // state still shared with the parent process.
163 ::_exit(EXIT_FAILURE
);
165 // Close the inherited descriptor, taking care to avoid closing the standard
166 // descriptors by mistake:
174 pub unsafe fn getpwent_r(
178 result
: *mut *mut passwd
,
180 let old_errno
= *::___errno();
182 *result
= native_getpwent_r(
185 min(buflen
, ::c_int
::max_value() as ::size_t
) as ::c_int
,
188 let ret
= if (*result
).is_null() {
193 *::___errno() = old_errno
;
198 pub unsafe fn getgrent_r(
202 result
: *mut *mut ::group
,
204 let old_errno
= *::___errno();
206 *result
= native_getgrent_r(
209 min(buflen
, ::c_int
::max_value() as ::size_t
) as ::c_int
,
212 let ret
= if (*result
).is_null() {
217 *::___errno() = old_errno
;