int spx_open(struct thread *td) { struct socket_args sock; struct sockaddr_un sun; int fd, error; /* obtain a socket. */ DPRINTF(("SPX: open socket\n")); sock.domain = AF_UNIX; sock.type = SOCK_STREAM; sock.protocol = 0; error = sys_socket(td, &sock); if (error) return error; fd = td->td_retval[0]; /* connect the socket to standard X socket */ DPRINTF(("SPX: connect to /tmp/X11-unix/X0\n")); sun.sun_family = AF_UNIX; strcpy(sun.sun_path, "/tmp/.X11-unix/X0"); sun.sun_len = sizeof(struct sockaddr_un) - sizeof(sun.sun_path) + strlen(sun.sun_path) + 1; error = kern_connect(td, fd, (struct sockaddr *)&sun); if (error) { kern_close(td, fd); return error; } td->td_retval[0] = fd; return 0; }
static int linux_connect(struct linux_connect_args *args, int *res) { struct thread *td = curthread; /* XXX */ struct proc *p = td->td_proc; struct linux_connect_args linux_args; struct sockaddr *sa; struct socket *so; struct file *fp; int error; KKASSERT(p); error = copyin(args, &linux_args, sizeof(linux_args)); if (error) return (error); error = linux_getsockaddr(&sa, linux_args.name, linux_args.namelen); if (error) return (error); error = kern_connect(linux_args.s, 0, sa); kfree(sa, M_SONAME); if (error != EISCONN) return (error); /* * Linux doesn't return EISCONN the first time it occurs, * when on a non-blocking socket. Instead it returns the * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. */ error = holdsock(p->p_fd, linux_args.s, &fp); if (error) return (error); error = EISCONN; if (fp->f_flag & FNONBLOCK) { so = (struct socket *)fp->f_data; if (so->so_emuldata == 0) error = so->so_error; so->so_emuldata = (void *)1; } fdrop(fp); return (error); }
int linux_connect(struct thread *td, struct linux_connect_args *args) { struct socket *so; struct sockaddr *sa; u_int fflag; int error; error = linux_getsockaddr(&sa, (struct osockaddr *)PTRIN(args->name), args->namelen); if (error) return (error); error = kern_connect(td, args->s, sa); free(sa, M_SONAME); if (error != EISCONN) return (error); /* * Linux doesn't return EISCONN the first time it occurs, * when on a non-blocking socket. Instead it returns the * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. * * XXXRW: Instead of using fgetsock(), check that it is a * socket and use the file descriptor reference instead of * creating a new one. */ error = fgetsock(td, args->s, &so, &fflag); if (error == 0) { error = EISCONN; if (fflag & FNONBLOCK) { SOCK_LOCK(so); if (so->so_emuldata == 0) error = so->so_error; so->so_emuldata = (void *)1; SOCK_UNLOCK(so); } fputsock(so); } return (error); }
/* * Establish a UNIX socket connection with user daemon */ static int kvp_connect_user(void) { int sock_error; struct socket_args unix_sock; struct sockaddr_un sock_sun; struct thread *thread_ptr; thread_ptr = curthread; /* Open a Unix Domain socket */ unix_sock.domain = AF_UNIX; unix_sock.type = SOCK_STREAM; unix_sock.protocol = 0; sock_error = socket(thread_ptr, &unix_sock); if (sock_error) { printf("kvp_connect_user: socket call failed %d\n", sock_error); return sock_error; } /* Try to connect to user daemon using Unix socket */ sock_fd = thread_ptr->td_retval[0]; sock_sun.sun_family = AF_UNIX; strcpy(sock_sun.sun_path, BSD_SOC_PATH); sock_sun.sun_len = sizeof(struct sockaddr_un) - sizeof(sock_sun.sun_path) + strlen(sock_sun.sun_path) + 1; sock_error = kern_connect(thread_ptr, sock_fd, (struct sockaddr *)&sock_sun); if (sock_error) { #ifdef DEBUG printf("kvp_connect_user:kern_connect failed:err:%d fd:%d\n", sock_error, sock_fd); #endif kern_close(thread_ptr, sock_fd); } return sock_error; }