diff -rc v1.1.62/fs/proc/net.c linux/fs/proc/net.c *** v1.1.62/fs/proc/net.c Thu Aug 11 03:14:05 1994 --- linux/fs/proc/net.c Mon Nov 21 18:55:11 1994 *************** *** 129,134 **** --- 129,135 ---- { PROC_NET_NR, 2, "nr" }, #endif /* CONFIG_NETROM */ #endif /* CONFIG_AX25 */ + { PROC_NET_SOCK, 7, "sockets" }, { 0, 0, NULL } }; *************** *** 270,275 **** --- 271,279 ---- break; #endif /* CONFIG_NETROM */ #endif /* CONFIG_AX25 */ + case PROC_NET_SOCK: + length = sock_get_info(page,&start, file->f_pos,thistime); + break; default: free_page((unsigned long) page); diff -rc v1.1.62/include/linux/net.h linux/include/linux/net.h *** v1.1.62/include/linux/net.h Fri Oct 21 02:41:17 1994 --- linux/include/linux/net.h Mon Nov 21 19:16:59 1994 *************** *** 23,29 **** #include ! #define NSOCKETS 128 /* should be dynamic, later... */ #define NPROTO 16 /* should be enough for now.. */ --- 23,29 ---- #include ! #define NSOCKETS 512 /* should be dynamic, later... */ #define NPROTO 16 /* should be enough for now.. */ *************** *** 132,137 **** --- 132,138 ---- extern int sock_wake_async(struct socket *sock); extern int sock_register(int family, struct proto_ops *ops); extern int sock_unregister(int family); + extern int sock_get_info(char *buf, char **start, int off, int max); #endif /* __KERNEL__ */ #endif /* _LINUX_NET_H */ diff -rc v1.1.62/include/linux/proc_fs.h linux/include/linux/proc_fs.h *** v1.1.62/include/linux/proc_fs.h Tue Aug 23 01:49:08 1994 --- linux/include/linux/proc_fs.h Mon Nov 21 18:46:16 1994 *************** *** 72,77 **** --- 72,78 ---- PROC_NET_NR, #endif #endif + PROC_NET_SOCK, PROC_NET_LAST }; diff -rc v1.1.62/net/socket.c linux/net/socket.c *** v1.1.62/net/socket.c Fri Dec 9 12:51:46 1994 --- linux/net/socket.c Mon Nov 21 23:23:14 1994 *************** *** 49,54 **** --- 49,56 ---- #include #include + #define DEBUG_SOCKET + #include #include *************** *** 90,95 **** --- 92,99 ---- /* * The list of sockets - make this atomic. */ + static int msocka; + static int nsocka, nsockf; /* for procfs: # of allocated/free sockets */ static struct socket sockets[NSOCKETS]; /* * Used to wait for a socket. *************** *** 256,261 **** --- 260,268 ---- * Got one.. */ sock->state = SS_UNCONNECTED; + nsocka++; nsockf--; + if(nsocka > msocka) + msocka = nsocka; sti(); sock->flags = 0; sock->ops = NULL; *************** *** 274,279 **** --- 281,290 ---- { printk("NET: sock_alloc: no more inodes\n"); sock->state = SS_FREE; + cli(); + nsockf++; + nsocka--; + sti(); return(NULL); } SOCK_INODE(sock)->i_mode = S_IFSOCK; *************** *** 321,326 **** --- 332,338 ---- int oldstate; struct inode *inode; struct socket *peersock, *nextsock; + unsigned long flags; if ((oldstate = sock->state) != SS_UNCONNECTED) sock->state = SS_DISCONNECTING; *************** *** 347,352 **** --- 359,369 ---- sock_release_peer(peersock); inode = SOCK_INODE(sock); sock->state = SS_FREE; /* this really releases us */ + save_flags(flags); + cli(); + nsockf++; + nsocka--; + restore_flags(flags); /* * This will wake anyone waiting for a free socket. *************** *** 809,815 **** --- 826,885 ---- return(0); } + #ifdef DEBUG_SOCKET + static unsigned long get_phys_addr(struct task_struct ** p, unsigned long ptr) + { + unsigned long page; + if (!p || !*p || ptr >= TASK_SIZE) + return 0; + page = *PAGE_DIR_OFFSET((*p)->tss.cr3,ptr); + if (!(page & PAGE_PRESENT)) + return 0; + page &= PAGE_MASK; + page += PAGE_PTR(ptr); + page = *(unsigned long *) page; + if (!(page & PAGE_PRESENT)) + return 0; + page &= PAGE_MASK; + page += ptr & ~PAGE_MASK; + return page; + } + + static int get_array(struct task_struct ** p, unsigned long start, unsigned long end, char * buffer) + { + unsigned long addr; + int size = 0, result = 0; + char c; + + if (start >= end) + return result; + for (;;) { + addr = get_phys_addr(p, start); + if (!addr) + goto ready; + do { + c = *(char *) addr; + if (!c) + result = size; + if (size < PAGE_SIZE) + buffer[size++] = c; + else + goto ready; + addr++; + start++; + if (!c && start >= end) + goto ready; + } while (addr & ~PAGE_MASK); + } + ready: + /* remove the trailing blanks, used to fill out argv,envp space */ + while (result>0 && buffer[result-1]==' ') + result--; + return result; + } + + #endif /* * For accept, we attempt to create a new socket, set up the link * with the client, wake up the client, then return the new *************** *** 841,846 **** --- 911,924 ---- if (!(newsock = sock_alloc(0))) { + #ifdef DEBUG_SOCKET + long page; + if ((page = __get_free_page(GFP_KERNEL))) { + get_array(¤t, current->mm->arg_start, current->mm->arg_end, (char *)page); + printk("NET: sock_accept: no more sockets for %s\n",(char *)page); + free_page(page); + } else + #endif printk("NET: sock_accept: no more sockets\n"); return(-EAGAIN); } *************** *** 1388,1393 **** --- 1466,1473 ---- */ for (sock = sockets; sock <= last_socket; ++sock) sock->state = SS_FREE; + nsocka = 0; + nsockf = NSOCKETS; /* * Initialize all address (protocol) families. *************** *** 1415,1418 **** --- 1495,1514 ---- bh_base[NET_BH].routine= net_bh; #endif + } + + /* for procfs: get # free/alloc'd sockets */ + int sock_get_info(char *buf, char **start, int off, int max) + { + register int l = sprintf(buf, "%d %d %d\n", nsockf, nsocka, msocka); + + *start = off+buf; + l -= off; + if(max>l) { + if(l > 0) + return l; + else + return 0; + } + return max; }