int svr4_netopen(dev_t dev, int flag, int mode, struct lwp *l) { int type, protocol; int fd; file_t *fp; struct socket *so; int error; int family; DPRINTF(("netopen(")); if (curlwp->l_dupfd >= 0) /* XXX */ return ENODEV; switch (minor(dev)) { case dev_udp: family = AF_INET; type = SOCK_DGRAM; protocol = IPPROTO_UDP; DPRINTF(("udp, ")); break; case dev_tcp: family = AF_INET; type = SOCK_STREAM; protocol = IPPROTO_TCP; DPRINTF(("tcp, ")); break; case dev_ip: case dev_rawip: family = AF_INET; type = SOCK_RAW; protocol = IPPROTO_IP; DPRINTF(("ip, ")); break; case dev_icmp: family = AF_INET; type = SOCK_RAW; protocol = IPPROTO_ICMP; DPRINTF(("icmp, ")); break; case dev_unix_dgram: family = AF_LOCAL; type = SOCK_DGRAM; protocol = 0; DPRINTF(("unix-dgram, ")); break; case dev_unix_stream: case dev_unix_ord_stream: family = AF_LOCAL; type = SOCK_STREAM; protocol = 0; DPRINTF(("unix-stream, ")); break; default: DPRINTF(("%d);\n", minor(dev))); return EOPNOTSUPP; } if ((error = fd_allocfile(&fp, &fd)) != 0) return error; if ((error = socreate(family, &so, type, protocol, l, NULL)) != 0) { DPRINTF(("socreate error %d\n", error)); fd_abort(curproc, fp, fd); return error; } error = fd_clone(fp, fd, flag, &svr4_netops, so); fp->f_type = DTYPE_SOCKET; (void)svr4_stream_get(fp); DPRINTF(("ok);\n")); return error; }
/* * We only need open() and close() routines. open() calls socreate() * to allocate a "real" object behind the stream and mallocs some state * info for use by the svr4 emulator; close() deallocates the state * information and passes the underlying object to the normal socket close * routine. */ static int streamsopen(dev_t dev, int oflags, int devtype, struct thread *td) { int type, protocol; int fd; struct file *fp; struct socket *so; int error; int family; struct proc *p = td->td_proc; PROC_LOCK(p); if (td->td_dupfd >= 0) { PROC_UNLOCK(p); return ENODEV; } PROC_UNLOCK(p); switch (minor(dev)) { case dev_udp: family = AF_INET; type = SOCK_DGRAM; protocol = IPPROTO_UDP; break; case dev_tcp: family = AF_INET; type = SOCK_STREAM; protocol = IPPROTO_TCP; break; case dev_ip: case dev_rawip: family = AF_INET; type = SOCK_RAW; protocol = IPPROTO_IP; break; case dev_icmp: family = AF_INET; type = SOCK_RAW; protocol = IPPROTO_ICMP; break; case dev_unix_dgram: family = AF_LOCAL; type = SOCK_DGRAM; protocol = 0; break; case dev_unix_stream: case dev_unix_ord_stream: family = AF_LOCAL; type = SOCK_STREAM; protocol = 0; break; case dev_ptm: return svr4_ptm_alloc(td); default: return EOPNOTSUPP; } if ((error = falloc(td, &fp, &fd)) != 0) return error; if ((error = socreate(family, &so, type, protocol, td->td_ucred, td)) != 0) { FILEDESC_LOCK(p->p_fd); p->p_fd->fd_ofiles[fd] = 0; FILEDESC_UNLOCK(p->p_fd); ffree(fp); return error; } FILEDESC_LOCK(p->p_fd); fp->f_data = (caddr_t)so; fp->f_flag = FREAD|FWRITE; fp->f_ops = &svr4_netops; fp->f_type = DTYPE_SOCKET; FILEDESC_UNLOCK(p->p_fd); (void)svr4_stream_get(fp); PROC_LOCK(p); td->td_dupfd = fd; PROC_UNLOCK(p); return ENXIO; }