Import 1.3.63
[davej-history.git] / net / unix / af_unix.c
blob3ba44b32f6adf5272c0e653602e6aa50b352b9b4
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 /* if msg->accrights != NULL, we have fds to pass.
681 * Current implementation passes at most one fd.
683 static intunix_sendmsg(struct socket *sock,struct msghdr *msg,int len,int nonblock,int flags)
685 unix_socket *sk=sock->data;
686 unix_socket *other;
687 struct sockaddr_un *sunaddr=msg->msg_name;
688 int err,size;
689 struct sk_buff *skb;
690 int limit=0;
691 int sent=0;
692 /* for passing fd, NULL indicates no fd */
693 struct file *filp;
695 if(sk->err)
696 returnsock_error(sk);
698 if(flags&MSG_OOB)
699 return-EOPNOTSUPP;
701 if(flags)/* For now */
702 return-EINVAL;
704 if(sunaddr!=NULL)
706 if(sock->type==SOCK_STREAM)
708 if(sk->state==TCP_ESTABLISHED)
709 return-EISCONN;
710 else
711 return-EOPNOTSUPP;
715 if(sunaddr==NULL)
717 if(sk->protinfo.af_unix.other==NULL)
718 return-ENOTCONN;
722 /* see if we want to access rights (fd) -- at the moment,
723 * we can pass none or 1 fd
725 filp = NULL;
726 if(msg->msg_accrights) {
727 /* then accrightslen is meaningful */
728 if(msg->msg_accrightslen ==sizeof(int)) {
729 int fd;
731 fd =get_user_long(msg->msg_accrights);
732 filp =file_from_fd(fd);
733 if(!filp)
734 return-EBADF;
735 }else if(msg->msg_accrightslen !=0) {
736 /* if we have accrights, we fail here */
737 return-EINVAL;
741 /* invariant -- flip points to a file to pass or NULL */
742 while(sent < len)
745 * Optimisation for the fact that under 0.01% of X messages typically
746 * need breaking up.
749 size=len-sent;
751 if(size>(sk->sndbuf-sizeof(struct sk_buff))/2)/* Keep two messages in the pipe so it schedules better */
753 if(sock->type==SOCK_DGRAM)
754 return-EMSGSIZE;
755 size=(sk->sndbuf-sizeof(struct sk_buff))/2;
758 * Keep to page sized kmalloc()'s as various people
759 * have suggested. Big mallocs stress the vm too
760 * much.
763 if(size >4000&& sock->type!=SOCK_DGRAM)
764 limit =4000;/* Fall back to 4K if we can't grab a big buffer this instant */
765 else
766 limit =0;/* Otherwise just grab and wait */
769 * Grab a buffer
772 skb=sock_alloc_send_skb(sk,size,limit,nonblock, &err);
774 if(skb==NULL)
776 if(sent)
778 sk->err=-err;
779 return sent;
781 return err;
783 size=skb_tailroom(skb);/* If we dropped back on a limit then our skb is smaller */
785 skb->sk=sk;
786 skb->free=1;
788 memcpy_fromiovec(skb_put(skb,size),msg->msg_iov, size);
790 cli();
791 if(sunaddr==NULL)
793 other=sk->protinfo.af_unix.other;
794 if(sock->type==SOCK_DGRAM && other->dead)
796 other->protinfo.af_unix.locks--;
797 sk->protinfo.af_unix.other=NULL;
798 sock->state=SS_UNCONNECTED;
799 sti();
800 kfree_skb(skb, FREE_WRITE);
801 if(!sent)
802 return-ECONNRESET;
803 else
804 return sent;
807 else
809 unix_mkname(sunaddr, msg->msg_namelen);
810 other=unix_find_other(sunaddr->sun_path, &err);
811 if(other==NULL)
813 sti();
814 kfree_skb(skb, FREE_WRITE);
815 if(sent)
816 return sent;
817 else
818 return err;
821 /* at this point, we want to add an fd if we have one */
822 skb->h.filp = filp;
823 if(filp) {
824 filp->f_count++;
827 skb_queue_tail(&other->receive_queue, skb);
828 sti();
829 /* if we sent an fd, only do it once */
830 filp = NULL;
831 other->data_ready(other,size);
832 sent+=size;
834 return sent;
838 * Sleep until data has arrive. But check for races..
841 static voidunix_data_wait(unix_socket * sk)
843 cli();
844 if(!skb_peek(&sk->receive_queue)) {
845 sk->socket->flags |= SO_WAITDATA;
846 interruptible_sleep_on(sk->sleep);
847 sk->socket->flags &= ~SO_WAITDATA;
849 sti();
854 * return 0 if we can stick the fd, negative errno if we can't
856 static intstick_fd(struct file *filp,int*uaddr,int size)
858 int slot;
859 int upper_bound;
861 if(!uaddr || size <sizeof(int))
862 return-EINVAL;
864 upper_bound = current->rlim[RLIMIT_NOFILE].rlim_cur;
866 if(upper_bound > NR_OPEN)
867 upper_bound = NR_OPEN;
869 for(slot =0; slot < upper_bound; slot++) {
870 if(current->files->fd[slot])
871 continue;
872 /* have an fd */
873 current->files->fd[slot] = filp;
874 FD_CLR(slot, &current->files->close_on_exec);
875 /* need verify area here? */
876 put_user_long(slot, uaddr);
877 return0;
879 return-EMFILE;
882 static intunix_recvmsg(struct socket *sock,struct msghdr *msg,int size,int noblock,int flags,int*addr_len)
884 unix_socket *sk=sock->data;
885 struct sockaddr_un *sunaddr=msg->msg_name;
886 struct sk_buff *skb;
887 int copied=0;
888 unsigned char*sp;
889 int len;
890 int num;
891 struct iovec *iov=msg->msg_iov;
892 int ct=msg->msg_iovlen;
893 struct file *filp;
895 if(flags&MSG_OOB)
896 return-EOPNOTSUPP;
898 if(addr_len)
899 *addr_len=0;
901 if(sk->err)
902 returnsock_error(sk);
904 down(&sk->protinfo.af_unix.readsem);/* Lock the socket */
905 while(ct--)
907 int done=0;
908 sp=iov->iov_base;
909 len=iov->iov_len;
910 iov++;
912 while(done<len)
914 if(copied && (flags & MSG_PEEK))
915 goto out;
916 if(copied == size)
917 goto out;
918 skb=skb_dequeue(&sk->receive_queue);
919 if(skb==NULL)
921 up(&sk->protinfo.af_unix.readsem);
922 if(sk->shutdown & RCV_SHUTDOWN)
923 return copied;
924 if(copied)
925 return copied;
926 if(noblock)
927 return-EAGAIN;
928 if(current->signal & ~current->blocked)
929 return-ERESTARTSYS;
930 unix_data_wait(sk);
931 down(&sk->protinfo.af_unix.readsem);
932 continue;
934 if(msg->msg_name!=NULL)
936 sunaddr->sun_family=AF_UNIX;
937 if(skb->sk->protinfo.af_unix.name)
939 memcpy(sunaddr->sun_path, skb->sk->protinfo.af_unix.name,108);
940 if(addr_len)
941 *addr_len=strlen(sunaddr->sun_path)+sizeof(short);
943 else
944 if(addr_len)
945 *addr_len=sizeof(short);
948 num=min(skb->len,size-copied);
949 memcpy_tofs(sp, skb->data, num);
951 if((filp = skb->h.filp) != NULL) {
952 skb->h.filp = NULL;
953 if(stick_fd(filp, msg->msg_accrights, msg->msg_accrightslen) <0)
954 close_fp(filp);
957 copied+=num;
958 done+=num;
959 sp+=num;
960 if(!(flags & MSG_PEEK))
961 skb_pull(skb, num);
962 /* put the skb back if we didn't use it up.. */
963 if(skb->len) {
964 skb_queue_head(&sk->receive_queue, skb);
965 continue;
967 kfree_skb(skb, FREE_WRITE);
968 if(sock->type==SOCK_DGRAM)
969 goto out;
972 out:
973 up(&sk->protinfo.af_unix.readsem);
974 return copied;
977 static intunix_shutdown(struct socket *sock,int mode)
979 unix_socket *sk=(unix_socket *)sock->data;
980 unix_socket *other=sk->protinfo.af_unix.other;
981 if(mode&SEND_SHUTDOWN)
983 sk->shutdown|=SEND_SHUTDOWN;
984 sk->state_change(sk);
985 if(other)
987 other->shutdown|=RCV_SHUTDOWN;
988 other->state_change(other);
991 other=sk->protinfo.af_unix.other;
992 if(mode&RCV_SHUTDOWN)
994 sk->shutdown|=RCV_SHUTDOWN;
995 sk->state_change(sk);
996 if(other)
998 other->shutdown|=SEND_SHUTDOWN;
999 other->state_change(other);
1002 return0;
1006 static intunix_select(struct socket *sock,int sel_type, select_table *wait)
1008 returndatagram_select(sock->data,sel_type,wait);
1011 static intunix_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
1013 unix_socket *sk=sock->data;
1014 int err;
1015 long amount=0;
1017 switch(cmd)
1020 case TIOCOUTQ:
1021 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
1022 if(err)
1023 return err;
1024 amount=sk->sndbuf-sk->wmem_alloc;
1025 if(amount<0)
1026 amount=0;
1027 put_fs_long(amount,(unsigned long*)arg);
1028 return0;
1029 case TIOCINQ:
1031 struct sk_buff *skb;
1032 if(sk->state==TCP_LISTEN)
1033 return-EINVAL;
1034 /* These two are safe on a single CPU system as only user tasks fiddle here */
1035 if((skb=skb_peek(&sk->receive_queue))!=NULL)
1036 amount=skb->len;
1037 err=verify_area(VERIFY_WRITE,(void*)arg,sizeof(unsigned long));
1038 put_fs_long(amount,(unsigned long*)arg);
1039 return0;
1042 default:
1043 return-EINVAL;
1045 /*NOTREACHED*/
1046 return(0);
1049 #ifdef CONFIG_PROC_FS
1050 static intunix_get_info(char*buffer,char**start, off_t offset,int length,int dummy)
1052 off_t pos=0;
1053 off_t begin=0;
1054 int len=0;
1055 unix_socket *s=unix_socket_list;
1057 len+=sprintf(buffer,"Num RefCount Protocol Flags Type St Path\n");
1059 while(s!=NULL)
1061 len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
1063 s->protinfo.af_unix.locks,
1065 s->socket->flags,
1066 s->socket->type,
1067 s->socket->state);
1068 if(s->protinfo.af_unix.name!=NULL)
1069 len+=sprintf(buffer+len," %s\n", s->protinfo.af_unix.name);
1070 else
1071 buffer[len++]='\n';
1073 pos=begin+len;
1074 if(pos<offset)
1076 len=0;
1077 begin=pos;
1079 if(pos>offset+length)
1080 break;
1081 s=s->next;
1083 *start=buffer+(offset-begin);
1084 len-=(offset-begin);
1085 if(len>length)
1086 len=length;
1087 return len;
1089 #endif
1091 static struct proto_ops unix_proto_ops = {
1092 AF_UNIX,
1094 unix_create,
1095 unix_dup,
1096 unix_release,
1097 unix_bind,
1098 unix_connect,
1099 unix_socketpair,
1100 unix_accept,
1101 unix_getname,
1102 unix_select,
1103 unix_ioctl,
1104 unix_listen,
1105 unix_shutdown,
1106 unix_setsockopt,
1107 unix_getsockopt,
1108 unix_fcntl,
1109 unix_sendmsg,
1110 unix_recvmsg
1114 voidunix_proto_init(struct net_proto *pro)
1116 printk("NET3: Unix domain sockets 0.10 BETA for Linux NET3.033.\n");
1117 sock_register(unix_proto_ops.family, &unix_proto_ops);
1118 #ifdef CONFIG_PROC_FS
1119 proc_net_register(&(struct proc_dir_entry) {
1120 PROC_NET_UNIX,4,"unix",
1121 S_IFREG | S_IRUGO,1,0,0,
1122 0, &proc_net_inode_operations,
1123 unix_get_info
1125 #endif
1128 * Local variables:
1129 * compile-command: "gcc -g -D__KERNEL__ -Wall -O6 -I/usr/src/linux/include -c af_unix.c"
1130 * End:
close