
APUE 第六章 系统数据文件和信息
第六章 系统数据文件和信息
6.2 口令文件
口令文件指的是 /etc/passwd 文件,该文件中包含了下图中所示的各个字段

这些字段包含在 <pwd.h>
中定义的 passwd
结构中
那么该怎么获得口令文件中的项呢?
使用下面这俩函数
1 |
|
这两个函数都返回一个指向 passwd
结构体的指针,结构体里包含了图 6.1 所示的字段
如果想查看整个口令文件,使用下面的三个函数
1 |
|
每次调用 getpwent
都返回口令文件中的下一个记录项,第一次调用时会打开所有它要用到的文件。 setpwent
rewinds 它使用的文件。 endpwent
关闭它使用的那些文件。
使用 getpwent、setpwent 和 endpwent 实现 getpwnam
6.3 阴影口令 shadow passwords
这个文件是专门用来放置 加密后的密码 的
shadow passwords 中的字段如下图所示

这其中只有 用户名 和 加密后的口令 是必需的
那么如何访问阴影口令文件呢? 和口令文件类似,有如下函数
1 |
|
6.4 组文件 group file
组文件中包含了下图中的各个字段

这些字段包含在 <grp.h>
中定义的 group
结构体中
类似地,可以使用下面的函数来查看组名或者 group ID
1 |
|
如果要搜索整个组文件,使用下面三个函数
1 |
|
每次调用 getgrent
都返回口令文件中的下一个记录项,第一次调用时会打开所有它要用到的文件。 setgrent
rewinds 它使用的文件。 endgrent
关闭它使用的那些文件。
6.5 附属组 ID
为了获取和设置附属组 ID,提供了以下函数
1 |
|
`getgroups
将用户所属的附属组名写到数组 grouplist
中,写入的个数由 gidsetsize
指定。实际写入的个数由函数返回。
6.6 实现区别
各种平台存储用户和组信息的方式:

6.7 其他数据文件
除了 口令文件 和 组文件,UNIX系统还使用很多其他文件。
一般来说,对于每个数据文件至少有三个函数
- get 函数: 读取下一个记录。 通常返回一个指向结构体的指针。此类指针通常指向一个静态存储类的结构,如果要保存返回的内容,则应该保存整个结构体,而非指针,因为返回指针指向的结构体在下一次调用 get 函数的时候会被重写
- set 函数:
- end 函数:关闭相应的数据文件
UNIX系统其他数据文件的相关信息:

6.8 登录账户记录
大多数UNIX 系统提供下列两个数据文件: utmp 和 wtmp
每次写入这两个文件中的是下面的这个结构
1 | struct utmp { |
6.9 系统标识
POSIX.1 定义了 uname 函数,它返回与主机和操作系统有关的信息
1 |
|
其中 utsname
结构体如下
1 | struct utsname { |
uname
负责填写 name
参数指向的结构体
6.10 时间和日期
UNIX内核提供的基本时间服务是计算自 协调世界时 (Coordinated Universal Time,UTC)公元1970年1月1日 00:00:00 以来经过的 秒数 ,数据类型是 time_t
time
函数返回当前日期和时间
1 |
|
POSIX.1 增加了多个系统时钟,用 clockid_t
类型的变量标识,如下图

使用 clock_gettime
函数获取指定时钟的时间
1 |
|
要对特定的时钟设置时间,使用
1 |
|
注意,修改时钟需要特权,而且有些时钟是不能修改的
注意,获得的 time_t 类型的整型值是一个很大的数字,我们不能从它直接得到当前的日期和时间。这时候就需要各种转换函数 了
localtime
和 gmtime
两个函数将转换后的日期时间放在 tm
结构体中
1 | struct tm {/* a broken-down time */ |
下图反映了各个时间函数之间的关系

1 |
|
这俩函数的区别在于: gmtime
把日历时间(很大的那个秒数) 转换为 协调统一时间的年月日分秒;而 localtime
把日历时间转换为当地的年月日分秒(考虑时区和夏令时)
函数 gmtime
把本地时间的年月日等作为参数,将其变成 time_t
值
1 |
|
下面这两个函数用来以不同的格式打印时间
1 |
|
strftime_l
函数除了可以用 locale
参数指定时区外与 strftime
函数没有区别
format
参数与 printf
函数中的 format
参数类似,它控制打印的格式。自然地, format
参数中也会包含转换说明
