This source file includes following definitions.
- sockaddr_un_printk
- unix_proto_listen
- unix_proto_setsockopt
- unix_proto_getsockopt
- unix_proto_sendto
- unix_proto_recvfrom
- unix_proto_shutdown
- unix_proto_send
- unix_proto_recv
- same_path
- 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, int flags);
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 int flags);
53 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
54 int *usockaddr_len, int peer);
55 static int unix_proto_read(struct socket *sock, char *ubuf, int size,
56 int nonblock);
57 static int unix_proto_write(struct socket *sock, char *ubuf, int size,
58 int nonblock);
59 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait);
60 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd,
61 unsigned long arg);
62 static int unix_proto_listen(struct socket *sock, int backlog);
63 static int unix_proto_send (struct socket *sock, void *buff, int len,
64 int nonblock, unsigned flags);
65 static int unix_proto_recv (struct socket *sock, void *buff, int len,
66 int nonblock, unsigned flags);
67 static int unix_proto_sendto (struct socket *sock, void *buff, int len,
68 int nonblock, unsigned flags,
69 struct sockaddr *addr, int addr_len);
70 static int unix_proto_recvfrom (struct socket *sock, void *buff, int len,
71 int nonblock, unsigned flags,
72 struct sockaddr *addr, int *addr_len);
73
74 static int unix_proto_shutdown (struct socket *sock, int how);
75
76 static int unix_proto_setsockopt (struct socket *sock, int level, int optname,
77 char *optval, int optlen);
78 static int unix_proto_getsockopt (struct socket *sock, int level, int optname,
79 char *optval, int *optlen);
80
81 struct proto_ops unix_proto_ops = {
82 unix_proto_init,
83 unix_proto_create,
84 unix_proto_dup,
85 unix_proto_release,
86 unix_proto_bind,
87 unix_proto_connect,
88 unix_proto_socketpair,
89 unix_proto_accept,
90 unix_proto_getname,
91 unix_proto_read,
92 unix_proto_write,
93 unix_proto_select,
94 unix_proto_ioctl,
95 unix_proto_listen,
96 unix_proto_send,
97 unix_proto_recv,
98 unix_proto_sendto,
99 unix_proto_recvfrom,
100 unix_proto_shutdown,
101 unix_proto_setsockopt,
102 unix_proto_getsockopt,
103 NULL
104 };
105
106 #ifdef SOCK_DEBUG
107 void
108 sockaddr_un_printk(struct sockaddr_un *sockun, int sockaddr_len)
109 {
110 char buf[sizeof(sockun->sun_path) + 1];
111
112 sockaddr_len -= UN_PATH_OFFSET;
113 if (sockun->sun_family != AF_UNIX)
114 printk("sockaddr_un: <BAD FAMILY: %d>\n", sockun->sun_family);
115 else if (sockaddr_len <= 0 || sockaddr_len >= sizeof(buf))
116 printk("sockaddr_un: <BAD LENGTH: %d>\n", sockaddr_len);
117 else {
118 memcpy(buf, sockun->sun_path, sockaddr_len);
119 buf[sockaddr_len] = '\0';
120 printk("sockaddr_un: '%s'[%d]\n", buf,
121 sockaddr_len + UN_PATH_OFFSET);
122 }
123 }
124 #endif
125
126
127 static int
128 unix_proto_listen (struct socket *sock, int backlog)
129 {
130 return (0);
131 }
132
133 static int
134 unix_proto_setsockopt(struct socket *sock, int level, int optname,
135 char *optval, int optlen)
136 {
137 return (-EOPNOTSUPP);
138 }
139
140 static int
141 unix_proto_getsockopt(struct socket *sock, int level, int optname,
142 char *optval, int *optlen)
143 {
144 return (-EOPNOTSUPP);
145 }
146
147 static int
148 unix_proto_sendto(struct socket *sock, void *buff, int len, int nonblock,
149 unsigned flags, struct sockaddr *addr, int addr_len)
150 {
151 return (-EOPNOTSUPP);
152 }
153
154 static int
155 unix_proto_recvfrom(struct socket *sock, void *buff, int len, int nonblock,
156 unsigned flags, struct sockaddr *addr, int *addr_len)
157 {
158 return (-EOPNOTSUPP);
159 }
160
161 static int
162 unix_proto_shutdown (struct socket *sock, int how)
163 {
164 return (-EOPNOTSUPP);
165 }
166
167 static int
168 unix_proto_send(struct socket *sock, void *buff, int len, int nonblock,
169 unsigned flags)
170 {
171
172 if (flags != 0)
173 return (-EINVAL);
174 return (unix_proto_write (sock, buff, len, nonblock));
175 }
176
177 static int
178 unix_proto_recv(struct socket *sock, void *buff, int len, int nonblock,
179 unsigned flags)
180 {
181
182 if (flags != 0)
183 return (-EINVAL);
184 return (unix_proto_read (sock, buff, len, nonblock));
185 }
186
187
188
189
190
191
192 static int
193 same_path(char *s1, int l1, char *s2, int l2)
194 {
195
196
197
198 for (; l1 && l2 && *s1 == *s2; ++s1, ++s2, --l1, --l2);
199
200
201
202
203
204
205 return ((l1 == 0 || *s1 == '\0') && (l2 == 0 || *s2 == '\0'));
206 }
207
208 static struct unix_proto_data *
209 unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len)
210 {
211 struct unix_proto_data *upd;
212
213 for (upd = unix_datas; upd <= last_unix_data; ++upd) {
214 if (upd->refcnt && upd->socket &&
215 upd->socket->state == SS_UNCONNECTED &&
216 upd->sockaddr_un.sun_family == sockun->sun_family &&
217 same_path(sockun->sun_path, sockaddr_len - UN_PATH_OFFSET,
218 upd->sockaddr_un.sun_path,
219 upd->sockaddr_len - UN_PATH_OFFSET))
220 return upd;
221 }
222 return NULL;
223 }
224
225 static struct unix_proto_data *
226 unix_data_alloc(void)
227 {
228 struct unix_proto_data *upd;
229
230 cli();
231 for (upd = unix_datas; upd <= last_unix_data; ++upd) {
232 if (!upd->refcnt) {
233 upd->refcnt = 1;
234 sti();
235 upd->socket = NULL;
236 upd->sockaddr_len = 0;
237 upd->buf = NULL;
238 upd->bp_head = upd->bp_tail = 0;
239 upd->inode = NULL;
240 upd->peerupd = NULL;
241 return upd;
242 }
243 }
244 sti();
245 return NULL;
246 }
247
248 static inline void
249 unix_data_ref(struct unix_proto_data *upd)
250 {
251 ++upd->refcnt;
252 PRINTK("unix_data_ref: refing data 0x%x (%d)\n", upd, upd->refcnt);
253 }
254
255 static void
256 unix_data_deref(struct unix_proto_data *upd)
257 {
258 if (upd->refcnt == 1) {
259 PRINTK("unix_data_deref: releasing data 0x%x\n", upd);
260 if (upd->buf) {
261 free_page((unsigned long)upd->buf);
262 upd->buf = NULL;
263 upd->bp_head = upd->bp_tail = 0;
264 }
265 }
266 --upd->refcnt;
267 }
268
269
270
271
272
273 static int
274 unix_proto_create(struct socket *sock, int protocol)
275 {
276 struct unix_proto_data *upd;
277
278 PRINTK("unix_proto_create: socket 0x%x, proto %d\n", sock, protocol);
279 if (protocol != 0) {
280 PRINTK("unix_proto_create: protocol != 0\n");
281 return -EINVAL;
282 }
283 if (!(upd = unix_data_alloc())) {
284 printk("unix_proto_create: can't allocate buffer\n");
285 return -ENOMEM;
286 }
287 if (!(upd->buf = (char *)get_free_page(GFP_USER))) {
288 printk("unix_proto_create: can't get page!\n");
289 unix_data_deref(upd);
290 return -ENOMEM;
291 }
292 upd->protocol = protocol;
293 upd->socket = sock;
294 UN_DATA(sock) = upd;
295 PRINTK("unix_proto_create: allocated data 0x%x\n", upd);
296 return 0;
297 }
298
299 static int
300 unix_proto_dup(struct socket *newsock, struct socket *oldsock)
301 {
302 struct unix_proto_data *upd = UN_DATA(oldsock);
303
304 return unix_proto_create(newsock, upd->protocol);
305 }
306
307 static int
308 unix_proto_release(struct socket *sock, struct socket *peer)
309 {
310 struct unix_proto_data *upd = UN_DATA(sock);
311
312 PRINTK("unix_proto_release: socket 0x%x, unix_data 0x%x\n",
313 sock, upd);
314 if (!upd)
315 return 0;
316 if (upd->socket != sock) {
317 printk("unix_proto_release: socket link mismatch!\n");
318 return -EINVAL;
319 }
320 if (upd->inode) {
321 PRINTK("unix_proto_release: releasing inode 0x%x\n",
322 upd->inode);
323 iput(upd->inode);
324 upd->inode = NULL;
325 }
326 UN_DATA(sock) = NULL;
327 upd->socket = NULL;
328 if (upd->peerupd)
329 unix_data_deref(upd->peerupd);
330 unix_data_deref(upd);
331 return 0;
332 }
333
334
335
336
337
338
339
340
341
342
343 static int
344 unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
345 int sockaddr_len)
346 {
347 struct unix_proto_data *upd = UN_DATA(sock);
348 char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
349 int i;
350 unsigned long old_fs;
351
352 PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock,
353 sockaddr_len);
354 if (sockaddr_len <= UN_PATH_OFFSET ||
355 sockaddr_len > sizeof(struct sockaddr_un)) {
356 PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len);
357 return -EINVAL;
358 }
359 if (upd->sockaddr_len || upd->inode) {
360 printk("unix_proto_bind: already bound!\n");
361 return -EINVAL;
362 }
363 verify_area(umyaddr, sockaddr_len);
364 memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
365 if (upd->sockaddr_un.sun_family != AF_UNIX) {
366 PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
367 upd->sockaddr_un.sun_family, AF_UNIX);
368 return -EINVAL;
369 }
370
371 memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
372 fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
373 old_fs = get_fs();
374 set_fs(get_ds());
375 i = do_mknod(fname, S_IFSOCK | 0777, 0);
376 if (i == 0)
377 i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
378 set_fs(old_fs);
379 if (i < 0) {
380 printk("unix_proto_bind: can't open socket %s\n", fname);
381 return i;
382 }
383
384 upd->sockaddr_len = sockaddr_len;
385 PRINTK("unix_proto_bind: bound socket address: ");
386 #ifdef SOCK_DEBUG
387 sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
388 #endif
389 return 0;
390 }
391
392
393
394
395
396 static int
397 unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
398 int sockaddr_len, int flags)
399 {
400 int i;
401 struct unix_proto_data *serv_upd;
402 struct sockaddr_un sockun;
403
404 PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
405 sockaddr_len);
406
407 if (sockaddr_len <= UN_PATH_OFFSET ||
408 sockaddr_len > sizeof(struct sockaddr_un)) {
409 PRINTK("unix_proto_connect: bad length %d\n", sockaddr_len);
410 return -EINVAL;
411 }
412
413 if (sock->state == SS_CONNECTING)
414 return (-EINPROGRESS);
415
416 if (sock->state == SS_CONNECTED)
417 return (-EISCONN);
418
419 verify_area(uservaddr, sockaddr_len);
420 memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
421 if (sockun.sun_family != AF_UNIX) {
422 PRINTK("unix_proto_connect: family is %d, not AF_UNIX (%d)\n",
423 sockun.sun_family, AF_UNIX);
424 return -EINVAL;
425 }
426 if (!(serv_upd = unix_data_lookup(&sockun, sockaddr_len))) {
427 PRINTK("unix_proto_connect: can't locate peer\n");
428 return -EINVAL;
429 }
430 if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
431 PRINTK("unix_proto_connect: can't await connection\n");
432 return i;
433 }
434 unix_data_ref(UN_DATA(sock->conn));
435 UN_DATA(sock)->peerupd = UN_DATA(sock->conn);
436 return 0;
437 }
438
439
440
441
442
443
444
445 static int
446 unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
447 {
448 struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
449
450 unix_data_ref(upd1);
451 unix_data_ref(upd2);
452 upd1->peerupd = upd2;
453 upd2->peerupd = upd1;
454 return 0;
455 }
456
457
458
459
460 static int
461 unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
462 {
463 struct socket *clientsock;
464
465 PRINTK("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n",
466 sock, newsock);
467
468
469
470
471
472 while (!(clientsock = sock->iconn)) {
473 if (flags & O_NONBLOCK)
474 return -EAGAIN;
475 interruptible_sleep_on(sock->wait);
476 if (current->signal & ~current->blocked) {
477 PRINTK("sys_accept: sleep was interrupted\n");
478 return -ERESTARTSYS;
479 }
480 }
481
482
483
484
485
486 sock->iconn = clientsock->next;
487 clientsock->next = NULL;
488 newsock->conn = clientsock;
489 clientsock->conn = newsock;
490 clientsock->state = SS_CONNECTED;
491 newsock->state = SS_CONNECTED;
492 wake_up(clientsock->wait);
493 unix_data_ref (UN_DATA(newsock->conn));
494 UN_DATA(newsock)->peerupd = UN_DATA(newsock->conn);
495 UN_DATA(newsock)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
496 UN_DATA(newsock)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
497 UN_DATA(newsock->conn)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
498 UN_DATA(newsock->conn)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
499 return 0;
500 }
501
502
503
504
505 static int
506 unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
507 int *usockaddr_len, int peer)
508 {
509 struct unix_proto_data *upd;
510 int len;
511
512 PRINTK("unix_proto_getname: socket 0x%x for %s\n", sock,
513 peer ? "peer" : "self");
514 if (peer) {
515 if (sock->state != SS_CONNECTED) {
516 PRINTK("unix_proto_getname: socket not connected\n");
517 return -EINVAL;
518 }
519 upd = UN_DATA(sock->conn);
520 }
521 else
522 upd = UN_DATA(sock);
523 verify_area(usockaddr_len, sizeof(*usockaddr_len));
524 if ((len = get_fs_long(usockaddr_len)) <= 0)
525 return -EINVAL;
526 if (len > upd->sockaddr_len)
527 len = upd->sockaddr_len;
528 if (len) {
529 verify_area(usockaddr, len);
530 memcpy_tofs(usockaddr, &upd->sockaddr_un, len);
531 }
532 put_fs_long(len, usockaddr_len);
533 return 0;
534 }
535
536
537
538
539 static int
540 unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
541 {
542 struct unix_proto_data *upd;
543 int todo, avail;
544
545 if ((todo = size) <= 0)
546 return 0;
547 upd = UN_DATA(sock);
548 while (!(avail = UN_BUF_AVAIL(upd))) {
549 if (sock->state != SS_CONNECTED) {
550 PRINTK("unix_proto_read: socket not connected\n");
551 return (sock->state == SS_DISCONNECTING) ? 0 : -EINVAL;
552 }
553 PRINTK("unix_proto_read: no data available...\n");
554 if (nonblock)
555 return -EAGAIN;
556 interruptible_sleep_on(sock->wait);
557 if (current->signal & ~current->blocked) {
558 PRINTK("unix_proto_read: interrupted\n");
559 return -ERESTARTSYS;
560 }
561 if (sock->state == SS_DISCONNECTING) {
562 PRINTK("unix_proto_read: disconnected\n");
563 return 0;
564 }
565 }
566
567
568
569
570
571 do {
572 int part, cando;
573
574 if (avail <= 0) {
575 PRINTK("unix_proto_read: AVAIL IS NEGATIVE!!!\n");
576 send_sig(SIGKILL,current,1);
577 return -EINTR;
578 }
579
580 if ((cando = todo) > avail)
581 cando = avail;
582 if (cando > (part = BUF_SIZE - upd->bp_tail))
583 cando = part;
584 PRINTK("unix_proto_read: avail=%d, todo=%d, cando=%d\n",
585 avail, todo, cando);
586 verify_area(ubuf, cando);
587 memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
588 upd->bp_tail = (upd->bp_tail + cando) & (BUF_SIZE-1);
589 ubuf += cando;
590 todo -= cando;
591 if (sock->state == SS_CONNECTED)
592 wake_up(sock->conn->wait);
593 avail = UN_BUF_AVAIL(upd);
594 } while (todo && avail);
595 return size - todo;
596 }
597
598
599
600
601
602
603 static int
604 unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
605 {
606 struct unix_proto_data *pupd;
607 int todo, space;
608
609 if ((todo = size) <= 0)
610 return 0;
611 if (sock->state != SS_CONNECTED) {
612 PRINTK("unix_proto_write: socket not connected\n");
613 if (sock->state == SS_DISCONNECTING) {
614 send_sig(SIGPIPE,current,1);
615 return -EINTR;
616 }
617 return -EINVAL;
618 }
619 pupd = UN_DATA(sock)->peerupd;
620
621 while (!(space = UN_BUF_SPACE(pupd))) {
622 PRINTK("unix_proto_write: no space left...\n");
623 if (nonblock)
624 return -EAGAIN;
625 interruptible_sleep_on(sock->wait);
626 if (current->signal & ~current->blocked) {
627 PRINTK("unix_proto_write: interrupted\n");
628 return -ERESTARTSYS;
629 }
630 if (sock->state == SS_DISCONNECTING) {
631 PRINTK("unix_proto_write: disconnected (SIGPIPE)\n");
632 send_sig(SIGPIPE,current,1);
633 return -EINTR;
634 }
635 }
636
637
638
639
640
641 do {
642 int part, cando;
643
644 if (space <= 0) {
645 PRINTK("unix_proto_write: SPACE IS NEGATIVE!!!\n");
646 send_sig(SIGKILL,current,1);
647 return -EINTR;
648 }
649
650
651
652
653
654 if (sock->state == SS_DISCONNECTING) {
655 send_sig(SIGPIPE,current,1);
656 return -EINTR;
657 }
658 if ((cando = todo) > space)
659 cando = space;
660 if (cando > (part = BUF_SIZE - pupd->bp_head))
661 cando = part;
662 PRINTK("unix_proto_write: space=%d, todo=%d, cando=%d\n",
663 space, todo, cando);
664 verify_area(ubuf, cando);
665 memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
666 pupd->bp_head = (pupd->bp_head + cando) & (BUF_SIZE-1);
667 ubuf += cando;
668 todo -= cando;
669 if (sock->state == SS_CONNECTED)
670 wake_up(sock->conn->wait);
671 space = UN_BUF_SPACE(pupd);
672 } while (todo && space);
673 return size - todo;
674 }
675
676 static int
677 unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
678 {
679 struct unix_proto_data *upd, *peerupd;
680
681
682
683
684 if (sock->flags & SO_ACCEPTCON) {
685 if (sel_type == SEL_IN) {
686 PRINTK("sock_select: %sconnections pending\n",
687 sock->iconn ? "" : "no ");
688 if (sock->iconn)
689 return 1;
690 select_wait(sock->wait, wait);
691 return sock->iconn ? 1 : 0;
692 }
693 PRINTK("sock_select: nothing else for server socket\n");
694 select_wait(sock->wait, wait);
695 return 0;
696 }
697
698 if (sel_type == SEL_IN) {
699 upd = UN_DATA(sock);
700 PRINTK("unix_proto_select: there is%s data available\n",
701 UN_BUF_AVAIL(upd) ? "" : " no");
702 if (UN_BUF_AVAIL(upd))
703 return 1;
704 else if (sock->state != SS_CONNECTED) {
705 PRINTK("unix_proto_select: socket not connected (read EOF)\n");
706 return 1;
707 }
708 select_wait(sock->wait,wait);
709 return 0;
710 }
711 if (sel_type == SEL_OUT) {
712 if (sock->state != SS_CONNECTED) {
713 PRINTK("unix_proto_select: socket not connected (write EOF)\n");
714 return 1;
715 }
716 peerupd = UN_DATA(sock->conn);
717 PRINTK("unix_proto_select: there is%s space available\n",
718 UN_BUF_SPACE(peerupd) ? "" : " no");
719 if (UN_BUF_SPACE(peerupd) > 0)
720 return 1;
721 select_wait(sock->wait,wait);
722 return 0;
723 }
724
725 PRINTK("unix_proto_select: there are no exceptions here?!\n");
726 return 0;
727 }
728
729 static int
730 unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
731 {
732 struct unix_proto_data *upd, *peerupd;
733
734 upd = UN_DATA(sock);
735 peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
736
737 switch (cmd) {
738
739 case TIOCINQ:
740 if (sock->flags & SO_ACCEPTCON)
741 return -EINVAL;
742 verify_area((void *)arg, sizeof(unsigned long));
743 if (UN_BUF_AVAIL(upd) || peerupd)
744 put_fs_long(UN_BUF_AVAIL(upd), (unsigned long *)arg);
745 else
746 put_fs_long(1, (unsigned long *)arg);
747 break;
748
749 case TIOCOUTQ:
750 if (sock->flags & SO_ACCEPTCON)
751 return -EINVAL;
752 verify_area((void *)arg, sizeof(unsigned long));
753 if (peerupd)
754 put_fs_long(UN_BUF_SPACE(peerupd),
755 (unsigned long *)arg);
756 else
757 put_fs_long(0, (unsigned long *)arg);
758 break;
759
760 default:
761 return -EINVAL;
762 }
763 return 0;
764 }
765
766 static int
767 unix_proto_init(void)
768 {
769 struct unix_proto_data *upd;
770
771 PRINTK("unix_proto_init: initializing...\n");
772 for (upd = unix_datas; upd <= last_unix_data; ++upd)
773 upd->refcnt = 0;
774 return 0;
775 }