This source file includes following definitions.
- unix_mkname
- unix_remove_socket
- unix_insert_socket
- unix_find_socket
- unix_destroy_timer
- unix_delayed_delete
- unix_destroy_socket
- unix_fcntl
- unix_setsockopt
- unix_getsockopt
- unix_listen
- def_callback1
- def_callback2
- def_callback3
- unix_create
- unix_dup
- unix_release
- unix_find_other
- unix_bind
- unix_connect
- unix_socketpair
- unix_accept
- unix_getname
- unix_copyrights
- unix_returnrights
- unix_fd_copy
- unix_fd_free
- unix_files_free
- unix_detach_fds
- unix_destruct_fds
- unix_attach_fds
- unix_sendmsg
- unix_data_wait
- unix_recvmsg
- unix_shutdown
- unix_select
- unix_ioctl
- unix_get_info
- 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 #include <linux/config.h>
46 #include <linux/kernel.h>
47 #include <linux/major.h>
48 #include <linux/signal.h>
49 #include <linux/sched.h>
50 #include <linux/errno.h>
51 #include <linux/string.h>
52 #include <linux/stat.h>
53 #include <linux/socket.h>
54 #include <linux/un.h>
55 #include <linux/fcntl.h>
56 #include <linux/termios.h>
57 #include <linux/socket.h>
58 #include <linux/sockios.h>
59 #include <linux/net.h>
60 #include <linux/in.h>
61 #include <linux/fs.h>
62 #include <linux/malloc.h>
63 #include <asm/segment.h>
64 #include <linux/skbuff.h>
65 #include <linux/netdevice.h>
66 #include <net/sock.h>
67 #include <net/tcp.h>
68 #include <net/af_unix.h>
69 #include <linux/proc_fs.h>
70
71 static unix_socket *unix_socket_list=NULL;
72
73 #define min(a,b) (((a)<(b))?(a):(b))
74
75
76
77
78
79 static inline void unix_mkname(struct sockaddr_un * sunaddr, unsigned long len)
80 {
81 if (len >= sizeof(*sunaddr))
82 len = sizeof(*sunaddr)-1;
83 ((char *)sunaddr)[len]=0;
84 }
85
86
87
88
89
90
91
92 static void unix_remove_socket(unix_socket *sk)
93 {
94 unix_socket **s;
95
96 cli();
97 s=&unix_socket_list;
98
99 while(*s!=NULL)
100 {
101 if(*s==sk)
102 {
103 *s=sk->next;
104 sti();
105 return;
106 }
107 s=&((*s)->next);
108 }
109 sti();
110 }
111
112 static void unix_insert_socket(unix_socket *sk)
113 {
114 cli();
115 sk->next=unix_socket_list;
116 unix_socket_list=sk;
117 sti();
118 }
119
120 static unix_socket *unix_find_socket(struct inode *i)
121 {
122 unix_socket *s;
123 cli();
124 s=unix_socket_list;
125 while(s)
126 {
127 if(s->protinfo.af_unix.inode==i)
128 {
129 sti();
130 return(s);
131 }
132 s=s->next;
133 }
134 sti();
135 return(NULL);
136 }
137
138
139
140
141
142 static void unix_destroy_timer(unsigned long data)
143 {
144 unix_socket *sk=(unix_socket *)data;
145 if(sk->protinfo.af_unix.locks==0 && sk->wmem_alloc==0)
146 {
147 if(sk->protinfo.af_unix.name)
148 kfree(sk->protinfo.af_unix.name);
149 kfree_s(sk,sizeof(*sk));
150 return;
151 }
152
153
154
155
156
157 sk->timer.expires=jiffies+10*HZ;
158 add_timer(&sk->timer);
159 }
160
161
162 static void unix_delayed_delete(unix_socket *sk)
163 {
164 sk->timer.data=(unsigned long)sk;
165 sk->timer.expires=jiffies+HZ;
166 sk->timer.function=unix_destroy_timer;
167 add_timer(&sk->timer);
168 }
169
170 static void unix_destroy_socket(unix_socket *sk)
171 {
172 struct sk_buff *skb;
173
174 unix_remove_socket(sk);
175
176 while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
177 {
178 if(sk->state==TCP_LISTEN)
179 {
180 unix_socket *osk=skb->sk;
181 osk->state=TCP_CLOSE;
182 kfree_skb(skb, FREE_WRITE);
183 osk->state_change(osk);
184
185 }
186 else
187 {
188
189 kfree_skb(skb,FREE_WRITE);
190 }
191 }
192
193 if(sk->protinfo.af_unix.inode!=NULL)
194 {
195 iput(sk->protinfo.af_unix.inode);
196 sk->protinfo.af_unix.inode=NULL;
197 }
198
199 if(--sk->protinfo.af_unix.locks==0 && sk->wmem_alloc==0)
200 {
201 if(sk->protinfo.af_unix.name)
202 kfree(sk->protinfo.af_unix.name);
203 kfree_s(sk,sizeof(*sk));
204 }
205 else
206 {
207 sk->dead=1;
208 unix_delayed_delete(sk);
209 }
210 }
211
212
213
214
215
216 static int unix_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
217 {
218 return -EINVAL;
219 }
220
221
222
223
224
225 static int unix_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
226 {
227 unix_socket *sk=sock->data;
228 if(level!=SOL_SOCKET)
229 return -EOPNOTSUPP;
230 return sock_setsockopt(sk,level,optname,optval,optlen);
231 }
232
233 static int unix_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
234 {
235 unix_socket *sk=sock->data;
236 if(level!=SOL_SOCKET)
237 return -EOPNOTSUPP;
238 return sock_getsockopt(sk,level,optname,optval,optlen);
239 }
240
241 static int unix_listen(struct socket *sock, int backlog)
242 {
243 unix_socket *sk=sock->data;
244 if(sk->type!=SOCK_STREAM)
245 return -EOPNOTSUPP;
246 if(sk->protinfo.af_unix.name==NULL)
247 return -EINVAL;
248 sk->max_ack_backlog=backlog;
249 sk->state=TCP_LISTEN;
250 return 0;
251 }
252
253 static void def_callback1(struct sock *sk)
254 {
255 if(!sk->dead)
256 wake_up_interruptible(sk->sleep);
257 }
258
259 static void def_callback2(struct sock *sk, int len)
260 {
261 if(!sk->dead)
262 {
263 wake_up_interruptible(sk->sleep);
264 sock_wake_async(sk->socket, 1);
265 }
266 }
267
268 static void def_callback3(struct sock *sk)
269 {
270 if(!sk->dead)
271 {
272 wake_up_interruptible(sk->sleep);
273 sock_wake_async(sk->socket, 2);
274 }
275 }
276
277 static int unix_create(struct socket *sock, int protocol)
278 {
279 unix_socket *sk;
280 if(protocol && protocol != PF_UNIX)
281 return -EPROTONOSUPPORT;
282 sk=(unix_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
283 if(sk==NULL)
284 return -ENOMEM;
285 switch(sock->type)
286 {
287 case SOCK_STREAM:
288 break;
289
290
291
292
293 case SOCK_RAW:
294 sock->type=SOCK_DGRAM;
295 case SOCK_DGRAM:
296 break;
297 default:
298 kfree_s(sk,sizeof(*sk));
299 return -ESOCKTNOSUPPORT;
300 }
301 sk->type=sock->type;
302 init_timer(&sk->timer);
303 skb_queue_head_init(&sk->write_queue);
304 skb_queue_head_init(&sk->receive_queue);
305 skb_queue_head_init(&sk->back_log);
306 sk->protinfo.af_unix.family=AF_UNIX;
307 sk->protinfo.af_unix.inode=NULL;
308 sk->protinfo.af_unix.locks=1;
309 sk->protinfo.af_unix.readsem=MUTEX;
310 sk->protinfo.af_unix.name=NULL;
311 sk->protinfo.af_unix.other=NULL;
312 sk->protocol=0;
313 sk->rmem_alloc=0;
314 sk->wmem_alloc=0;
315 sk->dead=0;
316 sk->next=NULL;
317 sk->broadcast=0;
318 sk->rcvbuf=SK_RMEM_MAX;
319 sk->sndbuf=SK_WMEM_MAX;
320 sk->allocation=GFP_KERNEL;
321 sk->users=0;
322 sk->bsdism=0;
323 sk->debug=0;
324 sk->prot=NULL;
325 sk->err=0;
326 sk->localroute=0;
327 sk->send_head=NULL;
328 sk->state=TCP_CLOSE;
329 sk->priority=SOPRI_NORMAL;
330 sk->ack_backlog=0;
331 sk->shutdown=0;
332 sk->state_change=def_callback1;
333 sk->data_ready=def_callback2;
334 sk->write_space=def_callback3;
335 sk->error_report=def_callback1;
336 sk->mtu=4096;
337 sk->socket=sock;
338 sock->data=(void *)sk;
339 sk->sleep=sock->wait;
340 sk->zapped=0;
341 unix_insert_socket(sk);
342 return 0;
343 }
344
345 static int unix_dup(struct socket *newsock, struct socket *oldsock)
346 {
347 return unix_create(newsock,0);
348 }
349
350 static int unix_release(struct socket *sock, struct socket *peer)
351 {
352 unix_socket *sk=sock->data;
353 unix_socket *skpair;
354
355
356
357 if(sk==NULL)
358 return 0;
359
360 sk->state_change(sk);
361 sk->dead=1;
362 skpair=(unix_socket *)sk->protinfo.af_unix.other;
363 if(sk->type==SOCK_STREAM && skpair!=NULL && skpair->state!=TCP_LISTEN)
364 {
365 skpair->shutdown=SHUTDOWN_MASK;
366 skpair->state_change(skpair);
367 }
368 if(skpair!=NULL)
369 skpair->protinfo.af_unix.locks--;
370 sk->protinfo.af_unix.other=NULL;
371 unix_destroy_socket(sk);
372
373
374
375
376
377
378 return 0;
379 }
380
381
382 static unix_socket *unix_find_other(char *path, int *error)
383 {
384 int old_fs;
385 int err;
386 struct inode *inode;
387 unix_socket *u;
388
389 old_fs=get_fs();
390 set_fs(get_ds());
391 err = open_namei(path, 2, S_IFSOCK, &inode, NULL);
392 set_fs(old_fs);
393 if(err<0)
394 {
395 *error=err;
396 return NULL;
397 }
398 u=unix_find_socket(inode);
399 iput(inode);
400 if(u==NULL)
401 {
402 *error=-ECONNREFUSED;
403 return NULL;
404 }
405 return u;
406 }
407
408
409 static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
410 {
411 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
412 unix_socket *sk=sock->data;
413 int old_fs;
414 int err;
415
416 if(sk->protinfo.af_unix.name)
417 return -EINVAL;
418
419 if(addr_len>sizeof(struct sockaddr_un) || addr_len<3 || sunaddr->sun_family!=AF_UNIX)
420 return -EINVAL;
421 unix_mkname(sunaddr, addr_len);
422
423
424
425 if(sk->protinfo.af_unix.inode!=NULL)
426 return -EINVAL;
427
428 sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
429 if(sk->protinfo.af_unix.name==NULL)
430 return -ENOMEM;
431 memcpy(sk->protinfo.af_unix.name, sunaddr->sun_path, addr_len+1);
432
433 old_fs=get_fs();
434 set_fs(get_ds());
435
436 err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
437 if(err==0)
438 err=open_namei(sk->protinfo.af_unix.name, 2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);
439
440 set_fs(old_fs);
441
442 if(err<0)
443 {
444 kfree_s(sk->protinfo.af_unix.name,addr_len+1);
445 sk->protinfo.af_unix.name=NULL;
446 if(err==-EEXIST)
447 return -EADDRINUSE;
448 else
449 return err;
450 }
451
452 return 0;
453
454 }
455
456 static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
457 {
458 unix_socket *sk=sock->data;
459 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
460 unix_socket *other;
461 struct sk_buff *skb;
462 int err;
463
464 if(sk->type==SOCK_STREAM && sk->protinfo.af_unix.other)
465 {
466 if(sock->state==SS_CONNECTING && sk->state==TCP_ESTABLISHED)
467 {
468 sock->state=SS_CONNECTED;
469 return 0;
470 }
471 if(sock->state==SS_CONNECTING && sk->state == TCP_CLOSE)
472 {
473 sock->state=SS_UNCONNECTED;
474 return -ECONNREFUSED;
475 }
476 if(sock->state!=SS_CONNECTING)
477 return -EISCONN;
478 if(flags&O_NONBLOCK)
479 return -EALREADY;
480
481
482
483 }
484
485 if(addr_len < sizeof(sunaddr->sun_family)+1 || sunaddr->sun_family!=AF_UNIX)
486 return -EINVAL;
487
488 unix_mkname(sunaddr, addr_len);
489
490 if(sk->type==SOCK_DGRAM)
491 {
492 if(sk->protinfo.af_unix.other)
493 {
494 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
495 sk->protinfo.af_unix.other=NULL;
496 sock->state=SS_UNCONNECTED;
497 }
498 other=unix_find_other(sunaddr->sun_path, &err);
499 if(other==NULL)
500 return err;
501 if(other->type!=sk->type)
502 return -EPROTOTYPE;
503 other->protinfo.af_unix.locks++;
504 sk->protinfo.af_unix.other=other;
505 sock->state=SS_CONNECTED;
506 sk->state=TCP_ESTABLISHED;
507 return 0;
508 }
509
510
511 if(sock->state==SS_UNCONNECTED)
512 {
513
514
515
516
517 skb=sock_alloc_send_skb(sk, 0, 0, 0, &err);
518 if(skb==NULL)
519 return err;
520 skb->sk=sk;
521 skb->free=1;
522 sk->state=TCP_CLOSE;
523 unix_mkname(sunaddr, addr_len);
524 other=unix_find_other(sunaddr->sun_path, &err);
525 if(other==NULL)
526 {
527 kfree_skb(skb, FREE_WRITE);
528 return err;
529 }
530 if(other->type!=sk->type)
531 {
532 kfree_skb(skb, FREE_WRITE);
533 return -EPROTOTYPE;
534 }
535 other->protinfo.af_unix.locks++;
536 other->ack_backlog++;
537 sk->protinfo.af_unix.other=other;
538 skb_queue_tail(&other->receive_queue,skb);
539 sk->state=TCP_SYN_SENT;
540 sock->state=SS_CONNECTING;
541 sti();
542 other->data_ready(other,0);
543 }
544
545
546
547
548 cli();
549 while(sk->state==TCP_SYN_SENT)
550 {
551 if(flags&O_NONBLOCK)
552 {
553 sti();
554 return -EINPROGRESS;
555 }
556 interruptible_sleep_on(sk->sleep);
557 if(current->signal & ~current->blocked)
558 {
559 sti();
560 return -ERESTARTSYS;
561 }
562 }
563
564
565
566
567
568 if(sk->state==TCP_CLOSE)
569 {
570 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
571 sk->protinfo.af_unix.other=NULL;
572 sock->state=SS_UNCONNECTED;
573 sti();
574 return -ECONNREFUSED;
575 }
576
577
578
579
580
581 sock->state=SS_CONNECTED;
582 sti();
583 return 0;
584
585 }
586
587 static int unix_socketpair(struct socket *a, struct socket *b)
588 {
589 unix_socket *ska,*skb;
590
591 ska=a->data;
592 skb=b->data;
593
594
595 ska->protinfo.af_unix.locks++;
596 skb->protinfo.af_unix.locks++;
597 ska->protinfo.af_unix.other=skb;
598 skb->protinfo.af_unix.other=ska;
599 ska->state=TCP_ESTABLISHED;
600 skb->state=TCP_ESTABLISHED;
601 return 0;
602 }
603
604 static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
605 {
606 unix_socket *sk=sock->data;
607 unix_socket *newsk, *tsk;
608 struct sk_buff *skb;
609
610 if(sk->type!=SOCK_STREAM)
611 {
612 return -EOPNOTSUPP;
613 }
614 if(sk->state!=TCP_LISTEN)
615 {
616 return -EINVAL;
617 }
618
619 newsk=newsock->data;
620 if(sk->protinfo.af_unix.name!=NULL)
621 {
622 newsk->protinfo.af_unix.name=kmalloc(strlen(sk->protinfo.af_unix.name)+1, GFP_KERNEL);
623 if(newsk->protinfo.af_unix.name==NULL)
624 return -ENOMEM;
625 strcpy(newsk->protinfo.af_unix.name, sk->protinfo.af_unix.name);
626 }
627
628 do
629 {
630 cli();
631 skb=skb_dequeue(&sk->receive_queue);
632 if(skb==NULL)
633 {
634 if(flags&O_NONBLOCK)
635 {
636 sti();
637 return -EAGAIN;
638 }
639 interruptible_sleep_on(sk->sleep);
640 if(current->signal & ~current->blocked)
641 {
642 sti();
643 return -ERESTARTSYS;
644 }
645 sti();
646 }
647 }
648 while(skb==NULL);
649 tsk=skb->sk;
650 kfree_skb(skb, FREE_WRITE);
651 sk->ack_backlog--;
652 newsk->protinfo.af_unix.other=tsk;
653 tsk->protinfo.af_unix.other=newsk;
654 tsk->state=TCP_ESTABLISHED;
655 newsk->state=TCP_ESTABLISHED;
656 newsk->protinfo.af_unix.locks++;
657 sk->protinfo.af_unix.locks--;
658 tsk->protinfo.af_unix.locks++;
659 sti();
660 tsk->state_change(tsk);
661 sock_wake_async(tsk->socket, 0);
662 return 0;
663 }
664
665 static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
666 {
667 unix_socket *sk=sock->data;
668 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
669
670 if(peer)
671 {
672 if(sk->protinfo.af_unix.other==NULL)
673 return -ENOTCONN;
674 sk=sk->protinfo.af_unix.other;
675 }
676 sunaddr->sun_family=AF_UNIX;
677 if(sk->protinfo.af_unix.name==NULL)
678 {
679 *sunaddr->sun_path=0;
680 *uaddr_len=sizeof(sunaddr->sun_family)+1;
681 return 0;
682 }
683 *uaddr_len=sizeof(sunaddr->sun_family)+strlen(sk->protinfo.af_unix.name)+1;
684 strcpy(sunaddr->sun_path,sk->protinfo.af_unix.name);
685 return 0;
686 }
687
688
689
690
691
692 static struct cmsghdr *unix_copyrights(void *userp, int len)
693 {
694 struct cmsghdr *cm;
695
696 if(len>256|| len <=0)
697 return NULL;
698 cm=kmalloc(len, GFP_KERNEL);
699 memcpy_fromfs(cm, userp, len);
700 return cm;
701 }
702
703
704
705
706
707 static void unix_returnrights(void *userp, int len, struct cmsghdr *cm)
708 {
709 memcpy_tofs(userp, cm, len);
710 kfree(cm);
711 }
712
713
714
715
716
717
718 static int unix_fd_copy(struct sock *sk, struct cmsghdr *cmsg, struct file **fp)
719 {
720 int num=cmsg->cmsg_len-sizeof(struct cmsghdr);
721 int i;
722 int *fdp=(int *)cmsg->cmsg_data;
723 num/=4;
724
725
726 if(num>=UNIX_MAX_FD)
727 return -EINVAL;
728
729
730
731
732
733 for(i=0; i< num; i++)
734 {
735 int fd;
736
737 fd = fdp[i];
738 #if 0
739 printk("testing fd %d\n", fd);
740 #endif
741 if(fd < 0|| fd >=NR_OPEN)
742 return -EBADF;
743 if(current->files->fd[fd]==NULL)
744 return -EBADF;
745 }
746
747
748
749
750
751 if(unix_gc_free<num)
752 return -ENOBUFS;
753
754
755 for(i=0; i< num; i++)
756 {
757 fp[i]=current->files->fd[fdp[i]];
758 fp[i]->f_count++;
759 unix_gc_add(sk, fp[i]);
760 }
761
762 return num;
763 }
764
765
766
767
768
769 static void unix_fd_free(struct sock *sk, struct file **fp, int num)
770 {
771 int i;
772 for(i=0;i<num;i++)
773 {
774 close_fp(fp[i]);
775 unix_gc_remove(fp[i]);
776 }
777 }
778
779
780
781
782
783
784
785
786 static int unix_files_free(void)
787 {
788 int i;
789 int n=0;
790 for (i=0;i<NR_OPEN;i++)
791 {
792 if(current->files->fd[i])
793 n++;
794 }
795
796 i=NR_OPEN;
797 if(i>current->rlim[RLIMIT_NOFILE].rlim_cur)
798 i=current->rlim[RLIMIT_NOFILE].rlim_cur;
799 if(n>=i)
800 return 0;
801 return i-n;
802 }
803
804
805
806
807
808
809 static void unix_detach_fds(struct sk_buff *skb, struct cmsghdr *cmsg)
810 {
811 int i;
812
813 int cmnum;
814 struct file **fp;
815 struct file **ufp;
816 int *cmfptr=NULL;
817
818 int fdnum;
819 int ffree;
820 int ufn=0;
821
822 if(cmsg==NULL)
823 cmnum=0;
824 else
825 {
826 cmnum=cmsg->cmsg_len-sizeof(struct cmsghdr);
827 cmnum/=sizeof(int);
828 cmfptr=(int *)&cmsg->cmsg_data;
829 }
830
831 memcpy(&fdnum,skb->h.filp,sizeof(int));
832 fp=(struct file **)(skb->h.filp+sizeof(int));
833 if(cmnum>fdnum)
834 cmnum=fdnum;
835 ffree=unix_files_free();
836 if(cmnum>ffree)
837 cmnum=ffree;
838 ufp=¤t->files->fd[0];
839
840
841
842
843 for(i=0;i<cmnum;i++)
844 {
845
846
847
848 while(ufp[ufn]!=NULL)
849 ufn++;
850 ufp[ufn]=fp[i];
851 *cmfptr++=ufn;
852 FD_CLR(ufn,¤t->files->close_on_exec);
853 unix_gc_remove(fp[i]);
854 }
855
856
857
858 for(;i<fdnum;i++)
859 {
860 close_fp(fp[i]);
861 unix_gc_remove(fp[i]);
862 }
863 kfree(skb->h.filp);
864 skb->h.filp=NULL;
865
866
867 skb->destructor = NULL;
868 }
869
870 static void unix_destruct_fds(struct sk_buff *skb)
871 {
872 unix_detach_fds(skb,NULL);
873 }
874
875
876
877
878 static void unix_attach_fds(int fpnum,struct file **fp,struct sk_buff *skb)
879 {
880
881 skb->h.filp=kmalloc(sizeof(int)+fpnum*sizeof(struct file *),
882 GFP_KERNEL);
883
884 memcpy(skb->h.filp,&fpnum,sizeof(int));
885
886 memcpy(skb->h.filp+sizeof(int),fp,fpnum*sizeof(struct file *));
887 skb->destructor = unix_destruct_fds;
888 }
889
890
891
892
893
894 static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
895 {
896 unix_socket *sk=sock->data;
897 unix_socket *other;
898 struct sockaddr_un *sunaddr=msg->msg_name;
899 int err,size;
900 struct sk_buff *skb;
901 int limit=0;
902 int sent=0;
903 struct file *fp[UNIX_MAX_FD];
904
905
906
907 int fpnum=0;
908
909 if(sk->err)
910 return sock_error(sk);
911
912 if(flags&MSG_OOB)
913 return -EOPNOTSUPP;
914
915 if(flags) {
916 return -EINVAL;
917 }
918
919 if(sunaddr!=NULL)
920 {
921 if(sock->type==SOCK_STREAM)
922 {
923 if(sk->state==TCP_ESTABLISHED)
924 return -EISCONN;
925 else
926 return -EOPNOTSUPP;
927 }
928 }
929
930 if(sunaddr==NULL)
931 {
932 if(sk->protinfo.af_unix.other==NULL)
933 return -ENOTCONN;
934 }
935
936
937
938
939 if(msg->msg_accrights)
940 {
941 struct cmsghdr *cm=unix_copyrights(msg->msg_accrights,
942 msg->msg_accrightslen);
943 if(cm==NULL || msg->msg_accrightslen<sizeof(struct cmsghdr) ||
944 cm->cmsg_type!=SCM_RIGHTS ||
945 cm->cmsg_level!=SOL_SOCKET ||
946 msg->msg_accrightslen!=cm->cmsg_len)
947 {
948 kfree(cm);
949 return -EINVAL;
950 }
951 fpnum=unix_fd_copy(sk,cm,fp);
952 kfree(cm);
953 if(fpnum<0) {
954 return fpnum;
955 }
956 }
957
958 while(sent < len)
959 {
960
961
962
963
964
965 size=len-sent;
966
967 if(size>(sk->sndbuf-sizeof(struct sk_buff))/2)
968 {
969 if(sock->type==SOCK_DGRAM)
970 {
971 unix_fd_free(sk,fp,fpnum);
972 return -EMSGSIZE;
973 }
974 size=(sk->sndbuf-sizeof(struct sk_buff))/2;
975 }
976
977
978
979
980
981
982 if(size > 4000 && sock->type!=SOCK_DGRAM)
983 limit = 4000;
984 else
985 limit = 0;
986
987
988
989
990
991 skb=sock_alloc_send_skb(sk,size,limit,nonblock, &err);
992
993 if(skb==NULL)
994 {
995 unix_fd_free(sk,fp,fpnum);
996 if(sent)
997 {
998 sk->err=-err;
999 return sent;
1000 }
1001 return err;
1002 }
1003 size=skb_tailroom(skb);
1004
1005 skb->sk=sk;
1006 skb->free=1;
1007
1008 if(fpnum)
1009 {
1010 unix_attach_fds(fpnum,fp,skb);
1011 fpnum=0;
1012 }
1013 else
1014 skb->h.filp=NULL;
1015
1016 memcpy_fromiovec(skb_put(skb,size),msg->msg_iov, size);
1017
1018 cli();
1019 if(sunaddr==NULL)
1020 {
1021 other=sk->protinfo.af_unix.other;
1022 if(sock->type==SOCK_DGRAM && other->dead)
1023 {
1024 other->protinfo.af_unix.locks--;
1025 sk->protinfo.af_unix.other=NULL;
1026 sock->state=SS_UNCONNECTED;
1027 sti();
1028 kfree_skb(skb, FREE_WRITE);
1029 if(!sent)
1030 return -ECONNRESET;
1031 else
1032 return sent;
1033 }
1034 }
1035 else
1036 {
1037 unix_mkname(sunaddr, msg->msg_namelen);
1038 other=unix_find_other(sunaddr->sun_path, &err);
1039 if(other==NULL)
1040 {
1041 sti();
1042 kfree_skb(skb, FREE_WRITE);
1043 if(sent)
1044 return sent;
1045 else
1046 return err;
1047 }
1048 }
1049 skb_queue_tail(&other->receive_queue, skb);
1050 sti();
1051
1052 other->data_ready(other,size);
1053 sent+=size;
1054 }
1055 return sent;
1056 }
1057
1058
1059
1060
1061
1062 static void unix_data_wait(unix_socket * sk)
1063 {
1064 cli();
1065 if (!skb_peek(&sk->receive_queue)) {
1066 sk->socket->flags |= SO_WAITDATA;
1067 interruptible_sleep_on(sk->sleep);
1068 sk->socket->flags &= ~SO_WAITDATA;
1069 }
1070 sti();
1071 }
1072
1073 static int unix_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
1074 {
1075 unix_socket *sk=sock->data;
1076 struct sockaddr_un *sunaddr=msg->msg_name;
1077 struct sk_buff *skb;
1078 int copied=0;
1079 unsigned char *sp;
1080 int len;
1081 int num;
1082 struct iovec *iov=msg->msg_iov;
1083 struct cmsghdr *cm=NULL;
1084 int ct=msg->msg_iovlen;
1085
1086 if(flags&MSG_OOB)
1087 return -EOPNOTSUPP;
1088
1089 if(addr_len)
1090 *addr_len=0;
1091
1092 if(sk->err)
1093 return sock_error(sk);
1094
1095 if(msg->msg_accrights)
1096 {
1097 cm=unix_copyrights(msg->msg_accrights,
1098 msg->msg_accrightslen);
1099 if(msg->msg_accrightslen<sizeof(struct cmsghdr)
1100 #if 0
1101
1102 ||
1103 cm->cmsg_type!=SCM_RIGHTS ||
1104 cm->cmsg_level!=SOL_SOCKET ||
1105 msg->msg_accrightslen!=cm->cmsg_len
1106 #endif
1107 )
1108 {
1109 kfree(cm);
1110 printk("recvmsg: Bad msg_accrights\n");
1111 return -EINVAL;
1112 }
1113 }
1114
1115 down(&sk->protinfo.af_unix.readsem);
1116 while(ct--)
1117 {
1118 int done=0;
1119 sp=iov->iov_base;
1120 len=iov->iov_len;
1121 iov++;
1122
1123 while(done<len)
1124 {
1125 if (copied && (flags & MSG_PEEK))
1126 goto out;
1127 if (copied == size)
1128 goto out;
1129 skb=skb_dequeue(&sk->receive_queue);
1130 if(skb==NULL)
1131 {
1132 up(&sk->protinfo.af_unix.readsem);
1133 if(sk->shutdown & RCV_SHUTDOWN)
1134 return copied;
1135 if(copied)
1136 return copied;
1137 if(noblock)
1138 return -EAGAIN;
1139 if(current->signal & ~current->blocked)
1140 return -ERESTARTSYS;
1141 unix_data_wait(sk);
1142 down(&sk->protinfo.af_unix.readsem);
1143 continue;
1144 }
1145 if(msg->msg_name!=NULL)
1146 {
1147 sunaddr->sun_family=AF_UNIX;
1148 if(skb->sk->protinfo.af_unix.name)
1149 {
1150 memcpy(sunaddr->sun_path, skb->sk->protinfo.af_unix.name, 108);
1151 if(addr_len)
1152 *addr_len=strlen(sunaddr->sun_path)+sizeof(short);
1153 }
1154 else
1155 if(addr_len)
1156 *addr_len=sizeof(short);
1157 }
1158
1159 num=min(skb->len,size-copied);
1160 memcpy_tofs(sp, skb->data, num);
1161
1162 if (skb->h.filp!=NULL)
1163 unix_detach_fds(skb,cm);
1164
1165 copied+=num;
1166 done+=num;
1167 sp+=num;
1168 if (!(flags & MSG_PEEK))
1169 skb_pull(skb, num);
1170
1171 if (skb->len) {
1172 skb_queue_head(&sk->receive_queue, skb);
1173 continue;
1174 }
1175 kfree_skb(skb, FREE_WRITE);
1176 if(sock->type==SOCK_DGRAM || cm)
1177 goto out;
1178 }
1179 }
1180 out:
1181 up(&sk->protinfo.af_unix.readsem);
1182 if(cm)
1183 unix_returnrights(msg->msg_accrights,msg->msg_accrightslen,cm);
1184 return copied;
1185 }
1186
1187 static int unix_shutdown(struct socket *sock, int mode)
1188 {
1189 unix_socket *sk=(unix_socket *)sock->data;
1190 unix_socket *other=sk->protinfo.af_unix.other;
1191 if(mode&SEND_SHUTDOWN)
1192 {
1193 sk->shutdown|=SEND_SHUTDOWN;
1194 sk->state_change(sk);
1195 if(other)
1196 {
1197 other->shutdown|=RCV_SHUTDOWN;
1198 other->state_change(other);
1199 }
1200 }
1201 other=sk->protinfo.af_unix.other;
1202 if(mode&RCV_SHUTDOWN)
1203 {
1204 sk->shutdown|=RCV_SHUTDOWN;
1205 sk->state_change(sk);
1206 if(other)
1207 {
1208 other->shutdown|=SEND_SHUTDOWN;
1209 other->state_change(other);
1210 }
1211 }
1212 return 0;
1213 }
1214
1215
1216 static int unix_select(struct socket *sock, int sel_type, select_table *wait)
1217 {
1218 return datagram_select(sock->data,sel_type,wait);
1219 }
1220
1221 static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1222 {
1223 unix_socket *sk=sock->data;
1224 int err;
1225 long amount=0;
1226
1227 switch(cmd)
1228 {
1229
1230 case TIOCOUTQ:
1231 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1232 if(err)
1233 return err;
1234 amount=sk->sndbuf-sk->wmem_alloc;
1235 if(amount<0)
1236 amount=0;
1237 put_fs_long(amount,(unsigned long *)arg);
1238 return 0;
1239 case TIOCINQ:
1240 {
1241 struct sk_buff *skb;
1242 if(sk->state==TCP_LISTEN)
1243 return -EINVAL;
1244
1245 if((skb=skb_peek(&sk->receive_queue))!=NULL)
1246 amount=skb->len;
1247 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1248 put_fs_long(amount,(unsigned long *)arg);
1249 return 0;
1250 }
1251
1252 default:
1253 return -EINVAL;
1254 }
1255
1256 return(0);
1257 }
1258
1259 #ifdef CONFIG_PROC_FS
1260 static int unix_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
1261 {
1262 off_t pos=0;
1263 off_t begin=0;
1264 int len=0;
1265 unix_socket *s=unix_socket_list;
1266
1267 len+= sprintf(buffer,"Num RefCount Protocol Flags Type St Path\n");
1268
1269 while(s!=NULL)
1270 {
1271 len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
1272 s,
1273 s->protinfo.af_unix.locks,
1274 0,
1275 s->socket->flags,
1276 s->socket->type,
1277 s->socket->state);
1278 if(s->protinfo.af_unix.name!=NULL)
1279 len+=sprintf(buffer+len, " %s\n", s->protinfo.af_unix.name);
1280 else
1281 buffer[len++]='\n';
1282
1283 pos=begin+len;
1284 if(pos<offset)
1285 {
1286 len=0;
1287 begin=pos;
1288 }
1289 if(pos>offset+length)
1290 break;
1291 s=s->next;
1292 }
1293 *start=buffer+(offset-begin);
1294 len-=(offset-begin);
1295 if(len>length)
1296 len=length;
1297 return len;
1298 }
1299 #endif
1300
1301 static struct proto_ops unix_proto_ops = {
1302 AF_UNIX,
1303
1304 unix_create,
1305 unix_dup,
1306 unix_release,
1307 unix_bind,
1308 unix_connect,
1309 unix_socketpair,
1310 unix_accept,
1311 unix_getname,
1312 unix_select,
1313 unix_ioctl,
1314 unix_listen,
1315 unix_shutdown,
1316 unix_setsockopt,
1317 unix_getsockopt,
1318 unix_fcntl,
1319 unix_sendmsg,
1320 unix_recvmsg
1321 };
1322
1323
1324 void unix_proto_init(struct net_proto *pro)
1325 {
1326 printk("NET3: Unix domain sockets 0.12 for Linux NET3.033.\n");
1327 sock_register(unix_proto_ops.family, &unix_proto_ops);
1328 #ifdef CONFIG_PROC_FS
1329 proc_net_register(&(struct proc_dir_entry) {
1330 PROC_NET_UNIX, 4, "unix",
1331 S_IFREG | S_IRUGO, 1, 0, 0,
1332 0, &proc_net_inode_operations,
1333 unix_get_info
1334 });
1335 #endif
1336 }
1337
1338
1339
1340
1341