~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/um/drivers/pty.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <unistd.h>
  9 #include <errno.h>
 10 #include <fcntl.h>
 11 #include <string.h>
 12 #include <termios.h>
 13 #include <sys/stat.h>
 14 #include "chan_user.h"
 15 #include <os.h>
 16 #include <um_malloc.h>
 17 
 18 struct pty_chan {
 19         void (*announce)(char *dev_name, int dev);
 20         int dev;
 21         int raw;
 22         struct termios tt;
 23         char dev_name[sizeof("/dev/pts/0123456\0")];
 24 };
 25 
 26 static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
 27 {
 28         struct pty_chan *data;
 29 
 30         data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 31         if (data == NULL)
 32                 return NULL;
 33 
 34         *data = ((struct pty_chan) { .announce          = opts->announce,
 35                                      .dev               = device,
 36                                      .raw               = opts->raw });
 37         return data;
 38 }
 39 
 40 static int pts_open(int input, int output, int primary, void *d,
 41                     char **dev_out)
 42 {
 43         struct pty_chan *data = d;
 44         char *dev;
 45         int fd, err;
 46 
 47         fd = get_pty();
 48         if (fd < 0) {
 49                 err = -errno;
 50                 printk(UM_KERN_ERR "open_pts : Failed to open pts\n");
 51                 return err;
 52         }
 53 
 54         if (data->raw) {
 55                 CATCH_EINTR(err = tcgetattr(fd, &data->tt));
 56                 if (err)
 57                         goto out_close;
 58 
 59                 err = raw(fd);
 60                 if (err)
 61                         goto out_close;
 62         }
 63 
 64         dev = ptsname(fd);
 65         sprintf(data->dev_name, "%s", dev);
 66         *dev_out = data->dev_name;
 67 
 68         if (data->announce)
 69                 (*data->announce)(dev, data->dev);
 70 
 71         return fd;
 72 
 73 out_close:
 74         close(fd);
 75         return err;
 76 }
 77 
 78 static int getmaster(char *line)
 79 {
 80         struct stat buf;
 81         char *pty, *bank, *cp;
 82         int master, err;
 83 
 84         pty = &line[strlen("/dev/ptyp")];
 85         for (bank = "pqrs"; *bank; bank++) {
 86                 line[strlen("/dev/pty")] = *bank;
 87                 *pty = '';
 88                 /* Did we hit the end ? */
 89                 if ((stat(line, &buf) < 0) && (errno == ENOENT))
 90                         break;
 91 
 92                 for (cp = "0123456789abcdef"; *cp; cp++) {
 93                         *pty = *cp;
 94                         master = open(line, O_RDWR);
 95                         if (master >= 0) {
 96                                 char *tp = &line[strlen("/dev/")];
 97 
 98                                 /* verify slave side is usable */
 99                                 *tp = 't';
100                                 err = access(line, R_OK | W_OK);
101                                 *tp = 'p';
102                                 if (!err)
103                                         return master;
104                                 close(master);
105                         }
106                 }
107         }
108 
109         printk(UM_KERN_ERR "getmaster - no usable host pty devices\n");
110         return -ENOENT;
111 }
112 
113 static int pty_open(int input, int output, int primary, void *d,
114                     char **dev_out)
115 {
116         struct pty_chan *data = d;
117         int fd, err;
118         char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
119 
120         fd = getmaster(dev);
121         if (fd < 0)
122                 return fd;
123 
124         if (data->raw) {
125                 err = raw(fd);
126                 if (err) {
127                         close(fd);
128                         return err;
129                 }
130         }
131 
132         if (data->announce)
133                 (*data->announce)(dev, data->dev);
134 
135         sprintf(data->dev_name, "%s", dev);
136         *dev_out = data->dev_name;
137 
138         return fd;
139 }
140 
141 const struct chan_ops pty_ops = {
142         .type           = "pty",
143         .init           = pty_chan_init,
144         .open           = pty_open,
145         .close          = generic_close,
146         .read           = generic_read,
147         .write          = generic_write,
148         .console_write  = generic_console_write,
149         .window_size    = generic_window_size,
150         .free           = generic_free,
151         .winch          = 0,
152 };
153 
154 const struct chan_ops pts_ops = {
155         .type           = "pts",
156         .init           = pty_chan_init,
157         .open           = pts_open,
158         .close          = generic_close,
159         .read           = generic_read,
160         .write          = generic_write,
161         .console_write  = generic_console_write,
162         .window_size    = generic_window_size,
163         .free           = generic_free,
164         .winch          = 0,
165 };
166 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php