This source file includes following definitions.
- sockaddr_un_printk
- unix_data_lookup
- unix_data_alloc
- unix_data_ref
- unix_data_deref
- unix_proto_create
- unix_proto_dup
- unix_proto_release
- unix_proto_bind
- unix_proto_connect
- unix_proto_socketpair
- unix_proto_accept
- unix_proto_getname
- unix_proto_read
- unix_proto_write
- unix_proto_select
- unix_proto_ioctl
- unix_proto_init
1 #include <linux/signal.h>
2 #include <linux/sched.h>
3 #include <linux/kernel.h>
4 #include <linux/errno.h>
5 #include <linux/string.h>
6 #include <linux/stat.h>
7 #include <linux/socket.h>
8 #include <linux/un.h>
9 #include <linux/fcntl.h>
10 #include <linux/termios.h>
11
12 #include <asm/system.h>
13 #include <asm/segment.h>
14
15 #include "kern_sock.h"
16
17 static struct unix_proto_data {
18 int refcnt;
19 struct socket *socket;
20 int protocol;
21 struct sockaddr_un sockaddr_un;
22 short sockaddr_len;
23 char *buf;
24 int bp_head, bp_tail;
25 struct inode *inode;
26 struct unix_proto_data *peerupd;
27 } unix_datas[NSOCKETS];
28 #define last_unix_data (unix_datas + NSOCKETS - 1)
29
30 #define UN_DATA(SOCK) ((struct unix_proto_data *)(SOCK)->data)
31 #define UN_PATH_OFFSET ((unsigned long)((struct sockaddr_un *)0)->sun_path)
32
33
34
35
36
37
38 #define BUF_SIZE PAGE_SIZE
39 #define UN_BUF_AVAIL(UPD) (((UPD)->bp_head - (UPD)->bp_tail) & (BUF_SIZE-1))
40 #define UN_BUF_SPACE(UPD) ((BUF_SIZE-1) - UN_BUF_AVAIL(UPD))
41
42 static int unix_proto_init(void);
43 static int unix_proto_create(struct socket *sock, int protocol);
44 static int unix_proto_dup(struct socket *newsock, struct socket *oldsock);
45 static int unix_proto_release(struct socket *sock, struct socket *peer);
46 static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
47 int sockaddr_len);
48 static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
49 int sockaddr_len);
50 static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2);
51 static int unix_proto_accept(struct socket *sock, struct socket *newsock);
52 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
53 int *usockaddr_len, int peer);
54 static int unix_proto_read(struct socket *sock, char *ubuf, int size,
55 int nonblock);
56 static int unix_proto_write(struct socket *sock, char *ubuf, int size,
57 int nonblock);
58 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait);
59 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd,
60 unsigned long arg);
61
62 struct proto_ops unix_proto_ops = {
63 unix_proto_init,
64 unix_proto_create,
65 unix_proto_dup,
66 unix_proto_release,
67 unix_proto_bind,
68 unix_proto_connect,
69 unix_proto_socketpair,
70 unix_proto_accept,
71 unix_proto_getname,
72 unix_proto_read,
73 unix_proto_write,
74 unix_proto_select,
75 unix_proto_ioctl
76 };
77
78 #ifdef SOCK_DEBUG
79 void
80 sockaddr_un_printk(struct sockaddr_un *sockun, int sockaddr_len)
81 {
82 char buf[sizeof(sockun->sun_path) + 1];
83
84 sockaddr_len -= UN_PATH_OFFSET;
85 if (sockun->sun_family != AF_UNIX)
86 printk("sockaddr_un: <BAD FAMILY: %d>\n", sockun->sun_family);
87 else if (sockaddr_len <= 0 || sockaddr_len >= sizeof(buf)-1)
88 printk("sockaddr_un: <BAD LENGTH: %d>\n", sockaddr_len);
89 else {
90 memcpy(buf, sockun->sun_path, sockaddr_len);
91 buf[sockaddr_len] = '\0';
92 printk("sockaddr_un: '%s'[%d]\n", buf,
93 sockaddr_len + UN_PATH_OFFSET);
94 }
95 }
96 #endif
97
98 static struct unix_proto_data *
99 unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len)
100 {
101 struct unix_proto_data *upd;
102
103 for (upd = unix_datas; upd <= last_unix_data; ++upd) {
104 if (upd->refcnt && upd->socket &&
105 upd->sockaddr_len == sockaddr_len &&
106 memcmp(&upd->sockaddr_un, sockun, sockaddr_len) == 0)
107 return upd;
108 }
109 return NULL;
110 }
111
112 static struct unix_proto_data *
113 unix_data_alloc(void)
114 {
115 struct unix_proto_data *upd;
116
117 cli();
118 for (upd = unix_datas; upd <= last_unix_data; ++upd) {
119 if (!upd->refcnt) {
120 upd->refcnt = 1;
121 sti();
122 upd->socket = NULL;
123 upd->sockaddr_len = 0;
124 upd->buf = NULL;
125 upd->bp_head = upd->bp_tail = 0;
126 upd->inode = NULL;
127 upd->peerupd = NULL;
128 return upd;
129 }
130 }
131 sti();
132 return NULL;
133 }
134
135 static inline void
136 unix_data_ref(struct unix_proto_data *upd)
137 {
138 ++upd->refcnt;
139 PRINTK("unix_data_ref: refing data 0x%x (%d)\n", upd, upd->refcnt);
140 }
141
142 static void
143 unix_data_deref(struct unix_proto_data *upd)
144 {
145 if (upd->refcnt == 1) {
146 PRINTK("unix_data_deref: releasing data 0x%x\n", upd);
147 if (upd->buf) {
148 free_page((unsigned long)upd->buf);
149 upd->buf = NULL;
150 upd->bp_head = upd->bp_tail = 0;
151 }
152 }
153 --upd->refcnt;
154 }
155
156
157
158
159
160 static int
161 unix_proto_create(struct socket *sock, int protocol)
162 {
163 struct unix_proto_data *upd;
164
165 PRINTK("unix_proto_create: socket 0x%x, proto %d\n", sock, protocol);
166 if (protocol != 0) {
167 PRINTK("unix_proto_create: protocol != 0\n");
168 return -EINVAL;
169 }
170 if (!(upd = unix_data_alloc())) {
171 printk("unix_proto_create: can't allocate buffer\n");
172 return -ENOMEM;
173 }
174 if (!(upd->buf = (char *)get_free_page(GFP_USER))) {
175 printk("unix_proto_create: can't get page!\n");
176 unix_data_deref(upd);
177 return -ENOMEM;
178 }
179 upd->protocol = protocol;
180 upd->socket = sock;
181 UN_DATA(sock) = upd;
182 PRINTK("unix_proto_create: allocated data 0x%x\n", upd);
183 return 0;
184 }
185
186 static int
187 unix_proto_dup(struct socket *newsock, struct socket *oldsock)
188 {
189 struct unix_proto_data *upd = UN_DATA(oldsock);
190
191 return unix_proto_create(newsock, upd->protocol);
192 }
193
194 static int
195 unix_proto_release(struct socket *sock, struct socket *peer)
196 {
197 struct unix_proto_data *upd = UN_DATA(sock);
198
199 PRINTK("unix_proto_release: socket 0x%x, unix_data 0x%x\n",
200 sock, upd);
201 if (!upd)
202 return 0;
203 if (upd->socket != sock) {
204 printk("unix_proto_release: socket link mismatch!\n");
205 return -EINVAL;
206 }
207 if (upd->inode) {
208 PRINTK("unix_proto_release: releasing inode 0x%x\n",
209 upd->inode);
210 iput(upd->inode);
211 upd->inode = NULL;
212 }
213 UN_DATA(sock) = NULL;
214 upd->socket = NULL;
215 if (upd->peerupd)
216 unix_data_deref(upd->peerupd);
217 unix_data_deref(upd);
218 return 0;
219 }
220
221
222
223
224
225
226
227
228
229
230 static int
231 unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
232 int sockaddr_len)
233 {
234 struct unix_proto_data *upd = UN_DATA(sock);
235 char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
236 int i;
237 unsigned long old_fs;
238
239 PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock,
240 sockaddr_len);
241 if (sockaddr_len <= UN_PATH_OFFSET ||
242 sockaddr_len >= sizeof(struct sockaddr_un)) {
243 PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len);
244 return -EINVAL;
245 }
246 if (upd->sockaddr_len || upd->inode) {
247 printk("unix_proto_bind: already bound!\n");
248 return -EINVAL;
249 }
250 verify_area(umyaddr, sockaddr_len);
251 memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
252 if (upd->sockaddr_un.sun_family != AF_UNIX) {
253 PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
254 upd->sockaddr_un.sun_family, AF_UNIX);
255 return -EINVAL;
256 }
257
258 memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
259 fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
260 old_fs = get_fs();
261 set_fs(get_ds());
262 i = do_mknod(fname, S_IFSOCK | 0777, 0);
263 if (i == 0)
264 i = open_namei(fname, 0, S_IFSOCK, &upd->inode);
265 set_fs(old_fs);
266 if (i < 0) {
267 printk("unix_proto_bind: can't open socket %s\n", fname);
268 return i;
269 }
270
271 upd->sockaddr_len = sockaddr_len;
272 PRINTK("unix_proto_bind: bound socket address: ");
273 #ifdef SOCK_DEBUG
274 sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
275 #endif
276 return 0;
277 }
278
279
280
281
282
283 static int
284 unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
285 int sockaddr_len)
286 {
287 int i;
288 struct unix_proto_data *serv_upd;
289 struct sockaddr_un sockun;
290
291 PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
292 sockaddr_len);
293 if (sockaddr_len <= UN_PATH_OFFSET ||
294 sockaddr_len >= sizeof(struct sockaddr_un)) {
295 PRINTK("unix_proto_connect: bad length %d\n", sockaddr_len);
296 return -EINVAL;
297 }
298 verify_area(uservaddr, sockaddr_len);
299 memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
300 if (sockun.sun_family != AF_UNIX) {
301 PRINTK("unix_proto_connect: family is %d, not AF_UNIX (%d)\n",
302 sockun.sun_family, AF_UNIX);
303 return -EINVAL;
304 }
305 if (!(serv_upd = unix_data_lookup(&sockun, sockaddr_len))) {
306 PRINTK("unix_proto_connect: can't locate peer\n");
307 return -EINVAL;
308 }
309 if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
310 PRINTK("unix_proto_connect: can't await connection\n");
311 return i;
312 }
313 unix_data_ref(UN_DATA(sock->conn));
314 UN_DATA(sock)->peerupd = UN_DATA(sock->conn);
315 return 0;
316 }
317
318
319
320
321
322
323
324 static int
325 unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
326 {
327 struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
328
329 unix_data_ref(upd1);
330 unix_data_ref(upd2);
331 upd1->peerupd = upd2;
332 upd2->peerupd = upd1;
333 return 0;
334 }
335
336
337
338
339 static int
340 unix_proto_accept(struct socket *sock, struct socket *newsock)
341 {
342 PRINTK("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n",
343 sock, newsock);
344 unix_data_ref(UN_DATA(newsock->conn));
345 UN_DATA(newsock)->peerupd = UN_DATA(newsock->conn);
346 return 0;
347 }
348
349
350
351
352 static int
353 unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
354 int *usockaddr_len, int peer)
355 {
356 struct unix_proto_data *upd;
357 int len;
358
359 PRINTK("unix_proto_getname: socket 0x%x for %s\n", sock,
360 peer ? "peer" : "self");
361 if (peer) {
362 if (sock->state != SS_CONNECTED) {
363 PRINTK("unix_proto_getname: socket not connected\n");
364 return -EINVAL;
365 }
366 upd = UN_DATA(sock->conn);
367 }
368 else
369 upd = UN_DATA(sock);
370 verify_area(usockaddr_len, sizeof(*usockaddr_len));
371 if ((len = get_fs_long(usockaddr_len)) <= 0)
372 return -EINVAL;
373 if (len > upd->sockaddr_len)
374 len = upd->sockaddr_len;
375 if (len) {
376 verify_area(usockaddr, len);
377 memcpy_tofs(usockaddr, &upd->sockaddr_un, len);
378 }
379 put_fs_long(len, usockaddr_len);
380 return 0;
381 }
382
383
384
385
386 static int
387 unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
388 {
389 struct unix_proto_data *upd;
390 int todo, avail;
391
392 if ((todo = size) <= 0)
393 return 0;
394 upd = UN_DATA(sock);
395 while (!(avail = UN_BUF_AVAIL(upd))) {
396 if (sock->state != SS_CONNECTED) {
397 PRINTK("unix_proto_read: socket not connected\n");
398 return (sock->state == SS_DISCONNECTING) ? 0 : -EINVAL;
399 }
400 PRINTK("unix_proto_read: no data available...\n");
401 if (nonblock)
402 return -EAGAIN;
403 interruptible_sleep_on(sock->wait);
404 if (current->signal & ~current->blocked) {
405 PRINTK("unix_proto_read: interrupted\n");
406 return -ERESTARTSYS;
407 }
408 if (sock->state == SS_DISCONNECTING) {
409 PRINTK("unix_proto_read: disconnected\n");
410 return 0;
411 }
412 }
413
414
415
416
417
418 do {
419 int part, cando;
420
421 if (avail <= 0) {
422 PRINTK("unix_proto_read: AVAIL IS NEGATIVE!!!\n");
423 send_sig(SIGKILL,current,1);
424 return -EINTR;
425 }
426
427 if ((cando = todo) > avail)
428 cando = avail;
429 if (cando > (part = BUF_SIZE - upd->bp_tail))
430 cando = part;
431 PRINTK("unix_proto_read: avail=%d, todo=%d, cando=%d\n",
432 avail, todo, cando);
433 verify_area(ubuf, cando);
434 memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
435 upd->bp_tail = (upd->bp_tail + cando) & (BUF_SIZE-1);
436 ubuf += cando;
437 todo -= cando;
438 if (sock->state == SS_CONNECTED)
439 wake_up(sock->conn->wait);
440 avail = UN_BUF_AVAIL(upd);
441 } while (todo && avail);
442 return size - todo;
443 }
444
445
446
447
448
449
450 static int
451 unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
452 {
453 struct unix_proto_data *pupd;
454 int todo, space;
455
456 if ((todo = size) <= 0)
457 return 0;
458 if (sock->state != SS_CONNECTED) {
459 PRINTK("unix_proto_write: socket not connected\n");
460 if (sock->state == SS_DISCONNECTING) {
461 send_sig(SIGPIPE,current,1);
462 return -EINTR;
463 }
464 return -EINVAL;
465 }
466 pupd = UN_DATA(sock)->peerupd;
467
468 while (!(space = UN_BUF_SPACE(pupd))) {
469 PRINTK("unix_proto_write: no space left...\n");
470 if (nonblock)
471 return -EAGAIN;
472 interruptible_sleep_on(sock->wait);
473 if (current->signal & ~current->blocked) {
474 PRINTK("unix_proto_write: interrupted\n");
475 return -ERESTARTSYS;
476 }
477 if (sock->state == SS_DISCONNECTING) {
478 PRINTK("unix_proto_write: disconnected (SIGPIPE)\n");
479 send_sig(SIGPIPE,current,1);
480 return -EINTR;
481 }
482 }
483
484
485
486
487
488 do {
489 int part, cando;
490
491 if (space <= 0) {
492 PRINTK("unix_proto_write: SPACE IS NEGATIVE!!!\n");
493 send_sig(SIGKILL,current,1);
494 return -EINTR;
495 }
496
497
498
499
500
501 if (sock->state == SS_DISCONNECTING) {
502 send_sig(SIGPIPE,current,1);
503 return -EINTR;
504 }
505 if ((cando = todo) > space)
506 cando = space;
507 if (cando > (part = BUF_SIZE - pupd->bp_head))
508 cando = part;
509 PRINTK("unix_proto_write: space=%d, todo=%d, cando=%d\n",
510 space, todo, cando);
511 verify_area(ubuf, cando);
512 memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
513 pupd->bp_head = (pupd->bp_head + cando) & (BUF_SIZE-1);
514 ubuf += cando;
515 todo -= cando;
516 if (sock->state == SS_CONNECTED)
517 wake_up(sock->conn->wait);
518 space = UN_BUF_SPACE(pupd);
519 } while (todo && space);
520 return size - todo;
521 }
522
523 static int
524 unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
525 {
526 struct unix_proto_data *upd, *peerupd;
527
528 if (sel_type == SEL_IN) {
529 upd = UN_DATA(sock);
530 PRINTK("unix_proto_select: there is%s data available\n",
531 UN_BUF_AVAIL(upd) ? "" : " no");
532 if (UN_BUF_AVAIL(upd))
533 return 1;
534 else if (sock->state != SS_CONNECTED) {
535 PRINTK("unix_proto_select: socket not connected (read EOF)\n");
536 return 1;
537 }
538 select_wait(sock->wait,wait);
539 return 0;
540 }
541 if (sel_type == SEL_OUT) {
542 if (sock->state != SS_CONNECTED) {
543 PRINTK("unix_proto_select: socket not connected (write EOF)\n");
544 return 1;
545 }
546 peerupd = UN_DATA(sock->conn);
547 PRINTK("unix_proto_select: there is%s space available\n",
548 UN_BUF_SPACE(peerupd) ? "" : " no");
549 if (UN_BUF_SPACE(peerupd) > 0)
550 return 1;
551 select_wait(sock->wait,wait);
552 return 0;
553 }
554
555 PRINTK("unix_proto_select: there are no exceptions here?!\n");
556 return 0;
557 }
558
559 static int
560 unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
561 {
562 struct unix_proto_data *upd, *peerupd;
563
564 upd = UN_DATA(sock);
565 peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
566
567 switch (cmd) {
568 case TIOCINQ:
569 verify_area((void *)arg, sizeof(unsigned long));
570 if (UN_BUF_AVAIL(upd) || peerupd)
571 put_fs_long(UN_BUF_AVAIL(upd), (unsigned long *)arg);
572 else
573 put_fs_long(1, (unsigned long *)arg);
574 break;
575
576 case TIOCOUTQ:
577 verify_area((void *)arg, sizeof(unsigned long));
578 if (peerupd)
579 put_fs_long(UN_BUF_SPACE(peerupd),
580 (unsigned long *)arg);
581 else
582 put_fs_long(0, (unsigned long *)arg);
583 break;
584
585 default:
586 return -EINVAL;
587 }
588 return 0;
589 }
590
591 static int
592 unix_proto_init(void)
593 {
594 struct unix_proto_data *upd;
595
596 PRINTK("unix_proto_init: initializing...\n");
597 for (upd = unix_datas; upd <= last_unix_data; ++upd)
598 upd->refcnt = 0;
599 return 0;
600 }