Commit 7b033e1fdeef3d8bacac3cd5cfa53c9d670d1f3d

Authored by Jeff Dike
Committed by Linus Torvalds
1 parent 44700a4469

[PATCH] uml: add mconsole_reply variant with length param

This is needed for the console output patch, since we have a possibly
non-NULL-terminated string there.  So, the new interface takes a string and a
length, and the old interface calls strlen on its string and calls the new
interface with the length.

There's also a bit of whitespace cleanup.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 2 changed files with 14 additions and 6 deletions Inline Diff

arch/um/drivers/mconsole_user.c
1 /* 1 /*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
3 * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) 3 * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <errno.h> 9 #include <errno.h>
10 #include <signal.h> 10 #include <signal.h>
11 #include <sys/socket.h> 11 #include <sys/socket.h>
12 #include <sys/types.h> 12 #include <sys/types.h>
13 #include <sys/uio.h> 13 #include <sys/uio.h>
14 #include <sys/un.h> 14 #include <sys/un.h>
15 #include <unistd.h> 15 #include <unistd.h>
16 #include "user.h" 16 #include "user.h"
17 #include "mconsole.h" 17 #include "mconsole.h"
18 #include "umid.h" 18 #include "umid.h"
19 19
20 static struct mconsole_command commands[] = { 20 static struct mconsole_command commands[] = {
21 { "version", mconsole_version, MCONSOLE_INTR }, 21 { "version", mconsole_version, MCONSOLE_INTR },
22 { "halt", mconsole_halt, MCONSOLE_PROC }, 22 { "halt", mconsole_halt, MCONSOLE_PROC },
23 { "reboot", mconsole_reboot, MCONSOLE_PROC }, 23 { "reboot", mconsole_reboot, MCONSOLE_PROC },
24 { "config", mconsole_config, MCONSOLE_PROC }, 24 { "config", mconsole_config, MCONSOLE_PROC },
25 { "remove", mconsole_remove, MCONSOLE_PROC }, 25 { "remove", mconsole_remove, MCONSOLE_PROC },
26 { "sysrq", mconsole_sysrq, MCONSOLE_INTR }, 26 { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
27 { "help", mconsole_help, MCONSOLE_INTR }, 27 { "help", mconsole_help, MCONSOLE_INTR },
28 { "cad", mconsole_cad, MCONSOLE_INTR }, 28 { "cad", mconsole_cad, MCONSOLE_INTR },
29 { "stop", mconsole_stop, MCONSOLE_PROC }, 29 { "stop", mconsole_stop, MCONSOLE_PROC },
30 { "go", mconsole_go, MCONSOLE_INTR }, 30 { "go", mconsole_go, MCONSOLE_INTR },
31 { "log", mconsole_log, MCONSOLE_INTR }, 31 { "log", mconsole_log, MCONSOLE_INTR },
32 { "proc", mconsole_proc, MCONSOLE_PROC }, 32 { "proc", mconsole_proc, MCONSOLE_PROC },
33 { "stack", mconsole_stack, MCONSOLE_INTR }, 33 { "stack", mconsole_stack, MCONSOLE_INTR },
34 }; 34 };
35 35
36 /* Initialized in mconsole_init, which is an initcall */ 36 /* Initialized in mconsole_init, which is an initcall */
37 char mconsole_socket_name[256]; 37 char mconsole_socket_name[256];
38 38
39 int mconsole_reply_v0(struct mc_request *req, char *reply) 39 int mconsole_reply_v0(struct mc_request *req, char *reply)
40 { 40 {
41 struct iovec iov; 41 struct iovec iov;
42 struct msghdr msg; 42 struct msghdr msg;
43 43
44 iov.iov_base = reply; 44 iov.iov_base = reply;
45 iov.iov_len = strlen(reply); 45 iov.iov_len = strlen(reply);
46 46
47 msg.msg_name = &(req->origin); 47 msg.msg_name = &(req->origin);
48 msg.msg_namelen = req->originlen; 48 msg.msg_namelen = req->originlen;
49 msg.msg_iov = &iov; 49 msg.msg_iov = &iov;
50 msg.msg_iovlen = 1; 50 msg.msg_iovlen = 1;
51 msg.msg_control = NULL; 51 msg.msg_control = NULL;
52 msg.msg_controllen = 0; 52 msg.msg_controllen = 0;
53 msg.msg_flags = 0; 53 msg.msg_flags = 0;
54 54
55 return sendmsg(req->originating_fd, &msg, 0); 55 return sendmsg(req->originating_fd, &msg, 0);
56 } 56 }
57 57
58 static struct mconsole_command *mconsole_parse(struct mc_request *req) 58 static struct mconsole_command *mconsole_parse(struct mc_request *req)
59 { 59 {
60 struct mconsole_command *cmd; 60 struct mconsole_command *cmd;
61 int i; 61 int i;
62 62
63 for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){ 63 for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){
64 cmd = &commands[i]; 64 cmd = &commands[i];
65 if(!strncmp(req->request.data, cmd->command, 65 if(!strncmp(req->request.data, cmd->command,
66 strlen(cmd->command))){ 66 strlen(cmd->command))){
67 return(cmd); 67 return(cmd);
68 } 68 }
69 } 69 }
70 return(NULL); 70 return(NULL);
71 } 71 }
72 72
73 #define MIN(a,b) ((a)<(b) ? (a):(b)) 73 #define MIN(a,b) ((a)<(b) ? (a):(b))
74 74
75 #define STRINGX(x) #x 75 #define STRINGX(x) #x
76 #define STRING(x) STRINGX(x) 76 #define STRING(x) STRINGX(x)
77 77
78 int mconsole_get_request(int fd, struct mc_request *req) 78 int mconsole_get_request(int fd, struct mc_request *req)
79 { 79 {
80 int len; 80 int len;
81 81
82 req->originlen = sizeof(req->origin); 82 req->originlen = sizeof(req->origin);
83 req->len = recvfrom(fd, &req->request, sizeof(req->request), 0, 83 req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
84 (struct sockaddr *) req->origin, &req->originlen); 84 (struct sockaddr *) req->origin, &req->originlen);
85 if (req->len < 0) 85 if (req->len < 0)
86 return 0; 86 return 0;
87 87
88 req->originating_fd = fd; 88 req->originating_fd = fd;
89 89
90 if(req->request.magic != MCONSOLE_MAGIC){ 90 if(req->request.magic != MCONSOLE_MAGIC){
91 /* Unversioned request */ 91 /* Unversioned request */
92 len = MIN(sizeof(req->request.data) - 1, 92 len = MIN(sizeof(req->request.data) - 1,
93 strlen((char *) &req->request)); 93 strlen((char *) &req->request));
94 memmove(req->request.data, &req->request, len); 94 memmove(req->request.data, &req->request, len);
95 req->request.data[len] = '\0'; 95 req->request.data[len] = '\0';
96 96
97 req->request.magic = MCONSOLE_MAGIC; 97 req->request.magic = MCONSOLE_MAGIC;
98 req->request.version = 0; 98 req->request.version = 0;
99 req->request.len = len; 99 req->request.len = len;
100 100
101 mconsole_reply_v0(req, "ERR Version 0 mconsole clients are " 101 mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
102 "not supported by this driver"); 102 "not supported by this driver");
103 return(0); 103 return(0);
104 } 104 }
105 105
106 if(req->request.len >= MCONSOLE_MAX_DATA){ 106 if(req->request.len >= MCONSOLE_MAX_DATA){
107 mconsole_reply(req, "Request too large", 1, 0); 107 mconsole_reply(req, "Request too large", 1, 0);
108 return(0); 108 return(0);
109 } 109 }
110 if(req->request.version != MCONSOLE_VERSION){ 110 if(req->request.version != MCONSOLE_VERSION){
111 mconsole_reply(req, "This driver only supports version " 111 mconsole_reply(req, "This driver only supports version "
112 STRING(MCONSOLE_VERSION) " clients", 1, 0); 112 STRING(MCONSOLE_VERSION) " clients", 1, 0);
113 } 113 }
114 114
115 req->request.data[req->request.len] = '\0'; 115 req->request.data[req->request.len] = '\0';
116 req->cmd = mconsole_parse(req); 116 req->cmd = mconsole_parse(req);
117 if(req->cmd == NULL){ 117 if(req->cmd == NULL){
118 mconsole_reply(req, "Unknown command", 1, 0); 118 mconsole_reply(req, "Unknown command", 1, 0);
119 return(0); 119 return(0);
120 } 120 }
121 121
122 return(1); 122 return(1);
123 } 123 }
124 124
125 int mconsole_reply(struct mc_request *req, char *str, int err, int more) 125 int mconsole_reply_len(struct mc_request *req, const char *str, int total,
126 int err, int more)
126 { 127 {
127 struct mconsole_reply reply; 128 struct mconsole_reply reply;
128 int total, len, n; 129 int len, n;
129 130
130 total = strlen(str);
131 do { 131 do {
132 reply.err = err; 132 reply.err = err;
133 133
134 /* err can only be true on the first packet */ 134 /* err can only be true on the first packet */
135 err = 0; 135 err = 0;
136 136
137 len = MIN(total, MCONSOLE_MAX_DATA - 1); 137 len = MIN(total, MCONSOLE_MAX_DATA - 1);
138 138
139 if(len == total) reply.more = more; 139 if(len == total) reply.more = more;
140 else reply.more = 1; 140 else reply.more = 1;
141 141
142 memcpy(reply.data, str, len); 142 memcpy(reply.data, str, len);
143 reply.data[len] = '\0'; 143 reply.data[len] = '\0';
144 total -= len; 144 total -= len;
145 str += len; 145 str += len;
146 reply.len = len + 1; 146 reply.len = len + 1;
147 147
148 len = sizeof(reply) + reply.len - sizeof(reply.data); 148 len = sizeof(reply) + reply.len - sizeof(reply.data);
149 149
150 n = sendto(req->originating_fd, &reply, len, 0, 150 n = sendto(req->originating_fd, &reply, len, 0,
151 (struct sockaddr *) req->origin, req->originlen); 151 (struct sockaddr *) req->origin, req->originlen);
152 152
153 if(n < 0) return(-errno); 153 if(n < 0) return(-errno);
154 } while(total > 0); 154 } while(total > 0);
155 return(0); 155 return(0);
156 } 156 }
157
158 int mconsole_reply(struct mc_request *req, const char *str, int err, int more)
159 {
160 return mconsole_reply_len(req, str, strlen(str), err, more);
161 }
162
157 163
158 int mconsole_unlink_socket(void) 164 int mconsole_unlink_socket(void)
159 { 165 {
160 unlink(mconsole_socket_name); 166 unlink(mconsole_socket_name);
161 return 0; 167 return 0;
162 } 168 }
163 169
164 static int notify_sock = -1; 170 static int notify_sock = -1;
165 171
166 int mconsole_notify(char *sock_name, int type, const void *data, int len) 172 int mconsole_notify(char *sock_name, int type, const void *data, int len)
167 { 173 {
168 struct sockaddr_un target; 174 struct sockaddr_un target;
169 struct mconsole_notify packet; 175 struct mconsole_notify packet;
170 int n, err = 0; 176 int n, err = 0;
171 177
172 lock_notify(); 178 lock_notify();
173 if(notify_sock < 0){ 179 if(notify_sock < 0){
174 notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0); 180 notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
175 if(notify_sock < 0){ 181 if(notify_sock < 0){
176 err = -errno; 182 err = -errno;
177 printk("mconsole_notify - socket failed, errno = %d\n", 183 printk("mconsole_notify - socket failed, errno = %d\n",
178 err); 184 err);
179 } 185 }
180 } 186 }
181 unlock_notify(); 187 unlock_notify();
182 188
183 if(err) 189 if(err)
184 return(err); 190 return(err);
185 191
186 target.sun_family = AF_UNIX; 192 target.sun_family = AF_UNIX;
187 strcpy(target.sun_path, sock_name); 193 strcpy(target.sun_path, sock_name);
188 194
189 packet.magic = MCONSOLE_MAGIC; 195 packet.magic = MCONSOLE_MAGIC;
190 packet.version = MCONSOLE_VERSION; 196 packet.version = MCONSOLE_VERSION;
191 packet.type = type; 197 packet.type = type;
192 len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len; 198 len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
193 packet.len = len; 199 packet.len = len;
194 memcpy(packet.data, data, len); 200 memcpy(packet.data, data, len);
195 201
196 err = 0; 202 err = 0;
197 len = sizeof(packet) + packet.len - sizeof(packet.data); 203 len = sizeof(packet) + packet.len - sizeof(packet.data);
198 n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, 204 n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
199 sizeof(target)); 205 sizeof(target));
200 if(n < 0){ 206 if(n < 0){
201 err = -errno; 207 err = -errno;
202 printk("mconsole_notify - sendto failed, errno = %d\n", errno); 208 printk("mconsole_notify - sendto failed, errno = %d\n", errno);
203 } 209 }
204 return(err); 210 return(err);
205 } 211 }
206 212
207 /* 213 /*
208 * Overrides for Emacs so that we follow Linus's tabbing style. 214 * Overrides for Emacs so that we follow Linus's tabbing style.
209 * Emacs will notice this stuff at the end of the file and automatically 215 * Emacs will notice this stuff at the end of the file and automatically
210 * adjust the settings for this buffer only. This must remain at the end 216 * adjust the settings for this buffer only. This must remain at the end
211 * of the file. 217 * of the file.
212 * --------------------------------------------------------------------------- 218 * ---------------------------------------------------------------------------
213 * Local variables: 219 * Local variables:
214 * c-file-style: "linux" 220 * c-file-style: "linux"
215 * End: 221 * End:
216 */ 222 */
arch/um/include/mconsole.h
1 /* 1 /*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
3 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 3 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7 #ifndef __MCONSOLE_H__ 7 #ifndef __MCONSOLE_H__
8 #define __MCONSOLE_H__ 8 #define __MCONSOLE_H__
9 9
10 #ifndef __KERNEL__ 10 #ifndef __KERNEL__
11 #include <stdint.h> 11 #include <stdint.h>
12 #define u32 uint32_t 12 #define u32 uint32_t
13 #endif 13 #endif
14 14
15 #define MCONSOLE_MAGIC (0xcafebabe) 15 #define MCONSOLE_MAGIC (0xcafebabe)
16 #define MCONSOLE_MAX_DATA (512) 16 #define MCONSOLE_MAX_DATA (512)
17 #define MCONSOLE_VERSION 2 17 #define MCONSOLE_VERSION 2
18 18
19 struct mconsole_request { 19 struct mconsole_request {
20 u32 magic; 20 u32 magic;
21 u32 version; 21 u32 version;
22 u32 len; 22 u32 len;
23 char data[MCONSOLE_MAX_DATA]; 23 char data[MCONSOLE_MAX_DATA];
24 }; 24 };
25 25
26 struct mconsole_reply { 26 struct mconsole_reply {
27 u32 err; 27 u32 err;
28 u32 more; 28 u32 more;
29 u32 len; 29 u32 len;
30 char data[MCONSOLE_MAX_DATA]; 30 char data[MCONSOLE_MAX_DATA];
31 }; 31 };
32 32
33 struct mconsole_notify { 33 struct mconsole_notify {
34 u32 magic; 34 u32 magic;
35 u32 version; 35 u32 version;
36 enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG, 36 enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
37 MCONSOLE_USER_NOTIFY } type; 37 MCONSOLE_USER_NOTIFY } type;
38 u32 len; 38 u32 len;
39 char data[MCONSOLE_MAX_DATA]; 39 char data[MCONSOLE_MAX_DATA];
40 }; 40 };
41 41
42 struct mc_request; 42 struct mc_request;
43 43
44 enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC }; 44 enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
45 45
46 struct mconsole_command 46 struct mconsole_command
47 { 47 {
48 char *command; 48 char *command;
49 void (*handler)(struct mc_request *req); 49 void (*handler)(struct mc_request *req);
50 enum mc_context context; 50 enum mc_context context;
51 }; 51 };
52 52
53 struct mc_request 53 struct mc_request
54 { 54 {
55 int len; 55 int len;
56 int as_interrupt; 56 int as_interrupt;
57 57
58 int originating_fd; 58 int originating_fd;
59 unsigned int originlen; 59 unsigned int originlen;
60 unsigned char origin[128]; /* sockaddr_un */ 60 unsigned char origin[128]; /* sockaddr_un */
61 61
62 struct mconsole_request request; 62 struct mconsole_request request;
63 struct mconsole_command *cmd; 63 struct mconsole_command *cmd;
64 }; 64 };
65 65
66 extern char mconsole_socket_name[]; 66 extern char mconsole_socket_name[];
67 67
68 extern int mconsole_unlink_socket(void); 68 extern int mconsole_unlink_socket(void);
69 extern int mconsole_reply(struct mc_request *req, char *reply, int err, 69 extern int mconsole_reply_len(struct mc_request *req, const char *reply,
70 int len, int err, int more);
71 extern int mconsole_reply(struct mc_request *req, const char *str, int err,
70 int more); 72 int more);
71 73
72 extern void mconsole_version(struct mc_request *req); 74 extern void mconsole_version(struct mc_request *req);
73 extern void mconsole_help(struct mc_request *req); 75 extern void mconsole_help(struct mc_request *req);
74 extern void mconsole_halt(struct mc_request *req); 76 extern void mconsole_halt(struct mc_request *req);
75 extern void mconsole_reboot(struct mc_request *req); 77 extern void mconsole_reboot(struct mc_request *req);
76 extern void mconsole_config(struct mc_request *req); 78 extern void mconsole_config(struct mc_request *req);
77 extern void mconsole_remove(struct mc_request *req); 79 extern void mconsole_remove(struct mc_request *req);
78 extern void mconsole_sysrq(struct mc_request *req); 80 extern void mconsole_sysrq(struct mc_request *req);
79 extern void mconsole_cad(struct mc_request *req); 81 extern void mconsole_cad(struct mc_request *req);
80 extern void mconsole_stop(struct mc_request *req); 82 extern void mconsole_stop(struct mc_request *req);
81 extern void mconsole_go(struct mc_request *req); 83 extern void mconsole_go(struct mc_request *req);
82 extern void mconsole_log(struct mc_request *req); 84 extern void mconsole_log(struct mc_request *req);
83 extern void mconsole_proc(struct mc_request *req); 85 extern void mconsole_proc(struct mc_request *req);
84 extern void mconsole_stack(struct mc_request *req); 86 extern void mconsole_stack(struct mc_request *req);
85 87
86 extern int mconsole_get_request(int fd, struct mc_request *req); 88 extern int mconsole_get_request(int fd, struct mc_request *req);
87 extern int mconsole_notify(char *sock_name, int type, const void *data, 89 extern int mconsole_notify(char *sock_name, int type, const void *data,
88 int len); 90 int len);
89 extern char *mconsole_notify_socket(void); 91 extern char *mconsole_notify_socket(void);
90 extern void lock_notify(void); 92 extern void lock_notify(void);
91 extern void unlock_notify(void); 93 extern void unlock_notify(void);
92 94
93 #endif 95 #endif
94 96
95 /* 97 /*
96 * Overrides for Emacs so that we follow Linus's tabbing style. 98 * Overrides for Emacs so that we follow Linus's tabbing style.
97 * Emacs will notice this stuff at the end of the file and automatically 99 * Emacs will notice this stuff at the end of the file and automatically
98 * adjust the settings for this buffer only. This must remain at the end 100 * adjust the settings for this buffer only. This must remain at the end
99 * of the file. 101 * of the file.
100 * --------------------------------------------------------------------------- 102 * ---------------------------------------------------------------------------
101 * Local variables: 103 * Local variables:
102 * c-file-style: "linux" 104 * c-file-style: "linux"
103 * End: 105 * End:
104 */ 106 */
105 107