aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/drivers/pty.c76
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
18struct pty_chan { 20struct 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
38static int pts_open(int input, int output, int primary, void *d, 42static 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
69static int getmaster(char *line) 76static 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
98static int pty_open(int input, int output, int primary, void *d, 111static 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
122const struct chan_ops pty_ops = { 137const 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 */