This source file includes following definitions.
- min
- unix_lock
- unix_unlock
- unix_proto_listen
- unix_proto_setsockopt
- unix_proto_getsockopt
- unix_proto_sendto
- unix_proto_recvfrom
- unix_proto_shutdown
- unix_proto_send
- unix_proto_recv
- 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/kernel.h>
31 #include <linux/major.h>
32 #include <linux/signal.h>
33 #include <linux/sched.h>
34 #include <linux/errno.h>
35 #include <linux/string.h>
36 #include <linux/stat.h>
37 #include <linux/socket.h>
38 #include <linux/un.h>
39 #include <linux/fcntl.h>
40 #include <linux/termios.h>
41 #include <linux/sockios.h>
42 #include <linux/net.h>
43 #include <linux/fs.h>
44 #include <linux/malloc.h>
45
46 #include <asm/system.h>
47 #include <asm/segment.h>
48
49 #include <stdarg.h>
50
51 #include <net/unix.h>
52
53
54
55
56
57
58 struct unix_proto_data unix_datas[NSOCKETS_UNIX];
59
60 static int unix_proto_create(struct socket *sock, int protocol);
61 static int unix_proto_dup(struct socket *newsock, struct socket *oldsock);
62 static int unix_proto_release(struct socket *sock, struct socket *peer);
63 static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
64 int sockaddr_len);
65 static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
66 int sockaddr_len, int flags);
67 static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2);
68 static int unix_proto_accept(struct socket *sock, struct socket *newsock,
69 int flags);
70 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
71 int *usockaddr_len, int peer);
72 static int unix_proto_read(struct socket *sock, char *ubuf, int size,
73 int nonblock);
74 static int unix_proto_write(struct socket *sock, char *ubuf, int size,
75 int nonblock);
76 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait);
77 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd,
78 unsigned long arg);
79 static int unix_proto_listen(struct socket *sock, int backlog);
80 static int unix_proto_send(struct socket *sock, void *buff, int len,
81 int nonblock, unsigned flags);
82 static int unix_proto_recv(struct socket *sock, void *buff, int len,
83 int nonblock, unsigned flags);
84 static int unix_proto_sendto(struct socket *sock, void *buff, int len,
85 int nonblock, unsigned flags,
86 struct sockaddr *addr, int addr_len);
87 static int unix_proto_recvfrom(struct socket *sock, void *buff, int len,
88 int nonblock, unsigned flags,
89 struct sockaddr *addr, int *addr_len);
90
91 static int unix_proto_shutdown(struct socket *sock, int how);
92
93 static int unix_proto_setsockopt(struct socket *sock, int level, int optname,
94 char *optval, int optlen);
95 static int unix_proto_getsockopt(struct socket *sock, int level, int optname,
96 char *optval, int *optlen);
97
98
99 static inline int min(int a, int b)
100 {
101 if (a < b)
102 return(a);
103 return(b);
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118 static void unix_lock(struct unix_proto_data *upd)
119 {
120 while (upd->lock_flag)
121 sleep_on(&upd->wait);
122 upd->lock_flag = 1;
123 }
124
125
126 static void unix_unlock(struct unix_proto_data *upd)
127 {
128 upd->lock_flag = 0;
129 wake_up(&upd->wait);
130 }
131
132
133
134
135
136 static int unix_proto_listen(struct socket *sock, int backlog)
137 {
138 return(0);
139 }
140
141
142
143
144
145 static int unix_proto_setsockopt(struct socket *sock, int level, int optname,
146 char *optval, int optlen)
147 {
148 return(-EOPNOTSUPP);
149 }
150
151
152 static int unix_proto_getsockopt(struct socket *sock, int level, int optname,
153 char *optval, int *optlen)
154 {
155 return(-EOPNOTSUPP);
156 }
157
158
159
160
161
162
163 static int unix_proto_sendto(struct socket *sock, void *buff, int len, int nonblock,
164 unsigned flags, struct sockaddr *addr, int addr_len)
165 {
166 return(-EOPNOTSUPP);
167 }
168
169 static int unix_proto_recvfrom(struct socket *sock, void *buff, int len, int nonblock,
170 unsigned flags, struct sockaddr *addr, int *addr_len)
171 {
172 return(-EOPNOTSUPP);
173 }
174
175
176
177
178
179 static int unix_proto_shutdown(struct socket *sock, int how)
180 {
181 return(-EOPNOTSUPP);
182 }
183
184
185
186
187
188
189 static int unix_proto_send(struct socket *sock, void *buff, int len, int nonblock,
190 unsigned flags)
191 {
192 if (flags != 0)
193 return(-EINVAL);
194 return(unix_proto_write(sock, (char *) buff, len, nonblock));
195 }
196
197
198
199
200
201
202 static int unix_proto_recv(struct socket *sock, void *buff, int len, int nonblock,
203 unsigned flags)
204 {
205 if (flags != 0)
206 return(-EINVAL);
207 return(unix_proto_read(sock, (char *) buff, len, nonblock));
208 }
209
210
211
212
213
214 static struct unix_proto_data *
215 unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len,
216 struct inode *inode)
217 {
218 struct unix_proto_data *upd;
219
220 for(upd = unix_datas; upd <= last_unix_data; ++upd)
221 {
222 if (upd->refcnt > 0 && upd->socket &&
223 upd->socket->state == SS_UNCONNECTED &&
224 upd->sockaddr_un.sun_family == sockun->sun_family &&
225 upd->inode == inode)
226
227 return(upd);
228 }
229 return(NULL);
230 }
231
232
233
234
235
236
237
238
239 static struct unix_proto_data *
240 unix_data_alloc(void)
241 {
242 struct unix_proto_data *upd;
243
244 cli();
245 for(upd = unix_datas; upd <= last_unix_data; ++upd)
246 {
247 if (!upd->refcnt)
248 {
249 upd->refcnt = -1;
250 sti();
251 upd->socket = NULL;
252 upd->sockaddr_len = 0;
253 upd->sockaddr_un.sun_family = 0;
254 upd->buf = NULL;
255 upd->bp_head = upd->bp_tail = 0;
256 upd->inode = NULL;
257 upd->peerupd = NULL;
258 return(upd);
259 }
260 }
261 sti();
262 return(NULL);
263 }
264
265
266
267
268
269
270
271
272 static inline void unix_data_ref(struct unix_proto_data *upd)
273 {
274 if (!upd)
275 {
276 return;
277 }
278 ++upd->refcnt;
279 }
280
281
282 static void unix_data_deref(struct unix_proto_data *upd)
283 {
284 if (!upd)
285 {
286 return;
287 }
288 if (upd->refcnt == 1)
289 {
290 if (upd->buf)
291 {
292 free_page((unsigned long)upd->buf);
293 upd->buf = NULL;
294 upd->bp_head = upd->bp_tail = 0;
295 }
296 }
297 --upd->refcnt;
298 }
299
300
301
302
303
304
305
306 static int unix_proto_create(struct socket *sock, int protocol)
307 {
308 struct unix_proto_data *upd;
309
310
311
312
313
314 if (protocol != 0)
315 {
316 return(-EINVAL);
317 }
318
319 if (!(upd = unix_data_alloc()))
320 {
321 printk("UNIX: create: can't allocate buffer\n");
322 return(-ENOMEM);
323 }
324 if (!(upd->buf = (char*) get_free_page(GFP_USER)))
325 {
326 printk("UNIX: create: can't get page!\n");
327 unix_data_deref(upd);
328 return(-ENOMEM);
329 }
330 upd->protocol = protocol;
331 upd->socket = sock;
332 UN_DATA(sock) = upd;
333 upd->refcnt = 1;
334 return(0);
335 }
336
337
338
339
340
341 static int unix_proto_dup(struct socket *newsock, struct socket *oldsock)
342 {
343 struct unix_proto_data *upd = UN_DATA(oldsock);
344 return(unix_proto_create(newsock, upd->protocol));
345 }
346
347
348
349
350
351
352 static int unix_proto_release(struct socket *sock, struct socket *peer)
353 {
354 struct unix_proto_data *upd = UN_DATA(sock);
355
356 if (!upd)
357 return(0);
358
359 if (upd->socket != sock)
360 {
361 printk("UNIX: release: socket link mismatch!\n");
362 return(-EINVAL);
363 }
364
365 if (upd->inode)
366 {
367 iput(upd->inode);
368 upd->inode = NULL;
369 }
370
371 UN_DATA(sock) = NULL;
372 upd->socket = NULL;
373
374 if (upd->peerupd)
375 unix_data_deref(upd->peerupd);
376 unix_data_deref(upd);
377 return(0);
378 }
379
380
381
382
383
384
385
386
387
388
389
390
391 static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
392 int sockaddr_len)
393 {
394 char fname[UNIX_PATH_MAX + 1];
395 struct unix_proto_data *upd = UN_DATA(sock);
396 unsigned long old_fs;
397 int i;
398
399 if (sockaddr_len <= UN_PATH_OFFSET ||
400 sockaddr_len > sizeof(struct sockaddr_un))
401 {
402 return(-EINVAL);
403 }
404 if (upd->sockaddr_len || upd->inode)
405 {
406
407 return(-EINVAL);
408 }
409 memcpy(&upd->sockaddr_un, umyaddr, sockaddr_len);
410 upd->sockaddr_un.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
411 if (upd->sockaddr_un.sun_family != AF_UNIX)
412 {
413 return(-EINVAL);
414 }
415
416 memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
417 fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
418 old_fs = get_fs();
419 set_fs(get_ds());
420
421 i = do_mknod(fname, S_IFSOCK | S_IRWXUGO, 0);
422
423 if (i == 0)
424 i = open_namei(fname, 2, S_IFSOCK, &upd->inode, NULL);
425 set_fs(old_fs);
426 if (i < 0)
427 {
428
429 if(i==-EEXIST)
430 i=-EADDRINUSE;
431 return(i);
432 }
433 upd->sockaddr_len = sockaddr_len;
434
435 return(0);
436 }
437
438
439
440
441
442
443
444
445 static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
446 int sockaddr_len, int flags)
447 {
448 char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
449 struct sockaddr_un sockun;
450 struct unix_proto_data *serv_upd;
451 struct inode *inode;
452 unsigned long old_fs;
453 int i;
454
455 if (sockaddr_len <= UN_PATH_OFFSET ||
456 sockaddr_len > sizeof(struct sockaddr_un))
457 {
458 return(-EINVAL);
459 }
460
461 if (sock->state == SS_CONNECTING)
462 return(-EINPROGRESS);
463 if (sock->state == SS_CONNECTED)
464 return(-EISCONN);
465
466 memcpy(&sockun, uservaddr, sockaddr_len);
467 sockun.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
468 if (sockun.sun_family != AF_UNIX)
469 {
470 return(-EINVAL);
471 }
472
473
474
475
476
477
478
479
480 memcpy(fname, sockun.sun_path, sockaddr_len-UN_PATH_OFFSET);
481 fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
482 old_fs = get_fs();
483 set_fs(get_ds());
484 i = open_namei(fname, 2, S_IFSOCK, &inode, NULL);
485 set_fs(old_fs);
486 if (i < 0)
487 {
488 return(i);
489 }
490
491 serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
492 iput(inode);
493 if (!serv_upd)
494 {
495 return(-EINVAL);
496 }
497
498 if ((i = sock_awaitconn(sock, serv_upd->socket, flags)) < 0)
499 {
500 return(i);
501 }
502
503 if (sock->conn)
504 {
505 unix_data_ref(UN_DATA(sock->conn));
506 UN_DATA(sock)->peerupd = UN_DATA(sock->conn);
507 }
508 return(0);
509 }
510
511
512
513
514
515
516
517
518
519 static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
520 {
521 struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
522
523 unix_data_ref(upd1);
524 unix_data_ref(upd2);
525 upd1->peerupd = upd2;
526 upd2->peerupd = upd1;
527 return(0);
528 }
529
530
531
532
533
534
535 static int unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
536 {
537 struct socket *clientsock;
538
539
540
541
542
543
544 while(!(clientsock = sock->iconn))
545 {
546 if (flags & O_NONBLOCK)
547 return(-EAGAIN);
548 sock->flags |= SO_WAITDATA;
549 interruptible_sleep_on(sock->wait);
550 sock->flags &= ~SO_WAITDATA;
551 if (current->signal & ~current->blocked)
552 {
553 return(-ERESTARTSYS);
554 }
555 }
556
557
558
559
560
561 sock->iconn = clientsock->next;
562 clientsock->next = NULL;
563 newsock->conn = clientsock;
564 clientsock->conn = newsock;
565 clientsock->state = SS_CONNECTED;
566 newsock->state = SS_CONNECTED;
567 unix_data_ref(UN_DATA(clientsock));
568 UN_DATA(newsock)->peerupd = UN_DATA(clientsock);
569 UN_DATA(newsock)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
570 UN_DATA(newsock)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
571 wake_up_interruptible(clientsock->wait);
572 sock_wake_async(clientsock, 0);
573 return(0);
574 }
575
576
577
578
579
580
581 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
582 int *usockaddr_len, int peer)
583 {
584 struct unix_proto_data *upd;
585 int len;
586
587 if (peer)
588 {
589 if (sock->state != SS_CONNECTED)
590 {
591 return(-EINVAL);
592 }
593 upd = UN_DATA(sock->conn);
594 }
595 else
596 upd = UN_DATA(sock);
597
598 len = upd->sockaddr_len;
599 memcpy(usockaddr, &upd->sockaddr_un, len);
600 *usockaddr_len=len;
601 return(0);
602 }
603
604
605
606
607
608
609 static int unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
610 {
611 struct unix_proto_data *upd;
612 int todo, avail;
613
614 if ((todo = size) <= 0)
615 return(0);
616
617 upd = UN_DATA(sock);
618 while(!(avail = UN_BUF_AVAIL(upd)))
619 {
620 if (sock->state != SS_CONNECTED)
621 {
622 return((sock->state == SS_DISCONNECTING) ? 0 : -EINVAL);
623 }
624 if (nonblock)
625 return(-EAGAIN);
626 sock->flags |= SO_WAITDATA;
627 interruptible_sleep_on(sock->wait);
628 sock->flags &= ~SO_WAITDATA;
629 if (current->signal & ~current->blocked)
630 {
631 return(-ERESTARTSYS);
632 }
633 }
634
635
636
637
638
639
640 unix_lock(upd);
641 do
642 {
643 int part, cando;
644
645 if (avail <= 0)
646 {
647 printk("UNIX: read: AVAIL IS NEGATIVE!!!\n");
648 send_sig(SIGKILL, current, 1);
649 return(-EPIPE);
650 }
651
652 if ((cando = todo) > avail)
653 cando = avail;
654 if (cando >(part = BUF_SIZE - upd->bp_tail))
655 cando = part;
656 memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
657 upd->bp_tail =(upd->bp_tail + cando) &(BUF_SIZE-1);
658 ubuf += cando;
659 todo -= cando;
660 if (sock->state == SS_CONNECTED)
661 {
662 wake_up_interruptible(sock->conn->wait);
663 sock_wake_async(sock->conn, 2);
664 }
665 avail = UN_BUF_AVAIL(upd);
666 }
667 while(todo && avail);
668 unix_unlock(upd);
669 return(size - todo);
670 }
671
672
673
674
675
676
677
678
679 static int unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
680 {
681 struct unix_proto_data *pupd;
682 int todo, space;
683
684 if ((todo = size) <= 0)
685 return(0);
686 if (sock->state != SS_CONNECTED)
687 {
688 if (sock->state == SS_DISCONNECTING)
689 {
690 send_sig(SIGPIPE, current, 1);
691 return(-EPIPE);
692 }
693 return(-EINVAL);
694 }
695 pupd = UN_DATA(sock)->peerupd;
696
697 while(!(space = UN_BUF_SPACE(pupd)))
698 {
699 sock->flags |= SO_NOSPACE;
700 if (nonblock)
701 return(-EAGAIN);
702 sock->flags &= ~SO_NOSPACE;
703 interruptible_sleep_on(sock->wait);
704 if (current->signal & ~current->blocked)
705 {
706 return(-ERESTARTSYS);
707 }
708 if (sock->state == SS_DISCONNECTING)
709 {
710 send_sig(SIGPIPE, current, 1);
711 return(-EPIPE);
712 }
713 }
714
715
716
717
718
719
720 unix_lock(pupd);
721
722 do
723 {
724 int part, cando;
725
726 if (space <= 0)
727 {
728 printk("UNIX: write: SPACE IS NEGATIVE!!!\n");
729 send_sig(SIGKILL, current, 1);
730 return(-EPIPE);
731 }
732
733
734
735
736
737
738 if (sock->state == SS_DISCONNECTING)
739 {
740 send_sig(SIGPIPE, current, 1);
741 unix_unlock(pupd);
742 return(-EPIPE);
743 }
744
745 if ((cando = todo) > space)
746 cando = space;
747
748 if (cando >(part = BUF_SIZE - pupd->bp_head))
749 cando = part;
750
751 memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
752 pupd->bp_head =(pupd->bp_head + cando) &(BUF_SIZE-1);
753 ubuf += cando;
754 todo -= cando;
755 if (sock->state == SS_CONNECTED)
756 {
757 wake_up_interruptible(sock->conn->wait);
758 sock_wake_async(sock->conn, 1);
759 }
760 space = UN_BUF_SPACE(pupd);
761 }
762 while(todo && space);
763
764 unix_unlock(pupd);
765 return(size - todo);
766 }
767
768
769
770
771
772 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
773 {
774 struct unix_proto_data *upd, *peerupd;
775
776
777
778
779 if (sock->flags & SO_ACCEPTCON)
780 {
781 if (sel_type == SEL_IN)
782 {
783 if (sock->iconn)
784 return(1);
785 select_wait(sock->wait, wait);
786 return(sock->iconn ? 1 : 0);
787 }
788 select_wait(sock->wait, wait);
789 return(0);
790 }
791
792 if (sel_type == SEL_IN)
793 {
794 upd = UN_DATA(sock);
795 if (UN_BUF_AVAIL(upd))
796 return(1);
797 else if (sock->state != SS_CONNECTED)
798 {
799 return(1);
800 }
801 select_wait(sock->wait,wait);
802 return(0);
803 }
804
805 if (sel_type == SEL_OUT)
806 {
807 if (sock->state != SS_CONNECTED)
808 {
809 return(1);
810 }
811 peerupd = UN_DATA(sock->conn);
812 if (UN_BUF_SPACE(peerupd) > 0)
813 return(1);
814 select_wait(sock->wait,wait);
815 return(0);
816 }
817
818
819
820
821
822 return(0);
823 }
824
825
826
827
828
829
830 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
831 {
832 struct unix_proto_data *upd, *peerupd;
833 int er;
834
835 upd = UN_DATA(sock);
836 peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
837
838 switch(cmd)
839 {
840 case TIOCINQ:
841 if (sock->flags & SO_ACCEPTCON)
842 return(-EINVAL);
843 er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
844 if(er)
845 return er;
846 if (UN_BUF_AVAIL(upd) || peerupd)
847 put_fs_long(UN_BUF_AVAIL(upd),(unsigned long *)arg);
848 else
849 put_fs_long(0,(unsigned long *)arg);
850 break;
851 case TIOCOUTQ:
852 if (sock->flags & SO_ACCEPTCON)
853 return(-EINVAL);
854 er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
855 if(er)
856 return er;
857 if (peerupd)
858 put_fs_long(UN_BUF_SPACE(peerupd),(unsigned long *)arg);
859 else
860 put_fs_long(0,(unsigned long *)arg);
861 break;
862 default:
863 return(-EINVAL);
864 }
865 return(0);
866 }
867
868
869 static struct proto_ops unix_proto_ops = {
870 AF_UNIX,
871 unix_proto_create,
872 unix_proto_dup,
873 unix_proto_release,
874 unix_proto_bind,
875 unix_proto_connect,
876 unix_proto_socketpair,
877 unix_proto_accept,
878 unix_proto_getname,
879 unix_proto_read,
880 unix_proto_write,
881 unix_proto_select,
882 unix_proto_ioctl,
883 unix_proto_listen,
884 unix_proto_send,
885 unix_proto_recv,
886 unix_proto_sendto,
887 unix_proto_recvfrom,
888 unix_proto_shutdown,
889 unix_proto_setsockopt,
890 unix_proto_getsockopt,
891 NULL
892 };
893
894
895
896
897
898 void unix_proto_init(struct net_proto *pro)
899 {
900 struct unix_proto_data *upd;
901
902
903
904
905
906 (void) sock_register(unix_proto_ops.family, &unix_proto_ops);
907
908 for(upd = unix_datas; upd <= last_unix_data; ++upd)
909 {
910 upd->refcnt = 0;
911 }
912 }