Esempio n. 1
0
static mp_obj_t py_select(uint n_args, const mp_obj_t *args)
{
    int nfds=0; //highest-numbered fd plus 1
    timeval tv={0};
    fd_set rfds, wfds, xfds;

    mp_obj_t *rlist, *wlist, *xlist;
    uint rlist_len, wlist_len, xlist_len;

    /* read args */
    mp_obj_get_array(args[0], &rlist_len, &rlist);
    mp_obj_get_array(args[1], &wlist_len, &wlist);
    mp_obj_get_array(args[2], &xlist_len, &xlist);

    if (n_args == 4) {
        float timeout = mp_obj_get_float(args[3]);
        tv.tv_sec = (int)timeout;
        tv.tv_usec = (timeout-(int)timeout)*1000*1000;
    }

    // add fds to their respective sets
    set_fds(&nfds, rlist, rlist_len, &rfds);
    set_fds(&nfds, wlist, wlist_len, &wfds);
    set_fds(&nfds, xlist, xlist_len, &xfds);

    // call select
    nfds = select(nfds+1, &rfds, &wfds, &xfds, &tv);

    // if any of the read sockets is closed, we add it to the read fd set,
    // a subsequent call to recv() returns 0. This behavior is consistent with BSD.
    for (int i=0; i<rlist_len; i++) {
        socket_t *s = rlist[i];
        if (wlan_get_fd_state(s->fd)) {
            FD_SET(s->fd, &rfds);
            nfds = max(nfds, s->fd);
        }
    }

    // return value; a tuple of 3 lists
    mp_obj_t fds[3] = {
        mp_obj_new_list(0, NULL),
        mp_obj_new_list(0, NULL),
        mp_obj_new_list(0, NULL)
    };

    // On success, select() returns the number of file descriptors contained
    // in the three returned descriptor sets which may be zero if the timeout
    // expires before anything interesting happens, -1 is returned on error.
    if (nfds == -1) {   // select failed
        nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "select failed"));
    } else if (nfds) {  // an fd is ready
        get_fds(rlist, rlist_len, fds[0], &rfds);
        get_fds(wlist, wlist_len, fds[1], &wfds);
        get_fds(xlist, xlist_len, fds[2], &xfds);
    } // select timedout

    return mp_obj_new_tuple(3, fds);
}
Esempio n. 2
0
File: get_fds.c Progetto: csj561/c
int system2(const char * cmdstring)
{ 
	pid_t pid; 
	int status; 
	if(cmdstring == NULL)
	{ 
		return (1); 
	} 
	if((pid = fork())<0)
	{ 
		status = -1; 
	} 
	else if(pid = 0)
	{
		int i=0,*fds=get_fds(getpid());
		//while(fds&&fds[i]!=-1)
		//	close(fds[i++]);
		execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);exit(127); 
	} 
	else
	{ 
		while(waitpid(pid, &status, 0) < 0)
		{
			status = -EINTR; break;
		}
	} 
	return status; 
} 
Esempio n. 3
0
int net_init_tap(const NetClientOptions *opts, const char *name,
                 NetClientState *peer)
{
    const NetdevTapOptions *tap;
    int fd, vnet_hdr = 0, i = 0, queues;
    /* for the no-fd, no-helper case */
    const char *script = NULL; /* suppress wrong "uninit'd use" gcc warning */
    const char *downscript = NULL;
    const char *vhostfdname;
    char ifname[128];

    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_TAP);
    tap = opts->tap;
    queues = tap->has_queues ? tap->queues : 1;
    vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;

    /* QEMU vlans does not support multiqueue tap, in this case peer is set.
     * For -netdev, peer is always NULL. */
    if (peer && (tap->has_queues || tap->has_fds || tap->has_vhostfds)) {
        error_report("Multiqueue tap cannot be used with QEMU vlans");
        return -1;
    }

    if (tap->has_fd) {
        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
            tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
            tap->has_fds || tap->has_vhostfds) {
            error_report("ifname=, script=, downscript=, vnet_hdr=, "
                         "helper=, queues=, fds=, and vhostfds= "
                         "are invalid with fd=");
            return -1;
        }

        fd = monitor_handle_fd_param(cur_mon, tap->fd);
        if (fd == -1) {
            return -1;
        }

        fcntl(fd, F_SETFL, O_NONBLOCK);

        vnet_hdr = tap_probe_vnet_hdr(fd);

        if (net_init_tap_one(tap, peer, "tap", name, NULL,
                             script, downscript,
                             vhostfdname, vnet_hdr, fd)) {
            return -1;
        }
    } else if (tap->has_fds) {
        char *fds[MAX_TAP_QUEUES];
        char *vhost_fds[MAX_TAP_QUEUES];
        int nfds, nvhosts;

        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
            tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
            tap->has_vhostfd) {
            error_report("ifname=, script=, downscript=, vnet_hdr=, "
                         "helper=, queues=, and vhostfd= "
                         "are invalid with fds=");
            return -1;
        }

        nfds = get_fds(tap->fds, fds, MAX_TAP_QUEUES);
        if (tap->has_vhostfds) {
            nvhosts = get_fds(tap->vhostfds, vhost_fds, MAX_TAP_QUEUES);
            if (nfds != nvhosts) {
                error_report("The number of fds passed does not match the "
                             "number of vhostfds passed");
                return -1;
            }
        }

        for (i = 0; i < nfds; i++) {
            fd = monitor_handle_fd_param(cur_mon, fds[i]);
            if (fd == -1) {
                return -1;
            }

            fcntl(fd, F_SETFL, O_NONBLOCK);

            if (i == 0) {
                vnet_hdr = tap_probe_vnet_hdr(fd);
            } else if (vnet_hdr != tap_probe_vnet_hdr(fd)) {
                error_report("vnet_hdr not consistent across given tap fds");
                return -1;
            }

            if (net_init_tap_one(tap, peer, "tap", name, ifname,
                                 script, downscript,
                                 tap->has_vhostfds ? vhost_fds[i] : NULL,
                                 vnet_hdr, fd)) {
                return -1;
            }
        }
    } else if (tap->has_helper) {
        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
            tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) {
            error_report("ifname=, script=, downscript=, and vnet_hdr= "
                         "queues=, and vhostfds= are invalid with helper=");
            return -1;
        }

        fd = net_bridge_run_helper(tap->helper, DEFAULT_BRIDGE_INTERFACE);
        if (fd == -1) {
            return -1;
        }

        fcntl(fd, F_SETFL, O_NONBLOCK);
        vnet_hdr = tap_probe_vnet_hdr(fd);

        if (net_init_tap_one(tap, peer, "bridge", name, ifname,
                             script, downscript, vhostfdname,
                             vnet_hdr, fd)) {
            return -1;
        }
    } else {
        if (tap->has_vhostfds) {
            error_report("vhostfds= is invalid if fds= wasn't specified");
            return -1;
        }
        script = tap->has_script ? tap->script : DEFAULT_NETWORK_SCRIPT;
        downscript = tap->has_downscript ? tap->downscript :
            DEFAULT_NETWORK_DOWN_SCRIPT;

        if (tap->has_ifname) {
            pstrcpy(ifname, sizeof ifname, tap->ifname);
        } else {
            ifname[0] = '\0';
        }

        for (i = 0; i < queues; i++) {
            fd = net_tap_init(tap, &vnet_hdr, i >= 1 ? "no" : script,
                              ifname, sizeof ifname, queues > 1);
            if (fd == -1) {
                return -1;
            }

            if (queues > 1 && i == 0 && !tap->has_ifname) {
                if (tap_fd_get_ifname(fd, ifname)) {
                    error_report("Fail to get ifname");
                    return -1;
                }
            }

            if (net_init_tap_one(tap, peer, "tap", name, ifname,
                                 i >= 1 ? "no" : script,
                                 i >= 1 ? "no" : downscript,
                                 vhostfdname, vnet_hdr, fd)) {
                return -1;
            }
        }
    }

    return 0;
}
Esempio n. 4
0
File: tap.c Progetto: PennPanda/qemu
int net_init_tap(const Netdev *netdev, const char *name,
                 NetClientState *peer, Error **errp)
{
    const NetdevTapOptions *tap;
    int fd, vnet_hdr = 0, i = 0, queues;
    /* for the no-fd, no-helper case */
    const char *script = NULL; /* suppress wrong "uninit'd use" gcc warning */
    const char *downscript = NULL;
    Error *err = NULL;
    const char *vhostfdname;
    char ifname[128];

    assert(netdev->type == NET_CLIENT_DRIVER_TAP);
    tap = &netdev->u.tap;
    queues = tap->has_queues ? tap->queues : 1;
    vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;

    /* QEMU vlans does not support multiqueue tap, in this case peer is set.
     * For -netdev, peer is always NULL. */
    if (peer && (tap->has_queues || tap->has_fds || tap->has_vhostfds)) {
        error_setg(errp, "Multiqueue tap cannot be used with QEMU vlans");
        return -1;
    }

    if (tap->has_fd) {
        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
            tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
            tap->has_fds || tap->has_vhostfds) {
            error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
                       "helper=, queues=, fds=, and vhostfds= "
                       "are invalid with fd=");
            return -1;
        }

        fd = monitor_fd_param(cur_mon, tap->fd, &err);
        if (fd == -1) {
            error_propagate(errp, err);
            return -1;
        }

        fcntl(fd, F_SETFL, O_NONBLOCK);

        vnet_hdr = tap_probe_vnet_hdr(fd);

        net_init_tap_one(tap, peer, "tap", name, NULL,
                         script, downscript,
                         vhostfdname, vnet_hdr, fd, &err);
        if (err) {
            error_propagate(errp, err);
            return -1;
        }
    } else if (tap->has_fds) {
        char **fds = g_new0(char *, MAX_TAP_QUEUES);
        char **vhost_fds = g_new0(char *, MAX_TAP_QUEUES);
        int nfds, nvhosts;

        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
            tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
            tap->has_vhostfd) {
            error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
                       "helper=, queues=, and vhostfd= "
                       "are invalid with fds=");
            return -1;
        }

        nfds = get_fds(tap->fds, fds, MAX_TAP_QUEUES);
        if (tap->has_vhostfds) {
            nvhosts = get_fds(tap->vhostfds, vhost_fds, MAX_TAP_QUEUES);
            if (nfds != nvhosts) {
                error_setg(errp, "The number of fds passed does not match "
                           "the number of vhostfds passed");
                goto free_fail;
            }
        }

        for (i = 0; i < nfds; i++) {
            fd = monitor_fd_param(cur_mon, fds[i], &err);
            if (fd == -1) {
                error_propagate(errp, err);
                goto free_fail;
            }

            fcntl(fd, F_SETFL, O_NONBLOCK);

            if (i == 0) {
                vnet_hdr = tap_probe_vnet_hdr(fd);
            } else if (vnet_hdr != tap_probe_vnet_hdr(fd)) {
                error_setg(errp,
                           "vnet_hdr not consistent across given tap fds");
                goto free_fail;
            }

            net_init_tap_one(tap, peer, "tap", name, ifname,
                             script, downscript,
                             tap->has_vhostfds ? vhost_fds[i] : NULL,
                             vnet_hdr, fd, &err);
            if (err) {
                error_propagate(errp, err);
                goto free_fail;
            }
        }
        g_free(fds);
        g_free(vhost_fds);
        return 0;

free_fail:
        for (i = 0; i < nfds; i++) {
            g_free(fds[i]);
            g_free(vhost_fds[i]);
        }
        g_free(fds);
        g_free(vhost_fds);
        return -1;
    } else if (tap->has_helper) {
Esempio n. 5
0
/*
 * ip_main --
 *      This is the main loop for the vi-as-library editor.
 */
int
main(int argc, char **argv)
{
	IP_PRIVATE *ipp;
	int rval;
	char *ip_arg;
	char **p_av, **t_av;
	GS *gp;
	WIN *wp;
	int i_fd, o_fd, t_fd, main_ifd, main_ofd;

	/* Create and initialize the global structure. */
	__global_list = gp = gs_init(argv[0]);

	/*
	 * Strip out any arguments that vi isn't going to understand.  There's
	 * no way to portably call getopt twice, so arguments parsed here must
	 * be removed from the argument list.
	 */
	ip_arg = NULL;
	for (p_av = t_av = argv;;) {
		if (*t_av == NULL) {
			*p_av = NULL;
			break;
		}
		if (!strcmp(*t_av, "--")) {
			while ((*p_av++ = *t_av++) != NULL);
			break;
		}
		if (!memcmp(*t_av, "-I", sizeof("-I") - 1)) {
			if (t_av[0][2] != '\0') {
				ip_arg = t_av[0] + 2;
				++t_av;
				--argc;
				continue;
			}
			else if (t_av[1] != NULL) {
				ip_arg = t_av[1];
				t_av += 2;
				argc -= 2;
				continue;
			}
		}
		*p_av++ = *t_av++;
	}

	if (get_fds(ip_arg, &main_ifd, &main_ofd))
		return 1;

	wp = NULL;

	while (get_connection(wp, main_ifd, main_ofd, &i_fd, &o_fd, &t_fd, 1) == 0) {
		/* Create new window */
		wp = gs_new_win(gp);

		/* Create and partially initialize the IP structure. */
		if ((ipp = ip_init(wp, i_fd, o_fd, t_fd, argc, argv)) == NULL)
			return (1);

		gp->run(wp, run_editor, (void *)wp);
	}

	/* Clean out the global structure. */
	gs_end(gp);

	/* Free the global and IP private areas. */
#if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
	free(gp);
#endif
	exit (rval);
}