GETPROTOENT_R - Linux手册页

时间:2019-08-20 18:00:30  来源:igfitidea点击:

Linux程序员手册 第3部分
更新日期: 2020-06-09

名称

getprotoent_r,getprotobyname_r,getprotobynumber_r-获取协议条目(可重入)

语法

#include <netdb.h>

int getprotoent_r(struct protoent *result_buf, char *buf,
                size_t buflen, struct protoent **result);

int getprotobyname_r(const char *name,
                struct protoent *result_buf, char *buf,
                size_t buflen, struct protoent **result);

int getprotobynumber_r(int proto,
                struct protoent *result_buf, char *buf,
                size_t buflen, struct protoent **result);

Feature Test Macro Requirements for glibc (see
feature_test_macros(7)):

getprotoent_r(),getprotobyname_r(),getprotobynumber_r():
从glibc 2.19开始:
_DEFAULT_SOURCE
Glibc 2.19及更早版本:
_BSD_SOURCE _SVID_SOURCE

说明

getprotoent_r(),getprotobyname_r()和getprotobynumber_r()函数分别是getprotoent(3),getprotobybyname(3)和getprotobybynumber(3)的可重入等效项。它们的不同之处在于返回原型结构的方式以及调用签名和返回值的函数。本手册页仅介绍与不可重入功能的区别。

这些函数没有将指向静态分配的原型结构的指针作为函数结果返回,而是将结构复制到result_buf指向的位置。

buf数组用于存储返回的原型结构所指向的字符串字段。 (nonreentrant函数在静态存储中分配这些字符串。)此数组的大小在buflen中指定。如果buf太小,则调用将失败,并显示错误ERANGE,并且调用方必须使用更大的缓冲区再次尝试。 (对于大多数应用程序,长度为1024字节的缓冲区应该足够了。)

如果函数调用成功获取协议记录,则将* result设置为指向result_buf;否则,* result设置为NULL。

返回值

成功时,这些函数返回0。错误时,它们返回ERRORS中列出的正错误号之一。

发生错误时,找不到记录(getprotobyname_r(),getprotobynumber_r())或输入结尾(getprotoent_r())的结果设置为NULL。

错误说明

ENOENT
(getprotoent_r())数据库中没有更多记录。
ERANGE
buf太小。使用更大的缓冲区(并增加buflen)再试一次。

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
getprotoent_r(),
getprotobyname_r(),
getprotobynumber_r()
Thread safetyMT-Safe locale

遵循规范

这些功能是GNU扩展。具有相同名称的功能在其他一些系统上也存在,尽管通常具有不同的调用签名。

示例

下面的程序使用getprotobyname_r()检索在其第一个命令行参数中命名的协议的协议记录。如果提供了第二个(整数)命令行参数,它将用作buflen的初始值;否则,它将用作buflen的初始值。如果getprotobyname_r()失败并显示错误ERANGE,则程序将使用更大的缓冲区重试。以下shell会话显示了几个示例运行:

$ ./a.out tcp 1
ERANGE! Retrying with larger buffer
getprotobyname_r() returned: 0 (success)  (buflen=78)
p_name=tcp; p_proto=6; aliases=TCP
$ ./a.out xxx 1
ERANGE! Retrying with larger buffer
getprotobyname_r() returned: 0 (success)  (buflen=100)
Call failed/record not found

Program source

#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, s;
    struct protoent result_buf;
    struct protoent *result;
    char buf[MAX_BUF];
    char **p;

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

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

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

    erange_cnt = 0;
    do {
        s = getprotobyname_r(argv[1], &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("getprotobyname_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("p_name=%s; p_proto=%d; aliases=",
                result_buf.p_name, result_buf.p_proto);
    for (p = result_buf.p_aliases; *p != NULL; p++)
        printf("%s ", *p);
    printf("\n");

    exit(EXIT_SUCCESS);
}

另外参见

getprotoent(3),协议(5)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/