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); }
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; }
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; }
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) {
/* * 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); }