#include <linux/kd.h>
GLOBALS(
- unsigned long vt_num;
+ unsigned long vt_num;
)
int find_console_fd(void)
{
- char *console_name[] = {"/dev/tty", "/dev/tty0", "/dev/console"};
- int i;
- int fd;
- char arg;
-
- for (i = 0; i < 3; i++) {
- fd = open(console_name[i], O_RDWR);
- if (fd < 0 && errno == EACCES)
- fd = open(console_name[i], O_RDONLY);
-
- if (fd < 0 && errno == EACCES)
- fd = open(console_name[i], O_WRONLY);
-
- if (fd >= 0) {
- arg = 0;
- if (0 == ioctl(fd, KDGKBTYPE, &arg))
- return fd;
- else
- close(fd);
- }
- }
-
- /* check std fd 0, 1 and 2 */
- for (fd = 0; fd < 3; fd++) {
- arg = 0;
- if (0 == ioctl(fd, KDGKBTYPE, &arg))
- return fd;
- }
-
- return -1;
+ char *console_name[] = {"/dev/tty", "/dev/tty0", "/dev/console"};
+ int i;
+ int fd;
+ char arg;
+
+ for (i = 0; i < 3; i++) {
+ fd = open(console_name[i], O_RDONLY);
+ if (fd < 0 && errno == EACCES)
+ fd = open(console_name[i], O_WRONLY);
+
+ if (fd >= 0) {
+ arg = 0;
+ if (0 == ioctl(fd, KDGKBTYPE, &arg))
+ return fd;
+ else
+ close(fd);
+ }
+ }
+
+ /* check std fd 0, 1 and 2 */
+ for (fd = 0; fd < 3; fd++) {
+ arg = 0;
+ if (0 == ioctl(fd, KDGKBTYPE, &arg))
+ return fd;
+ }
+
+ return -1;
}
int xvtnum(int fd)
{
- int ret;
+ int ret;
- ret = ioctl(fd, VT_OPENQRY, (int *)&TT.vt_num);
- if (ret != 0 || TT.vt_num <= 0) perror_exit("can't find open VT");
+ ret = ioctl(fd, VT_OPENQRY, (int *)&TT.vt_num);
+ if (ret != 0 || TT.vt_num <= 0) perror_exit("can't find open VT");
- return TT.vt_num;
+ return TT.vt_num;
}
void openvt_main(void)
{
- int fd = -1, vt_fd = -1, pid, ret = 0;
- struct vt_stat vstate;
-
- if (!(toys.optflags & FLAG_c)) {
- // check if fd 0,1 or 2 is already opened
- for (fd = 0; fd < 3; fd++)
- if (!ioctl(fd, VT_GETSTATE, &vstate)) {
- ret = xvtnum(fd);
- break;
- }
-
- // find VT number using /dev/console
- if (!ret) {
- fd = xopen("/dev/console", O_RDONLY | O_NONBLOCK);
- xioctl(fd, VT_GETSTATE, &vstate);
- xvtnum(fd);
- }
- }
-
- sprintf(toybuf, "/dev/tty%lu", TT.vt_num);
- fd = find_console_fd();
- xioctl(fd, VT_GETSTATE, &vstate);
-
- close(0); //new vt becomes stdin
- vt_fd = xopen(toybuf, O_RDWR);
- if (toys.optflags & FLAG_s) {
- ioctl(vt_fd, VT_ACTIVATE, TT.vt_num);
- ioctl(vt_fd, VT_WAITACTIVE, TT.vt_num);
- }
-
- close(1);
- close(2);
- dup2(vt_fd, 1);
- dup2(vt_fd, 2);
- while (vt_fd > 2)
- close(vt_fd--);
-
- pid = vfork();
- if (pid < 0) perror_exit("Fork failed");
- else if (!pid) {
- setsid();
- ioctl(vt_fd, TIOCSCTTY, 0);
- xexec(toys.optargs);
- }
-
- if (toys.optflags & FLAG_w) {
- while (-1 == waitpid(pid, NULL, 0) && errno == EINTR)
- ;
- if (toys.optflags & FLAG_s) {
- ioctl(fd, VT_ACTIVATE, vstate.v_active);
- ioctl(fd, VT_WAITACTIVE, vstate.v_active);
- //check why deallocate isn't working here
- xioctl(fd, VT_DISALLOCATE, (void *)(ptrdiff_t)TT.vt_num);
- }
- }
+ int fd = -1, vt_fd = -1, pid, ret = 0;
+ struct vt_stat vstate;
+
+ if (!(toys.optflags & FLAG_c)) {
+ // check if fd 0,1 or 2 is already opened
+ for (fd = 0; fd < 3; fd++)
+ if (!ioctl(fd, VT_GETSTATE, &vstate)) {
+ ret = xvtnum(fd);
+ break;
+ }
+
+ // find VT number using /dev/console
+ if (!ret) {
+ fd = xopen("/dev/console", O_RDONLY | O_NONBLOCK);
+ xioctl(fd, VT_GETSTATE, &vstate);
+ xvtnum(fd);
+ }
+ }
+
+ sprintf(toybuf, "/dev/tty%lu", TT.vt_num);
+ fd = find_console_fd();
+ xioctl(fd, VT_GETSTATE, &vstate);
+
+ close(0); //new vt becomes stdin
+ vt_fd = xopen(toybuf, O_RDWR);
+ if (toys.optflags & FLAG_s) {
+ ioctl(vt_fd, VT_ACTIVATE, TT.vt_num);
+ ioctl(vt_fd, VT_WAITACTIVE, TT.vt_num);
+ }
+
+ close(1);
+ close(2);
+ dup2(vt_fd, 1);
+ dup2(vt_fd, 2);
+ while (vt_fd > 2)
+ close(vt_fd--);
+
+ pid = vfork();
+ if (pid < 0) perror_exit("Fork failed");
+ else if (!pid) {
+ setsid();
+ ioctl(vt_fd, TIOCSCTTY, 0);
+ xexec(toys.optargs);
+ }
+
+ if (toys.optflags & FLAG_w) {
+ while (-1 == waitpid(pid, NULL, 0) && errno == EINTR)
+ ;
+ if (toys.optflags & FLAG_s) {
+ ioctl(fd, VT_ACTIVATE, vstate.v_active);
+ ioctl(fd, VT_WAITACTIVE, vstate.v_active);
+ //check why deallocate isn't working here
+ xioctl(fd, VT_DISALLOCATE, (void *)(ptrdiff_t)TT.vt_num);
+ }
+ }
}