Import 1.3.60
[davej-history.git] / net / unix / af_unix.c
blob35b5c742719f27df3d53f1596b1e9dce327d9217
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.
21 * Alan Cox : Fixed the stupid socketpair bug.
22 * Alan Cox : BSD compatibility fine tuning.
25 * Known differences from reference BSD that was tested:
27 * [TO FIX]
28 * No fd passing yet.
29 * ECONNREFUSED is not returned from one end of a connected() socket to the
30 * other the moment one end closes.
31 * fstat() doesn't return st_dev=NODEV, and give the blksize as high water mark
32 * and a fake inode identifier (nor the BSD first socket fstat twice bug).
33 * [NOT TO FIX]
34 * accept() returns a path name even if the connecting socket has closed
35 * in the meantime (BSD loses the path and gives up).
36 * accept() returns 0 length path for an unbound connector. BSD returns 16
37 * and a null first byte in the path (but not for gethost/peername - BSD bug ??)
38 * socketpair(...SOCK_RAW..) doesnt panic the kernel.
41 #include <linux/config.h>
42 #include <linux/kernel.h>
43 #include <linux/major.h>
44 #include <linux/signal.h>
45 #include <linux/sched.h>
46 #include <linux/errno.h>
47 #include <linux/string.h>
48 #include <linux/stat.h>
49 #include <linux/socket.h>
50 #include <linux/un.h>
51 #include <linux/fcntl.h>
52 #include <linux/termios.h>
53 #include <linux/socket.h>
54 #include <linux/sockios.h>
55 #include <linux/net.h>
56 #include <linux/in.h>
57 #include <linux/fs.h>
58 #include <linux/malloc.h>
59 #include <asm/segment.h>
60 #include <linux/skbuff.h>
61 #include <linux/netdevice.h>
62 #include <net/sock.h>
63 #include <net/tcp.h>
64 #include <net/af_unix.h>
65 #include <linux/proc_fs.h>
67 static unix_socket *unix_socket_list=NULL;
69 #define min(a,b) (((a)<(b))?(a):(b))
72 * Make sure the unix name is null-terminated.
74 staticinlinevoidunix_mkname(struct sockaddr_un * sunaddr,unsigned long len)
76 if(len >=sizeof(*sunaddr))
77 len =sizeof(*sunaddr)-1;
78 ((char*)sunaddr)[len]=0;
82 * Note: Sockets may not be removed _during_ an interrupt or net_bh
83 * handler using this technique. They can be added although we do not
84 * use this facility.
87 static voidunix_remove_socket(unix_socket *sk)
89 unix_socket **s;
91 cli();
92 s=&unix_socket_list;
94 while(*s!=NULL)
96 if(*s==sk)
98 *s=sk->next;
99 sti();
100 return;
102 s=&((*s)->next);
104 sti();
107 static voidunix_insert_socket(unix_socket *sk)
109 cli();
110 sk->next=unix_socket_list;
111 unix_socket_list=sk;
112 sti();
115 static unix_socket *unix_find_socket(struct inode *i)
117 unix_socket *s;
118 cli();
119 s=unix_socket_list;
120 while(s)
122 if(s->protinfo.af_unix.inode==i)
124 sti();
125 return(s);
127 s=s->next;
129 sti();
130 return(NULL);
134 * Delete a unix socket. We have to allow for deferring this on a timer.
137 static voidunix_destroy_timer(unsigned long data)
139 unix_socket *sk=(unix_socket *)data;
140 if(sk->protinfo.af_unix.locks==0&& sk->wmem_alloc==0)
142 if(sk->protinfo.af_unix.name)
143 kfree(sk->protinfo.af_unix.name);
144 kfree_s(sk,sizeof(*sk));
145 return;
149 * Retry;
152 sk->timer.expires=jiffies+10*HZ;/* No real hurry try it every 10 seconds or so */
153 add_timer(&sk->timer);
157 static voidunix_delayed_delete(unix_socket *sk)
159 sk->timer.data=(unsigned long)sk;
160 sk->timer.expires=jiffies+HZ;/* Normally 1 second after will clean up. After that we try every 10 */
161 sk->timer.function=unix_destroy_timer;
162 add_timer(&sk->timer);
165 static voidunix_destroy_socket(unix_socket *sk)
167 struct sk_buff *skb;
168 unix_remove_socket(sk);
170 while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
172 if(sk->state==TCP_LISTEN)
174 unix_socket *osk=skb->sk;
175 osk->state=TCP_CLOSE;
176 kfree_skb(skb, FREE_WRITE);/* Now surplus - free the skb first before the socket */
177 osk->state_change(osk);/* So the connect wakes and cleans up (if any) */
178 /* osk will be destroyed when it gets to close or the timer fires */
180 else
182 /* unix_kill_credentials(skb); *//* Throw out any passed fd's */
183 kfree_skb(skb,FREE_WRITE);
187 if(sk->protinfo.af_unix.inode!=NULL)
189 iput(sk->protinfo.af_unix.inode);
190 sk->protinfo.af_unix.inode=NULL;
193 if(--sk->protinfo.af_unix.locks==0&& sk->wmem_alloc==0)
195 if(sk->protinfo.af_unix.name)
196 kfree(sk->protinfo.af_unix.name);
197 kfree_s(sk,sizeof(*sk));
199 else
201 sk->dead=1;
202 unix_delayed_delete(sk);/* Try every so often until buffers are all freed */
207 * Fixme: We need async I/O on AF_UNIX doing next.
210 static intunix_fcntl(struct socket *sock,unsigned int cmd,unsigned long arg)
212 return-EINVAL;
216 * Yes socket options work with the new unix domain socketry!!!!!!!
219 static intunix_setsockopt(struct socket *sock,int level,int optname,char*optval,int optlen)
221 unix_socket *sk=sock->data;
222 if(level!=SOL_SOCKET)
223 return-EOPNOTSUPP;
224 returnsock_setsockopt(sk,level,optname,optval,optlen);
227 static intunix_getsockopt(struct socket *sock,int level,int optname,char*optval,int*optlen)
229 unix_socket *sk=sock->data;
230 if(level!=SOL_SOCKET)
231 return-EOPNOTSUPP;
232 returnsock_getsockopt(sk,level,optname,optval,optlen);
235 static intunix_listen(struct socket *sock,int backlog)
237 unix_socket *sk=sock->data;
238 if(sk->type!=SOCK_STREAM)
239 return-EOPNOTSUPP;/* Only stream sockets accept */
240 if(sk->protinfo.af_unix.name==NULL)
241 return-EINVAL;/* No listens on an unbound socket */
242 sk->max_ack_backlog=backlog;
243 sk->state=TCP_LISTEN;
244 return0;
247 static voiddef_callback1(struct sock *sk)
249 if(!sk->dead)
250 wake_up_interruptible(sk->sleep);
253 static voiddef_callback2(struct sock *sk,int len)
255 if(!sk->dead)
257 wake_up_interruptible(sk->sleep);
258 sock_wake_async(sk->socket,1);
262 static voiddef_callback3(struct sock *sk)
264 if(!sk->dead)
266 wake_up_interruptible(sk->sleep);
267 sock_wake_async(sk->socket,2);
271 static intunix_create(struct socket *sock,int protocol)
273 unix_socket *sk;
274 /* printk("Unix create\n");*/
275 if(protocol && protocol != PF_UNIX)
276 return-EPROTONOSUPPORT;
277 sk=(unix_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
278 if(sk==NULL)
279 return-ENOMEM;
280 switch(sock->type)
282 case SOCK_STREAM:
283 break;
285 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
286 * nothing uses it.
288 case SOCK_RAW:
289 sock->type=SOCK_DGRAM;
290 case SOCK_DGRAM:
291 break;
292 default:
293 kfree_s(sk,sizeof(*sk));
294 return-ESOCKTNOSUPPORT;
296 sk->type=sock->type;
297 init_timer(&sk->timer);
298 skb_queue_head_init(&sk->write_queue);
299 skb_queue_head_init(&sk->receive_queue);
300 skb_queue_head_init(&sk->back_log);
301 sk->protinfo.af_unix.family=AF_UNIX;
302 sk->protinfo.af_unix.inode=NULL;
303 sk->protinfo.af_unix.locks=1;/* Us */
304 sk->protinfo.af_unix.readsem=MUTEX;/* single task reading lock */
305 sk->protinfo.af_unix.name=NULL;
306 sk->protinfo.af_unix.other=NULL;
307 sk->protocol=0;
308 sk->rmem_alloc=0;
309 sk->wmem_alloc=0;
310 sk->dead=0;
311 sk->next=NULL;
312 sk->broadcast=0;
313 sk->rcvbuf=SK_RMEM_MAX;
314 sk->sndbuf=SK_WMEM_MAX;
315 sk->allocation=GFP_KERNEL;
316 sk->inuse=0;
317 sk->bsdism=0;
318 sk->debug=0;
319 sk->prot=NULL;
320 sk->err=0;
321 sk->localroute=0;
322 sk->send_head=NULL;
323 sk->state=TCP_CLOSE;
324 sk->priority=SOPRI_NORMAL;
325 sk->ack_backlog=0;
326 sk->shutdown=0;
327 sk->state_change=def_callback1;
328 sk->data_ready=def_callback2;
329 sk->write_space=def_callback3;
330 sk->error_report=def_callback1;
331 sk->mtu=4096;
332 sk->socket=sock;
333 sock->data=(void*)sk;
334 sk->sleep=sock->wait;
335 sk->zapped=0;
336 unix_insert_socket(sk);
337 return0;
340 static intunix_dup(struct socket *newsock,struct socket *oldsock)
342 returnunix_create(newsock,0);
345 static intunix_release(struct socket *sock,struct socket *peer)
347 unix_socket *sk=sock->data;
348 unix_socket *skpair;
350 /* May not have data attached */
352 if(sk==NULL)
353 return0;
355 sk->state_change(sk);
356 sk->dead=1;
357 skpair=(unix_socket *)sk->protinfo.af_unix.other;/* Person we send to (default) */
358 if(sk->type==SOCK_STREAM && skpair!=NULL && skpair->state!=TCP_LISTEN)
360 skpair->shutdown=SHUTDOWN_MASK;/* No more writes */
361 skpair->state_change(skpair);/* Wake any blocked writes */
363 if(skpair!=NULL)
364 skpair->protinfo.af_unix.locks--;/* It may now die */
365 sk->protinfo.af_unix.other=NULL;/* No pair */
366 unix_destroy_socket(sk);/* Try and flush out this socket. Throw our buffers at least */
369 * FIXME: BSD difference: In BSD all sockets connected to use get ECONNRESET and we die on the spot. In
370 * Linux we behave like files and pipes do and wait for the last dereference.
373 return0;
377 static unix_socket *unix_find_other(char*path,int*error)
379 int old_fs;
380 int err;
381 struct inode *inode;
382 unix_socket *u;
384 old_fs=get_fs();
385 set_fs(get_ds());
386 err =open_namei(path,2, S_IFSOCK, &inode, NULL);
387 set_fs(old_fs);
388 if(err<0)
390 *error=err;
391 return NULL;
393 u=unix_find_socket(inode);
394 iput(inode);
395 if(u==NULL)
397 *error=-ECONNREFUSED;
398 return NULL;
400 return u;
404 static intunix_bind(struct socket *sock,struct sockaddr *uaddr,int addr_len)
406 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
407 unix_socket *sk=sock->data;
408 int old_fs;
409 int err;
411 if(sk->protinfo.af_unix.name)
412 return-EINVAL;/* Already bound */
414 if(addr_len>sizeof(struct sockaddr_un) || addr_len<3|| sunaddr->sun_family!=AF_UNIX)
415 return-EINVAL;
416 unix_mkname(sunaddr, addr_len);
418 * Put ourselves in the filesystem
420 if(sk->protinfo.af_unix.inode!=NULL)
421 return-EINVAL;
423 sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
424 if(sk->protinfo.af_unix.name==NULL)
425 return-ENOMEM;
426 memcpy(sk->protinfo.af_unix.name, sunaddr->sun_path, addr_len+1);
428 old_fs=get_fs();
429 set_fs(get_ds());
431 err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
432 if(err==0)
433 err=open_namei(sk->protinfo.af_unix.name,2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);
435 set_fs(old_fs);
437 if(err<0)
439 kfree_s(sk->protinfo.af_unix.name,addr_len+1);
440 sk->protinfo.af_unix.name=NULL;
441 if(err==-EEXIST)
442 return-EADDRINUSE;
443 else
444 return err;
447 return0;
451 static intunix_connect(struct socket *sock,struct sockaddr *uaddr,int addr_len,int flags)
453 unix_socket *sk=sock->data;
454 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
455 unix_socket *other;
456 struct sk_buff *skb;
457 int err;
459 if(sk->type==SOCK_STREAM && sk->protinfo.af_unix.other)
461 if(sock->state==SS_CONNECTING && sk->state==TCP_ESTABLISHED)
463 sock->state=SS_CONNECTED;
464 return0;
466 if(sock->state==SS_CONNECTING && sk->state == TCP_CLOSE)
468 sock->state=SS_UNCONNECTED;
469 return-ECONNREFUSED;
471 if(sock->state==SS_CONNECTING)
472 return-EALREADY;
473 return-EISCONN;
476 if(addr_len <sizeof(sunaddr->sun_family)+1|| sunaddr->sun_family!=AF_UNIX)
477 return-EINVAL;
479 unix_mkname(sunaddr, addr_len);
481 if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other)
483 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
484 sk->protinfo.af_unix.other=NULL;
485 sock->state=SS_UNCONNECTED;
488 if(sock->type==SOCK_DGRAM)
490 other=unix_find_other(sunaddr->sun_path, &err);
491 if(other==NULL)
492 return err;
493 if(other->type!=sk->type)
494 return-EPROTOTYPE;
495 other->protinfo.af_unix.locks++;
496 sk->protinfo.af_unix.other=other;
497 sock->state=SS_CONNECTED;
498 sk->state=TCP_ESTABLISHED;
499 return0;/* Done */
503 if(sock->state==SS_UNCONNECTED)
506 * Now ready to connect
509 skb=sock_alloc_send_skb(sk,0,0,0, &err);/* Marker object */
510 if(skb==NULL)
511 return err;
512 skb->sk=sk;/* So they know it is us */
513 skb->free=1;
514 sk->state=TCP_CLOSE;
515 unix_mkname(sunaddr, addr_len);
516 other=unix_find_other(sunaddr->sun_path, &err);
517 if(other==NULL)
519 kfree_skb(skb, FREE_WRITE);
520 return err;
522 if(other->type!=sk->type)
524 kfree_skb(skb, FREE_WRITE);
525 return-EPROTOTYPE;
527 other->protinfo.af_unix.locks++;/* Lock the other socket so it doesn't run off for a moment */
528 other->ack_backlog++;
529 sk->protinfo.af_unix.other=other;
530 skb_queue_tail(&other->receive_queue,skb);
531 sk->state=TCP_SYN_SENT;
532 sock->state=SS_CONNECTING;
533 sti();
534 other->data_ready(other,0);/* Wake up ! */
538 /* Wait for an accept */
540 cli();
541 while(sk->state==TCP_SYN_SENT)
543 if(flags&O_NONBLOCK)
545 sti();
546 return-EINPROGRESS;
548 interruptible_sleep_on(sk->sleep);
549 if(current->signal & ~current->blocked)
551 sti();
552 return-ERESTARTSYS;
557 * Has the other end closed on us ?
560 if(sk->state==TCP_CLOSE)
562 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
563 sk->protinfo.af_unix.other=NULL;
564 sock->state=SS_UNCONNECTED;
565 sti();
566 return-ECONNREFUSED;
570 * Amazingly it has worked
573 sock->state=SS_CONNECTED;
574 sti();
575 return0;
579 static intunix_socketpair(struct socket *a,struct socket *b)
581 unix_socket *ska,*skb;
583 ska=a->data;
584 skb=b->data;
586 /* Join our sockets back to back */
587 ska->protinfo.af_unix.locks++;
588 skb->protinfo.af_unix.locks++;
589 ska->protinfo.af_unix.other=skb;
590 skb->protinfo.af_unix.other=ska;
591 ska->state=TCP_ESTABLISHED;
592 skb->state=TCP_ESTABLISHED;
593 return0;
596 static intunix_accept(struct socket *sock,struct socket *newsock,int flags)
598 unix_socket *sk=sock->data;
599 unix_socket *newsk, *tsk;
600 struct sk_buff *skb;
602 if(sk->type!=SOCK_STREAM)
604 return-EOPNOTSUPP;
606 if(sk->state!=TCP_LISTEN)
608 return-EINVAL;
611 newsk=newsock->data;
612 if(sk->protinfo.af_unix.name!=NULL)
614 newsk->protinfo.af_unix.name=kmalloc(strlen(sk->protinfo.af_unix.name)+1, GFP_KERNEL);
615 if(newsk->protinfo.af_unix.name==NULL)
616 return-ENOMEM;
617 strcpy(newsk->protinfo.af_unix.name, sk->protinfo.af_unix.name);
622 cli();
623 skb=skb_dequeue(&sk->receive_queue);
624 if(skb==NULL)
626 if(flags&O_NONBLOCK)
628 sti();
629 return-EAGAIN;
631 interruptible_sleep_on(sk->sleep);
632 if(current->signal & ~current->blocked)
634 sti();
635 return-ERESTARTSYS;
637 sti();
640 while(skb==NULL);
641 tsk=skb->sk;
642 kfree_skb(skb, FREE_WRITE);/* The buffer is just used as a tag */
643 sk->ack_backlog--;
644 newsk->protinfo.af_unix.other=tsk;
645 tsk->protinfo.af_unix.other=newsk;
646 tsk->state=TCP_ESTABLISHED;
647 newsk->state=TCP_ESTABLISHED;
648 newsk->protinfo.af_unix.locks++;/* Swap lock over */
649 sk->protinfo.af_unix.locks--;/* Locked to child socket not master */
650 tsk->protinfo.af_unix.locks++;/* Back lock */
651 sti();
652 tsk->state_change(tsk);/* Wake up any sleeping connect */
653 sock_wake_async(tsk->socket,0);
654 return0;
657 static intunix_getname(struct socket *sock,struct sockaddr *uaddr,int*uaddr_len,int peer)
659 unix_socket *sk=sock->data;
660 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
662 if(peer)
664 if(sk->protinfo.af_unix.other==NULL)
665 return-ENOTCONN;
666 sk=sk->protinfo.af_unix.other;
668 sunaddr->sun_family=AF_UNIX;
669 if(sk->protinfo.af_unix.name==NULL)
671 *sunaddr->sun_path=0;
672 *uaddr_len=sizeof(sunaddr->sun_family)+1;
673 return0;/* Not bound */
675 *uaddr_len=sizeof(sunaddr->sun_family)+strlen(sk->protinfo.af_unix.name)+1;
676 strcpy(sunaddr->sun_path,sk->protinfo.af_unix.name);/* 108 byte limited */
677 return0;
680 static intunix_sendmsg(struct socket *sock,struct msghdr *msg,int len,int nonblock,int flags)
682 unix_socket *sk=sock->data;
683 unix_socket *other;
684 struct sockaddr_un *sunaddr=msg->msg_name;
685 int err,size;
686 struct sk_buff *skb;
687 int limit=0;
688 int sent=0;
690 if(sk->err)
691 returnsock_error(sk);
693 if(flags&MSG_OOB)
694 return-EOPNOTSUPP;
696 if(flags || msg->msg_accrights)/* For now */
697 return-EINVAL;
699 if(sunaddr!=NULL)
701 if(sock->type==SOCK_STREAM)
703 if(sk->state==TCP_ESTABLISHED)
704 return-EISCONN;
705 else
706 return-EOPNOTSUPP;
709 if(sunaddr==NULL)
711 if(sk->protinfo.af_unix.other==NULL)
712 return-ENOTCONN;
716 while(sent < len)
719 * Optimisation for the fact that under 0.01% of X messages typically
720 * need breaking up.
723 size=len-sent;
725 if(size>(sk->sndbuf-sizeof(struct sk_buff))/2)/* Keep two messages in the pipe so it schedules better */
727 if(sock->type==SOCK_DGRAM)
728 return-EMSGSIZE;
729 size=(sk->sndbuf-sizeof(struct sk_buff))/2;
732 * Keep to page sized kmalloc()'s as various people
733 * have suggested. Big mallocs stress the vm too
734 * much.
737 if(size >4000&& sock->type!=SOCK_DGRAM)
738 limit =4000;/* Fall back to 4K if we can't grab a big buffer this instant */
739 else
740 limit =0;/* Otherwise just grab and wait */
743 * Grab a buffer
746 skb=sock_alloc_send_skb(sk,size,limit,nonblock, &err);
748 if(skb==NULL)
750 if(sent)
752 sk->err=-err;
753 return sent;
755 return err;
757 size=skb_tailroom(skb);/* If we dropped back on a limit then our skb is smaller */
759 skb->sk=sk;
760 skb->free=1;
762 memcpy_fromiovec(skb_put(skb,size),msg->msg_iov, size);
764 cli();
765 if(sunaddr==NULL)
767 other=sk->protinfo.af_unix.other;
768 if(sock->type==SOCK_DGRAM && other->dead)
770 other->protinfo.af_unix.locks--;
771 sk->protinfo.af_unix.other=NULL;
772 sock->state=SS_UNCONNECTED;
773 sti();
774 if(!sent)
775 return-ECONNRESET;
776 else
777 return sent;
780 else
782 unix_mkname(sunaddr, msg->msg_namelen);
783 other=unix_find_other(sunaddr->sun_path, &err);
784 if(other==NULL)
786 kfree_skb(skb, FREE_WRITE);
787 sti();
788 if(sent)
789 return sent;
790 else
791 return err;
794 skb_queue_tail(&other->receive_queue, skb);
795 sti();
796 other->data_ready(other,size);
797 sent+=size;
799 return sent;
803 * Sleep until data has arrive. But check for races..
806 static voidunix_data_wait(unix_socket * sk)
808 cli();
809 if(!skb_peek(&sk->receive_queue)) {
810 sk->socket->flags |= SO_WAITDATA;
811 interruptible_sleep_on(sk->sleep);
812 sk->socket->flags &= ~SO_WAITDATA;
814 sti();
817 static intunix_recvmsg(struct socket *sock,struct msghdr *msg,int size,int noblock,int flags,int*addr_len)
819 unix_socket *sk=sock->data;
820 struct sockaddr_un *sunaddr=msg->msg_name;
821 struct sk_buff *skb;
822 int copied=0;
823 unsigned char*sp;
824 int len;
825 int num;
826 struct iovec *iov=msg->msg_iov;
827 int ct=msg->msg_iovlen;
829 if(flags&MSG_OOB)
830 return-EOPNOTSUPP;
832 if(addr_len)
833 *addr_len=0;
835 if(sk->err)
836 returnsock_error(sk);
838 down(&sk->protinfo.af_unix.readsem);/* Lock the socket */
839 while(ct--)
841 int done=0;
842 sp=iov->iov_base;
843 len=iov->iov_len;
844 iov++;
846 while(done<len)
848 if(copied && (flags & MSG_PEEK))
849 goto out;
850 if(copied == size)
851 goto out;
852 skb=skb_dequeue(&sk->receive_queue);
853 if(skb==NULL)
855 up(&sk->protinfo.af_unix.readsem);
856 if(sk->shutdown & RCV_SHUTDOWN)
857 return copied;
858 if(copied)
859 return copied;
860 if(noblock)
861 return-EAGAIN;
862 if(current->signal & ~current->blocked)
863 return-ERESTARTSYS;
864 unix_data_wait(sk);
865 down(&sk->protinfo.af_unix.readsem);
866 continue;
868 if(msg->msg_name!=NULL)
870 sunaddr->sun_family=AF_UNIX;
871 if(skb->sk->protinfo.af_unix.name)
873 memcpy(sunaddr->sun_path, skb->sk->protinfo.af_unix.name,108);
874 if(addr_len)
875 *addr_len=strlen(sunaddr->sun_path)+sizeof(short);
877 else
878 if(addr_len)
879 *addr_len=sizeof(short);
881 num=min(skb->len,size-copied);
882 memcpy_tofs(sp, skb->data, num);
883 copied+=num;
884 done+=num;
885 sp+=num;
886 if(!(flags & MSG_PEEK))
887 skb_pull(skb, num);
888 /* put the skb back if we didn't use it up.. */
889 if(skb->len) {
890 skb_queue_head(&sk->receive_queue, skb);
891 continue;
893 kfree_skb(skb, FREE_WRITE);
894 if(sock->type==SOCK_DGRAM)
895 goto out;
898 out:
899 up(&sk->protinfo.af_unix.readsem);
900 return copied;
903 static intunix_shutdown(struct socket *sock,int mode)
905 unix_socket *sk=(unix_socket *)sock->data;
906 unix_socket *other=sk->protinfo.af_unix.other;
907 if(mode&SEND_SHUTDOWN)
909 sk->shutdown|=SEND_SHUTDOWN;
910 sk->state_change(sk);
911 if(other)
913 other->shutdown|=RCV_SHUTDOWN;
914 other->state_change(other);
917 other=sk->protinfo.af_unix.other;
918 if(mode&RCV_SHUTDOWN)
920 sk->shutdown|=RCV_SHUTDOWN;
921 sk->state_change(sk);
922 if(other)
924 other->shutdown|=SEND_SHUTDOWN;
925 other->state_change(other);
928 return0;
932 static intunix_select(struct socket *sock,int sel_type, select_table *wait)
934 returndatagram_select(sock->data,sel_type,wait);
937 static intunix_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
939 unix_socket *sk=sock->data;
940 int err;
941 long amount=0;
943 switch(cmd)
946 case TIOCOUTQ:
947 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
948 if(err)
949 return err;
950 amount=sk->sndbuf-sk->wmem_alloc;
951 if(amount<0)
952 amount=0;
953 put_fs_long(amount,(unsigned long*)arg);
954 return0;
955 case TIOCINQ:
957 struct sk_buff *skb;
958 if(sk->state==TCP_LISTEN)
959 return-EINVAL;
960 /* These two are safe on a single CPU system as only user tasks fiddle here */
961 if((skb=skb_peek(&sk->receive_queue))!=NULL)
962 amount=skb->len;
963 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
964 put_fs_long(amount,(unsigned long*)arg);
965 return0;
968 default:
969 return-EINVAL;
971 /*NOTREACHED*/
972 return(0);
975 #ifdef CONFIG_PROC_FS
976 static intunix_get_info(char*buffer,char**start, off_t offset,int length,int dummy)
978 off_t pos=0;
979 off_t begin=0;
980 int len=0;
981 unix_socket *s=unix_socket_list;
983 len+=sprintf(buffer,"Num RefCount Protocol Flags Type St Path\n");
985 while(s!=NULL)
987 len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
989 s->protinfo.af_unix.locks,
991 s->socket->flags,
992 s->socket->type,
993 s->socket->state);
994 if(s->protinfo.af_unix.name!=NULL)
995 len+=sprintf(buffer+len," %s\n", s->protinfo.af_unix.name);
996 else
997 buffer[len++]='\n';
999 pos=begin+len;
1000 if(pos<offset)
1002 len=0;
1003 begin=pos;
1005 if(pos>offset+length)
1006 break;
1007 s=s->next;
1009 *start=buffer+(offset-begin);
1010 len-=(offset-begin);
1011 if(len>length)
1012 len=length;
1013 return len;
1015 #endif
1017 static struct proto_ops unix_proto_ops = {
1018 AF_UNIX,
1020 unix_create,
1021 unix_dup,
1022 unix_release,
1023 unix_bind,
1024 unix_connect,
1025 unix_socketpair,
1026 unix_accept,
1027 unix_getname,
1028 unix_select,
1029 unix_ioctl,
1030 unix_listen,
1031 unix_shutdown,
1032 unix_setsockopt,
1033 unix_getsockopt,
1034 unix_fcntl,
1035 unix_sendmsg,
1036 unix_recvmsg
1040 voidunix_proto_init(struct net_proto *pro)
1042 printk("NET3: Unix domain sockets 0.10 BETA for Linux NET3.033.\n");
1043 sock_register(unix_proto_ops.family, &unix_proto_ops);
1044 #ifdef CONFIG_PROC_FS
1045 proc_net_register(&(struct proc_dir_entry) {
1046 PROC_NET_UNIX,4,"unix",
1047 S_IFREG | S_IRUGO,1,0,0,
1048 0, &proc_net_inode_operations,
1049 unix_get_info
1051 #endif
1054 * Local variables:
1055 * compile-command: "gcc -g -D__KERNEL__ -Wall -O6 -I/usr/src/linux/include -c af_unix.c"
1056 * End:
close