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