博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android wpa_supplicant 启动过程
阅读量:6955 次
发布时间:2019-06-27

本文共 22134 字,大约阅读时间需要 73 分钟。

记录wpa_supplicant启动过程

ini脚本:service wpa_supplicant /vendor/bin/hw/wpa_supplicant \    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \    -I/vendor/etc/wifi/p2p_supplicant_overlay.conf -N \     -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \    -I/vendor/etc/wifi/wpa_supplicant_overlay.conf \    -O/data/misc/wifi/sockets -puse_p2p_group_interface=1 -dd \    -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0#   we will start as root and wpa_supplicant will switch to user wifi #   after setting up the capabilities required for WEXT #   user wifi #   group wifi inet keystore    class main     socket wpa_wlan0 dgram 660 wifi wifi     disabled    oneshotexternal\wpa_supplicant_8\wpa_supplicant\main.cint main(int argc, char *argv[]){    int c, i;    struct wpa_interface *ifaces, *iface;    int iface_count, exitcode = -1;    struct wpa_params params;    struct wpa_global *global;    if (os_program_init())        return -1;    os_memset(&params, 0, sizeof(params));    params.wpa_debug_level = MSG_INFO;  // 日志等级    iface = ifaces = os_zalloc(sizeof(struct wpa_interface));    if (ifaces == NULL)        return -1;    iface_count = 1;    wpa_supplicant_fd_workaround(1);    for (;;) {        c = getopt(argc, argv,               "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsS:TtuvW");        if (c < 0)            break;        switch (c) {        case 'b':            iface->bridge_ifname = optarg;            break;        case 'B':            params.daemonize++;            break;        case 'c':       // 配置文件 /data/misc/wifi/wpa_supplicant.conf            iface->confname = optarg;            break;        case 'C':            iface->ctrl_interface = optarg;            break;        case 'D':       // 驱动 nl80211            iface->driver = optarg;            break;        case 'd':#ifdef CONFIG_NO_STDOUT_DEBUG            printf("Debugging disabled with "                   "CONFIG_NO_STDOUT_DEBUG=y build time "                   "option.\n");            goto out;#else /* CONFIG_NO_STDOUT_DEBUG */            params.wpa_debug_level--;            break;#endif /* CONFIG_NO_STDOUT_DEBUG */        case 'e':       // 加密文件 /data/misc/wifi/entropy.bin            params.entropy_file = optarg;            break;#ifdef CONFIG_DEBUG_FILE        case 'f':            params.wpa_debug_file_path = optarg;            break;#endif /* CONFIG_DEBUG_FILE */        case 'g':   // 接口 @android:wpa_wlan0            params.ctrl_interface = optarg;            break;        case 'G':            params.ctrl_interface_group = optarg;            break;        case 'h':            usage();            exitcode = 0;            goto out;        case 'i':   // 接口名称 wlan0            iface->ifname = optarg;            break;            ......        default:            usage();            exitcode = 0;            goto out;        }    }    exitcode = 0;    global = wpa_supplicant_init(&params);          //    if (global == NULL) {        wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");        exitcode = -1;        goto out;    } else {        wpa_printf(MSG_INFO, "Successfully initialized "               "wpa_supplicant");    }        if (fst_global_init()) {        wpa_printf(MSG_ERROR, "Failed to initialize FST");        exitcode = -1;        goto out;    }#if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE)    if (!fst_global_add_ctrl(fst_ctrl_cli))        wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl");#endif    for (i = 0; exitcode == 0 && i < iface_count; i++) {        struct wpa_supplicant *wpa_s;        if ((ifaces[i].confname == NULL &&             ifaces[i].ctrl_interface == NULL) ||            ifaces[i].ifname == NULL) {            if (iface_count == 1 && (params.ctrl_interface ||#ifdef CONFIG_MATCH_IFACE                         params.match_iface_count ||#endif /* CONFIG_MATCH_IFACE */                         params.dbus_ctrl_interface))                break;            usage();            exitcode = -1;            break;        }        wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);         // 添加接口        if (wpa_s == NULL) {            exitcode = -1;            break;        }    }#ifdef CONFIG_MATCH_IFACE    if (exitcode == 0)        exitcode = wpa_supplicant_init_match(global);#endif /* CONFIG_MATCH_IFACE */    if (exitcode == 0)        exitcode = wpa_supplicant_run(global);              // 启动eloop,监听wpa的事件    wpa_supplicant_deinit(global);    fst_global_deinit();out:    wpa_supplicant_fd_workaround(0);    os_free(ifaces);#ifdef CONFIG_MATCH_IFACE    os_free(params.match_ifaces);#endif /* CONFIG_MATCH_IFACE */    os_free(params.pid_file);    os_program_deinit();    return exitcode;}external\wpa_supplicant_8\wpa_supplicant\wpa_supplicant.cstruct wpa_global * wpa_supplicant_init(struct wpa_params *params){    struct wpa_global *global;    int ret, i;    if (params == NULL)        return NULL;#ifdef CONFIG_DRIVER_NDIS    {        void driver_ndis_init_ops(void);        driver_ndis_init_ops();    }#endif /* CONFIG_DRIVER_NDIS */#ifndef CONFIG_NO_WPA_MSG    wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);#endif /* CONFIG_NO_WPA_MSG */    // 如果没有设置debug文件,将日志写道stdout    if (params->wpa_debug_file_path)        wpa_debug_open_file(params->wpa_debug_file_path);    else        wpa_debug_setup_stdout();    if (params->wpa_debug_syslog)        wpa_debug_open_syslog();    if (params->wpa_debug_tracing) {        ret = wpa_debug_open_linux_tracing();        if (ret) {            wpa_printf(MSG_ERROR,                   "Failed to enable trace logging");            return NULL;        }    }    // 注册eap方法,是一个链表,将支持的eap方法添加到链表中    ret = eap_register_methods();   // 注册eap方法    if (ret) {        wpa_printf(MSG_ERROR, "Failed to register EAP methods");        if (ret == -2)            wpa_printf(MSG_ERROR, "Two or more EAP methods used "                   "the same EAP type.");        return NULL;    }    global = os_zalloc(sizeof(*global));    if (global == NULL)        return NULL;    dl_list_init(&global->p2p_srv_bonjour);    dl_list_init(&global->p2p_srv_upnp);    /// 将启动参数添加到global->params中    global->params.daemonize = params->daemonize;    global->params.wait_for_monitor = params->wait_for_monitor;    global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;    if (params->pid_file)        global->params.pid_file = os_strdup(params->pid_file);    if (params->ctrl_interface)        global->params.ctrl_interface =            os_strdup(params->ctrl_interface);    if (params->ctrl_interface_group)        global->params.ctrl_interface_group =            os_strdup(params->ctrl_interface_group);    if (params->override_driver)        global->params.override_driver =            os_strdup(params->override_driver);    if (params->override_ctrl_interface)        global->params.override_ctrl_interface =            os_strdup(params->override_ctrl_interface);#ifdef CONFIG_MATCH_IFACE    global->params.match_iface_count = params->match_iface_count;    if (params->match_iface_count) {        global->params.match_ifaces =            os_calloc(params->match_iface_count,                  sizeof(struct wpa_interface));        os_memcpy(global->params.match_ifaces,              params->match_ifaces,              params->match_iface_count *              sizeof(struct wpa_interface));    }#endif /* CONFIG_MATCH_IFACE */#ifdef CONFIG_P2P    if (params->conf_p2p_dev)        global->params.conf_p2p_dev =            os_strdup(params->conf_p2p_dev);#endif /* CONFIG_P2P */    wpa_debug_level = global->params.wpa_debug_level =        params->wpa_debug_level;    wpa_debug_show_keys = global->params.wpa_debug_show_keys =        params->wpa_debug_show_keys;    wpa_debug_timestamp = global->params.wpa_debug_timestamp =        params->wpa_debug_timestamp;#ifdef CONFIG_HIDL    if (params->hidl_service_name)        global->params.hidl_service_name =            os_strdup(params->hidl_service_name);#endif /* CONFIG_HIDL */    wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);    if (eloop_init()) {        wpa_printf(MSG_ERROR, "Failed to initialize event loop");        wpa_supplicant_deinit(global);        return NULL;    }    // 随机数    random_init(params->entropy_file);    global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);    if (global->ctrl_iface == NULL) {        wpa_supplicant_deinit(global);        return NULL;    }    if (wpas_notify_supplicant_initialized(global)) {        wpa_supplicant_deinit(global);        return NULL;    }    // wpa_drivers记录了不同接口的操作方法。    for (i = 0; wpa_drivers[i]; i++)        global->drv_count++;    if (global->drv_count == 0) {        wpa_printf(MSG_ERROR, "No drivers enabled");        wpa_supplicant_deinit(global);        return NULL;    }    global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));    if (global->drv_priv == NULL) {        wpa_supplicant_deinit(global);        return NULL;    }#ifdef CONFIG_WIFI_DISPLAY    if (wifi_display_init(global) < 0) {        wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");        wpa_supplicant_deinit(global);        return NULL;    }#endif /* CONFIG_WIFI_DISPLAY */    eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,                   wpas_periodic, global, NULL);#ifdef CONFIG_WAPI    if (wapi_asue_init()) {        wpa_printf(MSG_ERROR, "wapi: wapi_asue_init fail\n");        return NULL;    }#endif    return global;}external\wpa_supplicant_8\src\drivers\drivers.cconst struct wpa_driver_ops *const wpa_drivers[] ={#ifdef CONFIG_DRIVER_NL80211    &wpa_driver_nl80211_ops,#endif /* CONFIG_DRIVER_NL80211 */#ifdef CONFIG_DRIVER_WEXT    &wpa_driver_wext_ops,#endif /* CONFIG_DRIVER_WEXT */#ifdef CONFIG_DRIVER_HOSTAP    &wpa_driver_hostap_ops,#endif /* CONFIG_DRIVER_HOSTAP */#ifdef CONFIG_DRIVER_BSD    &wpa_driver_bsd_ops,#endif /* CONFIG_DRIVER_BSD */#ifdef CONFIG_DRIVER_OPENBSD    &wpa_driver_openbsd_ops,#endif /* CONFIG_DRIVER_OPENBSD */#ifdef CONFIG_DRIVER_NDIS    &wpa_driver_ndis_ops,#endif /* CONFIG_DRIVER_NDIS */#ifdef CONFIG_DRIVER_WIRED    &wpa_driver_wired_ops,#endif /* CONFIG_DRIVER_WIRED */#ifdef CONFIG_DRIVER_MACSEC_LINUX    &wpa_driver_macsec_linux_ops,#endif /* CONFIG_DRIVER_MACSEC_LINUX */#ifdef CONFIG_DRIVER_MACSEC_QCA    &wpa_driver_macsec_qca_ops,#endif /* CONFIG_DRIVER_MACSEC_QCA */#ifdef CONFIG_DRIVER_ROBOSWITCH    &wpa_driver_roboswitch_ops,#endif /* CONFIG_DRIVER_ROBOSWITCH */#ifdef CONFIG_DRIVER_ATHEROS    &wpa_driver_atheros_ops,#endif /* CONFIG_DRIVER_ATHEROS */#ifdef CONFIG_DRIVER_NONE    &wpa_driver_none_ops,#endif /* CONFIG_DRIVER_NONE */    NULL};对应驱动函数external\wpa_supplicant_8\src\drivers\driver_nl80211.cconst struct wpa_driver_ops wpa_driver_nl80211_ops = {    .name = "nl80211",    .desc = "Linux nl80211/cfg80211",    .get_bssid = wpa_driver_nl80211_get_bssid,    .get_ssid = wpa_driver_nl80211_get_ssid,    .set_key = driver_nl80211_set_key,    .scan2 = driver_nl80211_scan2,    .sched_scan = wpa_driver_nl80211_sched_scan,    .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,    .get_scan_results2 = wpa_driver_nl80211_get_scan_results,    .abort_scan = wpa_driver_nl80211_abort_scan,    .deauthenticate = driver_nl80211_deauthenticate,    .authenticate = driver_nl80211_authenticate,    .associate = wpa_driver_nl80211_associate,    .global_init = nl80211_global_init,    .global_deinit = nl80211_global_deinit,    .init2 = wpa_driver_nl80211_init,    .deinit = driver_nl80211_deinit,    .get_capa = wpa_driver_nl80211_get_capa,    .set_operstate = wpa_driver_nl80211_set_operstate,    .set_supp_port = wpa_driver_nl80211_set_supp_port,    .set_country = wpa_driver_nl80211_set_country,    .get_country = wpa_driver_nl80211_get_country,    .set_ap = wpa_driver_nl80211_set_ap,    .set_acl = wpa_driver_nl80211_set_acl,    .if_add = wpa_driver_nl80211_if_add,    .if_remove = driver_nl80211_if_remove,    .send_mlme = driver_nl80211_send_mlme,    .get_hw_feature_data = nl80211_get_hw_feature_data,    .sta_add = wpa_driver_nl80211_sta_add,    .sta_remove = driver_nl80211_sta_remove,    .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,    .sta_set_flags = wpa_driver_nl80211_sta_set_flags,    .hapd_init = i802_init,    .hapd_deinit = i802_deinit,    .set_wds_sta = i802_set_wds_sta,    .get_seqnum = i802_get_seqnum,    .flush = i802_flush,    .get_inact_sec = i802_get_inact_sec,    .sta_clear_stats = i802_sta_clear_stats,    .set_rts = i802_set_rts,    .set_frag = i802_set_frag,    .set_tx_queue_params = i802_set_tx_queue_params,    .set_sta_vlan = driver_nl80211_set_sta_vlan,    .sta_deauth = i802_sta_deauth,    .sta_disassoc = i802_sta_disassoc,    .read_sta_data = driver_nl80211_read_sta_data,    .set_freq = i802_set_freq,    .send_action = driver_nl80211_send_action,    .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,    .remain_on_channel = wpa_driver_nl80211_remain_on_channel,    .cancel_remain_on_channel =    wpa_driver_nl80211_cancel_remain_on_channel,    .probe_req_report = driver_nl80211_probe_req_report,    .deinit_ap = wpa_driver_nl80211_deinit_ap,    .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,    .resume = wpa_driver_nl80211_resume,    .signal_monitor = nl80211_signal_monitor,...}struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,                         struct wpa_interface *iface,                         struct wpa_supplicant *parent){    struct wpa_supplicant *wpa_s;    struct wpa_interface t_iface;    struct wpa_ssid *ssid;    if (global == NULL || iface == NULL)        return NULL;    wpa_s = wpa_supplicant_alloc(parent);    if (wpa_s == NULL)        return NULL;    wpa_s->global = global;    t_iface = *iface;    if (global->params.override_driver) {        wpa_printf(MSG_DEBUG, "Override interface parameter: driver "               "('%s' -> '%s')",               iface->driver, global->params.override_driver);        t_iface.driver = global->params.override_driver;    }    if (global->params.override_ctrl_interface) {        wpa_printf(MSG_DEBUG, "Override interface parameter: "               "ctrl_interface ('%s' -> '%s')",               iface->ctrl_interface,               global->params.override_ctrl_interface);        t_iface.ctrl_interface =            global->params.override_ctrl_interface;    }    if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {        wpa_printf(MSG_DEBUG, "Failed to add interface %s",               iface->ifname);        wpa_supplicant_deinit_iface(wpa_s, 0, 0);        return NULL;    }    /* Notify the control interfaces about new iface */    if (wpas_notify_iface_added(wpa_s)) {        wpa_supplicant_deinit_iface(wpa_s, 1, 0);        return NULL;    }    /* Notify the control interfaces about new networks for non p2p mgmt     * ifaces. */    if (iface->p2p_mgmt == 0) {        for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)            wpas_notify_network_added(wpa_s, ssid);    }    wpa_s->next = global->ifaces;    global->ifaces = wpa_s;    wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);    wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);#ifdef CONFIG_P2P    if (wpa_s->global->p2p == NULL &&        !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&        (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&        wpas_p2p_add_p2pdev_interface(            wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {        wpa_printf(MSG_INFO,               "P2P: Failed to enable P2P Device interface");        /* Try to continue without. P2P will be disabled. */    }#endif /* CONFIG_P2P */    return wpa_s;}static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,                     struct wpa_interface *iface){    struct wpa_driver_capa capa;    int capa_res;    u8 dfs_domain;    wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "           "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,           iface->confname ? iface->confname : "N/A",           iface->driver ? iface->driver : "default",           iface->ctrl_interface ? iface->ctrl_interface : "N/A",           iface->bridge_ifname ? iface->bridge_ifname : "N/A");    if (iface->confname) {#ifdef CONFIG_BACKEND_FILE        wpa_s->confname = os_rel2abs_path(iface->confname);        if (wpa_s->confname == NULL) {            wpa_printf(MSG_ERROR, "Failed to get absolute path "                   "for configuration file '%s'.",                   iface->confname);            return -1;        }        wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",               iface->confname, wpa_s->confname);#else /* CONFIG_BACKEND_FILE */        wpa_s->confname = os_strdup(iface->confname);#endif /* CONFIG_BACKEND_FILE */        // 读取conf文件        wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);        if (wpa_s->conf == NULL) {            wpa_printf(MSG_ERROR, "Failed to read or parse "                   "configuration '%s'.", wpa_s->confname);            return -1;        }        // 为什么还有一个文件        wpa_s->confanother = os_rel2abs_path(iface->confanother);        wpa_config_read(wpa_s->confanother, wpa_s->conf);    }}    external\wpa_supplicant_8\wpa_supplicant\wpa_supplicant.cint wpa_supplicant_run(struct wpa_global *global){    struct wpa_supplicant *wpa_s;    if (global->params.daemonize &&        (wpa_supplicant_daemon(global->params.pid_file) ||         eloop_sock_requeue()))        return -1;#ifdef CONFIG_MATCH_IFACE    if (wpa_supplicant_match_existing(global))        return -1;#endif    if (global->params.wait_for_monitor) {        for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)            if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)                wpa_supplicant_ctrl_iface_wait(                    wpa_s->ctrl_iface);    }    eloop_register_signal_terminate(wpa_supplicant_terminate, global);    eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);    eloop_run();    return 0;}external\wpa_supplicant_8\wpa_supplicant\src\utils\eloop.cvoid eloop_run(void){#ifdef CONFIG_ELOOP_POLL    int num_poll_fds;    int timeout_ms = 0;#endif /* CONFIG_ELOOP_POLL */#ifdef CONFIG_ELOOP_SELECT    fd_set *rfds, *wfds, *efds;    struct timeval _tv;#endif /* CONFIG_ELOOP_SELECT */#ifdef CONFIG_ELOOP_EPOLL    int timeout_ms = -1;#endif /* CONFIG_ELOOP_EPOLL */#ifdef CONFIG_ELOOP_KQUEUE    struct timespec ts;#endif /* CONFIG_ELOOP_KQUEUE */    int res;    struct os_reltime tv, now;#ifdef CONFIG_ELOOP_SELECT    rfds = os_malloc(sizeof(*rfds));    wfds = os_malloc(sizeof(*wfds));    efds = os_malloc(sizeof(*efds));    if (rfds == NULL || wfds == NULL || efds == NULL)        goto out;#endif /* CONFIG_ELOOP_SELECT */    while (!eloop.terminate &&           (!dl_list_empty(&eloop.timeout) || eloop.readers.count > 0 ||        eloop.writers.count > 0 || eloop.exceptions.count > 0)) {        struct eloop_timeout *timeout;        if (eloop.pending_terminate) {            /*             * This may happen in some corner cases where a signal             * is received during a blocking operation. We need to             * process the pending signals and exit if requested to             * avoid hitting the SIGALRM limit if the blocking             * operation took more than two seconds.             */            eloop_process_pending_signals();            if (eloop.terminate)                break;        }        timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,                    list);        if (timeout) {            os_get_reltime(&now);            if (os_reltime_before(&now, &timeout->time))                os_reltime_sub(&timeout->time, &now, &tv);            else                tv.sec = tv.usec = 0;#if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL)            timeout_ms = tv.sec * 1000 + tv.usec / 1000;#endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */#ifdef CONFIG_ELOOP_SELECT            _tv.tv_sec = tv.sec;            _tv.tv_usec = tv.usec;#endif /* CONFIG_ELOOP_SELECT */#ifdef CONFIG_ELOOP_KQUEUE            ts.tv_sec = tv.sec;            ts.tv_nsec = tv.usec * 1000L;#endif /* CONFIG_ELOOP_KQUEUE */        }#ifdef CONFIG_ELOOP_POLL        // 将事件添加到监听队列里面        num_poll_fds = eloop_sock_table_set_fds(            &eloop.readers, &eloop.writers, &eloop.exceptions,            eloop.pollfds, eloop.pollfds_map,            eloop.max_pollfd_map);        // 监听事件变化        res = poll(eloop.pollfds, num_poll_fds,               timeout ? timeout_ms : -1);#endif /* CONFIG_ELOOP_POLL */#ifdef CONFIG_ELOOP_SELECT        // 将事件添加到监听队列里面        eloop_sock_table_set_fds(&eloop.readers, rfds);        eloop_sock_table_set_fds(&eloop.writers, wfds);        eloop_sock_table_set_fds(&eloop.exceptions, efds);        // 监听事件变化        res = select(eloop.max_sock + 1, rfds, wfds, efds,                 timeout ? &_tv : NULL);#endif /* CONFIG_ELOOP_SELECT */#ifdef CONFIG_ELOOP_EPOLL        if (eloop.count == 0) {            res = 0;        } else {            res = epoll_wait(eloop.epollfd, eloop.epoll_events,                     eloop.count, timeout_ms);        }#endif /* CONFIG_ELOOP_EPOLL */#ifdef CONFIG_ELOOP_KQUEUE        if (eloop.count == 0) {            res = 0;        } else {            res = kevent(eloop.kqueuefd, NULL, 0,                     eloop.kqueue_events, eloop.kqueue_nevents,                     timeout ? &ts : NULL);        }#endif /* CONFIG_ELOOP_KQUEUE */        if (res < 0 && errno != EINTR && errno != 0) {            wpa_printf(MSG_ERROR, "eloop: %s: %s",#ifdef CONFIG_ELOOP_POLL                   "poll"#endif /* CONFIG_ELOOP_POLL */#ifdef CONFIG_ELOOP_SELECT                   "select"#endif /* CONFIG_ELOOP_SELECT */#ifdef CONFIG_ELOOP_EPOLL                   "epoll"#endif /* CONFIG_ELOOP_EPOLL */#ifdef CONFIG_ELOOP_KQUEUE                   "kqueue"#endif /* CONFIG_ELOOP_EKQUEUE */                   , strerror(errno));            goto out;        }        eloop.readers.changed = 0;        eloop.writers.changed = 0;        eloop.exceptions.changed = 0;        eloop_process_pending_signals();......    }    eloop.terminate = 0;out:#ifdef CONFIG_ELOOP_SELECT    os_free(rfds);    os_free(wfds);    os_free(efds);#endif /* CONFIG_ELOOP_SELECT */    return;}

转载地址:http://dsvil.baihongyu.com/

你可能感兴趣的文章