GETSERVENT_R

Section: Linux Programmer's Manual (3)
Updated: 2020-11-01
Index JM Home Page
 

名前

getservent_r, getservbyname_r, getservbyport_r - サービスエントリーを 取得する (リエントラント版)  

書式

#include <netdb.h>

int getservent_r(struct servent *result_buf, char *buf,
                size_t buflen, struct servent **result);

int getservbyname_r(const char *name, const char *proto,
                struct servent *result_buf, char *buf,
                size_t buflen, struct servent **result);

int getservbyport_r(int port, const char *proto,
                struct servent *result_buf, char *buf,
                size_t buflen, struct servent **result);

glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):

getservent_r(), getservbyname_r(), getservbyport_r():
    Since glibc 2.19:
        _DEFAULT_SOURCE
    Glibc 2.19 and earlier:
        _BSD_SOURCE || _SVID_SOURCE  

説明

関数 getservent_r(), getservbyname_r(), getservbyport_r() は、 それぞれ getservent(3), getservbyname(3), getservbyport(3) の リエントラント版である。 servent 構造体の返し方と、関数呼び出し時の引数と返り値が異なる。 このマニュアルページでは、リエントラントでない関数との違いだけを 説明する。

これらの関数は、関数の結果として静的に割り当てられた servent 構造体 へのポインターを返すのではなく、 servent 構造体を result_buf が 指す場所にコピーする。

配列 buf は、返される servent 構造体が指す文字列フィールドを 格納するのに使用される (リエントラントでない関数の場合は、 これらの文字列は静的な領域に格納される)。 この配列の大きさは buflen で指定される。 buf が小さすぎる場合、関数呼び出しはエラー ERANGE で失敗し、 呼び出し側ではもっと大きなバッファーで再度呼び出す必要がある (ほとんどの アプリケーションでは、長さ 1024 バイトのバッファーで十分なはずである)。

関数呼び出しでサービスレコードの取得に成功すると、 *result は result_buf を指すように設定される。 それ以外の場合は *result に NULL が設定される。  

返り値

成功すると、これらの関数は 0 を返す。エラーの場合、「エラー」の節の リストにある正のエラー番号のいずれかを返す。

エラーの場合、レコードが見つからなかった場合 (getservbyname_r(), getservbyaddr_r()) やこれ以上レコードがない場合 (getservent_r())、 result には NULL が設定される。  

エラー

ENOENT
(getservent_r()) データベースにこれ以上レコードがない。
ERANGE
buf が小さすぎる。もっと大きなバッファーにして (または buflen を増やして) 再度呼び出すこと。
 

属性

この節で使用されている用語の説明は attributes(7) を参照のこと。
Interface Attribute Value
getservent_r(), getservbyname_r(), getservbyport_r() Thread safety MT-Safe locale
 

準拠

これらの関数は GNU による拡張である。 他のシステムにも同様の名前の関数が存在する場合があるが、 通常は関数の引数が異なる。  

例

以下のプログラムは、 getservbyport_r() を使って、コマンド ライン引数で指定されたポート番号とプロトコル名を持つ サービスレコードを取得する。 三番目のコマンドライン引数 (整数値) が指定された場合は、 その値が buflen の初期値として使用される。 getservbyport_r() がエラー ERANGE で失敗すると、プログラムは より大きなバッファーサイズで再度 getservbyport_r を呼び出す。 下記のシェルのセッションは実行例を示している。

$ ./a.out 7 tcp 1 ERANGE! Retrying with larger buffer getservbyport_r() returned: 0 (success) (buflen=87) s_name=echo; s_proto=tcp; s_port=7; aliases= $ ./a.out 77777 tcp getservbyport_r() returned: 0 (success) (buflen=1024) Call failed/record not found  

プログラムのソース

#define _GNU_SOURCE #include <ctype.h> #include <netdb.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h>

#define MAX_BUF 10000

int main(int argc, char *argv[]) {
    int buflen, erange_cnt, port, s;
    struct servent result_buf;
    struct servent *result;
    char buf[MAX_BUF];
    char *protop;


    if (argc < 3) {
        printf("Usage: %s port-num proto-name [buflen]\n", argv[0]);
        exit(EXIT_FAILURE);
    }


    port = htons(atoi(argv[1]));
    protop = (strcmp(argv[2], "null") == 0 ||
              strcmp(argv[2], "NULL") == 0) ?  NULL : argv[2];


    buflen = 1024;
    if (argc > 3)
        buflen = atoi(argv[3]);


    if (buflen > MAX_BUF) {
        printf("Exceeded buffer limit (%d)\n", MAX_BUF);
        exit(EXIT_FAILURE);
    }


    erange_cnt = 0;
    do {
        s = getservbyport_r(port, protop, &result_buf,
                     buf, buflen, &result);
        if (s == ERANGE) {
            if (erange_cnt == 0)
                printf("ERANGE! Retrying with larger buffer\n");
            erange_cnt++;


            /* Increment a byte at a time so we can see exactly
               what size buffer was required */


            buflen++;


            if (buflen > MAX_BUF) {
                printf("Exceeded buffer limit (%d)\n", MAX_BUF);
                exit(EXIT_FAILURE);
            }
        }
    } while (s == ERANGE);


    printf("getservbyport_r() returned: %s  (buflen=%d)\n",
            (s == 0) ? "0 (success)" : (s == ENOENT) ? "ENOENT" :
            strerror(s), buflen);


    if (s != 0 || result == NULL) {
        printf("Call failed/record not found\n");
        exit(EXIT_FAILURE);
    }


    printf("s_name=%s; s_proto=%s; s_port=%d; aliases=",
                result_buf.s_name, result_buf.s_proto,
                ntohs(result_buf.s_port));
    for (char **p = result_buf.s_aliases; *p != NULL; p++)
        printf("%s ", *p);
    printf("\n");


    exit(EXIT_SUCCESS); }  

関連項目

getservent(3), services(5)  

この文書について

この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。

関連キーワード

buflen   printf   struct   servent   port   argv   getservbyport   レコード   buffer   exit   size   構造体   バッファー   proto   erange   サービス   再度   returned   success   aliases   argc   protop   getservent   getservbyname   netdb

Linux マニュアル 一覧

関連するコマンド・関数

getservbyname_r.3   getservbyport_r.3   getprotobyname_r.3   getprotobynumber_r.3   getprotoent_r.3   endservent.3
 

Index

名前
書式
説明
返り値
エラー
属性
準拠
例
プログラムのソース
関連項目
この文書について

This document was created by man2html, using the manual pages.
Time: 04:39:23 GMT, October 11, 2026