diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/drivers/pty.c | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index df4976c9eef2..640bcdaad9f4 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -7,12 +7,14 @@ | |||
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <unistd.h> | 8 | #include <unistd.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | #include <fcntl.h> | ||
10 | #include <errno.h> | 11 | #include <errno.h> |
11 | #include <termios.h> | 12 | #include <termios.h> |
13 | #include <sys/stat.h> | ||
12 | #include "chan_user.h" | 14 | #include "chan_user.h" |
13 | #include "user.h" | ||
14 | #include "kern_util.h" | ||
15 | #include "os.h" | 15 | #include "os.h" |
16 | #include "user.h" | ||
17 | #include "kern_constants.h" | ||
16 | #include "um_malloc.h" | 18 | #include "um_malloc.h" |
17 | 19 | ||
18 | struct pty_chan { | 20 | struct pty_chan { |
@@ -28,11 +30,13 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts) | |||
28 | struct pty_chan *data; | 30 | struct pty_chan *data; |
29 | 31 | ||
30 | data = um_kmalloc(sizeof(*data)); | 32 | data = um_kmalloc(sizeof(*data)); |
31 | if(data == NULL) return(NULL); | 33 | if (data == NULL) |
34 | return NULL; | ||
35 | |||
32 | *data = ((struct pty_chan) { .announce = opts->announce, | 36 | *data = ((struct pty_chan) { .announce = opts->announce, |
33 | .dev = device, | 37 | .dev = device, |
34 | .raw = opts->raw }); | 38 | .raw = opts->raw }); |
35 | return(data); | 39 | return data; |
36 | } | 40 | } |
37 | 41 | ||
38 | static int pts_open(int input, int output, int primary, void *d, | 42 | static int pts_open(int input, int output, int primary, void *d, |
@@ -43,31 +47,35 @@ static int pts_open(int input, int output, int primary, void *d, | |||
43 | int fd, err; | 47 | int fd, err; |
44 | 48 | ||
45 | fd = get_pty(); | 49 | fd = get_pty(); |
46 | if(fd < 0){ | 50 | if (fd < 0) { |
47 | err = -errno; | 51 | err = -errno; |
48 | printk("open_pts : Failed to open pts\n"); | 52 | printk(UM_KERN_ERR "open_pts : Failed to open pts\n"); |
49 | return err; | 53 | return err; |
50 | } | 54 | } |
51 | if(data->raw){ | 55 | |
56 | if (data->raw) { | ||
52 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); | 57 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); |
53 | if(err) | 58 | if (err) |
54 | return(err); | 59 | return err; |
55 | 60 | ||
56 | err = raw(fd); | 61 | err = raw(fd); |
57 | if(err) | 62 | if (err) |
58 | return(err); | 63 | return err; |
59 | } | 64 | } |
60 | 65 | ||
61 | dev = ptsname(fd); | 66 | dev = ptsname(fd); |
62 | sprintf(data->dev_name, "%s", dev); | 67 | sprintf(data->dev_name, "%s", dev); |
63 | *dev_out = data->dev_name; | 68 | *dev_out = data->dev_name; |
69 | |||
64 | if (data->announce) | 70 | if (data->announce) |
65 | (*data->announce)(dev, data->dev); | 71 | (*data->announce)(dev, data->dev); |
66 | return(fd); | 72 | |
73 | return fd; | ||
67 | } | 74 | } |
68 | 75 | ||
69 | static int getmaster(char *line) | 76 | static int getmaster(char *line) |
70 | { | 77 | { |
78 | struct stat buf; | ||
71 | char *pty, *bank, *cp; | 79 | char *pty, *bank, *cp; |
72 | int master, err; | 80 | int master, err; |
73 | 81 | ||
@@ -75,24 +83,29 @@ static int getmaster(char *line) | |||
75 | for (bank = "pqrs"; *bank; bank++) { | 83 | for (bank = "pqrs"; *bank; bank++) { |
76 | line[strlen("/dev/pty")] = *bank; | 84 | line[strlen("/dev/pty")] = *bank; |
77 | *pty = '0'; | 85 | *pty = '0'; |
78 | if (os_stat_file(line, NULL) < 0) | 86 | /* Did we hit the end ? */ |
87 | if ((stat(line, &buf) < 0) && (errno == ENOENT)) | ||
79 | break; | 88 | break; |
89 | |||
80 | for (cp = "0123456789abcdef"; *cp; cp++) { | 90 | for (cp = "0123456789abcdef"; *cp; cp++) { |
81 | *pty = *cp; | 91 | *pty = *cp; |
82 | master = os_open_file(line, of_rdwr(OPENFLAGS()), 0); | 92 | master = open(line, O_RDWR); |
83 | if (master >= 0) { | 93 | if (master >= 0) { |
84 | char *tp = &line[strlen("/dev/")]; | 94 | char *tp = &line[strlen("/dev/")]; |
85 | 95 | ||
86 | /* verify slave side is usable */ | 96 | /* verify slave side is usable */ |
87 | *tp = 't'; | 97 | *tp = 't'; |
88 | err = os_access(line, OS_ACC_RW_OK); | 98 | err = access(line, R_OK | W_OK); |
89 | *tp = 'p'; | 99 | *tp = 'p'; |
90 | if(err == 0) return(master); | 100 | if(!err) |
91 | (void) os_close_file(master); | 101 | return master; |
102 | close(master); | ||
92 | } | 103 | } |
93 | } | 104 | } |
94 | } | 105 | } |
95 | return(-1); | 106 | |
107 | printk(UM_KERN_ERR "getmaster - no usable host pty devices\n"); | ||
108 | return -ENOENT; | ||
96 | } | 109 | } |
97 | 110 | ||
98 | static int pty_open(int input, int output, int primary, void *d, | 111 | static int pty_open(int input, int output, int primary, void *d, |
@@ -103,20 +116,22 @@ static int pty_open(int input, int output, int primary, void *d, | |||
103 | char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; | 116 | char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; |
104 | 117 | ||
105 | fd = getmaster(dev); | 118 | fd = getmaster(dev); |
106 | if(fd < 0) | 119 | if (fd < 0) |
107 | return(-errno); | 120 | return fd; |
108 | 121 | ||
109 | if(data->raw){ | 122 | if(data->raw){ |
110 | err = raw(fd); | 123 | err = raw(fd); |
111 | if(err) | 124 | if (err) |
112 | return(err); | 125 | return err; |
113 | } | 126 | } |
114 | 127 | ||
115 | if(data->announce) (*data->announce)(dev, data->dev); | 128 | if (data->announce) |
129 | (*data->announce)(dev, data->dev); | ||
116 | 130 | ||
117 | sprintf(data->dev_name, "%s", dev); | 131 | sprintf(data->dev_name, "%s", dev); |
118 | *dev_out = data->dev_name; | 132 | *dev_out = data->dev_name; |
119 | return(fd); | 133 | |
134 | return fd; | ||
120 | } | 135 | } |
121 | 136 | ||
122 | const struct chan_ops pty_ops = { | 137 | const struct chan_ops pty_ops = { |
@@ -144,14 +159,3 @@ const struct chan_ops pts_ops = { | |||
144 | .free = generic_free, | 159 | .free = generic_free, |
145 | .winch = 0, | 160 | .winch = 0, |
146 | }; | 161 | }; |
147 | |||
148 | /* | ||
149 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
150 | * Emacs will notice this stuff at the end of the file and automatically | ||
151 | * adjust the settings for this buffer only. This must remain at the end | ||
152 | * of the file. | ||
153 | * --------------------------------------------------------------------------- | ||
154 | * Local variables: | ||
155 | * c-file-style: "linux" | ||
156 | * End: | ||
157 | */ | ||