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. 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: 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). 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> 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> 57 #include <linux/malloc.h> 58 #include <asm/segment.h> 59 #include <linux/skbuff.h> 60 #include <linux/netdevice.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 86 static voidunix_remove_socket(unix_socket
*sk
) 106 static voidunix_insert_socket(unix_socket
*sk
) 109 sk
->next
=unix_socket_list
; 114 static unix_socket
*unix_find_socket(struct inode
*i
) 121 if(s
->protinfo
.af_unix
.inode
==i
) 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
)); 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
) 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 */ 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
)); 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
) 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
) 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
) 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
; 246 static voiddef_callback1(struct sock
*sk
) 249 wake_up_interruptible(sk
->sleep
); 252 static voiddef_callback2(struct sock
*sk
,int len
) 256 wake_up_interruptible(sk
->sleep
); 257 sock_wake_async(sk
->socket
,1); 261 static voiddef_callback3(struct sock
*sk
) 265 wake_up_interruptible(sk
->sleep
); 266 sock_wake_async(sk
->socket
,2); 270 static intunix_create(struct socket
*sock
,int protocol
) 273 /* printk("Unix create\n");*/ 274 if(protocol
&& protocol
!= PF_UNIX
) 275 return-EPROTONOSUPPORT
; 276 sk
=(unix_socket
*)kmalloc(sizeof(*sk
),GFP_KERNEL
); 284 * Believe it or not BSD has AF_UNIX, SOCK_RAW though 288 sock
->type
=SOCK_DGRAM
; 292 kfree_s(sk
,sizeof(*sk
)); 293 return-ESOCKTNOSUPPORT
; 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
; 312 sk
->rcvbuf
=SK_RMEM_MAX
; 313 sk
->sndbuf
=SK_WMEM_MAX
; 314 sk
->allocation
=GFP_KERNEL
; 322 sk
->priority
=SOPRI_NORMAL
; 325 sk
->state_change
=def_callback1
; 326 sk
->data_ready
=def_callback2
; 327 sk
->write_space
=def_callback3
; 328 sk
->error_report
=def_callback1
; 331 sock
->data
=(void*)sk
; 332 sk
->sleep
=sock
->wait
; 334 unix_insert_socket(sk
); 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
; 348 /* May not have data attached */ 353 sk
->state_change(sk
); 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 */ 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. 375 static unix_socket
*unix_find_other(char*path
,int*error
) 384 err
=open_namei(path
,2, S_IFSOCK
, &inode
, NULL
); 391 u
=unix_find_socket(inode
); 395 *error
=-ECONNREFUSED
; 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
; 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
) 414 unix_mkname(sunaddr
, addr_len
); 416 * Put ourselves in the filesystem 418 if(sk
->protinfo
.af_unix
.inode
!=NULL
) 421 sk
->protinfo
.af_unix
.name
=kmalloc(addr_len
+1, GFP_KERNEL
); 422 if(sk
->protinfo
.af_unix
.name
==NULL
) 424 memcpy(sk
->protinfo
.af_unix
.name
, sunaddr
->sun_path
, addr_len
+1); 429 err
=do_mknod(sk
->protinfo
.af_unix
.name
,S_IFSOCK
|S_IRWXUGO
,0); 431 err
=open_namei(sk
->protinfo
.af_unix
.name
,2, S_IFSOCK
, &sk
->protinfo
.af_unix
.inode
, NULL
); 437 kfree_s(sk
->protinfo
.af_unix
.name
,addr_len
+1); 438 sk
->protinfo
.af_unix
.name
=NULL
; 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
; 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
; 464 if(sock
->state
==SS_CONNECTING
&& sk
->state
== TCP_CLOSE
) 466 sock
->state
=SS_UNCONNECTED
; 469 if(sock
->state
==SS_CONNECTING
) 474 if(addr_len
<sizeof(sunaddr
->sun_family
)+1|| sunaddr
->sun_family
!=AF_UNIX
) 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
); 491 if(other
->type
!=sk
->type
) 493 other
->protinfo
.af_unix
.locks
++; 494 sk
->protinfo
.af_unix
.other
=other
; 495 sock
->state
=SS_CONNECTED
; 496 sk
->state
=TCP_ESTABLISHED
; 501 if(sock
->state
==SS_UNCONNECTED
) 504 * Now ready to connect 507 skb
=sock_alloc_send_skb(sk
,0,0,0, &err
);/* Marker object */ 510 skb
->sk
=sk
;/* So they know it is us */ 513 unix_mkname(sunaddr
, addr_len
); 514 other
=unix_find_other(sunaddr
->sun_path
, &err
); 517 kfree_skb(skb
, FREE_WRITE
); 520 if(other
->type
!=sk
->type
) 522 kfree_skb(skb
, FREE_WRITE
); 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
; 532 other
->data_ready(other
,0);/* Wake up ! */ 536 /* Wait for an accept */ 539 while(sk
->state
==TCP_SYN_SENT
) 546 interruptible_sleep_on(sk
->sleep
); 547 if(current
->signal
& ~current
->blocked
) 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
; 568 * Amazingly it has worked 571 sock
->state
=SS_CONNECTED
; 577 static intunix_socketpair(struct socket
*a
,struct socket
*b
) 579 unix_socket
*ska
,*skb
; 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
; 594 static intunix_accept(struct socket
*sock
,struct socket
*newsock
,int flags
) 596 unix_socket
*sk
=sock
->data
; 597 unix_socket
*newsk
, *tsk
; 600 if(sk
->type
!=SOCK_STREAM
) 604 if(sk
->state
!=TCP_LISTEN
) 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
) 615 strcpy(newsk
->protinfo
.af_unix
.name
, sk
->protinfo
.af_unix
.name
); 621 skb
=skb_dequeue(&sk
->receive_queue
); 629 interruptible_sleep_on(sk
->sleep
); 630 if(current
->signal
& ~current
->blocked
) 640 kfree_skb(skb
, FREE_WRITE
);/* The buffer is just used as a tag */ 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 */ 650 tsk
->state_change(tsk
);/* Wake up any sleeping connect */ 651 sock_wake_async(tsk
->socket
,0); 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
; 662 if(sk
->protinfo
.af_unix
.other
==NULL
) 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 */ 678 static intunix_sendmsg(struct socket
*sock
,struct msghdr
*msg
,int len
,int nonblock
,int flags
) 680 unix_socket
*sk
=sock
->data
; 682 struct sockaddr_un
*sunaddr
=msg
->msg_name
; 689 returnsock_error(sk
); 694 if(flags
|| msg
->msg_accrights
)/* For now */ 699 if(sock
->type
==SOCK_STREAM
) 701 if(sk
->state
==TCP_ESTABLISHED
) 709 if(sk
->protinfo
.af_unix
.other
==NULL
) 717 * Optimisation for the fact that under 0.01% of X messages typically 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
) 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 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 */ 738 limit
=0;/* Otherwise just grab and wait */ 744 skb
=sock_alloc_send_skb(sk
,size
,limit
,nonblock
, &err
); 755 size
=skb_tailroom(skb
);/* If we dropped back on a limit then our skb is smaller */ 760 memcpy_fromiovec(skb_put(skb
,size
),msg
->msg_iov
, size
); 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
; 780 unix_mkname(sunaddr
, msg
->msg_namelen
); 781 other
=unix_find_other(sunaddr
->sun_path
, &err
); 784 kfree_skb(skb
, FREE_WRITE
); 792 skb_queue_tail(&other
->receive_queue
, skb
); 794 other
->data_ready(other
,size
); 801 * Sleep until data has arrive. But check for races.. 803 static voidunix_data_wait(unix_socket
* sk
) 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
; 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
; 823 struct iovec
*iov
=msg
->msg_iov
; 824 int ct
=msg
->msg_iovlen
; 833 returnsock_error(sk
); 835 down(&sk
->protinfo
.af_unix
.readsem
);/* Lock the socket */ 845 if(copied
&& (flags
& MSG_PEEK
)) 849 skb
=skb_dequeue(&sk
->receive_queue
); 852 up(&sk
->protinfo
.af_unix
.readsem
); 853 if(sk
->shutdown
& RCV_SHUTDOWN
) 859 if(current
->signal
& ~current
->blocked
) 862 down(&sk
->protinfo
.af_unix
.readsem
); 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); 872 *addr_len
=strlen(sunaddr
->sun_path
)+sizeof(short); 876 *addr_len
=sizeof(short); 878 num
=min(skb
->len
,size
-copied
); 879 memcpy_tofs(sp
, skb
->data
, num
); 883 if(!(flags
& MSG_PEEK
)) 885 /* put the skb back if we didn't use it up.. */ 887 skb_queue_head(&sk
->receive_queue
, skb
); 890 kfree_skb(skb
, FREE_WRITE
); 891 if(sock
->type
==SOCK_DGRAM
) 896 up(&sk
->protinfo
.af_unix
.readsem
); 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
); 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
); 921 other
->shutdown
|=SEND_SHUTDOWN
; 922 other
->state_change(other
); 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
; 944 err
=verify_area(VERIFY_WRITE
,(void*)arg
,sizeof(unsigned long)); 947 amount
=sk
->sndbuf
-sk
->wmem_alloc
; 950 put_fs_long(amount
,(unsigned long*)arg
); 955 if(sk
->state
==TCP_LISTEN
) 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
) 960 err
=verify_area(VERIFY_WRITE
,(void*)arg
,sizeof(unsigned long)); 961 put_fs_long(amount
,(unsigned long*)arg
); 972 static intunix_get_info(char*buffer
,char**start
, off_t offset
,int length
,int dummy
) 977 unix_socket
*s
=unix_socket_list
; 979 len
+=sprintf(buffer
,"Num RefCount Protocol Flags Type St Path\n"); 983 len
+=sprintf(buffer
+len
,"%p: %08X %08X %08lX %04X %02X", 985 s
->protinfo
.af_unix
.locks
, 990 if(s
->protinfo
.af_unix
.name
!=NULL
) 991 len
+=sprintf(buffer
+len
," %s\n", s
->protinfo
.af_unix
.name
); 1001 if(pos
>offset
+length
) 1005 *start
=buffer
+(offset
-begin
); 1006 len
-=(offset
-begin
); 1012 static struct proto_ops unix_proto_ops
= { 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
, 1048 * compile-command: "gcc -g -D__KERNEL__ -Wall -O6 -I/usr/src/linux/include -c af_unix.c"