asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen){ struct socket *sock, *newsock; struct file *newfile; int err, len, newfd, fput_needed; char address[MAX_SOCK_ADDR]; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; err = -ENFILE; if (!(newsock = sock_alloc())) goto out_put; newsock->type = sock->type; newsock->ops = sock->ops; /* * We don't need try_module_get here, as the listening socket (sock) * has the PRotocol module (sock->ops->owner) held. */ __module_get(newsock->ops->owner); newfd = sock_alloc_fd(&newfile); if (unlikely(newfd < 0)) { err = newfd; sock_release(newsock); goto out_put; } err = sock_attach_fd(newsock, newfile); if (err < 0) goto out_fd_simple; err = security_socket_accept(sock, newsock); if (err) goto out_fd; err = sock->ops->accept(sock, newsock, sock->file->f_flags); if (err < 0) goto out_fd; if (upeer_sockaddr) { if (newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2) < 0) { err = -ECONNABORTED; goto out_fd; } err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen); if (err < 0) goto out_fd; } /* File flags are not inherited via accept() unlike another OSes. */ fd_install(newfd, newfile); err = newfd; security_socket_post_accept(sock, newsock);out_put: fput_light(sock->file, fput_needed);out: return err;out_fd_simple: sock_release(newsock); put_filp(newfile); put_unused_fd(newfd); goto out_put;out_fd: fput(newfile); put_unused_fd(newfd); goto out_put;}
新闻热点
疑难解答