Пример #1
0
/* 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;
}
Пример #2
0
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;
}
Пример #3
0
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);
	}
}
Пример #4
0
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;
}
Пример #5
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;
}
Пример #6
0
/*
 * 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;
}
Пример #7
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");
}
Пример #8
0
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);
}
Пример #9
0
/*
 * 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;
}
Пример #10
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;
}