2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
14 #include <sys/ioctl.h>
15 #include <sys/socket.h>
16 #include "kern_util.h"
17 #include "user_util.h"
18 #include "chan_user.h"
22 #include "choose-mode.h"
25 void generic_close(int fd, void *unused)
30 int generic_read(int fd, char *c_out, void *unused)
34 n = read(fd, c_out, sizeof(*c_out));
36 if(errno == EAGAIN) return(0);
39 else if(n == 0) return(-EIO);
43 int generic_write(int fd, const char *buf, int n, void *unused)
47 count = write(fd, buf, n);
48 if(count < 0) return(-errno);
52 int generic_console_write(int fd, const char *buf, int n, void *unused)
54 struct termios save, new;
61 tcsetattr(fd, TCSAFLUSH, &new);
63 err = generic_write(fd, buf, n, NULL);
64 if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
68 int generic_window_size(int fd, void *unused, unsigned short *rows_out,
69 unsigned short *cols_out)
74 if(ioctl(fd, TIOCGWINSZ, &size) == 0){
75 ret = ((*rows_out != size.ws_row) ||
76 (*cols_out != size.ws_col));
77 *rows_out = size.ws_row;
78 *cols_out = size.ws_col;
83 void generic_free(void *data)
88 static void winch_handler(int sig)
98 static int winch_thread(void *arg)
100 struct winch_data *data = arg;
105 close(data->close_me);
106 pty_fd = data->pty_fd;
107 pipe_fd = data->pipe_fd;
108 if(write(pipe_fd, &c, sizeof(c)) != sizeof(c))
109 printk("winch_thread : failed to write synchronization "
110 "byte, errno = %d\n", errno);
112 signal(SIGWINCH, winch_handler);
114 sigdelset(&sigs, SIGWINCH);
115 if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
116 printk("winch_thread : sigprocmask failed, errno = %d\n",
122 printk("winch_thread : setsid failed, errno = %d\n", errno);
126 if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
127 printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
130 if(tcsetpgrp(pty_fd, os_getpid()) < 0){
131 printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno);
135 if(read(pipe_fd, &c, sizeof(c)) != sizeof(c))
136 printk("winch_thread : failed to read synchronization byte, "
137 "errno = %d\n", errno);
142 if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
143 printk("winch_thread : write failed, errno = %d\n",
149 static int winch_tramp(int fd, void *device_data, int *fd_out)
151 struct winch_data data;
153 int fds[2], pid, n, err;
156 err = os_pipe(fds, 1, 1);
158 printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
162 data = ((struct winch_data) { .pty_fd = fd,
164 .close_me = fds[0] } );
165 pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
167 printk("fork of winch_thread failed - errno = %d\n", errno);
173 n = read(fds[0], &c, sizeof(c));
175 printk("winch_tramp : failed to read synchronization byte\n");
176 printk("read returned %d, errno = %d\n", n, errno);
177 printk("fd %d will not support SIGWINCH\n", fd);
183 void register_winch(int fd, void *device_data)
185 int pid, thread, thread_fd;
188 if(!isatty(fd)) return;
191 if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) &&
193 thread = winch_tramp(fd, device_data, &thread_fd);
195 register_winch_irq(thread_fd, fd, thread, device_data);
197 if(write(thread_fd, &c, sizeof(c)) != sizeof(c))
198 printk("register_winch : failed to write "
199 "synchronization byte\n");
205 * Overrides for Emacs so that we follow Linus's tabbing style.
206 * Emacs will notice this stuff at the end of the file and automatically
207 * adjust the settings for this buffer only. This must remain at the end
209 * ---------------------------------------------------------------------------
211 * c-file-style: "linux"