getprotoent_r函数用法详解
getprotoent_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 );
getprotoent_r函数常见使用错误
- 编译错误
warning: implicit declaration of function ‘getprotoent_r’ [-Wimplicit-function-declaration]
解决办法:包含头文件
#include <netdb.h>
getprotoent_r函数详细描述
getprotoent_r () getprotobyname_r ()和getprotobynumber_r ()函数分别是getprotoent (3) getprotobyname (3)和getprotobynumber (3)的可重入等价物。它们的不同之处在于返回protoent结构的方式,以及调用签名和返回值的函数。本手册页只描述了与不可重入函数的区别。
这些函数不返回指向静态分配的protoent结构的指针作为函数结果,而是将该结构复制到result_buf 所指向的位置
buf数组用于存储返回的protoent结构所指向的字符串字段。(不可重入函数在静态存储中分配这些字符串。)此数组的大小在buflen 中指定。如果buf太小,则调用失败,错误为ERANGE ,调用方必须使用更大的缓冲区重试。(对于大多数应用程序,长度为1024字节的缓冲区应该足够了。)
如果函数调用成功获得协议记录,则*result被设置为指向result_buf ;,否则,*result被设置为NULL。
getprotoent_r函数返回值
成功后,这些函数返回0。出错时,它们返回错误中列出的正错误号之一。
出错时,记录未找到( getprotobyname_r () getprotobynumber_r ())或输入( getprotoent_r ()) result的结尾设置为空。
getprotoent_r函数错误码
- ENOENT ( getprotoent_r ())数据库中没有更多记录。
- ERANGE buf太小。使用更大的缓冲区(和增加的buflen ))重试
getprotoent_r函数使用举例
下面的程序使用getprotobyname_r ()检索其第一个命令行参数中命名的协议的协议记录。如果提供了第二个(整数)命令行参数,它将用作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];
if (argc < 2) {
printf("Usage: %s proto\-name [buflen]\en", argv[0]);
exit(EXIT_FAILURE);
}
buflen = 1024;
if (argc > 2)
buflen = atoi(argv[2]);
if (buflen > MAX_BUF) {
printf("Exceeded buffer limit (%d)\en", 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\en");
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)\en", MAX_BUF);
exit(EXIT_FAILURE);
}
}
} while (s == ERANGE);
printf("getprotobyname_r() returned: %s (buflen=%d)\en",
(s == 0) ? "0 (success)" : (s == ENOENT) ? "ENOENT" :
strerror(s), buflen);
if (s != 0 || result == NULL) {
printf("Call failed/record not found\en");
exit(EXIT_FAILURE);
}
printf("p_name=%s; p_proto=%d; aliases=",
result_buf.p_name, result_buf.p_proto);
for (char **p = result_buf.p_aliases; *p != NULL; p++)
printf("%s ", *p);
printf("\en");
exit(EXIT_SUCCESS);
}
评论区