diff -urNp --exclude CVS --exclude BitKeeper x-ref/include/linux/socket.h x/include/linux/socket.h --- x-ref/include/linux/socket.h 2003-07-18 06:07:45.000000000 +0200 +++ x/include/linux/socket.h 2003-07-19 01:59:02.000000000 +0200 @@ -275,6 +275,11 @@ extern void memcpy_tokerneliovec(struct extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen); extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr); extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); +struct socket; +struct file * sock_map_file(struct socket *sock); +extern int sock_map_fd(struct socket *sock); +extern struct socket *sockfd_lookup(int fd, int *err); + #endif #endif /* not kernel and not glibc */ #endif /* _LINUX_SOCKET_H */ diff -urNp --exclude CVS --exclude BitKeeper x-ref/include/net/tcp.h x/include/net/tcp.h --- x-ref/include/net/tcp.h 2003-07-19 01:58:56.000000000 +0200 +++ x/include/net/tcp.h 2003-07-19 01:59:02.000000000 +0200 @@ -811,6 +811,7 @@ extern void tcp_send_skb(struct sock *, extern void tcp_push_one(struct sock *, unsigned mss_now); extern void tcp_send_ack(struct sock *sk); extern void tcp_send_delayed_ack(struct sock *sk); +extern void cleanup_rbuf(struct sock *sk, int copied); /* tcp_timer.c */ extern void tcp_init_xmit_timers(struct sock *); diff -urNp --exclude CVS --exclude BitKeeper x-ref/net/ipv4/tcp.c x/net/ipv4/tcp.c --- x-ref/net/ipv4/tcp.c 2003-07-19 01:58:58.000000000 +0200 +++ x/net/ipv4/tcp.c 2003-07-19 01:59:02.000000000 +0200 @@ -1280,7 +1280,7 @@ static inline void tcp_eat_skb(struct so * calculation of whether or not we must ACK for the sake of * a window update. */ -static void cleanup_rbuf(struct sock *sk, int copied) +void cleanup_rbuf(struct sock *sk, int copied) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int time_to_ack = 0; diff -urNp --exclude CVS --exclude BitKeeper x-ref/net/netsyms.c x/net/netsyms.c --- x-ref/net/netsyms.c 2003-07-19 01:58:56.000000000 +0200 +++ x/net/netsyms.c 2003-07-19 01:59:46.000000000 +0200 @@ -112,6 +112,7 @@ EXPORT_SYMBOL(memcpy_tokerneliovec); EXPORT_SYMBOL(sock_create); EXPORT_SYMBOL(sock_alloc); EXPORT_SYMBOL(sock_release); +EXPORT_SYMBOL(sock_map_fd); EXPORT_SYMBOL(sock_setsockopt); EXPORT_SYMBOL(sock_getsockopt); EXPORT_SYMBOL(sock_sendmsg); @@ -332,6 +333,7 @@ EXPORT_SYMBOL(ip_queue_xmit); EXPORT_SYMBOL(memcpy_fromiovecend); EXPORT_SYMBOL(csum_partial_copy_fromiovecend); EXPORT_SYMBOL(tcp_v4_lookup_listener); +EXPORT_SYMBOL(cleanup_rbuf); /* UDP/TCP exported functions for TCPv6 */ EXPORT_SYMBOL(udp_ioctl); EXPORT_SYMBOL(udp_connect); @@ -349,6 +351,7 @@ EXPORT_SYMBOL(tcp_setsockopt); EXPORT_SYMBOL(tcp_getsockopt); EXPORT_SYMBOL(tcp_recvmsg); EXPORT_SYMBOL(tcp_send_synack); +EXPORT_SYMBOL(tcp_send_skb); EXPORT_SYMBOL(tcp_check_req); EXPORT_SYMBOL(tcp_child_process); EXPORT_SYMBOL(tcp_parse_options); diff -urNp --exclude CVS --exclude BitKeeper x-ref/net/socket.c x/net/socket.c --- x-ref/net/socket.c 2003-07-19 01:58:56.000000000 +0200 +++ x/net/socket.c 2003-07-19 01:59:02.000000000 +0200 @@ -325,51 +325,62 @@ static struct dentry_operations sockfs_d * but we take care of internal coherence yet. */ -static int sock_map_fd(struct socket *sock) +struct file * sock_map_file(struct socket *sock) { - int fd; + struct file *file; struct qstr this; char name[32]; + file = get_empty_filp(); + + if (!file) + return ERR_PTR(-ENFILE); + + sprintf(name, "[%lu]", sock->inode->i_ino); + this.name = name; + this.len = strlen(name); + this.hash = sock->inode->i_ino; + + file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); + if (!file->f_dentry) { + put_filp(file); + return ERR_PTR(-ENOMEM); + } + file->f_dentry->d_op = &sockfs_dentry_operations; + d_add(file->f_dentry, sock->inode); + file->f_vfsmnt = mntget(sock_mnt); + + if (sock->file) + BUG(); + sock->file = file; + file->f_op = sock->inode->i_fop = &socket_file_ops; + file->f_mode = 3; + file->f_flags = O_RDWR; + file->f_pos = 0; + + return file; +} + +int sock_map_fd(struct socket *sock) +{ + int fd; + struct file *file; + /* * Find a file descriptor suitable for return to the user. */ fd = get_unused_fd(); - if (fd >= 0) { - struct file *file = get_empty_filp(); - - if (!file) { - put_unused_fd(fd); - fd = -ENFILE; - goto out; - } + if (fd < 0) + return fd; - sprintf(name, "[%lu]", sock->inode->i_ino); - this.name = name; - this.len = strlen(name); - this.hash = sock->inode->i_ino; - - file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); - if (!file->f_dentry) { - put_filp(file); - put_unused_fd(fd); - fd = -ENOMEM; - goto out; - } - file->f_dentry->d_op = &sockfs_dentry_operations; - d_add(file->f_dentry, sock->inode); - file->f_vfsmnt = mntget(sock_mnt); - - sock->file = file; - file->f_op = sock->inode->i_fop = &socket_file_ops; - file->f_mode = 3; - file->f_flags = O_RDWR; - file->f_pos = 0; - fd_install(fd, file); + file = sock_map_file(sock); + if (IS_ERR(file)) { + put_unused_fd(fd); + return PTR_ERR(file); } + fd_install(fd, file); -out: return fd; } @@ -790,6 +801,8 @@ static int sock_fasync(int fd, struct fi } out: + if (sock->sk != sk) + BUG(); release_sock(sock->sk); return 0; }