Import 1.3.22
[davej-history.git] / net / unix / af_unix.c
blobe91b9ec61cdaa28e199f44de631da44eca96c1c3
1 /*
2 * NET3: Implementation of BSD Unix domain sockets.
4 * Authors: Alan Cox, <alan@cymru.net>
6 * Currently this contains all but the file descriptor passing code.
7 * Before that goes in the odd bugs in the iovec handlers need
8 * fixing, and this bit testing. BSD fd passing is not a trivial part
9 * of the exercise it turns out. Anyone like writing garbage collectors.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
16 * Fixes:
17 * Linus Torvalds : Assorted bug cures.
18 * Niibe Yutaka : async I/O support.
19 * Carsten Paeth : PF_UNIX check, address fixes.
20 * Alan Cox : Limit size of allocated blocks.
23 #include <linux/config.h>
24 #include <linux/kernel.h>
25 #include <linux/major.h>
26 #include <linux/signal.h>
27 #include <linux/sched.h>
28 #include <linux/errno.h>
29 #include <linux/string.h>
30 #include <linux/stat.h>
31 #include <linux/socket.h>
32 #include <linux/un.h>
33 #include <linux/fcntl.h>
34 #include <linux/termios.h>
35 #include <linux/socket.h>
36 #include <linux/sockios.h>
37 #include <linux/net.h>
38 #include <linux/in.h>
39 #include <linux/fs.h>
40 #include <linux/malloc.h>
41 #include <asm/segment.h>
42 #include <linux/skbuff.h>
43 #include <linux/netdevice.h>
44 #include <net/sock.h>
45 #include <net/tcp.h>
46 #include <net/af_unix.h>
47 #include <linux/proc_fs.h>
49 static unix_socket *volatile unix_socket_list=NULL;
51 #define min(a,b) (((a)<(b))?(a):(b))
54 * Make sure the unix name is null-terminated.
56 staticinlinevoidunix_mkname(struct sockaddr_un * sun,unsigned long len)
58 if(len >=sizeof(*sun))
59 len =sizeof(*sun)-1;
60 ((char*)sun)[len]=0;
64 * Note: Sockets may not be removed _during_ an interrupt or net_bh
65 * handler using this technique. They can be added although we do not
66 * use this facility.
69 static voidunix_remove_socket(unix_socket *sk)
71 unix_socket *s;
73 cli();
74 s=unix_socket_list;
75 if(s==sk)
77 unix_socket_list=s->next;
78 sti();
79 return;
81 while(s && s->next)
83 if(s->next==sk)
85 s->next=sk->next;
86 sti();
87 return;
89 s=s->next;
91 sti();
94 static voidunix_insert_socket(unix_socket *sk)
96 cli();
97 sk->next=unix_socket_list;
98 unix_socket_list=sk;
99 sti();
102 static unix_socket *unix_find_socket(struct inode *i)
104 unix_socket *s;
105 cli();
106 s=unix_socket_list;
107 while(s)
109 if(s->protinfo.af_unix.inode==i)
111 sti();
112 return(s);
114 s=s->next;
116 sti();
117 return(NULL);
121 * Delete a unix socket. We have to allow for deferring this on a timer.
124 static voidunix_destroy_timer(unsigned long data)
126 unix_socket *sk=(unix_socket *)data;
127 if(sk->protinfo.af_unix.locks==0&& sk->wmem_alloc==0)
129 if(sk->protinfo.af_unix.name)
130 kfree(sk->protinfo.af_unix.name);
131 kfree_s(sk,sizeof(*sk));
132 return;
136 * Retry;
139 init_timer(&sk->timer);
140 sk->timer.expires=jiffies+10*HZ;/* No real hurry try it every 10 seconds or so */
141 add_timer(&sk->timer);
145 static voidunix_delayed_delete(unix_socket *sk)
147 init_timer(&sk->timer);
148 sk->timer.data=(unsigned long)sk;
149 sk->timer.expires=jiffies+HZ;/* Normally 1 second after will clean up. After that we try every 10 */
150 sk->timer.function=unix_destroy_timer;
151 add_timer(&sk->timer);
154 static voidunix_destroy_socket(unix_socket *sk)
156 struct sk_buff *skb;
157 unix_remove_socket(sk);
159 while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
161 if(sk->state==TCP_LISTEN)
163 unix_socket *osk=skb->sk;
164 osk->state=TCP_CLOSE;
165 kfree_skb(skb, FREE_WRITE);/* Now surplus - free the skb first before the socket */
166 osk->state_change(osk);/* So the connect wakes and cleans up (if any) */
167 /* osk will be destroyed when it gets to close or the timer fires */
169 else
171 /* unix_kill_credentials(skb); *//* Throw out any passed fd's */
172 kfree_skb(skb,FREE_WRITE);
176 if(sk->protinfo.af_unix.inode!=NULL)
178 iput(sk->protinfo.af_unix.inode);
179 sk->protinfo.af_unix.inode=NULL;
182 if(--sk->protinfo.af_unix.locks==0&& sk->wmem_alloc==0)
184 if(sk->protinfo.af_unix.name)
185 kfree(sk->protinfo.af_unix.name);
186 kfree_s(sk,sizeof(*sk));
188 else
190 sk->dead=1;
191 unix_delayed_delete(sk);/* Try every so often until buffers are all freed */
196 * Fixme: We need async I/O on AF_UNIX doing next.
199 static intunix_fcntl(struct socket *sock,unsigned int cmd,unsigned long arg)
201 return-EINVAL;
205 * Yes socket options work with the new unix domain socketry!!!!!!!
208 static intunix_setsockopt(struct socket *sock,int level,int optname,char*optval,int optlen)
210 unix_socket *sk=sock->data;
211 if(level!=SOL_SOCKET)
212 return-EOPNOTSUPP;
213 returnsock_setsockopt(sk,level,optname,optval,optlen);
216 static intunix_getsockopt(struct socket *sock,int level,int optname,char*optval,int*optlen)
218 unix_socket *sk=sock->data;
219 if(level!=SOL_SOCKET)
220 return-EOPNOTSUPP;
221 returnsock_getsockopt(sk,level,optname,optval,optlen);
224 static intunix_listen(struct socket *sock,int backlog)
226 unix_socket *sk=sock->data;
227 if(sk->type!=SOCK_STREAM)
228 return-EOPNOTSUPP;/* Only stream sockets accept */
229 sk->max_ack_backlog=backlog;
230 sk->state=TCP_LISTEN;
231 return0;
234 static voiddef_callback1(struct sock *sk)
236 if(!sk->dead)
237 wake_up_interruptible(sk->sleep);
240 static voiddef_callback2(struct sock *sk,int len)
242 if(!sk->dead)
244 wake_up_interruptible(sk->sleep);
245 sock_wake_async(sk->socket,1);
249 static voiddef_callback3(struct sock *sk)
251 if(!sk->dead)
253 wake_up_interruptible(sk->sleep);
254 sock_wake_async(sk->socket,2);
258 static intunix_create(struct socket *sock,int protocol)
260 unix_socket *sk;
261 /* printk("Unix create\n");*/
262 if(protocol && protocol != PF_UNIX)
263 return-EPROTONOSUPPORT;
264 sk=(unix_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
265 if(sk==NULL)
266 return-ENOMEM;
267 sk->type=sock->type;
268 switch(sock->type)
270 case SOCK_STREAM:
271 break;
272 case SOCK_DGRAM:
273 break;
274 default:
275 kfree_s(sk,sizeof(*sk));
276 return-ESOCKTNOSUPPORT;
278 skb_queue_head_init(&sk->write_queue);
279 skb_queue_head_init(&sk->receive_queue);
280 skb_queue_head_init(&sk->back_log);
281 sk->protinfo.af_unix.family=AF_UNIX;
282 sk->protinfo.af_unix.inode=NULL;
283 sk->protinfo.af_unix.locks=1;/* Us */
284 sk->protinfo.af_unix.readsem=MUTEX;/* single task reading lock */
285 sk->protinfo.af_unix.name=NULL;
286 sk->protinfo.af_unix.other=NULL;
287 sk->protocol=0;
288 sk->rmem_alloc=0;
289 sk->wmem_alloc=0;
290 sk->dead=0;
291 sk->next=NULL;
292 sk->broadcast=0;
293 sk->rcvbuf=SK_RMEM_MAX;
294 sk->sndbuf=SK_WMEM_MAX;
295 sk->inuse=0;
296 sk->debug=0;
297 sk->prot=NULL;
298 sk->err=0;
299 sk->localroute=0;
300 sk->send_head=NULL;
301 sk->state=TCP_CLOSE;
302 sk->priority=SOPRI_NORMAL;
303 sk->ack_backlog=0;
304 sk->shutdown=0;
305 sk->state_change=def_callback1;
306 sk->data_ready=def_callback2;
307 sk->write_space=def_callback3;
308 sk->error_report=def_callback1;
309 sk->mtu=4096;
310 sk->socket=sock;
311 sock->data=(void*)sk;
312 sk->sleep=sock->wait;
313 sk->zapped=0;
314 unix_insert_socket(sk);
315 return0;
318 static intunix_dup(struct socket *newsock,struct socket *oldsock)
320 returnunix_create(newsock,0);
323 static intunix_release(struct socket *sock,struct socket *peer)
325 unix_socket *sk=sock->data;
326 unix_socket *skpair;
328 /* May not have data attached */
330 if(sk==NULL)
331 return0;
333 sk->state_change(sk);
334 sk->dead=1;
335 skpair=(unix_socket *)sk->protinfo.af_unix.other;/* Person we send to (default) */
336 if(sk->type==SOCK_STREAM && skpair!=NULL && skpair->state!=TCP_LISTEN)
338 skpair->shutdown=SHUTDOWN_MASK;/* No more writes */
339 skpair->state_change(skpair);/* Wake any blocked writes */
341 if(skpair!=NULL)
342 skpair->protinfo.af_unix.locks--;/* It may now die */
343 sk->protinfo.af_unix.other=NULL;/* No pair */
344 unix_destroy_socket(sk);/* Try and flush out this socket. Throw our buffers at least */
345 return0;
349 static unix_socket *unix_find_other(char*path,int*error)
351 int old_fs;
352 int err;
353 struct inode *inode;
354 unix_socket *u;
356 old_fs=get_fs();
357 set_fs(get_ds());
358 err =open_namei(path,2, S_IFSOCK, &inode, NULL);
359 set_fs(old_fs);
360 if(err<0)
362 *error=err;
363 return NULL;
365 u=unix_find_socket(inode);
366 iput(inode);
367 if(u==NULL)
369 *error=-ECONNREFUSED;
370 return NULL;
372 return u;
376 static intunix_bind(struct socket *sock,struct sockaddr *uaddr,int addr_len)
378 struct sockaddr_un *sun=(struct sockaddr_un *)uaddr;
379 unix_socket *sk=sock->data;
380 int old_fs;
381 int err;
383 if(addr_len>sizeof(struct sockaddr_un) || addr_len<3|| sun->sun_family!=AF_UNIX)
384 return-EINVAL;
385 unix_mkname(sun, addr_len);
387 * Put ourselves in the filesystem
389 if(sk->protinfo.af_unix.inode!=NULL)
390 return-EINVAL;
392 sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
393 if(sk->protinfo.af_unix.name==NULL)
394 return-ENOMEM;
395 memcpy(sk->protinfo.af_unix.name, sun->sun_path, addr_len+1);
397 old_fs=get_fs();
398 set_fs(get_ds());
400 err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
401 if(err==0)
402 err=open_namei(sk->protinfo.af_unix.name,2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);
404 set_fs(old_fs);
406 if(err<0)
408 kfree_s(sk->protinfo.af_unix.name,addr_len+1);
409 sk->protinfo.af_unix.name=NULL;
410 if(err==-EEXIST)
411 return-EADDRINUSE;
412 else
413 return err;
416 return0;
420 static intunix_connect(struct socket *sock,struct sockaddr *uaddr,int addr_len,int flags)
422 unix_socket *sk=sock->data;
423 struct sockaddr_un *sun=(struct sockaddr_un *)uaddr;
424 unix_socket *other;
425 struct sk_buff *skb;
426 int err;
428 if(sk->type==SOCK_STREAM && sk->protinfo.af_unix.other)
430 if(sock->state==SS_CONNECTING && sk->state==TCP_ESTABLISHED)
432 sock->state=SS_CONNECTED;
433 return0;
435 if(sock->state==SS_CONNECTING && sk->state == TCP_CLOSE)
437 sock->state=SS_UNCONNECTED;
438 return-ECONNREFUSED;
440 if(sock->state==SS_CONNECTING)
441 return-EALREADY;
442 return-EISCONN;
445 if(addr_len <sizeof(sun->sun_family)+1|| sun->sun_family!=AF_UNIX)
446 return-EINVAL;
448 unix_mkname(sun, addr_len);
450 if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other)
452 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
453 sk->protinfo.af_unix.other=NULL;
454 sock->state=SS_UNCONNECTED;
457 if(sock->type==SOCK_DGRAM)
459 other=unix_find_other(sun->sun_path, &err);
460 if(other==NULL)
461 return err;
462 other->protinfo.af_unix.locks++;
463 sk->protinfo.af_unix.other=other;
464 sock->state=SS_CONNECTED;
465 sk->state=TCP_ESTABLISHED;
466 return0;/* Done */
470 if(sock->state==SS_UNCONNECTED)
473 * Now ready to connect
476 skb=sock_alloc_send_skb(sk,0,0, &err);/* Marker object */
477 if(skb==NULL)
478 return err;
479 skb->sk=sk;/* So they know it is us */
480 skb->free=1;
481 sk->state=TCP_CLOSE;
482 unix_mkname(sun, addr_len);
483 other=unix_find_other(sun->sun_path, &err);
484 if(other==NULL)
486 kfree_skb(skb, FREE_WRITE);
487 return err;
489 other->protinfo.af_unix.locks++;/* Lock the other socket so it doesn't run off for a moment */
490 other->ack_backlog++;
491 sk->protinfo.af_unix.other=other;
492 skb_queue_tail(&other->receive_queue,skb);
493 sk->state=TCP_SYN_SENT;
494 sock->state=SS_CONNECTING;
495 sti();
496 other->data_ready(other,0);/* Wake up ! */
500 /* Wait for an accept */
502 cli();
503 while(sk->state==TCP_SYN_SENT)
505 if(flags&O_NONBLOCK)
507 sti();
508 return-EINPROGRESS;
510 interruptible_sleep_on(sk->sleep);
511 if(current->signal & ~current->blocked)
513 sti();
514 return-ERESTARTSYS;
519 * Has the other end closed on us ?
522 if(sk->state==TCP_CLOSE)
524 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
525 sk->protinfo.af_unix.other=NULL;
526 sock->state=SS_UNCONNECTED;
527 sti();
528 return-ECONNREFUSED;
532 * Amazingly it has worked
535 sock->state=SS_CONNECTED;
536 sti();
537 return0;
541 static intunix_socketpair(struct socket *a,struct socket *b)
543 int err;
544 unix_socket *ska,*skb;
546 err=unix_create(a,0);
547 if(err)
548 return err;
549 err=unix_create(b,0);
550 if(err)
552 unix_release(a, NULL);
553 a->data=NULL;
554 return err;
557 ska=a->data;
558 skb=b->data;
560 /* Join our sockets back to back */
561 ska->protinfo.af_unix.locks++;
562 skb->protinfo.af_unix.locks++;
563 ska->protinfo.af_unix.other=skb;
564 skb->protinfo.af_unix.other=ska;
565 ska->state=TCP_ESTABLISHED;
566 skb->state=TCP_ESTABLISHED;
567 return0;
570 static intunix_accept(struct socket *sock,struct socket *newsock,int flags)
572 unix_socket *sk=sock->data;
573 unix_socket *newsk, *tsk;
574 struct sk_buff *skb;
576 if(sk->type!=SOCK_STREAM)
578 return-EOPNOTSUPP;
580 if(sk->state!=TCP_LISTEN)
582 return-EINVAL;
585 newsk=newsock->data;
586 if(sk->protinfo.af_unix.name!=NULL)
588 newsk->protinfo.af_unix.name=kmalloc(strlen(sk->protinfo.af_unix.name)+1, GFP_KERNEL);
589 if(newsk->protinfo.af_unix.name==NULL)
590 return-ENOMEM;
591 strcpy(newsk->protinfo.af_unix.name, sk->protinfo.af_unix.name);
596 cli();
597 skb=skb_dequeue(&sk->receive_queue);
598 if(skb==NULL)
600 if(flags&O_NONBLOCK)
602 sti();
603 return-EAGAIN;
605 interruptible_sleep_on(sk->sleep);
606 if(current->signal & ~current->blocked)
608 sti();
609 return-ERESTARTSYS;
611 sti();
614 while(skb==NULL);
615 tsk=skb->sk;
616 kfree_skb(skb, FREE_WRITE);/* The buffer is just used as a tag */
617 sk->ack_backlog--;
618 newsk->protinfo.af_unix.other=tsk;
619 tsk->protinfo.af_unix.other=newsk;
620 tsk->state=TCP_ESTABLISHED;
621 newsk->state=TCP_ESTABLISHED;
622 newsk->protinfo.af_unix.locks++;/* Swap lock over */
623 sk->protinfo.af_unix.locks--;/* Locked to child socket not master */
624 tsk->protinfo.af_unix.locks++;/* Back lock */
625 sti();
626 tsk->state_change(tsk);/* Wake up any sleeping connect */
627 sock_wake_async(tsk->socket,0);
628 return0;
631 static intunix_getname(struct socket *sock,struct sockaddr *uaddr,int*uaddr_len,int peer)
633 unix_socket *sk=sock->data;
634 struct sockaddr_un *sun=(struct sockaddr_un *)uaddr;
636 if(peer)
638 if(sk->protinfo.af_unix.other==NULL)
639 return-ENOTCONN;
640 sk=sk->protinfo.af_unix.other;
642 sun->sun_family=AF_UNIX;
643 if(sk->protinfo.af_unix.name==NULL)
645 *sun->sun_path=0;
646 *uaddr_len=sizeof(sun->sun_family)+1;
647 return0;/* Not bound */
649 *uaddr_len=sizeof(sun->sun_family)+strlen(sk->protinfo.af_unix.name)+1;
650 strcpy(sun->sun_path,sk->protinfo.af_unix.name);/* 108 byte limited */
651 return0;
654 static intunix_sendmsg(struct socket *sock,struct msghdr *msg,int len,int nonblock,int flags)
656 unix_socket *sk=sock->data;
657 unix_socket *other;
658 struct sockaddr_un *sun=msg->msg_name;
659 int err,size;
660 struct sk_buff *skb;
662 if(sk->err)
664 cli();
665 err=sk->err;
666 sk->err=0;
667 sti();
668 return-err;
671 if(flags || msg->msg_accrights)/* For now */
672 return-EINVAL;
674 if(sun!=NULL)
676 if(sock->type==SOCK_STREAM)
678 if(sk->state==TCP_ESTABLISHED)
679 return-EISCONN;
680 else
681 return-EOPNOTSUPP;
684 if(sun==NULL)
686 if(sk->protinfo.af_unix.other==NULL)
687 return-ENOTCONN;
691 * Optimisation for the fact that under 0.01% of X messages typically
692 * need breaking up.
695 if(len>(sk->sndbuf-sizeof(struct sk_buff))/2)/* Keep two messages in the pipe so it schedules better */
697 if(sock->type==SOCK_DGRAM)
698 return-EMSGSIZE;
699 len=(sk->sndbuf-sizeof(struct sk_buff))/2;
701 * Keep to page sized kmalloc()'s as various people
702 * have suggested. Big mallocs stress the vm too
703 * much.
705 if(len >4000&& sock->type!=SOCK_DGRAM)
706 len =4000;
709 size=/*protocol_size(&proto_unix)+*/len;
710 skb=sock_alloc_send_skb(sk,size,nonblock, &err);
711 if(skb==NULL)
712 return err;
713 /* protocol_adjust(skb,&proto_unix);*/
714 skb->sk=sk;
715 skb->free=1;
716 memcpy_fromiovec(skb_put(skb,len),msg->msg_iov, len);
718 cli();
719 if(sun==NULL)
721 other=sk->protinfo.af_unix.other;
722 if(sock->type==SOCK_DGRAM && other->dead)
724 other->protinfo.af_unix.locks--;
725 sk->protinfo.af_unix.other=NULL;
726 sock->state=SS_UNCONNECTED;
727 sti();
728 return-ECONNRESET;
731 else
733 unix_mkname(sun, msg->msg_namelen);
734 other=unix_find_other(sun->sun_path, &err);
735 if(other==NULL)
737 kfree_skb(skb, FREE_WRITE);
738 sti();
739 return err;
742 skb_queue_tail(&other->receive_queue, skb);
743 sti();
744 other->data_ready(other,len);
745 return len;
748 static intunix_recvmsg(struct socket *sock,struct msghdr *msg,int size,int noblock,int flags,int*addr_len)
750 unix_socket *sk=sock->data;
751 struct sockaddr_un *sun=msg->msg_name;
752 int err;
753 struct sk_buff *skb;
754 int copied=0;
755 unsigned char*sp;
756 int len;
757 int num;
758 struct iovec *iov=msg->msg_iov;
759 int ct=msg->msg_iovlen;
761 if(addr_len)
762 *addr_len=0;
764 if(sk->err)
766 cli();
767 err=sk->err;
768 sk->err=0;
769 sti();
770 return-err;
773 /* printk("get rcv sem\n");*/
774 down(&sk->protinfo.af_unix.readsem);/* Lock the socket */
775 /* printk("got rcv sem\n");*/
777 while(ct--)
779 int done=0;
780 sp=iov->iov_base;
781 len=iov->iov_len;
782 iov++;
784 while(done<len)
786 if(copied & (flags&MSG_PEEK))
788 up(&sk->protinfo.af_unix.readsem);
789 return copied;
791 cli();
792 skb=skb_peek(&sk->receive_queue);
793 if(skb==NULL)
795 up(&sk->protinfo.af_unix.readsem);
796 if(sk->shutdown & RCV_SHUTDOWN)
798 sti();
799 return copied;
801 if(copied)
803 sti();
804 return copied;
806 if(noblock)
808 sti();
809 return-EAGAIN;
811 sk->socket->flags |= SO_WAITDATA;
812 interruptible_sleep_on(sk->sleep);
813 sk->socket->flags &= ~SO_WAITDATA;
814 if( current->signal & ~current->blocked)
816 sti();
817 if(copied)
818 return copied;
819 return-ERESTARTSYS;
821 sti();
822 down(&sk->protinfo.af_unix.readsem);
823 continue;
825 if(msg->msg_name!=NULL)
827 sun->sun_family=AF_UNIX;
828 if(skb->sk->protinfo.af_unix.name)
830 memcpy(sun->sun_path, skb->sk->protinfo.af_unix.name,108);
831 if(addr_len)
832 *addr_len=strlen(sun->sun_path)+sizeof(short);
834 else
835 if(addr_len)
836 *addr_len=sizeof(short);
838 num=min(skb->len,size-copied);
839 copied+=num;
840 done+=num;
841 if(flags&MSG_PEEK)
843 memcpy_tofs(sp, skb->data, num);
844 break;
846 else
848 memcpy_tofs(sp, skb->data,num);
849 skb_pull(skb,num);
850 sp+=num;
851 if(skb->len==0)
853 skb_unlink(skb);
854 kfree_skb(skb, FREE_WRITE);
855 if(sock->type==SOCK_DGRAM)
856 break;
859 sti();
862 up(&sk->protinfo.af_unix.readsem);
863 return copied;
866 static intunix_shutdown(struct socket *sock,int mode)
868 unix_socket *sk=(unix_socket *)sock->data;
869 unix_socket *other=sk->protinfo.af_unix.other;
870 if(mode&SEND_SHUTDOWN)
872 sk->shutdown|=SEND_SHUTDOWN;
873 sk->state_change(sk);
874 if(other)
876 other->shutdown|=RCV_SHUTDOWN;
877 other->state_change(other);
880 other=sk->protinfo.af_unix.other;
881 if(mode&RCV_SHUTDOWN)
883 sk->shutdown|=RCV_SHUTDOWN;
884 sk->state_change(sk);
885 if(other)
887 other->shutdown|=SEND_SHUTDOWN;
888 other->state_change(other);
891 return0;
895 static intunix_select(struct socket *sock,int sel_type, select_table *wait)
897 returndatagram_select(sock->data,sel_type,wait);
900 static intunix_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
902 unix_socket *sk=sock->data;
903 int err;
904 long amount=0;
906 switch(cmd)
909 case TIOCOUTQ:
910 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
911 if(err)
912 return err;
913 amount=sk->sndbuf-sk->wmem_alloc;
914 if(amount<0)
915 amount=0;
916 put_fs_long(amount,(unsigned long*)arg);
917 return0;
918 case TIOCINQ:
920 struct sk_buff *skb;
921 if(sk->state==TCP_LISTEN)
922 return-EINVAL;
923 /* These two are safe on a single CPU system as only user tasks fiddle here */
924 if((skb=skb_peek(&sk->receive_queue))!=NULL)
925 amount=skb->len;
926 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
927 put_fs_long(amount,(unsigned long*)arg);
928 return0;
931 default:
932 return-EINVAL;
934 /*NOTREACHED*/
935 return(0);
938 static intunix_get_info(char*buffer,char**start, off_t offset,int length,int dummy)
940 off_t pos=0;
941 off_t begin=0;
942 int len=0;
943 unix_socket *s=unix_socket_list;
945 len+=sprintf(buffer,"Num RefCount Protocol Flags Type St Path\n");
947 while(s!=NULL)
949 len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
951 s->protinfo.af_unix.locks,
953 s->socket->flags,
954 s->socket->type,
955 s->socket->state);
956 if(s->protinfo.af_unix.name!=NULL)
957 len+=sprintf(buffer+len," %s\n", s->protinfo.af_unix.name);
958 else
959 buffer[len++]='\n';
961 pos=begin+len;
962 if(pos<offset)
964 len=0;
965 begin=pos;
967 if(pos>offset+length)
968 break;
969 s=s->next;
971 *start=buffer+(offset-begin);
972 len-=(offset-begin);
973 if(len>length)
974 len=length;
975 return len;
979 * For AF_UNIX we flip everything into an iovec. If this doesnt do any speed harm then it will
980 * be easier for all the low levels to be totally iovec based.
983 static intunix_recvfrom(struct socket *sock,void*ubuf,int size,int noblock,unsigned flags,
984 struct sockaddr *sa,int*addr_len)
986 struct iovec iov;
987 struct msghdr msg;
988 iov.iov_base=ubuf;
989 iov.iov_len=size;
990 msg.msg_name=(void*)sa;
991 msg.msg_namelen=0;
992 if(addr_len)
993 msg.msg_namelen = *addr_len;
994 msg.msg_accrights=NULL;
995 msg.msg_iov=&iov;
996 msg.msg_iovlen=1;
997 returnunix_recvmsg(sock,&msg,size,noblock,flags,addr_len);
1000 static intunix_read(struct socket *sock,char*ubuf,int size,int noblock)
1002 returnunix_recvfrom(sock,ubuf,size,noblock,0,NULL,NULL);
1005 static intunix_recv(struct socket *sock,void*ubuf,int size,int noblock,unsigned int flags)
1007 returnunix_recvfrom(sock,ubuf,size,noblock,flags,NULL,NULL);
1010 static intunix_sendto(struct socket *sock,const void*ubuf,int size,int noblock,unsigned flags,
1011 struct sockaddr *sa,int addr_len)
1013 struct iovec iov;
1014 struct msghdr msg;
1015 iov.iov_base=(void*)ubuf;
1016 iov.iov_len=size;
1017 msg.msg_name=(void*)sa;
1018 msg.msg_namelen=addr_len;
1019 msg.msg_accrights=NULL;
1020 msg.msg_iov=&iov;
1021 msg.msg_iovlen=1;
1022 returnunix_sendmsg(sock,&msg,size,noblock,flags);
1025 static intunix_write(struct socket *sock,const char*ubuf,int size,int noblock)
1027 returnunix_sendto(sock,ubuf,size,noblock,0, NULL,0);
1030 static intunix_send(struct socket *sock,const void*ubuf,int size,int noblock,unsigned int flags)
1032 returnunix_sendto(sock,ubuf,size,noblock, flags, NULL,0);
1036 static struct proto_ops unix_proto_ops = {
1037 AF_UNIX,
1039 unix_create,
1040 unix_dup,
1041 unix_release,
1042 unix_bind,
1043 unix_connect,
1044 unix_socketpair,
1045 unix_accept,
1046 unix_getname,
1047 unix_read,
1048 unix_write,
1049 unix_select,
1050 unix_ioctl,
1051 unix_listen,
1052 unix_send,
1053 unix_recv,
1054 unix_sendto,
1055 unix_recvfrom,
1056 unix_shutdown,
1057 unix_setsockopt,
1058 unix_getsockopt,
1059 unix_fcntl,
1060 unix_sendmsg,
1061 unix_recvmsg
1065 voidunix_proto_init(struct net_proto *pro)
1067 printk("NET3: Unix domain sockets 0.09 BETA for Linux NET3.030.\n");
1068 sock_register(unix_proto_ops.family, &unix_proto_ops);
1069 proc_net_register(&(struct proc_dir_entry) {
1070 PROC_NET_UNIX,4,"unix",
1071 S_IFREG | S_IRUGO,1,0,0,
1072 0, &proc_net_inode_operations,
1073 unix_get_info
1077 * Local variables:
1078 * compile-command: "gcc -g -D__KERNEL__ -Wall -O6 -I/usr/src/linux/include -c af_unix.c"
1079 * End:
close