/** * オプション引数 * * オプション引数ごとに処理を分岐する. * @param[in] argc 引数の数 * @param[in] argv コマンド引数・オプション引数 * @return なし */ static void parse_args(int argc, char *argv[]) { int opt = 0; /* オプション */ const int base = 10; /* 基数 */ dbglog("start"); /* デフォルトのポート番号を設定 */ if (set_port_string(DEFAULT_PORTNO) < 0) exit(EXIT_FAILURE); /* デフォルトのIPアドレスを設定 */ if (set_host_string(DEFAULT_IPADDR) < 0) exit(EXIT_FAILURE); /* デフォルトのスレッド数を設定 */ threads = MAX_THREADS; while ((opt = getopt_long(argc, argv, shortopts, longopts, NULL)) != EOF) { dbglog("opt=%c, optarg=%s", opt, optarg); switch (opt) { case 'i': /* IPアドレス指定 */ if (set_host_string(optarg) < 0) { fprintf(stderr, "Hostname string length %d", (HOST_SIZE - 1)); exit(EXIT_FAILURE); } break; case 'p': /* ポート番号指定 */ if (set_port_string(optarg) < 0) { fprintf(stderr, "Portno string length %d", (PORT_SIZE - 1)); exit(EXIT_FAILURE); } break; case 't': /* スレッド数設定 */ threads = (int)strtol(optarg, NULL, base); break; case 'h': /* ヘルプ表示 */ print_help(get_progname()); exit(EXIT_SUCCESS); case 'V': /* バージョン情報表示 */ print_version(get_progname()); exit(EXIT_SUCCESS); case '?': case ':': parse_error(opt, NULL); exit(EXIT_FAILURE); default: parse_error(opt, "internal error"); exit(EXIT_FAILURE); } } if (optind < argc) { (void)printf("non-option ARGV-elements: "); while (optind < argc) (void)printf("%s ", argv[optind++]); (void)printf("\n"); } }
/** * test_set_port_string() 関数テスト * * @return なし */ void test_set_port_string(void) { int retval = 0; /* 戻り値 */ const char *err_port = "123456"; /* エラー用 */ /* 正常系 */ retval = set_port_string(port); cut_assert_equal_int(EX_OK, retval); /* 異常系 */ retval = set_port_string(err_port); cut_assert_equal_int(EX_NG, retval); }
/** * test_server_loop() 関数テスト * * @return なし */ void test_server_loop(void) { pid_t cpid = 0; /* 子プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* wait引数 */ int retval = 0; /* 戻り値 */ int count = 1; /* ループカウント */ if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return; } if (cpid == 0) { dbglog("child"); count = 2; g_sig_handled = 1; while (count--) server_loop(ssock); exit(EXIT_SUCCESS); } else { dbglog("parent: cpid=%d", (int)cpid); csock = inet_sock_client(); if (csock < 0) return; /* 送信 */ retval = send_client(csock, expr, sizeof(expr)); if (retval < 0) { cut_error("send_client: csock=%d(%d)", csock, errno); return; } /* 受信 */ retval = recv_client(csock, readbuf); if (retval < 0) { cut_error("recv_client: csock=%d(%d)", csock, errno); return; } cut_assert_equal_string((char *)expected, (char *)readbuf); w = wait(&status); if (w < 0) cut_notify("wait(%d)", errno); dbglog("w=%d", (int)w); } }
/** * test_server_sock() 関数テスト * * @return なし */ void test_server_sock(void) { dbglog("start"); if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); dbglog("server_sock=%d", ssock); cut_assert_not_equal_int(EX_NG, ssock); csock = inet_sock_client(); if (csock < 0) cut_error("inet_sock_client"); }
/** * test_server_proc() 関数テスト * * @return なし */ void test_server_proc(void) { pid_t cpid = 0; /* 子プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* wait引数 */ int retval = 0; /* 戻り値 */ thread_data *dt = NULL; /* ソケット情報構造体 */ void *servret = NULL; /* テスト関数戻り値 */ if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return; } if (cpid == 0) { dbglog("child"); dt = (thread_data *)malloc(sizeof(thread_data)); if (!dt) { outlog("malloc: size=%zu", sizeof(thread_data)); exit(EXIT_FAILURE); } (void)memset(dt, 0, sizeof(thread_data)); dt->len = (socklen_t)sizeof(dt->addr); dt->sock = accept(ssock, (struct sockaddr *)&dt->addr, &dt->len); if (dt->sock < 0) { outlog("accept: ssock=%d", ssock); memfree((void **)&dt, NULL); exit(EXIT_FAILURE); } g_sig_handled = 1; /* テスト関数実行 */ servret = server.server_proc(dt); if (servret) { outlog("server_proc"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } else { dbglog("parent: cpid=%d", (int)cpid); csock = inet_sock_client(); if (csock < 0) return; /* 送信 */ retval = send_client(csock, expr, sizeof(expr)); if (retval < 0) { cut_error("send_client: csock=%d(%d)", csock, errno); return; } /* 受信 */ retval = recv_client(csock, readbuf); if (retval < 0) { cut_error("recv_client: csock=%d(%d)", csock, errno); return; } cut_assert_equal_string((char *)expected, (char *)readbuf); w = wait(&status); if (w < 0) cut_notify("wait(%d)", errno); dbglog("w=%d", (int)w); if (WEXITSTATUS(status)) cut_error("child failed"); } }