分类: LINUX
2008-12-09 13:01:34
包括但不限于passwd(5), shadow(5), group(5), hosts(5), networks(5), protocols(5), services(5)等,它们的文档位于man手册的第5部分。它们均存于/etc目录下。UNIX系统提供了相应的数据结构和函数对它们进行读取。但是这一块根据书中的表6-1可以看出,POSIX对此并没有作出特别具体的定义。对于Linux,可以参考中的相关定义或查看当前系统中的man手册。
口令文件passwd
对于文件passwd(5),值得注意的一点是,如果里面注册的某个用户只打算用于守护进程之类而不打算给予登录shell,应将其home directory相应字段设置为/dev/null或者/bin/false等。
#include
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
这两个函数分别通过uid和用户名取得其passwd结构。
#include
struct passwd *getpwent(void);
void setpwent(void);
void endpwent(void);
getpwent返回passwd文件下一个记录项;
setpwent重置getpwent的当前位置到开始处;
endpwent关闭getpwent打开的文件(必须);
阴影口令文件shadow
管理shadow文件的相应API主要包括以下,用法类似passwd的函数:
#include
struct spwd *getspnam(const char *name);
struct spwd *getspent(void);
void setspent(void)
void endspent(void);
组文件group
管理group(5)文件的相应API主要包括以下,用法也类似passwd的函数:
#include
struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
struct group *getgrent(void);
void setgrent(void);
void endgrent(void);
对于进程的附加组操作,还包括以下函数:
#include
int getgroups(int gidsetsize, gid_t grouplist][);
#include
int setgroups(int ngroups, const gid_t grouplist[]);
int initgroups(const char *username, gid_t basegid);
getgroups和setgroups用于读取/设置当前用户进程的附加组id,并返回实际读取/设置的附加组id数量;
initgroups初始化附加组id表,basegid为用户进程的主gid。
service(5)、networks(5)、protocols(5)等数据可通过getxxxbyxxx或getaddrinfo等函数取得。具体见第十六章《网络IPC》或Richard Stevens的《UNIX网络编程第一卷》;
utmp(5)位于/var/run下,记录当前登录的用户,为who(1)的数据源;wtmp(5)位于/var/log下,记录上次登录的用户,为last(1)的数据源。另外还/var/log还存在一个btmp文件,用于记录失败的登录操作,为blast(1)的数据源,但btmp本身没有手册页。
POSIX对这些文件及其结构都没有作专门要求;使用时应查看具体系统上的手册页;
#include
int uname(stuct ustname *name);
该函数将与操作系统相关的信息读到指定的utsname结构指针中,POSIX要求ustname至少包括sysname(内核名,如:Linux)、nodename(主机名,但手册称这个字段基本上没有意义,可用gethostname(2)代替)、release(发行名,如:Ubuntu)、version(版本号,如:2.6.24)、machine(体系结构,如:i686)这几个字段。对应的shell命令也是uname(1)。
本节提及的库函数除了gettimeofday外,都属于ISO C的一部分。时间日期的数据结构包括:time_t(标准格式,以秒为单位)、struct timeval(日期格式,包括年月日时分秒)、struct tm(时间格式,包括秒和微秒);查询时间日期相应的shell系统命令包括date(1)、cal(1)等。
读取时间值
#include
time_t time(time_t *calptr);
该函数返回以秒为单位的当前UNIX标准时间值,如果指定了指针calptr,也同时将该值存入其中;time(2)同时也是从内核取得时间值的基本系统调用;注意另有一个POSIX函数times(2)用于取进程时间,它使用是tms和clock_t结构。
#include
int gettimeofday(struct timeval *restrict tp, void *restrict tzp);
该函数读取当前时间的timeval结构到指针fp处,并用tzp调整(时区,若指定)。timeval结构定义了毫秒级的精度;
转换时间值
#include
struct tm *gmtime(const time_t *calptr);
struct tm *localtime(const time_t *calptr);
该函数将指定的UNIX标准时间值转换为格林尼治时间或本地时间并存到tm结构中返回其指针;
#include
time_t mktime(struct tm *tmptr);
该函数将tm结构的时间转换为UNIX标准时间;
#include
char *asctime(const struct tm *tmptr);
char *ctime(const time_t *calptr);
以上两个函数将参数指定的时间转换为常见的时间日期格式字符串,受环境变量TZ影响;
格式化时间字符串
#include
size_t strftime(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr);
该函数将tmptr转换为format指定的格式,并存放在长度为buf中,buf长度为maxsize(注意字符串最后一个字符为'\0')。buf长度不足时返回0,否则返回存放的字符数(不包括'\0')。
format的格式化用法类似printf等函数,但使用不同的格式化标记。如:
strftime(buf, maxsize, "%Y年%m月%d日 %H:%M:%S %Z", localtime(&time_t_obj));
要注意大小写。
这是位于内存中的各种内核数据结构信息挂载在/文件系统下的一个虚拟文件系统,可以像对普通文件一样对其进行读写操作。其内容不是POSIX的一部分,书中也几乎未提及这部分。对于Linux,是通过构建一个procfs并用VFS接口实现的。这里是我以前对Linux文件系统诸信息的一个笔记。