Import 1.3.16
[davej-history.git] / net / unix / af_unix.c
blobe8fdd26ea84fd55c5374ce5dcbfd1279d811745d
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 a trivial part
9 * of the exercise.
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.
17 #include <linux/config.h>
18 #include <linux/kernel.h>
19 #include <linux/major.h>
20 #include <linux/signal.h>
21 #include <linux/sched.h>
22 #include <linux/errno.h>
23 #include <linux/string.h>
24 #include <linux/stat.h>
25 #include <linux/socket.h>
26 #include <linux/un.h>
27 #include <linux/fcntl.h>
28 #include <linux/termios.h>
29 #include <linux/socket.h>
30 #include <linux/sockios.h>
31 #include <linux/net.h>
32 #include <linux/in.h>
33 #include <linux/fs.h>
34 #include <linux/malloc.h>
35 #include <asm/segment.h>
36 #include <linux/skbuff.h>
37 /*#include <linux/netprotocol.h>*/
38 #include <linux/netdevice.h>
39 #include <net/sock.h>
40 #include <net/tcp.h>
41 #include <net/af_unix.h>
43 static unix_socket *volatile unix_socket_list=NULL;
45 #define min(a,b) (((a)<(b))?(a):(b))
48 * Make sure the unix name is null-terminated.
50 staticinlinevoidunix_mkname(struct sockaddr_un * sun,unsigned long len)
52 if(len >=sizeof(*sun))
53 len =sizeof(*sun)-1;
54 ((char*)sun)[len]=0;
58 * Note: Sockets may not be removed _during_ an interrupt or net_bh
59 * handler using this technique. They can be added although we do not
60 * use this facility.
63 static voidunix_remove_socket(unix_socket *sk)
65 unix_socket *s;
67 cli();
68 s=unix_socket_list;
69 if(s==sk)
71 unix_socket_list=s->next;
72 sti();
73 return;
75 while(s && s->next)
77 if(s->next==sk)
79 s->next=sk->next;
80 sti();
81 return;
83 s=s->next;
85 sti();
88 static voidunix_insert_socket(unix_socket *sk)
90 cli();
91 sk->next=unix_socket_list;
92 unix_socket_list=sk;
93 sti();
96 static unix_socket *unix_find_socket(struct inode *i)
98 unix_socket *s;
99 cli();
100 s=unix_socket_list;
101 while(s)
103 if(s->protinfo.af_unix.inode==i)
105 sti();
106 return(s);
108 s=s->next;
110 sti();
111 return(NULL);
115 * Delete a unix socket. We have to allow for deferring this on a timer.
118 static voidunix_destroy_timer(unsigned long data)
120 unix_socket *sk=(unix_socket *)data;
121 if(sk->protinfo.af_unix.locks==0&& sk->wmem_alloc==0)
123 if(sk->protinfo.af_unix.name)
124 kfree(sk->protinfo.af_unix.name);
125 kfree_s(sk,sizeof(*sk));
126 return;
130 * Retry;
133 init_timer(&sk->timer);
134 sk->timer.expires=jiffies+10*HZ;/* No real hurry try it every 10 seconds or so */
135 add_timer(&sk->timer);
139 static voidunix_delayed_delete(unix_socket *sk)
141 init_timer(&sk->timer);
142 sk->timer.data=(unsigned long)sk;
143 sk->timer.expires=jiffies+HZ;/* Normally 1 second after will clean up. After that we try every 10 */
144 sk->timer.function=unix_destroy_timer;
145 add_timer(&sk->timer);
148 static voidunix_destroy_socket(unix_socket *sk)
150 struct sk_buff *skb;
151 unix_remove_socket(sk);
153 while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
155 if(sk->state==TCP_LISTEN)
157 unix_socket *osk=skb->sk;
158 osk->state=TCP_CLOSE;
159 kfree_skb(skb, FREE_WRITE);/* Now surplus - free the skb first before the socket */
160 osk->state_change(osk);/* So the connect wakes and cleans up (if any) */
161 /* osk will be destroyed when it gets to close or the timer fires */
163 else
165 /* unix_kill_credentials(skb); *//* Throw out any passed fd's */
166 kfree_skb(skb,FREE_WRITE);
170 if(sk->protinfo.af_unix.inode!=NULL)
172 iput(sk->protinfo.af_unix.inode);
173 sk->protinfo.af_unix.inode=NULL;
176 if(--sk->protinfo.af_unix.locks==0&& sk->wmem_alloc==0)
178 if(sk->protinfo.af_unix.name)
179 kfree(sk->protinfo.af_unix.name);
180 kfree_s(sk,sizeof(*sk));
182 else
184 sk->dead=1;
185 unix_delayed_delete(sk);/* Try every so often until buffers are all freed */
190 * Fixme: We need async I/O on AF_UNIX doing next.
193 static intunix_fcntl(struct socket *sock,unsigned int cmd,unsigned long arg)
195 return-EINVAL;
199 * Yes socket options work with the new unix domain socketry!!!!!!!
202 static intunix_setsockopt(struct socket *sock,int level,int optname,char*optval,int optlen)
204 unix_socket *sk=sock->data;
205 if(level!=SOL_SOCKET)
206 return-EOPNOTSUPP;
207 returnsock_setsockopt(sk,level,optname,optval,optlen);
210 static intunix_getsockopt(struct socket *sock,int level,int optname,char*optval,int*optlen)
212 unix_socket *sk=sock->data;
213 if(level!=SOL_SOCKET)
214 return-EOPNOTSUPP;
215 returnsock_getsockopt(sk,level,optname,optval,optlen);
218 static intunix_listen(struct socket *sock,int backlog)
220 unix_socket *sk=sock->data;
221 if(sk->type!=SOCK_STREAM)
222 return-EOPNOTSUPP;/* Only stream sockets accept */
223 sk->max_ack_backlog=backlog;
224 sk->state=TCP_LISTEN;
225 return0;
228 static voiddef_callback1(struct sock *sk)
230 if(!sk->dead)
231 wake_up_interruptible(sk->sleep);
234 static voiddef_callback2(struct sock *sk,int len)
236 if(!sk->dead)
237 wake_up_interruptible(sk->sleep);
240 static intunix_create(struct socket *sock,int protocol)
242 unix_socket *sk;
243 /* printk("Unix create\n");*/
244 if(protocol)
245 return-EPROTONOSUPPORT;
246 sk=(unix_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
247 if(sk==NULL)
248 return-ENOMEM;
249 sk->type=sock->type;
250 switch(sock->type)
252 case SOCK_STREAM:
253 break;
254 case SOCK_DGRAM:
255 break;
256 default:
257 kfree_s(sk,sizeof(*sk));
258 return-ESOCKTNOSUPPORT;
260 skb_queue_head_init(&sk->write_queue);
261 skb_queue_head_init(&sk->receive_queue);
262 skb_queue_head_init(&sk->back_log);
263 sk->protinfo.af_unix.family=AF_UNIX;
264 sk->protinfo.af_unix.inode=NULL;
265 sk->protinfo.af_unix.locks=1;/* Us */
266 sk->protinfo.af_unix.readsem=MUTEX;/* single task reading lock */
267 sk->protinfo.af_unix.name=NULL;
268 sk->protinfo.af_unix.other=NULL;
269 sk->protocol=0;
270 sk->rmem_alloc=0;
271 sk->wmem_alloc=0;
272 sk->dead=0;
273 sk->next=NULL;
274 sk->broadcast=0;
275 sk->rcvbuf=SK_RMEM_MAX;
276 sk->sndbuf=SK_WMEM_MAX;
277 sk->inuse=0;
278 sk->debug=0;
279 sk->prot=NULL;
280 sk->err=0;
281 sk->localroute=0;
282 sk->send_head=NULL;
283 sk->state=TCP_CLOSE;
284 sk->priority=SOPRI_NORMAL;
285 sk->ack_backlog=0;
286 sk->shutdown=0;
287 sk->state_change=def_callback1;
288 sk->data_ready=def_callback2;
289 sk->write_space=def_callback1;
290 sk->error_report=def_callback1;
291 sk->mtu=4096;
292 sk->socket=sock;
293 sock->data=(void*)sk;
294 sk->sleep=sock->wait;
295 sk->zapped=0;
296 unix_insert_socket(sk);
297 return0;
300 static intunix_dup(struct socket *newsock,struct socket *oldsock)
302 returnunix_create(newsock,0);
305 static intunix_release(struct socket *sock,struct socket *peer)
307 unix_socket *sk=sock->data;
308 unix_socket *skpair;
310 /* May not have data attached */
312 if(sk==NULL)
313 return0;
315 sk->state_change(sk);
316 sk->dead=1;
317 skpair=(unix_socket *)sk->protinfo.af_unix.other;/* Person we send to (default) */
318 if(sk->type==SOCK_STREAM && skpair!=NULL && skpair->state!=TCP_LISTEN)
320 skpair->shutdown=SHUTDOWN_MASK;/* No more writes */
321 skpair->state_change(skpair);/* Wake any blocked writes */
323 if(skpair!=NULL)
324 skpair->protinfo.af_unix.locks--;/* It may now die */
325 sk->protinfo.af_unix.other=NULL;/* No pair */
326 unix_destroy_socket(sk);/* Try and flush out this socket. Throw our buffers at least */
327 return0;
331 static unix_socket *unix_find_other(char*path,int*error)
333 int old_fs;
334 int err;
335 struct inode *inode;
336 unix_socket *u;
338 old_fs=get_fs();
339 set_fs(get_ds());
340 err =open_namei(path,2, S_IFSOCK, &inode, NULL);
341 set_fs(old_fs);
342 if(err<0)
344 *error=err;
345 return NULL;
347 u=unix_find_socket(inode);
348 iput(inode);
349 if(u==NULL)
351 *error=-ECONNREFUSED;
352 return NULL;
354 return u;
358 static intunix_bind(struct socket *sock,struct sockaddr *uaddr,int addr_len)
360 struct sockaddr_un *sun=(struct sockaddr_un *)uaddr;
361 unix_socket *sk=sock->data;
362 int old_fs;
363 int err;
365 if(addr_len>sizeof(struct sockaddr_un) || addr_len<3|| sun->sun_family!=AF_UNIX)
366 return-EINVAL;
367 unix_mkname(sun, addr_len);
369 * Put ourselves in the filesystem
371 if(sk->protinfo.af_unix.inode!=NULL)
372 return-EINVAL;
374 sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
375 if(sk->protinfo.af_unix.name==NULL)
376 return-ENOMEM;
377 memcpy(sk->protinfo.af_unix.name, sun->sun_path, addr_len+1);
379 old_fs=get_fs();
380 set_fs(get_ds());
382 err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
383 if(err==0)
384 err=open_namei(sk->protinfo.af_unix.name,2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);
386 set_fs(old_fs);
388 if(err<0)
390 kfree_s(sk->protinfo.af_unix.name,addr_len+1);
391 sk->protinfo.af_unix.name=NULL;
392 if(err==-EEXIST)
393 return-EADDRINUSE;
394 else
395 return err;
398 return0;
402 static intunix_connect(struct socket *sock,struct sockaddr *uaddr,int addr_len,int flags)
404 unix_socket *sk=sock->data;
405 struct sockaddr_un *sun=(struct sockaddr_un *)uaddr;
406 unix_socket *other;
407 struct sk_buff *skb;
408 int err;
410 unix_mkname(sun, addr_len);
411 if(sk->type==SOCK_STREAM && sk->protinfo.af_unix.other)
413 if(sock->state==SS_CONNECTING && sk->state==TCP_ESTABLISHED)
415 sock->state=SS_CONNECTED;
416 return0;
418 if(sock->state==SS_CONNECTING && sk->state == TCP_CLOSE)
420 sock->state=SS_UNCONNECTED;
421 return-ECONNREFUSED;
423 if(sock->state==SS_CONNECTING)
424 return-EALREADY;
425 return-EISCONN;
428 if(sun->sun_family!=AF_UNIX)
429 return-EINVAL;
431 if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other)
433 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
434 sk->protinfo.af_unix.other=NULL;
435 sock->state=SS_UNCONNECTED;
438 if(sock->type==SOCK_DGRAM)
440 sock->state=SS_CONNECTED;
441 sk->state=TCP_ESTABLISHED;
442 return0;/* Done */
446 if(sock->state==SS_UNCONNECTED)
449 * Now ready to connect
452 skb=sock_alloc_send_skb(sk,0,0, &err);/* Marker object */
453 if(skb==NULL)
454 return err;
455 skb->sk=sk;/* So they know it is us */
456 skb->free=1;
457 sk->state=TCP_CLOSE;
458 unix_mkname(sun, addr_len);
459 other=unix_find_other(sun->sun_path, &err);
460 if(other==NULL)
462 kfree_skb(skb, FREE_WRITE);
463 return err;
465 other->protinfo.af_unix.locks++;/* Lock the other socket so it doesn't run off for a moment */
466 other->ack_backlog++;
467 sk->protinfo.af_unix.other=other;
468 skb_queue_tail(&other->receive_queue,skb);
469 sk->state=TCP_SYN_SENT;
470 sock->state=SS_CONNECTING;
471 sti();
472 other->data_ready(other,0);/* Wake up ! */
476 /* Wait for an accept */
478 cli();
479 while(sk->state==TCP_SYN_SENT)
481 if(flags&O_NONBLOCK)
483 sti();
484 return-EINPROGRESS;
486 interruptible_sleep_on(sk->sleep);
487 if(current->signal & ~current->blocked)
489 sti();
490 return-ERESTARTSYS;
495 * Has the other end closed on us ?
498 if(sk->state==TCP_CLOSE)
500 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
501 sk->protinfo.af_unix.other=NULL;
502 sock->state=SS_UNCONNECTED;
503 return-ECONNREFUSED;
507 * Amazingly it has worked
510 sock->state=SS_CONNECTED;
511 return0;
515 static intunix_socketpair(struct socket *a,struct socket *b)
517 int err;
518 unix_socket *ska,*skb;
520 err=unix_create(a,0);
521 if(err)
522 return err;
523 err=unix_create(b,0);
524 if(err)
526 unix_release(a, NULL);
527 a->data=NULL;
528 return err;
531 ska=a->data;
532 skb=b->data;
534 /* Join our sockets back to back */
535 ska->protinfo.af_unix.locks++;
536 skb->protinfo.af_unix.locks++;
537 ska->protinfo.af_unix.other=skb;
538 skb->protinfo.af_unix.other=ska;
539 ska->state=TCP_ESTABLISHED;
540 skb->state=TCP_ESTABLISHED;
541 return0;
544 static intunix_accept(struct socket *sock,struct socket *newsock,int flags)
546 unix_socket *sk=sock->data;
547 unix_socket *newsk, *tsk;
548 struct sk_buff *skb;
550 if(sk->type!=SOCK_STREAM)
552 return-EOPNOTSUPP;
554 if(sk->state!=TCP_LISTEN)
556 return-EINVAL;
559 newsk=newsock->data;
560 if(sk->protinfo.af_unix.name!=NULL)
562 newsk->protinfo.af_unix.name=kmalloc(strlen(sk->protinfo.af_unix.name)+1, GFP_KERNEL);
563 if(newsk->protinfo.af_unix.name==NULL)
564 return-ENOMEM;
565 strcpy(newsk->protinfo.af_unix.name, sk->protinfo.af_unix.name);
570 cli();
571 skb=skb_dequeue(&sk->receive_queue);
572 if(skb==NULL)
574 if(flags&O_NONBLOCK)
576 sti();
577 return-EAGAIN;
579 interruptible_sleep_on(sk->sleep);
580 if(current->signal & ~current->blocked)
582 sti();
583 return-ERESTARTSYS;
585 sti();
588 while(skb==NULL);
589 tsk=skb->sk;
590 kfree_skb(skb, FREE_WRITE);/* The buffer is just used as a tag */
591 sk->ack_backlog--;
592 newsk->protinfo.af_unix.other=tsk;
593 tsk->protinfo.af_unix.other=newsk;
594 tsk->state=TCP_ESTABLISHED;
595 newsk->state=TCP_ESTABLISHED;
596 newsk->protinfo.af_unix.locks++;/* Swap lock over */
597 sk->protinfo.af_unix.locks--;/* Locked to child socket not master */
598 tsk->protinfo.af_unix.locks++;/* Back lock */
599 sti();
600 tsk->state_change(tsk);/* Wake up any sleeping connect */
601 return0;
604 static intunix_getname(struct socket *sock,struct sockaddr *uaddr,int*uaddr_len,int peer)
606 unix_socket *sk=sock->data;
607 struct sockaddr_un *sun=(struct sockaddr_un *)uaddr;
609 if(peer)
611 if(sk->protinfo.af_unix.other==NULL)
612 return-ENOTCONN;
613 sk=sk->protinfo.af_unix.other;
615 sun->sun_family=AF_UNIX;
616 if(sk->protinfo.af_unix.name==NULL)
618 *sun->sun_path=0;
619 *uaddr_len=3;
620 return0;/* Not bound */
622 *uaddr_len=sizeof(short)+strlen(sk->protinfo.af_unix.name)+1;
623 strcpy(sun->sun_path,sk->protinfo.af_unix.name);/* 108 byte limited */
624 return0;
627 static intunix_sendmsg(struct socket *sock,struct msghdr *msg,int len,int nonblock,int flags)
629 unix_socket *sk=sock->data;
630 unix_socket *other;
631 struct sockaddr_un *sun=msg->msg_name;
632 int err,size;
633 struct sk_buff *skb;
635 if(sk->err)
637 cli();
638 err=sk->err;
639 sk->err=0;
640 sti();
641 return-err;
644 if(flags || msg->msg_accrights)/* For now */
645 return-EINVAL;
647 if(sun!=NULL)
649 if(sock->type==SOCK_STREAM)
651 if(sk->state==TCP_ESTABLISHED)
652 return-EISCONN;
653 else
654 return-EOPNOTSUPP;
657 if(sun==NULL)
659 if(sk->protinfo.af_unix.other==NULL)
660 return-EINVAL;
664 * Optimisation for the fact that under 0.01% of X messages typically
665 * need breaking up.
668 if(len>(sk->sndbuf-sizeof(struct sk_buff))/2)/* Keep two messages in the pipe so it schedules better */
670 if(sock->type==SOCK_DGRAM)
671 return-EMSGSIZE;
672 len=(sk->sndbuf-sizeof(struct sk_buff))/2;
675 size=/*protocol_size(&proto_unix)+*/len;
676 skb=sock_alloc_send_skb(sk,size,nonblock, &err);
677 if(skb==NULL)
678 return err;
679 /* protocol_adjust(skb,&proto_unix);*/
680 skb->sk=sk;
681 skb->free=1;
682 memcpy_fromiovec(skb_put(skb,len),msg->msg_iov, len);
684 cli();
685 if(sun==NULL)
687 other=sk->protinfo.af_unix.other;
689 else
691 unix_mkname(sun, msg->msg_namelen);
692 other=unix_find_other(sun->sun_path, &err);
693 if(other==NULL)
695 kfree_skb(skb, FREE_WRITE);
696 return err;
699 skb_queue_tail(&other->receive_queue, skb);
700 sti();
701 other->data_ready(other,len);
702 return len;
705 static intunix_recvmsg(struct socket *sock,struct msghdr *msg,int size,int noblock,int flags,int*addr_len)
707 unix_socket *sk=sock->data;
708 struct sockaddr_un *sun=msg->msg_name;
709 int err;
710 struct sk_buff *skb;
711 int copied=0;
712 unsigned char*sp;
713 int len;
714 int num;
715 struct iovec *iov=msg->msg_iov;
716 int ct=msg->msg_iovlen;
718 if(addr_len)
719 *addr_len=0;
721 if(sk->err)
723 cli();
724 err=sk->err;
725 sk->err=0;
726 sti();
727 return-sk->err;
730 /* printk("get rcv sem\n");*/
731 down(&sk->protinfo.af_unix.readsem);/* Lock the socket */
732 /* printk("got rcv sem\n");*/
734 while(ct--)
736 int done=0;
737 sp=iov->iov_base;
738 len=iov->iov_len;
739 iov++;
741 while(done<len)
743 if(copied & (flags&MSG_PEEK))
745 up(&sk->protinfo.af_unix.readsem);
746 return copied;
748 cli();
749 skb=skb_peek(&sk->receive_queue);
750 if(skb==NULL)
752 up(&sk->protinfo.af_unix.readsem);
753 if(sk->shutdown&RCV_SHUTDOWN)
754 return copied;
755 if(noblock)
757 if(copied)
758 return copied;
759 return-EAGAIN;
761 interruptible_sleep_on(sk->sleep);
762 if( current->signal & ~current->blocked)
764 sti();
765 if(copied)
766 return copied;
767 return-ERESTARTSYS;
769 sti();
770 down(&sk->protinfo.af_unix.readsem);
771 continue;
773 if(msg->msg_name!=NULL)
775 sun->sun_family=AF_UNIX;
776 if(skb->sk->protinfo.af_unix.name)
778 memcpy(sun->sun_path, skb->sk->protinfo.af_unix.name,108);
779 if(addr_len)
780 *addr_len=strlen(sun->sun_path)+sizeof(short);
782 else
783 if(addr_len)
784 *addr_len=sizeof(short);
786 num=min(skb->len,size-copied);
787 copied+=num;
788 done+=num;
789 if(flags&MSG_PEEK)
791 memcpy_tofs(sp, skb->data, num);
792 break;
794 else
796 memcpy_tofs(sp, skb->data,num);
797 skb_pull(skb,num);
798 sp+=num;
799 if(skb->len==0)
801 skb_unlink(skb);
802 kfree_skb(skb, FREE_WRITE);
803 if(sock->type==SOCK_DGRAM)
804 break;
809 up(&sk->protinfo.af_unix.readsem);
810 return copied;
813 static intunix_shutdown(struct socket *sock,int mode)
815 unix_socket *sk=(unix_socket *)sock->data;
816 unix_socket *other=sk->protinfo.af_unix.other;
817 if(mode&SEND_SHUTDOWN)
819 sk->shutdown|=SEND_SHUTDOWN;
820 sk->state_change(sk);
821 if(other)
823 other->shutdown|=RCV_SHUTDOWN;
824 other->state_change(other);
827 other=sk->protinfo.af_unix.other;
828 if(mode&RCV_SHUTDOWN)
830 sk->shutdown|=RCV_SHUTDOWN;
831 sk->state_change(sk);
832 if(other)
834 other->shutdown|=SEND_SHUTDOWN;
835 other->state_change(other);
838 return0;
842 static intunix_select(struct socket *sock,int sel_type, select_table *wait)
844 returndatagram_select(sock->data,sel_type,wait);
847 static intunix_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
849 unix_socket *sk=sock->data;
850 int err;
851 long amount=0;
853 switch(cmd)
856 case TIOCOUTQ:
857 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
858 if(err)
859 return err;
860 amount=sk->sndbuf-sk->wmem_alloc;
861 if(amount<0)
862 amount=0;
863 put_fs_long(amount,(unsigned long*)arg);
864 return0;
865 case TIOCINQ:
867 struct sk_buff *skb;
868 if(sk->state==TCP_LISTEN)
869 return-EINVAL;
870 /* These two are safe on a single CPU system as only user tasks fiddle here */
871 if((skb=skb_peek(&sk->receive_queue))!=NULL)
872 amount=skb->len;
873 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
874 put_fs_long(amount,(unsigned long*)arg);
875 return0;
878 default:
879 return-EINVAL;
881 /*NOTREACHED*/
882 return(0);
885 /* Exported for procfs. */
887 intunix_get_info(char*buffer,char**start, off_t offset,int length)
889 off_t pos=0;
890 off_t begin=0;
891 int len=0;
892 unix_socket *s=unix_socket_list;
894 len+=sprintf(buffer,"Num RefCount Protocol Flags Type St Path\n");
896 while(s!=NULL)
898 len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
900 s->protinfo.af_unix.locks,
902 s->socket->flags,
903 s->socket->type,
904 s->socket->state);
905 if(s->protinfo.af_unix.name!=NULL)
906 len+=sprintf(buffer+len," %s\n", s->protinfo.af_unix.name);
907 else
908 buffer[len++]='\n';
910 pos=begin+len;
911 if(pos<offset)
913 len=0;
914 begin=pos;
916 if(pos>offset+length)
917 break;
918 s=s->next;
920 *start=buffer+(offset-begin);
921 len-=(offset-begin);
922 if(len>length)
923 len=length;
924 return len;
928 * For AF_UNIX we flip everything into an iovec. If this doesnt do any speed harm then it will
929 * be easier for all the low levels to be totally iovec based.
932 static intunix_recvfrom(struct socket *sock,void*ubuf,int size,int noblock,unsigned flags,
933 struct sockaddr *sa,int*addr_len)
935 struct iovec iov;
936 struct msghdr msg;
937 iov.iov_base=ubuf;
938 iov.iov_len=size;
939 msg.msg_name=(void*)sa;
940 msg.msg_namelen=get_user(addr_len);
941 msg.msg_accrights=NULL;
942 msg.msg_iov=&iov;
943 msg.msg_iovlen=1;
944 returnunix_recvmsg(sock,&msg,size,noblock,flags,addr_len);
947 static intunix_read(struct socket *sock,char*ubuf,int size,int noblock)
949 returnunix_recvfrom(sock,ubuf,size,noblock,0,NULL,NULL);
952 static intunix_recv(struct socket *sock,void*ubuf,int size,int noblock,unsigned int flags)
954 returnunix_recvfrom(sock,ubuf,size,noblock,flags,NULL,NULL);
957 static intunix_sendto(struct socket *sock,const void*ubuf,int size,int noblock,unsigned flags,
958 struct sockaddr *sa,int addr_len)
960 struct iovec iov;
961 struct msghdr msg;
962 iov.iov_base=(void*)ubuf;
963 iov.iov_len=size;
964 msg.msg_name=(void*)sa;
965 msg.msg_namelen=addr_len;
966 msg.msg_accrights=NULL;
967 msg.msg_iov=&iov;
968 msg.msg_iovlen=1;
969 returnunix_sendmsg(sock,&msg,size,noblock,flags);
972 static intunix_write(struct socket *sock,const char*ubuf,int size,int noblock)
974 returnunix_sendto(sock,ubuf,size,noblock,0, NULL,0);
977 static intunix_send(struct socket *sock,const void*ubuf,int size,int noblock,unsigned int flags)
979 returnunix_sendto(sock,ubuf,size,noblock, flags, NULL,0);
983 static struct proto_ops unix_proto_ops = {
984 AF_UNIX,
986 unix_create,
987 unix_dup,
988 unix_release,
989 unix_bind,
990 unix_connect,
991 unix_socketpair,
992 unix_accept,
993 unix_getname,
994 unix_read,
995 unix_write,
996 unix_select,
997 unix_ioctl,
998 unix_listen,
999 unix_send,
1000 unix_recv,
1001 unix_sendto,
1002 unix_recvfrom,
1003 unix_shutdown,
1004 unix_setsockopt,
1005 unix_getsockopt,
1006 unix_fcntl,
1007 unix_sendmsg,
1008 unix_recvmsg
1012 voidunix_proto_init(struct net_proto *pro)
1014 printk("NET3: Unix domain sockets 0.07 BETA for Linux NET3.030.\n");
1015 sock_register(unix_proto_ops.family, &unix_proto_ops);
close