<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                main函數的前面部分做好了傳入參數的處理、config文件的讀取、初始化等準備工作,這里將進入最主要的部分,hostapd_global_run函數。 這里就不貼繁瑣的代碼了,這個函數主要分三步: 1.調用tncs_global_init完成tnc相關的初始化,這里就不詳細說了 2.? 調用os_daemonize函數實現將該程序以后臺進程運行,它主要實現過程是調用os_daemon將標準輸入、標準輸出和標準出錯都重定向到/dev/null文件下,這樣就不能通過 終端進行交互了,但是交互過程是使用hostapd_cli這個進程實現的,前面章節有介紹;然后檢查pid_file文件的合法性。 3.? eloop_run核心函數,這個函數很重要,所以下面將詳細介紹。 ~~~ void 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 */ 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; 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_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 */ 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 */ , strerror(errno)); goto out; } eloop_process_pending_signals(); /* check if some registered timeouts have occurred */ timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, list); if (timeout) { os_get_reltime(&now); if (!os_reltime_before(&now, &timeout->time)) { void *eloop_data = timeout->eloop_data; void *user_data = timeout->user_data; eloop_timeout_handler handler = timeout->handler; eloop_remove_timeout(timeout); handler(eloop_data, user_data); } } if (res <= 0) continue; #ifdef CONFIG_ELOOP_POLL eloop_sock_table_dispatch(&eloop.readers, &eloop.writers, &eloop.exceptions, eloop.pollfds_map, eloop.max_pollfd_map); #endif /* CONFIG_ELOOP_POLL */ #ifdef CONFIG_ELOOP_SELECT eloop_sock_table_dispatch(&eloop.readers, rfds); eloop_sock_table_dispatch(&eloop.writers, wfds); eloop_sock_table_dispatch(&eloop.exceptions, efds); #endif /* CONFIG_ELOOP_SELECT */ #ifdef CONFIG_ELOOP_EPOLL eloop_sock_table_dispatch(eloop.epoll_events, res); #endif /* CONFIG_ELOOP_EPOLL */ } eloop.terminate = 0; out: #ifdef CONFIG_ELOOP_SELECT os_free(rfds); os_free(wfds); os_free(efds); #endif /* CONFIG_ELOOP_SELECT */ return; ~~~ 首先為三個文件描述符集申請空間:? rfds = os_malloc(sizeof( * rfds)); wfds = os_malloc(sizeof( * wfds)); efds = os_malloc(sizeof( * efds)); 然后進入while循環: while (!eloop.terminate && (eloop.timeout || eloop.readers.count > 0 || eloop.writers.count > 0 || eloop.exceptions.count > 0)) 它的循環條件如括號里面描述,正常情況都在這里面循環,除非terminate為1,而這個有信號處理設置,參見 ~~~ eloop_register_signal_terminate(handle_term, NULL); static void handle_term(int sig, void *eloop_ctx, void *signal_ctx) { ?? wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig); ?? eloop_terminate(); } void eloop_terminate(void) { ?? eloop.terminate = 1; } ~~~ 接下來對超時時間進行設置timeout,主要是為下面調用的select函數會用到超時時間做準備。 ~~~ ???? 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; ??? ???? _tv.tv_sec = tv.sec; ??? ??? ?_tv.tv_usec = tv.usec; ??? ?} ~~~ 將申請的文件描述符集與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); ~~~ 最后eloop_process_pending_signals對發生的信號進行處理: ~~~ static void eloop_process_pending_signals(void) { int i; if (eloop.signaled == 0) //有沒有信號產生,如果有,那么這個標志位將為1,說明有信號需要處理,如果為0,那么沒有信號要處理,函數返回 return; eloop.signaled = 0; //將信號標示為置0,以便下次有信號產生時,置1 if (eloop.pending_terminate) { //如果不用處理后面將會產生的信號,則立即向進程發送一個SIGALARM信號,然后將這個標志置0 #ifndef CONFIG_NATIVE_WINDOWS alarm(0); #endif /* CONFIG_NATIVE_WINDOWS */ eloop.pending_terminate = 0; } for (i = 0; i < eloop.signal_count; i++) { //對信號標示進行處理 if (eloop.signals[i].signaled) { eloop.signals[i].signaled = 0; #ifndef CONFIG_NATIVE_WINDOWS eloop_register_signal(SIGHUP, handle_reload, NULL); //對中斷信號和中斷處理函數進行注冊 eloop_register_signal(SIGUSR1, handle_dump_state, NULL); #endif /* CONFIG_NATIVE_WINDOWS */ eloop_register_signal_terminate(handle_term, NULL); eloop.signals[i].handler(eloop.signals[i].sig, //調用處理函數對相應的信號進行處理,那么到底調用的是什么處理函數呢?這些處理函數的注冊是在 eloop.user_data, //什么地方呢?這個進程是怎么樣對數據包進行處理的呢?在哪里處理呢? eloop.signals[i].user_data); } } } ~~~ 到這里,應該對hostapd這個程序的整體有了一定的把握,應該能看懂第一篇中的那張結構圖了,但也有局限的地方,比如好多細節的地方沒有講清楚, 比如:數據包是在哪里接收的? 數據包是在哪里發送的? 數據包是這樣存放的?這些處理函數是在哪里注冊的? 客戶選擇的加密方式是怎么起作用的? hostapd怎么將一塊網卡切換到了ap模式? 等等。 接下來將盡力弄清楚這些問題。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看