Import 1.3.39
[davej-history.git] / net / unix / af_unix.c
blob7b7d521ea6f584af08f2d5e5c85184c4900d1e29
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/kernel.h>
42 #include <linux/major.h>
43 #include <linux/signal.h>
44 #include <linux/sched.h>
45 #include <linux/errno.h>
46 #include <linux/string.h>
47 #include <linux/stat.h>
48 #include <linux/socket.h>
49 #include <linux/un.h>
50 #include <linux/fcntl.h>
51 #include <linux/termios.h>
52 #include <linux/socket.h>
53 #include <linux/sockios.h>
54 #include <linux/net.h>
55 #include <linux/in.h>
56 #include <linux/fs.h>
57 #include <linux/malloc.h>
58 #include <asm/segment.h>
59 #include <linux/skbuff.h>
60 #include <linux/netdevice.h>
61 #include <net/sock.h>
62 #include <net/tcp.h>
63 #include <net/af_unix.h>
64 #include <linux/proc_fs.h>
66 static unix_socket *unix_socket_list=NULL;
68 #define min(a,b) (((a)<(b))?(a):(b))
71 * Make sure the unix name is null-terminated.
73 staticinlinevoidunix_mkname(struct sockaddr_un * sunaddr,unsigned long len)
75 if(len >=sizeof(*sunaddr))
76 len =sizeof(*sunaddr)-1;
77 ((char*)sunaddr)[len]=0;
81 * Note: Sockets may not be removed _during_ an interrupt or net_bh
82 * handler using this technique. They can be added although we do not
83 * use this facility.
86 static voidunix_remove_socket(unix_socket *sk)
88 unix_socket **s;
90 cli();
91 s=&unix_socket_list;
93 while(*s!=NULL)
95 if(*s==sk)
97 *s=sk->next;
98 sti();
99 return;
101 s=&((*s)->next);
103 sti();
106 static voidunix_insert_socket(unix_socket *sk)
108 cli();
109 sk->next=unix_socket_list;
110 unix_socket_list=sk;
111 sti();
114 static unix_socket *unix_find_socket(struct inode *i)
116 unix_socket *s;
117 cli();
118 s=unix_socket_list;
119 while(s)
121 if(s->protinfo.af_unix.inode==i)
123 sti();
124 return(s);
126 s=s->next;
128 sti();
129 return(NULL);
133 * Delete a unix socket. We have to allow for deferring this on a timer.
136 static voidunix_destroy_timer(unsigned long data)
138 unix_socket *sk=(unix_socket *)data;
139 if(sk->protinfo.af_unix.locks==0&& sk->wmem_alloc==0)
141 if(sk->protinfo.af_unix.name)
142 kfree(sk->protinfo.af_unix.name);
143 kfree_s(sk,sizeof(*sk));
144 return;
148 * Retry;
151 sk->timer.expires=jiffies+10*HZ;/* No real hurry try it every 10 seconds or so */
152 add_timer(&sk->timer);
156 static voidunix_delayed_delete(unix_socket *sk)
158 sk->timer.data=(unsigned long)sk;
159 sk->timer.expires=jiffies+HZ;/* Normally 1 second after will clean up. After that we try every 10 */
160 sk->timer.function=unix_destroy_timer;
161 add_timer(&sk->timer);
164 static voidunix_destroy_socket(unix_socket *sk)
166 struct sk_buff *skb;
167 unix_remove_socket(sk);
169 while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
171 if(sk->state==TCP_LISTEN)
173 unix_socket *osk=skb->sk;
174 osk->state=TCP_CLOSE;
175 kfree_skb(skb, FREE_WRITE);/* Now surplus - free the skb first before the socket */
176 osk->state_change(osk);/* So the connect wakes and cleans up (if any) */
177 /* osk will be destroyed when it gets to close or the timer fires */
179 else
181 /* unix_kill_credentials(skb); *//* Throw out any passed fd's */
182 kfree_skb(skb,FREE_WRITE);
186 if(sk->protinfo.af_unix.inode!=NULL)
188 iput(sk->protinfo.af_unix.inode);
189 sk->protinfo.af_unix.inode=NULL;
192 if(--sk->protinfo.af_unix.locks==0&& sk->wmem_alloc==0)
194 if(sk->protinfo.af_unix.name)
195 kfree(sk->protinfo.af_unix.name);
196 kfree_s(sk,sizeof(*sk));
198 else
200 sk->dead=1;
201 unix_delayed_delete(sk);/* Try every so often until buffers are all freed */
206 * Fixme: We need async I/O on AF_UNIX doing next.
209 static intunix_fcntl(struct socket *sock,unsigned int cmd,unsigned long arg)
211 return-EINVAL;
215 * Yes socket options work with the new unix domain socketry!!!!!!!
218 static intunix_setsockopt(struct socket *sock,int level,int optname,char*optval,int optlen)
220 unix_socket *sk=sock->data;
221 if(level!=SOL_SOCKET)
222 return-EOPNOTSUPP;
223 returnsock_setsockopt(sk,level,optname,optval,optlen);
226 static intunix_getsockopt(struct socket *sock,int level,int optname,char*optval,int*optlen)
228 unix_socket *sk=sock->data;
229 if(level!=SOL_SOCKET)
230 return-EOPNOTSUPP;
231 returnsock_getsockopt(sk,level,optname,optval,optlen);
234 static intunix_listen(struct socket *sock,int backlog)
236 unix_socket *sk=sock->data;
237 if(sk->type!=SOCK_STREAM)
238 return-EOPNOTSUPP;/* Only stream sockets accept */
239 if(sk->protinfo.af_unix.name==NULL)
240 return-EINVAL;/* No listens on an unbound socket */
241 sk->max_ack_backlog=backlog;
242 sk->state=TCP_LISTEN;
243 return0;
246 static voiddef_callback1(struct sock *sk)
248 if(!sk->dead)
249 wake_up_interruptible(sk->sleep);
252 static voiddef_callback2(struct sock *sk,int len)
254 if(!sk->dead)
256 wake_up_interruptible(sk->sleep);
257 sock_wake_async(sk->socket,1);
261 static voiddef_callback3(struct sock *sk)
263 if(!sk->dead)
265 wake_up_interruptible(sk->sleep);
266 sock_wake_async(sk->socket,2);
270 static intunix_create(struct socket *sock,int protocol)
272 unix_socket *sk;
273 /* printk("Unix create\n");*/
274 if(protocol && protocol != PF_UNIX)
275 return-EPROTONOSUPPORT;
276 sk=(unix_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
277 if(sk==NULL)
278 return-ENOMEM;
279 switch(sock->type)
281 case SOCK_STREAM:
282 break;
284 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
285 * nothing uses it.
287 case SOCK_RAW:
288 sock->type=SOCK_DGRAM;
289 case SOCK_DGRAM:
290 break;
291 default:
292 kfree_s(sk,sizeof(*sk));
293 return-ESOCKTNOSUPPORT;
295 sk->type=sock->type;
296 init_timer(&sk->timer);
297 skb_queue_head_init(&sk->write_queue);
298 skb_queue_head_init(&sk->receive_queue);
299 skb_queue_head_init(&sk->back_log);
300 sk->protinfo.af_unix.family=AF_UNIX;
301 sk->protinfo.af_unix.inode=NULL;
302 sk->protinfo.af_unix.locks=1;/* Us */
303 sk->protinfo.af_unix.readsem=MUTEX;/* single task reading lock */
304 sk->protinfo.af_unix.name=NULL;
305 sk->protinfo.af_unix.other=NULL;
306 sk->protocol=0;
307 sk->rmem_alloc=0;
308 sk->wmem_alloc=0;
309 sk->dead=0;
310 sk->next=NULL;
311 sk->broadcast=0;
312 sk->rcvbuf=SK_RMEM_MAX;
313 sk->sndbuf=SK_WMEM_MAX;
314 sk->allocation=GFP_KERNEL;
315 sk->inuse=0;
316 sk->debug=0;
317 sk->prot=NULL;
318 sk->err=0;
319 sk->localroute=0;
320 sk->send_head=NULL;
321 sk->state=TCP_CLOSE;
322 sk->priority=SOPRI_NORMAL;
323 sk->ack_backlog=0;
324 sk->shutdown=0;
325 sk->state_change=def_callback1;
326 sk->data_ready=def_callback2;
327 sk->write_space=def_callback3;
328 sk->error_report=def_callback1;
329 sk->mtu=4096;
330 sk->socket=sock;
331 sock->data=(void*)sk;
332 sk->sleep=sock->wait;
333 sk->zapped=0;
334 unix_insert_socket(sk);
335 return0;
338 static intunix_dup(struct socket *newsock,struct socket *oldsock)
340 returnunix_create(newsock,0);
343 static intunix_release(struct socket *sock,struct socket *peer)
345 unix_socket *sk=sock->data;
346 unix_socket *skpair;
348 /* May not have data attached */
350 if(sk==NULL)
351 return0;
353 sk->state_change(sk);
354 sk->dead=1;
355 skpair=(unix_socket *)sk->protinfo.af_unix.other;/* Person we send to (default) */
356 if(sk->type==SOCK_STREAM && skpair!=NULL && skpair->state!=TCP_LISTEN)
358 skpair->shutdown=SHUTDOWN_MASK;/* No more writes */
359 skpair->state_change(skpair);/* Wake any blocked writes */
361 if(skpair!=NULL)
362 skpair->protinfo.af_unix.locks--;/* It may now die */
363 sk->protinfo.af_unix.other=NULL;/* No pair */
364 unix_destroy_socket(sk);/* Try and flush out this socket. Throw our buffers at least */
367 * FIXME: BSD difference: In BSD all sockets connected to use get ECONNRESET and we die on the spot. In
368 * Linux we behave like files and pipes do and wait for the last dereference.
371 return0;
375 static unix_socket *unix_find_other(char*path,int*error)
377 int old_fs;
378 int err;
379 struct inode *inode;
380 unix_socket *u;
382 old_fs=get_fs();
383 set_fs(get_ds());
384 err =open_namei(path,2, S_IFSOCK, &inode, NULL);
385 set_fs(old_fs);
386 if(err<0)
388 *error=err;
389 return NULL;
391 u=unix_find_socket(inode);
392 iput(inode);
393 if(u==NULL)
395 *error=-ECONNREFUSED;
396 return NULL;
398 return u;
402 static intunix_bind(struct socket *sock,struct sockaddr *uaddr,int addr_len)
404 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
405 unix_socket *sk=sock->data;
406 int old_fs;
407 int err;
409 if(sk->protinfo.af_unix.name)
410 return-EINVAL;/* Already bound */
412 if(addr_len>sizeof(struct sockaddr_un) || addr_len<3|| sunaddr->sun_family!=AF_UNIX)
413 return-EINVAL;
414 unix_mkname(sunaddr, addr_len);
416 * Put ourselves in the filesystem
418 if(sk->protinfo.af_unix.inode!=NULL)
419 return-EINVAL;
421 sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
422 if(sk->protinfo.af_unix.name==NULL)
423 return-ENOMEM;
424 memcpy(sk->protinfo.af_unix.name, sunaddr->sun_path, addr_len+1);
426 old_fs=get_fs();
427 set_fs(get_ds());
429 err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
430 if(err==0)
431 err=open_namei(sk->protinfo.af_unix.name,2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);
433 set_fs(old_fs);
435 if(err<0)
437 kfree_s(sk->protinfo.af_unix.name,addr_len+1);
438 sk->protinfo.af_unix.name=NULL;
439 if(err==-EEXIST)
440 return-EADDRINUSE;
441 else
442 return err;
445 return0;
449 static intunix_connect(struct socket *sock,struct sockaddr *uaddr,int addr_len,int flags)
451 unix_socket *sk=sock->data;
452 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
453 unix_socket *other;
454 struct sk_buff *skb;
455 int err;
457 if(sk->type==SOCK_STREAM && sk->protinfo.af_unix.other)
459 if(sock->state==SS_CONNECTING && sk->state==TCP_ESTABLISHED)
461 sock->state=SS_CONNECTED;
462 return0;
464 if(sock->state==SS_CONNECTING && sk->state == TCP_CLOSE)
466 sock->state=SS_UNCONNECTED;
467 return-ECONNREFUSED;
469 if(sock->state==SS_CONNECTING)
470 return-EALREADY;
471 return-EISCONN;
474 if(addr_len <sizeof(sunaddr->sun_family)+1|| sunaddr->sun_family!=AF_UNIX)
475 return-EINVAL;
477 unix_mkname(sunaddr, addr_len);
479 if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other)
481 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
482 sk->protinfo.af_unix.other=NULL;
483 sock->state=SS_UNCONNECTED;
486 if(sock->type==SOCK_DGRAM)
488 other=unix_find_other(sunaddr->sun_path, &err);
489 if(other==NULL)
490 return err;
491 if(other->type!=sk->type)
492 return-EPROTOTYPE;
493 other->protinfo.af_unix.locks++;
494 sk->protinfo.af_unix.other=other;
495 sock->state=SS_CONNECTED;
496 sk->state=TCP_ESTABLISHED;
497 return0;/* Done */
501 if(sock->state==SS_UNCONNECTED)
504 * Now ready to connect
507 skb=sock_alloc_send_skb(sk,0,0,0, &err);/* Marker object */
508 if(skb==NULL)
509 return err;
510 skb->sk=sk;/* So they know it is us */
511 skb->free=1;
512 sk->state=TCP_CLOSE;
513 unix_mkname(sunaddr, addr_len);
514 other=unix_find_other(sunaddr->sun_path, &err);
515 if(other==NULL)
517 kfree_skb(skb, FREE_WRITE);
518 return err;
520 if(other->type!=sk->type)
522 kfree_skb(skb, FREE_WRITE);
523 return-EPROTOTYPE;
525 other->protinfo.af_unix.locks++;/* Lock the other socket so it doesn't run off for a moment */
526 other->ack_backlog++;
527 sk->protinfo.af_unix.other=other;
528 skb_queue_tail(&other->receive_queue,skb);
529 sk->state=TCP_SYN_SENT;
530 sock->state=SS_CONNECTING;
531 sti();
532 other->data_ready(other,0);/* Wake up ! */
536 /* Wait for an accept */
538 cli();
539 while(sk->state==TCP_SYN_SENT)
541 if(flags&O_NONBLOCK)
543 sti();
544 return-EINPROGRESS;
546 interruptible_sleep_on(sk->sleep);
547 if(current->signal & ~current->blocked)
549 sti();
550 return-ERESTARTSYS;
555 * Has the other end closed on us ?
558 if(sk->state==TCP_CLOSE)
560 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
561 sk->protinfo.af_unix.other=NULL;
562 sock->state=SS_UNCONNECTED;
563 sti();
564 return-ECONNREFUSED;
568 * Amazingly it has worked
571 sock->state=SS_CONNECTED;
572 sti();
573 return0;
577 static intunix_socketpair(struct socket *a,struct socket *b)
579 unix_socket *ska,*skb;
581 ska=a->data;
582 skb=b->data;
584 /* Join our sockets back to back */
585 ska->protinfo.af_unix.locks++;
586 skb->protinfo.af_unix.locks++;
587 ska->protinfo.af_unix.other=skb;
588 skb->protinfo.af_unix.other=ska;
589 ska->state=TCP_ESTABLISHED;
590 skb->state=TCP_ESTABLISHED;
591 return0;
594 static intunix_accept(struct socket *sock,struct socket *newsock,int flags)
596 unix_socket *sk=sock->data;
597 unix_socket *newsk, *tsk;
598 struct sk_buff *skb;
600 if(sk->type!=SOCK_STREAM)
602 return-EOPNOTSUPP;
604 if(sk->state!=TCP_LISTEN)
606 return-EINVAL;
609 newsk=newsock->data;
610 if(sk->protinfo.af_unix.name!=NULL)
612 newsk->protinfo.af_unix.name=kmalloc(strlen(sk->protinfo.af_unix.name)+1, GFP_KERNEL);
613 if(newsk->protinfo.af_unix.name==NULL)
614 return-ENOMEM;
615 strcpy(newsk->protinfo.af_unix.name, sk->protinfo.af_unix.name);
620 cli();
621 skb=skb_dequeue(&sk->receive_queue);
622 if(skb==NULL)
624 if(flags&O_NONBLOCK)
626 sti();
627 return-EAGAIN;
629 interruptible_sleep_on(sk->sleep);
630 if(current->signal & ~current->blocked)
632 sti();
633 return-ERESTARTSYS;
635 sti();
638 while(skb==NULL);
639 tsk=skb->sk;
640 kfree_skb(skb, FREE_WRITE);/* The buffer is just used as a tag */
641 sk->ack_backlog--;
642 newsk->protinfo.af_unix.other=tsk;
643 tsk->protinfo.af_unix.other=newsk;
644 tsk->state=TCP_ESTABLISHED;
645 newsk->state=TCP_ESTABLISHED;
646 newsk->protinfo.af_unix.locks++;/* Swap lock over */
647 sk->protinfo.af_unix.locks--;/* Locked to child socket not master */
648 tsk->protinfo.af_unix.locks++;/* Back lock */
649 sti();
650 tsk->state_change(tsk);/* Wake up any sleeping connect */
651 sock_wake_async(tsk->socket,0);
652 return0;
655 static intunix_getname(struct socket *sock,struct sockaddr *uaddr,int*uaddr_len,int peer)
657 unix_socket *sk=sock->data;
658 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
660 if(peer)
662 if(sk->protinfo.af_unix.other==NULL)
663 return-ENOTCONN;
664 sk=sk->protinfo.af_unix.other;
666 sunaddr->sun_family=AF_UNIX;
667 if(sk->protinfo.af_unix.name==NULL)
669 *sunaddr->sun_path=0;
670 *uaddr_len=sizeof(sunaddr->sun_family)+1;
671 return0;/* Not bound */
673 *uaddr_len=sizeof(sunaddr->sun_family)+strlen(sk->protinfo.af_unix.name)+1;
674 strcpy(sunaddr->sun_path,sk->protinfo.af_unix.name);/* 108 byte limited */
675 return0;
678 static intunix_sendmsg(struct socket *sock,struct msghdr *msg,int len,int nonblock,int flags)
680 unix_socket *sk=sock->data;
681 unix_socket *other;
682 struct sockaddr_un *sunaddr=msg->msg_name;
683 int err,size;
684 struct sk_buff *skb;
685 int limit=0;
686 int sent=0;
688 if(sk->err)
689 returnsock_error(sk);
691 if(flags&MSG_OOB)
692 return-EOPNOTSUPP;
694 if(flags || msg->msg_accrights)/* For now */
695 return-EINVAL;
697 if(sunaddr!=NULL)
699 if(sock->type==SOCK_STREAM)
701 if(sk->state==TCP_ESTABLISHED)
702 return-EISCONN;
703 else
704 return-EOPNOTSUPP;
707 if(sunaddr==NULL)
709 if(sk->protinfo.af_unix.other==NULL)
710 return-ENOTCONN;
714 while(sent < len)
717 * Optimisation for the fact that under 0.01% of X messages typically
718 * need breaking up.
721 size=len-sent;
723 if(size>(sk->sndbuf-sizeof(struct sk_buff))/2)/* Keep two messages in the pipe so it schedules better */
725 if(sock->type==SOCK_DGRAM)
726 return-EMSGSIZE;
727 size=(sk->sndbuf-sizeof(struct sk_buff))/2;
730 * Keep to page sized kmalloc()'s as various people
731 * have suggested. Big mallocs stress the vm too
732 * much.
735 if(size >4000&& sock->type!=SOCK_DGRAM)
736 limit =4000;/* Fall back to 4K if we can't grab a big buffer this instant */
737 else
738 limit =0;/* Otherwise just grab and wait */
741 * Grab a buffer
744 skb=sock_alloc_send_skb(sk,size,limit,nonblock, &err);
746 if(skb==NULL)
748 if(sent)
750 sk->err=-err;
751 return sent;
753 return err;
755 size=skb_tailroom(skb);/* If we dropped back on a limit then our skb is smaller */
757 skb->sk=sk;
758 skb->free=1;
760 memcpy_fromiovec(skb_put(skb,size),msg->msg_iov, size);
762 cli();
763 if(sunaddr==NULL)
765 other=sk->protinfo.af_unix.other;
766 if(sock->type==SOCK_DGRAM && other->dead)
768 other->protinfo.af_unix.locks--;
769 sk->protinfo.af_unix.other=NULL;
770 sock->state=SS_UNCONNECTED;
771 sti();
772 if(!sent)
773 return-ECONNRESET;
774 else
775 return sent;
778 else
780 unix_mkname(sunaddr, msg->msg_namelen);
781 other=unix_find_other(sunaddr->sun_path, &err);
782 if(other==NULL)
784 kfree_skb(skb, FREE_WRITE);
785 sti();
786 if(sent)
787 return sent;
788 else
789 return err;
792 skb_queue_tail(&other->receive_queue, skb);
793 sti();
794 other->data_ready(other,size);
795 sent+=size;
797 return sent;
801 * Sleep until data has arrive. But check for races..
803 static voidunix_data_wait(unix_socket * sk)
805 cli();
806 if(!skb_peek(&sk->receive_queue)) {
807 sk->socket->flags |= SO_WAITDATA;
808 interruptible_sleep_on(sk->sleep);
809 sk->socket->flags &= ~SO_WAITDATA;
811 sti();
814 static intunix_recvmsg(struct socket *sock,struct msghdr *msg,int size,int noblock,int flags,int*addr_len)
816 unix_socket *sk=sock->data;
817 struct sockaddr_un *sunaddr=msg->msg_name;
818 struct sk_buff *skb;
819 int copied=0;
820 unsigned char*sp;
821 int len;
822 int num;
823 struct iovec *iov=msg->msg_iov;
824 int ct=msg->msg_iovlen;
826 if(flags&MSG_OOB)
827 return-EOPNOTSUPP;
829 if(addr_len)
830 *addr_len=0;
832 if(sk->err)
833 returnsock_error(sk);
835 down(&sk->protinfo.af_unix.readsem);/* Lock the socket */
836 while(ct--)
838 int done=0;
839 sp=iov->iov_base;
840 len=iov->iov_len;
841 iov++;
843 while(done<len)
845 if(copied && (flags & MSG_PEEK))
846 goto out;
847 if(copied == size)
848 goto out;
849 skb=skb_dequeue(&sk->receive_queue);
850 if(skb==NULL)
852 up(&sk->protinfo.af_unix.readsem);
853 if(sk->shutdown & RCV_SHUTDOWN)
854 return copied;
855 if(copied)
856 return copied;
857 if(noblock)
858 return-EAGAIN;
859 if(current->signal & ~current->blocked)
860 return-ERESTARTSYS;
861 unix_data_wait(sk);
862 down(&sk->protinfo.af_unix.readsem);
863 continue;
865 if(msg->msg_name!=NULL)
867 sunaddr->sun_family=AF_UNIX;
868 if(skb->sk->protinfo.af_unix.name)
870 memcpy(sunaddr->sun_path, skb->sk->protinfo.af_unix.name,108);
871 if(addr_len)
872 *addr_len=strlen(sunaddr->sun_path)+sizeof(short);
874 else
875 if(addr_len)
876 *addr_len=sizeof(short);
878 num=min(skb->len,size-copied);
879 memcpy_tofs(sp, skb->data, num);
880 copied+=num;
881 done+=num;
882 sp+=num;
883 if(!(flags & MSG_PEEK))
884 skb_pull(skb, num);
885 /* put the skb back if we didn't use it up.. */
886 if(skb->len) {
887 skb_queue_head(&sk->receive_queue, skb);
888 continue;
890 kfree_skb(skb, FREE_WRITE);
891 if(sock->type==SOCK_DGRAM)
892 goto out;
895 out:
896 up(&sk->protinfo.af_unix.readsem);
897 return copied;
900 static intunix_shutdown(struct socket *sock,int mode)
902 unix_socket *sk=(unix_socket *)sock->data;
903 unix_socket *other=sk->protinfo.af_unix.other;
904 if(mode&SEND_SHUTDOWN)
906 sk->shutdown|=SEND_SHUTDOWN;
907 sk->state_change(sk);
908 if(other)
910 other->shutdown|=RCV_SHUTDOWN;
911 other->state_change(other);
914 other=sk->protinfo.af_unix.other;
915 if(mode&RCV_SHUTDOWN)
917 sk->shutdown|=RCV_SHUTDOWN;
918 sk->state_change(sk);
919 if(other)
921 other->shutdown|=SEND_SHUTDOWN;
922 other->state_change(other);
925 return0;
929 static intunix_select(struct socket *sock,int sel_type, select_table *wait)
931 returndatagram_select(sock->data,sel_type,wait);
934 static intunix_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
936 unix_socket *sk=sock->data;
937 int err;
938 long amount=0;
940 switch(cmd)
943 case TIOCOUTQ:
944 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
945 if(err)
946 return err;
947 amount=sk->sndbuf-sk->wmem_alloc;
948 if(amount<0)
949 amount=0;
950 put_fs_long(amount,(unsigned long*)arg);
951 return0;
952 case TIOCINQ:
954 struct sk_buff *skb;
955 if(sk->state==TCP_LISTEN)
956 return-EINVAL;
957 /* These two are safe on a single CPU system as only user tasks fiddle here */
958 if((skb=skb_peek(&sk->receive_queue))!=NULL)
959 amount=skb->len;
960 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
961 put_fs_long(amount,(unsigned long*)arg);
962 return0;
965 default:
966 return-EINVAL;
968 /*NOTREACHED*/
969 return(0);
972 static intunix_get_info(char*buffer,char**start, off_t offset,int length,int dummy)
974 off_t pos=0;
975 off_t begin=0;
976 int len=0;
977 unix_socket *s=unix_socket_list;
979 len+=sprintf(buffer,"Num RefCount Protocol Flags Type St Path\n");
981 while(s!=NULL)
983 len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
985 s->protinfo.af_unix.locks,
987 s->socket->flags,
988 s->socket->type,
989 s->socket->state);
990 if(s->protinfo.af_unix.name!=NULL)
991 len+=sprintf(buffer+len," %s\n", s->protinfo.af_unix.name);
992 else
993 buffer[len++]='\n';
995 pos=begin+len;
996 if(pos<offset)
998 len=0;
999 begin=pos;
1001 if(pos>offset+length)
1002 break;
1003 s=s->next;
1005 *start=buffer+(offset-begin);
1006 len-=(offset-begin);
1007 if(len>length)
1008 len=length;
1009 return len;
1012 static struct proto_ops unix_proto_ops = {
1013 AF_UNIX,
1015 unix_create,
1016 unix_dup,
1017 unix_release,
1018 unix_bind,
1019 unix_connect,
1020 unix_socketpair,
1021 unix_accept,
1022 unix_getname,
1023 unix_select,
1024 unix_ioctl,
1025 unix_listen,
1026 unix_shutdown,
1027 unix_setsockopt,
1028 unix_getsockopt,
1029 unix_fcntl,
1030 unix_sendmsg,
1031 unix_recvmsg
1035 voidunix_proto_init(struct net_proto *pro)
1037 printk("NET3: Unix domain sockets 0.10 BETA for Linux NET3.031.\n");
1038 sock_register(unix_proto_ops.family, &unix_proto_ops);
1039 proc_net_register(&(struct proc_dir_entry) {
1040 PROC_NET_UNIX,4,"unix",
1041 S_IFREG | S_IRUGO,1,0,0,
1042 0, &proc_net_inode_operations,
1043 unix_get_info
1047 * Local variables:
1048 * compile-command: "gcc -g -D__KERNEL__ -Wall -O6 -I/usr/src/linux/include -c af_unix.c"
1049 * End:
close