( standard c libraries translation )getpwnam

来源:互联网 发布:邮轮客房知乎 编辑:程序博客网 时间:2024/06/03 21:39
getpwnam, getpwnam_r, getpwuid, getpwuid_r - get password file entry
getpwnam, getpwnam_r, getpwuid, getpwuid_r - 获取password文件的入口

所需头文件
#include <sys/types.h>
#include <pwd.h>

struct passwd *getpwnam(const char *name);
struct passwd *getpwuid(uid_t uid);
int getpwnam_r(const char *name, struct passwd *pwd,
           char *buf, size_t buflen, struct passwd **result);
int getpwuid_r(uid_t uid, struct passwd *pwd,
           char *buf, size_t buflen, struct passwd **result);

The getpwnam() function returns a pointer to a structure containing the broken-out fields of the record in the password database (e.g., the local password file /etc/passwd, NIS, and LDAP) that matches the username name.
getpwnam函数返回一个指向包含password数据库结构体的指针,其中用户名与name匹配

The getpwuid() function returns a pointer to a structure containing the broken-out fields of the record in the password database that matches the  user ID uid.
getpwuid函数返回一个指向包含password数据库结构体的指针,其中用户id与uid匹配

       The passwd structure is defined in <pwd.h> as follows:
           struct passwd {
               char   *pw_name;       /* username */
               char   *pw_passwd;     /* user password */
               uid_t   pw_uid;        /* user ID */
               gid_t   pw_gid;        /* group ID */
               char   *pw_gecos;      /* user information */
               char   *pw_dir;        /* home directory */
               char   *pw_shell;      /* shell program */
           };
       See passwd(5) for more information about these fields.

The  getpwnam_r()  and getpwuid_r() functions obtain the same information as getpwnam() and getpwuid(), but store the retrieved passwd structure in the space pointed to by pwd.  The string fields pointed to by the members of the passwd structure are stored in the buffer buf of size buflen.   A  pointer to the result (in case of success) or NULL (in case no entry was found or an error occurred) is stored in *result.
getpwnam_r和getpwuid_r函数与getpwnam和getpwuid拥有同样的作用,但是把返回的结果存储在pwd指向的结构体中,passwd结构体里面的成员都存储在buflen大小的内存中,指向结果的指针(成功)或者NULL(如果没有入口或者发生错误)存储在result指针中

The call
    sysconf(_SC_GETPW_R_SIZE_MAX)
returns either -1, without changing errno, or an initial suggested size for buf.  (If this size is too small, the call fails with ERANGE, in which case the caller can retry with a larger buffer.)
sysconf(_SC_GETGR_R_SIZE_MAX)调用返回-1,但是没有设置errno,或者一个默认的建议buf size(如果size太小,调用会ERANGE出错,这种情况下调用者应该尝试一个大一些的内存)

The getpwnam() and getpwuid() functions return a pointer to a passwd structure, or NULL if the matching entry is not found or an error occurs.   If  an error occurs, errno is set appropriately.  If one wants to check errno after the call, it should be set to zero before the call.
getpwnam和getpwuid函数返回一个指向passwd的结构体,或者NULL如果入口没有找到或者发生错误,如果发生错误,errno会被设置成一个合适的值,如果需要在调用后检查errno的值,那么在调用之前需要把errno的值设置成0

The  return  value  may point to a static area, and may be overwritten by subsequent calls to getpwent(3), getpwnam(), or getpwuid().  (Do not pass the returned pointer to free(3).)
返回值保存在静态数据区,可能会被后续的getpwent,getpwnam或者getpwuid等调用所覆盖

On success, getpwnam_r() and getpwuid_r() return zero, and set *result to pwd.  If no matching password record was found, these functions return 0  and store NULL in *result.  In case of error, an error number is returned, and NULL is stored in *result.
成功的时候getpwnam_r和getpwuid_r返回0,把结果存到result中,如果没有匹配password的记录,这个函数会返回0,result会被赋值成NULL,发生错误的情况下,会返回error数,result会被赋值成NULL

0 or ENOENT or ESRCH or EBADF or EPERM or ... The given name or uid was not found.
0或者ENOENT或者ESRCH或者EBADF或者EPERM或者。。。没有找到所给的name或者uid
EINTR  A signal was caught.
一个信号被捕捉到了
EIO    I/O error.
I/O错误
EMFILE The maximum number (OPEN_MAX) of files was open already in the calling process.
调用进程已经打开最多数量的文件
ENFILE The maximum number of files was open already in the system.
系统已经打开最多数量的文件
ENOMEM Insufficient memory to allocate passwd structure.
分配passwd结构体的时候内存不足
ERANGE Insufficient buffer space supplied.
提供的buffer容量不足

The  user  password  database  mostly refers to /etc/passwd.  However, with recent systems it also refers to network wide databases using NIS, LDAP and other local files as configured in /etc/nsswitch.conf.
用户password数据库基本都是/etc/passwd,然后近来的系统用NIS,LDAP和一些其他的本地文件存储网络数据库到/etc/nsswitch.conf

FILES /etc/passwd local password database file
本地password数据库文件

/etc/nsswitch.conf System Databases and Name Service Switch configuration file
系统数据库和名字交换服务配置文件

The  pw_dir  field  contains  the name of the initial working directory of the user.  Login programs use the value of this field to initialize the HOME environment variable for the login shell.  An application that wants to determine its user's home directory should inspect the value  of  HOME  (rather than the value getpwuid(getuid())->pw_dir) since this allows the user to modify their notion of "the home directory" during a login session.  To determine the (initial) home directory of another user, it is necessary to use getpwnam("username")->pw_dir or similar.

pw_dir包含用户初始化工作路径的名字,登录程序用这个值来初始化shell HOME环境变量,应用程序想要确定用户的home路径需要检查HOME的值(而不是getpwuid(getuid())->pw_dir)的值),因为这个在登录会话期间允许用户修改home路径,如果需要确定其他用户默认的home路径,有必要使用getpwnam("username")->pw_dir或者类似的方法

testcase如下:

#include <pwd.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>intmain(int argc, char *argv[]){   struct passwd pwd;   struct passwd *result;   char *buf;   size_t bufsize;   int s;   if (argc != 2) {       fprintf(stderr, "Usage: %s username\n", argv[0]);       exit(EXIT_FAILURE);   }   bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);   if (bufsize == -1)          /* Value was indeterminate */       bufsize = 16384;        /* Should be more than enough */   buf = malloc(bufsize);   if (buf == NULL) {       perror("malloc");       exit(EXIT_FAILURE);   }   s = getpwnam_r(argv[1], &pwd, buf, bufsize, &result);   if (result == NULL) {       if (s == 0)           printf("Not found\n");       else {           errno = s;           perror("getpwnam_r");       }       exit(EXIT_FAILURE);   }   printf("Name: %s; UID: %ld\n", pwd.pw_gecos, (long) pwd.pw_uid);   exit(EXIT_SUCCESS);}

运行结果如下:

cheny.le@cheny-ThinkPad-T420:~/cheny/testCode$ ./a.out cheny.le
Name: cheny.le,,,; UID: 1001


0 0