/* setup all the stuff a new child needs */ rb_helper * rb_helper_child(rb_helper_cb * read_cb, rb_helper_cb * error_cb, log_cb * ilog, restart_cb * irestart, die_cb * idie, size_t lb_heap_size, size_t dh_size, size_t fd_heap_size) { rb_helper *helper; int maxfd, x = 0; int ifd, ofd; char *tifd, *tofd, *tmaxfd; tifd = getenv("IFD"); tofd = getenv("OFD"); tmaxfd = getenv("MAXFD"); if(tifd == NULL || tofd == NULL || tmaxfd == NULL) return NULL; helper = rb_malloc(sizeof(rb_helper)); ifd = (int)strtol(tifd, NULL, 10); ofd = (int)strtol(tofd, NULL, 10); maxfd = (int)strtol(tmaxfd, NULL, 10); #ifndef _WIN32 for(x = 0; x < maxfd; x++) { if(x != ifd && x != ofd) close(x); } x = open("/dev/null", O_RDWR); if(ifd != 0 && ofd != 0) dup2(x, 0); if(ifd != 1 && ofd != 1) dup2(x, 1); if(ifd != 2 && ofd != 2) dup2(x, 2); if(x > 2) /* don't undo what we just did */ close(x); #else (void) x; /* shut gcc up */ #endif rb_lib_init(ilog, irestart, idie, 0, maxfd, dh_size, fd_heap_size); rb_linebuf_init(lb_heap_size); rb_linebuf_newbuf(&helper->sendq); rb_linebuf_newbuf(&helper->recvq); helper->ifd = rb_open(ifd, RB_FD_PIPE, "incoming connection"); helper->ofd = rb_open(ofd, RB_FD_PIPE, "outgoing connection"); rb_set_nb(helper->ifd); rb_set_nb(helper->ofd); helper->read_cb = read_cb; helper->error_cb = error_cb; return helper; }
static int rb_epoll_sched_event_timerfd(struct ev_entry *event, int when) { struct itimerspec ts; static char buf[FD_DESC_SZ + 8]; int fd; rb_fde_t *F; if((fd = timerfd_create(CLOCK_REALTIME, 0)) < 0) { rb_lib_log("timerfd_create: %s\n", strerror(errno)); return 0; } memset(&ts, 0, sizeof(ts)); ts.it_value.tv_sec = when; ts.it_value.tv_nsec = 0; if(event->frequency != 0) ts.it_interval = ts.it_value; if(timerfd_settime(fd, 0, &ts, NULL) < 0) { rb_lib_log("timerfd_settime: %s\n", strerror(errno)); close(fd); return 0; } rb_snprintf(buf, sizeof(buf), "timerfd: %s", event->name); F = rb_open(fd, RB_FD_UNKNOWN, buf); rb_set_nb(F); event->comm_ptr = F; rb_setselect(F, RB_SELECT_READ, rb_read_timerfd, event); return 1; }
void rb_epoll_init_event(void) { sigset_t ss; rb_fde_t *F; int sfd; rb_epoll_supports_event(); if(!can_do_timerfd) { sigemptyset(&ss); sigaddset(&ss, RTSIGNAL); sigprocmask(SIG_BLOCK, &ss, 0); sigemptyset(&ss); sigaddset(&ss, RTSIGNAL); sfd = signalfd(-1, &ss, 0); if(sfd == -1) { can_do_event = -1; return; } F = rb_open(sfd, RB_FD_UNKNOWN, "signalfd"); rb_set_nb(F); signalfd_handler(F, NULL); } }
int _fat_open(struct vfs_file_s *file, struct mount_s *mount, const char *filename, int oflags, int perm) { int fd=rb_open(mount->index,filename,oflags); file->priv[0] = (void *) fd; file->ops = &vfs_fat_file_ops; return fd < 0; }
int rb_recv_fd_buf(rb_fde_t *F, void *data, size_t datasize, rb_fde_t **xF, int nfds) { struct msghdr msg; struct cmsghdr *cmsg; struct iovec iov[1]; struct stat st; uint8_t stype = RB_FD_UNKNOWN; const char *desc; int fd, len, x, rfds; int control_len = CMSG_SPACE(sizeof(int) * nfds); iov[0].iov_base = data; iov[0].iov_len = datasize; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_flags = 0; cmsg = alloca(control_len); msg.msg_control = cmsg; msg.msg_controllen = control_len; if((len = recvmsg(rb_get_fd(F), &msg, 0)) <= 0) return len; if(msg.msg_controllen > 0 && msg.msg_control != NULL && (cmsg = CMSG_FIRSTHDR(&msg)) != NULL) { rfds = ((unsigned char *)cmsg + cmsg->cmsg_len - CMSG_DATA(cmsg)) / sizeof(int); for(x = 0; x < nfds && x < rfds; x++) { fd = ((int *)CMSG_DATA(cmsg))[x]; stype = RB_FD_UNKNOWN; desc = "remote unknown"; if(!fstat(fd, &st)) { if(S_ISSOCK(st.st_mode)) { stype = RB_FD_SOCKET; desc = "remote socket"; } else if(S_ISFIFO(st.st_mode)) { stype = RB_FD_PIPE; desc = "remote pipe"; } else if(S_ISREG(st.st_mode)) { stype = RB_FD_FILE; desc = "remote file"; } } xF[x] = rb_open(fd, stype, desc); } } else *xF = NULL; return len; }
/* * rb_init_netio * * This is a needed exported function which will be called to initialise * the network loop code. */ int rb_init_netio_devpoll(void) { dpfd = open("/dev/poll", O_RDWR); if(dpfd < 0) { return errno; } maxfd = getdtablesize() - 2; /* This makes more sense than HARD_FDLIMIT */ fdmask = rb_malloc(sizeof(fdmask) * maxfd + 1); rb_open(dpfd, RB_FD_UNKNOWN, "/dev/poll file descriptor"); return 0; }
static rb_fde_t * make_fde_from_wsaprotocol_info(void *data) { WSAPROTOCOL_INFO *info = data; SOCKET t; t = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, info, 0, 0); if(t == INVALID_SOCKET) { rb_get_errno(); return NULL; } return rb_open(t, RB_FD_SOCKET, "remote_socket"); }
static int ringbuf_open(struct inode *inode, struct file *file) { int res; res = nonseekable_open(inode, file); if (res < 0) { printk(KERN_ERR "Failed to do nonseekable_open\n"); return res; } /* Tag number is minor number DIV devices per tag and * device type is minor number MOD devices per tag */ return rb_open(file, iminor(inode) / RB_DEV_PER_TAG, iminor(inode) % RB_DEV_PER_TAG); }
/* * rb_init_netio * * This is a needed exported function which will be called to initialise * the network loop code. */ int rb_init_netio_epoll(void) { can_do_event = 0; /* shut up gcc */ can_do_timerfd = 0; ep_info = rb_malloc(sizeof(struct epoll_info)); ep_info->pfd_size = getdtablesize(); ep_info->ep = epoll_create(ep_info->pfd_size); if(ep_info->ep < 0) { return -1; } rb_open(ep_info->ep, RB_FD_UNKNOWN, "epoll file descriptor"); ep_info->pfd = rb_malloc(sizeof(struct epoll_event) * ep_info->pfd_size); return 0; }
/* * rb_init_netio * * This is a needed exported function which will be called to initialise * the network loop code. */ int rb_init_netio_kqueue(void) { kq = kqueue(); if(kq < 0) { return errno; } kqmax = getdtablesize(); kqlst = rb_malloc(sizeof(struct kevent) * kqmax); kqout = rb_malloc(sizeof(struct kevent) * kqmax); rb_open(kq, RB_FD_UNKNOWN, "kqueue fd"); zero_timespec.tv_sec = 0; zero_timespec.tv_nsec = 0; return 0; }