Exemple #1
0
/**
 * ソケット受信
 *
 * @param[in] sock ソケット
 * @return ステータス
 */
static st_client
read_sock(int sock)
{
    int retval = 0;    /* 戻り値 */
    size_t length = 0; /* 送信または受信する長さ */
    struct header hd;  /* ヘッダ */

    dbglog("start");

    /* ヘッダ受信 */
    length = sizeof(struct header);
    (void)memset(&hd, 0, length);
    retval = recv_data(sock, &hd, &length);
    if (retval < 0) /* エラー */
        return EX_RECV_ERR;
    dbglog("recv_data: hd=%p, length=%zu", &hd, length);

    if (g_gflag)
        outdump(&hd, length, "recv: hd=%p, length=%zu", &hd, length);
    stddump(&hd, length, "recv: hd=%p, length=%zu", &hd, length);

    length = (size_t)ntohl((uint32_t)hd.length); /* データ長を保持 */

    /* データ受信 */
    answer = (unsigned char *)recv_data_new(sock, &length);
    if (!answer) /* メモリ確保できない */
        return EX_ALLOC_ERR;
    if (!length) /* 受信エラー */
        return EX_RECV_ERR;
    dbglog("answer=%p, length=%zu", answer, length);

    if (g_gflag)
        outdump(answer, length,
                "recv: answer=%p, length=%zu", answer, length);
    stddump(answer, length,
            "recv: answer=%p, length=%zu", answer, length);

    if (g_tflag) {
        unsigned int client_time = stop_timer(&start_time);
        print_timer(client_time);
    }

    retval = fprintf(stdout, "%s\n", answer);
    if (retval < 0)
        outlog("fprintf=%d", retval);

    memfree((void **)&answer, NULL);
    return EX_SUCCESS;
}
Exemple #2
0
/**
 * スレッド処理
 *
 * @return なし
 */
static void *
client_thread(void *arg)
{
    /* スレッドデータ */
    thread_data *dt = (thread_data *)arg;
    int retval = 0;    /* 戻り値 */
    size_t length = 0; /* 長さ */
    ssize_t slen = 0;  /* 送信するバイト数 */
    struct header hd;  /* ヘッダ */

    /* コネクト */
    dt->sock = connect_sock();
    if (dt->sock < 0) {
        outstd("Connect error");
        pthread_exit((void *)EX_CONNECT_ERR);
    }

    pthread_cleanup_push(thread_cleanup, &dt);

    length = strlen((char *)dt->expr) + 1;

    /* データ設定 */
    slen = set_client_data(&dt->sdata,  dt->expr, length);
    if (slen < 0) /* メモリ確保できない */
        pthread_exit((void *)EX_ALLOC_ERR);

    pthread_cleanup_push(thread_memfree, &dt->sdata);

    /* データ送信 */
    retval = send_data(dt->sock, dt->sdata, (size_t *)&slen);

    /* ヘッダ受信 */
    length = sizeof(struct header);
    (void)memset(&hd, 0, length);
    retval = recv_data(dt->sock, &hd, &length);
    if (retval < 0) /* エラー */
        pthread_exit((void *)EX_RECV_ERR);
    dbglog("recv_data: hd=%p, length=%zu", &hd, length);

    length = (size_t)ntohl((uint32_t)hd.length); /* データ長を保持 */

    /* データ受信 */
    dt->answer = (uchar *)recv_data_new(dt->sock, &length);
    if (!dt->answer) /* メモリ確保できない */
        pthread_exit((void *)EX_ALLOC_ERR);

    pthread_cleanup_push(thread_memfree, &dt->answer);

    if (!length) /* 受信エラー */
        pthread_exit((void *)EX_RECV_ERR);
    dbglog("answer=%p, length=%zu", dt->answer, length);

    stdlog("%s", dt->answer);

    retval = strcmp((char *)dt->expected, (char *)dt->answer);
    stdlog("strcmp=%d", retval);
    assert(0 == retval);

    retval = shutdown(dt->sock, SHUT_RDWR);
    if (retval < 0) {
        outstd("shutdown: sock=%d", dt->sock);
        pthread_exit((void *)EXIT_FAILURE);
    }

    pthread_cleanup_pop(1);
    pthread_cleanup_pop(1);
    pthread_cleanup_pop(1);

    pthread_exit((void *)EX_SUCCESS);
    return (void *)EX_SUCCESS;
}
Exemple #3
0
/**
 * サーバプロセス
 *
 * @param[in] arg ソケットディスクリプタ
 * @return 常にNULL
 */
static void *
server_proc(void *arg)
{
    thread_data dt;                   /* スレッドデータ構造体 */
    int retval = 0;                   /* 戻り値 */
    size_t length = 0;                /* 長さ */
    ssize_t slen = 0;                 /* 送信するバイト数 */
    struct header hd;                 /* ヘッダ構造体 */
    unsigned char *expr = NULL;       /* 受信データ */
    calcinfo calc;                    /* calc情報構造体 */
    struct server_data *sdata = NULL; /* 送信データ構造体 */

    (void)memcpy(&dt, arg, sizeof(thread_data));

    dbglog("start: accept=%d sin_addr=%s sin_port=%d, len=%d",
           dt.sock, inet_ntoa(dt.addr.sin_addr),
           ntohs(dt.addr.sin_port), dt.len);

    /* シグナルマスクを設定 */
    set_thread_sigmask(dt.sigmask);

    pthread_cleanup_push(thread_cleanup, &dt);
    do {
        /* ヘッダ受信 */
        length = sizeof(struct header);
        (void)memset(&hd, 0, length);
        retval = recv_data(dt.sock, &hd, &length);
        if (retval < 0) /* エラーまたは接続先がシャットダウンされた */
            pthread_exit((void *)EXIT_FAILURE);

        dbglog("recv_data: hd=%p, length=%zu, hd.length=%zu",
               &hd, length, hd.length);

        if (g_gflag)
            outdump(&hd, length, "recv: hd=%p, length=%zu", &hd, length);
        stddump(&hd, length, "recv: hd=%p, length=%zu", &hd, length);

        /* データ受信 */
        length = (size_t)ntohl((uint32_t)hd.length); /* データ長を保持 */
        expr = (unsigned char *)recv_data_new(dt.sock, &length);
        if (!expr) /* メモリ不足 */
            pthread_exit((void *)EXIT_FAILURE);

        pthread_cleanup_push(thread_memfree, &expr);

        if (!length) /* 受信エラー */
            pthread_exit((void *)EXIT_FAILURE);

        dbglog("expr=%p, length=%zu", expr, length);

        if (g_gflag)
            outdump(expr, length,
                    "recv: expr=%p, length=%zu", expr, length);
        stddump(expr, length,
                "recv: expr=%p, length=%zu", expr, length);

        /* サーバ処理 */
        (void)memset(&calc, 0, sizeof(calcinfo));
        if (!create_answer(&calc, expr))
            pthread_exit((void *)EXIT_FAILURE);

        pthread_cleanup_push(destroy_answer, &calc);

        length = strlen((char *)calc.answer) + 1; /* 文字列長保持 */

        dbgdump(calc.answer, length,
                "answer=%p, length=%zu", calc.answer, length);

        /* データ送信 */
        slen = set_server_data(&sdata, calc.answer, length);
        if (slen < 0) /* メモリ確保できない */
            pthread_exit((void *)EXIT_FAILURE);

        pthread_cleanup_push(thread_memfree, &sdata);
        dbglog("slen=%zd", slen);

        if (g_gflag)
            outdump(sdata, slen,
                    "send: sdata=%p, slen=%zd", sdata, slen);
        stddump(sdata, slen,
                "send: sdata=%p, slen=%zd", sdata, slen);

        retval = send_data(dt.sock, sdata, (size_t *)&slen);
        if (retval < 0) /* エラー */
            pthread_exit((void *)EXIT_FAILURE);

        dbglog("send_data: sdata=%p, slen=%zu", sdata, slen);

        pthread_cleanup_pop(1);
        pthread_cleanup_pop(1);
        pthread_cleanup_pop(1);

    } while (!g_sig_handled);

    pthread_cleanup_pop(1);
    pthread_exit((void *)EXIT_SUCCESS);
    return (void *)EXIT_SUCCESS;
}