【发布时间】:2018-05-07 20:32:27
【问题描述】:
背景资料
我正在尝试获取用户用户名的字符串,提供的关于该用户的唯一信息是他们的uid 号码。我有 uid 作为先前调用 fstat 的结果(并且 uid 存储在 struct stat 中)。
我需要以线程安全的方式获取用户名,因此我尝试使用getpwuid_r()。根据getpwuid (3)man page:
int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer,
size_t bufsize, struct passwd **result);
getpwuid_r()函数应更新指向的passwd结构 通过pwd并在该位置存储指向该结构的指针 结果指出。该结构应包含一个条目 具有匹配uid的用户数据库。引用的存储 结构是从缓冲区提供的内存中分配的 参数,大小为bufsize字节。打电话给sysconf(_SC_GETPW_R_SIZE_MAX)返回任一 -1 而不改变errno或为此缓冲区大小建议的初始值。一种 空指针应返回结果指向的位置 出错或未找到请求的条目。如果成功,
getpwuid_r()函数将返回零; 否则,将返回错误号以指示错误。
问题陈述
阅读下面的手册页示例后,我很困惑为什么他们需要迭代,同时增加缓冲区的大小,直到缓冲区可以保存其信息。
我假设缓冲区包含struct passwd pwd - 考虑到这一点,为什么我们不能只设置buffer = (void *) malloc(getsize(struct passwd)) 和bufsize = sizeof(struct passwd)?
long int initlen = sysconf(_SC_GETPW_R_SIZE_MAX);
size_t len;
if (initlen == −1)
/* Default initial length. */
len = 1024;
else
len = (size_t) initlen;
struct passwd result;
struct passwd *resultp;
char *buffer = malloc(len);
if (buffer == NULL)
...handle error...
int e;
while ((e = getpwuid_r(42, &result, buffer, len, &resultp)) == ERANGE)
{
size_t newlen = 2 * len;
if (newlen < len)
...handle error...
len = newlen;
char *newbuffer = realloc(buffer, len);
if (newbuffer == NULL)
...handle error...
buffer = newbuffer;
}
if (e != 0)
...handle error...
free (buffer);
关于这个函数如何在pwd 中设置数据,我有什么不明白的地方吗?可能我不完全明白我们设置的struct passwd和缓冲空间有什么关系。
【问题讨论】:
标签: c linux struct operating-system filesystems