C初心者がmemcached-1.4.5を追いかける。(1)
http://memcached.org/よりDLしたソースをスーパーpre記法ではてなに貼りつけてmainから少しずつ読んでいこう。
memcached.c
int main (int argc, char **argv) { int c; bool lock_memory = false; bool do_daemonize = false; bool preallocate = false; int maxcore = 0; char *username = NULL; char *pid_file = NULL; struct passwd *pw; struct rlimit rlim; char unit = '\0'; int size_max = 0; /* listening sockets */ static int *l_socket = NULL; /* udp socket */ static int *u_socket = NULL; bool protocol_specified = false; bool tcp_specified = false; bool udp_specified = false; /* handle SIGINT */ signal(SIGINT, sig_handler);
変数の定義と初期化後、
最初に出てきた命令部分から調べる。
memcached.c(4275行目あたり)
/* handle SIGINT */ signal(SIGINT, sig_handler);
google:C言語 signal
シグナル処理関数(シグナルハンドラ)を登録する | C言語入門講座
#include <signal.h> void (*signal(int signum, void (*sighandler)(int signum)))(int signum);signal関数は、シグナル(非同期イベント)が発生したときに、そのシグナルを受信して、シグナル特有の処理を行うシグナル処理関数(シグナルハンドラ)を登録します。
- SIGINT:端末から割り込みキー(通常 CTRL + C)を押下したときに発生。
memcached.c(4193行目あたり)
static void sig_handler(const int sig) { printf("SIGINT handled.\n"); exit(EXIT_SUCCESS); }
メッセージを出力して、
exitで終了。EXIT_SUCCESSは成功のマクロ。
ちなみに失敗はEXIT_FAILURE。
signalはここが分かりやすいかもしれない。
Redesign
<書式>
#include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t sighandler);
実際に試してみました。
signal(2) signal(SIGINT, sig_handler);を試した。 - 4丁目より
ちなみにWindowsだとSetConsoleCtrlHandler関数を使用するみたいですね。
Win2000でCntl+C割込みの処理方法
SetConsoleCtrlHandler 関数
memcached-1.2.1-win32-srcを見たのですがsignalが使われていました。(2360行目あたり)
#ifndef WIN32 struct passwd *pw; struct sigaction sa; struct rlimit rlim; /* handle SIGINT */ signal(SIGINT, sig_handler); #else /* !WIN32 */ WSADATA wsaData; if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0) { fprintf(stderr, "Socket Initialization Error. Program aborted\n"); return; } #endif /* WIN32 */