Index: sys/socketvar.h =================================================================== RCS file: /cvsroot/src/sys/sys/socketvar.h,v retrieving revision 1.167 diff -u -p -r1.167 socketvar.h --- sys/socketvar.h 2 Nov 2023 10:31:55 -0000 1.167 +++ sys/socketvar.h 21 Jan 2024 17:56:57 -0000 @@ -306,7 +306,8 @@ int soconnect(struct socket *, struct so int soconnect2(struct socket *, struct socket *); int socreate(int, struct socket **, int, int, struct lwp *, struct socket *); -int fsocreate(int, struct socket **, int, int, int *); +int fsocreate(int, struct socket **, int, int, int *, file_t **, + struct socket *); int sodisconnect(struct socket *); void sofree(struct socket *); int sogetopt(struct socket *, struct sockopt *); Index: net/if_gre.c =================================================================== RCS file: /cvsroot/src/sys/net/if_gre.c,v retrieving revision 1.184 diff -u -p -r1.184 if_gre.c --- net/if_gre.c 3 Sep 2022 02:47:59 -0000 1.184 +++ net/if_gre.c 21 Jan 2024 17:56:57 -0000 @@ -435,6 +435,7 @@ static int gre_socreate(struct gre_softc *sc, const struct gre_soparm *sp, int *fdout) { int fd, rc; + file_t *fp; struct socket *so; struct sockaddr_big sbig; sa_family_t af; @@ -443,15 +444,12 @@ gre_socreate(struct gre_softc *sc, const GRE_DPRINTF(sc, "enter\n"); af = sp->sp_src.ss_family; - rc = fsocreate(af, NULL, sp->sp_type, sp->sp_proto, &fd); + rc = fsocreate(af, &so, sp->sp_type, sp->sp_proto, &fd, &fp, NULL); if (rc != 0) { GRE_DPRINTF(sc, "fsocreate failed\n"); return rc; } - if ((rc = fd_getsock(fd, &so)) != 0) - return rc; - memcpy(&sbig, &sp->sp_src, sizeof(sp->sp_src)); if ((rc = sobind(so, (struct sockaddr *)&sbig, curlwp)) != 0) { GRE_DPRINTF(sc, "sobind failed\n"); @@ -484,10 +482,11 @@ gre_socreate(struct gre_softc *sc, const rc = 0; } out: - if (rc != 0) - fd_close(fd); - else { - fd_putfile(fd); + if (rc != 0) { + soclose(so); + fd_abort(curproc, fp, fd); + } else { + fd_affix(curproc, fp, fd); *fdout = fd; } Index: kern/uipc_socket.c =================================================================== RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v retrieving revision 1.307 diff -u -p -r1.307 uipc_socket.c --- kern/uipc_socket.c 2 Nov 2023 10:31:55 -0000 1.307 +++ kern/uipc_socket.c 21 Jan 2024 17:56:58 -0000 @@ -568,44 +568,51 @@ socreate(int dom, struct socket **aso, i /* * fsocreate: create a socket and a file descriptor associated with it. + * Returns the allocated file structure in *fpp, but the descriptor + * is not visible yet for the process. + * Caller is responsible for calling fd_affix() for the returned *fpp once + * it's socket initialization is finished successfully, or fd_abort() if it's + * initialization fails. + * * - * => On success, write file descriptor to fdout and return zero. - * => On failure, return non-zero; *fdout will be undefined. + * => On success, write file descriptor to *fdout and *fpp and return zero. + * => On failure, return non-zero; *fdout and *fpp will be undefined. */ int -fsocreate(int domain, struct socket **sop, int type, int proto, int *fdout) +fsocreate(int domain, struct socket **sop, int type, int proto, int *fdout, + file_t **fpp, struct socket *lockso) { lwp_t *l = curlwp; int error, fd, flags; struct socket *so; - struct file *fp; + file_t *fp; + + flags = type & SOCK_FLAGS_MASK; + type &= ~SOCK_FLAGS_MASK; + error = socreate(domain, &so, type, proto, l, lockso); + if (error) { + return error; + } if ((error = fd_allocfile(&fp, &fd)) != 0) { + soclose(so); return error; } - flags = type & SOCK_FLAGS_MASK; fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0); fp->f_flag = FREAD|FWRITE|((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)| ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0); fp->f_type = DTYPE_SOCKET; fp->f_ops = &socketops; - - type &= ~SOCK_FLAGS_MASK; - error = socreate(domain, &so, type, proto, l, NULL); - if (error) { - fd_abort(curproc, fp, fd); - return error; - } if (flags & SOCK_NONBLOCK) { so->so_state |= SS_NBIO; } fp->f_socket = so; - fd_affix(curproc, fp, fd); if (sop != NULL) { *sop = so; } *fdout = fd; + *fpp = fp; return error; } Index: kern/uipc_syscalls.c =================================================================== RCS file: /cvsroot/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.210 diff -u -p -r1.210 uipc_syscalls.c --- kern/uipc_syscalls.c 2 Nov 2023 10:31:55 -0000 1.210 +++ kern/uipc_syscalls.c 21 Jan 2024 17:56:58 -0000 @@ -111,10 +111,12 @@ sys___socket30(struct lwp *l, const stru syscallarg(int) protocol; } */ int fd, error; + file_t *fp; error = fsocreate(SCARG(uap, domain), NULL, SCARG(uap, type), - SCARG(uap, protocol), &fd); + SCARG(uap, protocol), &fd, &fp, NULL); if (error == 0) { + fd_affix(l->l_proc, fp, fd); *retval = fd; } return error; @@ -402,34 +404,6 @@ do_sys_connect(struct lwp *l, int fd, st return error; } -static int -makesocket(struct lwp *l, file_t **fp, int *fd, int flags, int type, - int domain, int proto, struct socket *soo) -{ - struct socket *so; - int error; - - if ((error = socreate(domain, &so, type, proto, l, soo)) != 0) { - return error; - } - if (flags & SOCK_NONBLOCK) { - so->so_state |= SS_NBIO; - } - - if ((error = fd_allocfile(fp, fd)) != 0) { - soclose(so); - return error; - } - fd_set_exclose(l, *fd, (flags & SOCK_CLOEXEC) != 0); - (*fp)->f_flag = FREAD|FWRITE| - ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)| - ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0); - (*fp)->f_type = DTYPE_SOCKET; - (*fp)->f_ops = &socketops; - (*fp)->f_socket = so; - return 0; -} - int sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap, register_t *retval) @@ -449,16 +423,14 @@ sys_socketpair(struct lwp *l, const stru int domain = SCARG(uap, domain); int proto = SCARG(uap, protocol); - error = makesocket(l, &fp1, &fd, flags, type, domain, proto, NULL); + error = fsocreate(domain, &so1, type|flags, proto, &fd, &fp1, NULL); if (error) return error; - so1 = fp1->f_socket; sv[0] = fd; - error = makesocket(l, &fp2, &fd, flags, type, domain, proto, so1); + error = fsocreate(domain, &so2, type|flags, proto, &fd, &fp2, so1); if (error) goto out; - so2 = fp2->f_socket; sv[1] = fd; solock(so1); @@ -1297,33 +1269,36 @@ pipe1(struct lwp *l, int *fildes, int fl { file_t *rf, *wf; struct socket *rso, *wso; - int fd, error; - proc_t *p; + int error, soflags = 0; + unsigned rfd, wfd; + proc_t *p = l->l_proc; if (flags & ~(O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE)) return EINVAL; - p = curproc; - if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0) - return error; - if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso)) != 0) + if (flags & O_CLOEXEC) + soflags |= SOCK_CLOEXEC; + if (flags & O_NONBLOCK) + soflags |= SOCK_NONBLOCK; + if (flags & O_NOSIGPIPE) + soflags |= SOCK_NOSIGPIPE; + + error = fsocreate(AF_LOCAL, &rso, SOCK_STREAM|soflags, 0, &rfd, &rf, + NULL); + if (error) goto free1; + error = fsocreate(AF_LOCAL, &wso, SOCK_STREAM|soflags, 0, &wfd, &wf, + rso); + if (error) + goto free2; + + /* make sure the descriptors are uni-directional */ + rf->f_type = rf->f_type & ~(FWRITE); + wf->f_type = wf->f_type & ~(FREAD); + /* remember this socket pair implements a pipe */ - wso->so_state |= SS_ISAPIPE; rso->so_state |= SS_ISAPIPE; - if ((error = fd_allocfile(&rf, &fd)) != 0) - goto free2; - fildes[0] = fd; - rf->f_flag = FREAD | flags; - rf->f_type = DTYPE_SOCKET; - rf->f_ops = &socketops; - rf->f_socket = rso; - if ((error = fd_allocfile(&wf, &fd)) != 0) - goto free3; - wf->f_flag = FWRITE | flags; - wf->f_type = DTYPE_SOCKET; - wf->f_ops = &socketops; - wf->f_socket = wso; - fildes[1] = fd; + wso->so_state |= SS_ISAPIPE; + solock(wso); /* * Pipes must be readable when there is at least 1 @@ -1342,19 +1317,22 @@ pipe1(struct lwp *l, int *fildes, int fl wso->so_snd.sb_lowat = PIPE_BUF; error = unp_connect2(wso, rso); sounlock(wso); + if (error != 0) - goto free4; - fd_affix(p, wf, fildes[1]); - fd_affix(p, rf, fildes[0]); + goto free3; + + fd_affix(p, wf, wfd); + fd_affix(p, rf, rfd); + fildes[0] = rfd; + fildes[1] = wfd; return (0); - free4: - fd_abort(p, wf, fildes[1]); free3: - fd_abort(p, rf, fildes[0]); - free2: (void)soclose(wso); - free1: + fd_abort(p, wf, wfd); + free2: (void)soclose(rso); + fd_abort(p, rf, rfd); + free1: return error; } #endif /* PIPE_SOCKETPAIR */