文章目录
- 其他数据文件
- 登录账户记录
- 系统标识
- 时间和日期例程
- `time`函数返回当前时间和日期。
- `clock_gettime`函数用于获取执行时钟的时间。
- `clock_getres`函数把参数`tsp`指向的`timespec`结构初始化为与`clock_id`参数对应的时钟精度。
- `clock_settime`函数对特定精度的时钟设置时间。
- `gettimeofday`函数获取的时间精度要比`time`函数更高。
- `localtime`函数将日历时间转换成本地时间,而`gmtime`则是将日历时间转换成协调统一时间的年、月、日、时、分、秒、周日的分解结构。
- `strftime`是一个类似于`printf`函数的时间值函数。
- `strptime`是`strftime`函数的反过来的版本,把字符串时间转换成分解时间。
其他数据文件
系统文件除了口令文件和组文件之外,还有一些其他的系统数据文件。比如记录各网络服务器所提供服务的数据文件(/etc/services),记录协议信息的的数据文件(/etc/protocols),还有一个则是记录网络信息的数据文件(/etc/networks)等。对于这些数据文件的接口与口令文件和组文件的相似。
一般情况下,对于每个数据文件至少有3个函数。
get
函数:读下一个记录,如果需要,还会打开该文件。此种函数通常返回指向一个结构的指针。当已到达文件末尾时返回空指针。
set
函数:打开相应数据文件(如果尚未打开),然后反绕该文件。
end
函数:关闭相应数据文件。
另外,如果数据文件支持某种形式的键搜索,则也提供搜索具有指定键的记录的例程。例如,对于口令文件,提供了两个按键进行搜索的程序:getpwnam
寻找具有执行用户名的记录;getpwuid
寻找具有指定用户ID的记录。
下面整理出UNIX中相关服务的这些例程(除了已有的get
、set
以及end
之外的)。
说明 | 数据文件 | 头文件 | 结构 | 附加的键搜索函数 |
---|---|---|---|---|
口令 | /etc/passwd | <pwd.h> | passwd | getpwnam、getpwuid |
组 | /etc/group | <grp.h> | group | getgrnam、getgrgid |
阴影 | /etc/shadow | <shadow.h> | spwd | getspnam |
主机 | /etc/hosts | <netdb.h> | hostent | getnameinfo、getaddrinfo |
网络 | /etc/networks | <netdb.h> | netent | getnetbyname、getnetbyaddr |
协议 | /etc/protocols | <netdb.h> | protoent | getprotobyname、getprotobynumber |
服务 | /etc/services | <netdb.h> | servent | getservbyname、getservbyport |
登录账户记录
大多数UNIX系统都提供下列两个数据文件:utmp文件记录当前登录到系统的各个用户;wtmp文件跟踪各个登录和注销事件。在Linux下,如需了解两个文件的具体详情,可命令行执行man 5 utmp
或man 5 wtmp
来查看。
系统标识
POSIX.1定义了uname
函数,它返回与主机和系统相关的信息。
#include <sys/utsname.h>
int uname(struct utsname *name);
返回值:若成功,返回非负值;若出错,返回-1。
该函数中参数的类型的结构体如下(Linux下实现):
struct utsname{
char sysname[]; /* Operation system name (eg. "Linux") */
char nodename[]; /* Name within "some implementation-defined network" */
char release[]; /* Operation system release (eg. "2.6.28") */
char version[]; /* Operation system version */
char machine[]; /* Hardware identifier */
#ifdef _GNU_SOURCE
char domainname[]; /* NIS or YP domain name */
#endif
};
历史上,BSD派生的系统提供gethostname
函数 ,它只返回主机名,该名字通常就是TCP/IP网络上主机名。
#include <unistd.h>
int gethostname(char *name, int namelen);
返回值:若成功,返回0;若出错,返回-1。
测试示例:
#include "../../include/apue.h"
void test()
{
char name[100];
memset(name, 0, sizeof(name));
if(gethostname(name, 100) < 0)
err_sys("gethostname error");
printf("host name = %s\n", name);
}
int main()
{
test();
return 0;
}
结果如下:
由上图可知此时该主机的名字为ubuntu。通过在命令行下执行hostname
,所得结果如下。
通过对比函数执行与命令行下执行的结果可以得知,主机名的确是ubuntu。
时间和日期例程
由UNIX内核提供的基本时间服务是计算自协调世界时(Coordinated Universal Time,UTC)公元1970年1月1日 00:00:00 这一特定时间以来经过的秒数。
time
函数返回当前时间和日期。
#include <time.h>
time_t time(time_t *calptr);
返回值:若成功,返回时间值;若出错,返回-1。
clock_gettime
函数用于获取执行时钟的时间。
#include <sys/time.h>
int clock_gettime(clockid_t clock_id, struct timespec *tsp);
返回值:若成功,返回0;若出错,返回-1。
clock_getres
函数把参数tsp
指向的timespec
结构初始化为与clock_id
参数对应的时钟精度。
#include <sys/time.h>
int clock_getres(clockid_t clock_id, struct timespec *tsp);
返回值:若成功,返回0;若出错,返回-1。
clock_settime
函数对特定精度的时钟设置时间。
#include <sys/time.h>
int clock_settime(clockid_t clock_id, const struct timespec *tsp);
返回值:若成功,返回0;若出错,返回-1。
gettimeofday
函数获取的时间精度要比time
函数更高。
#include <sys/time.h>
int gettimeofday(struct timeval *restrict tp, void *restrict tzp);
返回值:总是返回0。
localtime
函数将日历时间转换成本地时间,而gmtime
则是将日历时间转换成协调统一时间的年、月、日、时、分、秒、周日的分解结构。
#include <time.h>
time_t mktime(struct tm *tmptr);
返回值:若成功,返回日历时间;若出错,返回-1。
strftime
是一个类似于printf
函数的时间值函数。
#include <time.h>
size_t strftime(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr);
size_t strftime_l(char *restrict buf, size_t maxsize, const char *restrict format,
const struct tm *restrict tmptr, locale_t locale);
两个函数的返回值:若有空间,返回存入数组的字符数;否则,返回0。
注意: 较早的函数asctime
和ctime
易受到缓冲区溢出问题的影响,所以现在已被标记为弃用。
strftime_l
允许调用者将区域指定为参数,除此之外,strftime
和strftime_l
函数时相同的。
format
参数控制时间值的格式。如需了解具体的转换说明请查阅《UNIX环境高级编程》中时间和日期例程章节。
测试示例:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
time_t t;
struct tm *tmp;
char buf1[16];
char buf2[64];
time(&t);
tmp = localtime(&t);
if(strftime(buf1, 16, "time and date: %r, %a %b %d, %Y", tmp) == 0)
printf("buffer length 16 is too small\n");
else
printf("%s\n", buf1);
if(strftime(buf2, 64, "time and date: %r, %a %b %d, %Y", tmp) == 0)
printf("buffer length 64 is too small\n");
else
printf("%s\n", buf2);
return 0;
}
结果如下:
strptime
是strftime
函数的反过来的版本,把字符串时间转换成分解时间。
#include <time.h>
char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tmptr);
返回值:指向上次解析的字符的下一个字符的指针;否则,返回NULL。
format
参数的转换说明格式详情请查阅《UNIX环境高级编程》中时间和日期例程章节。
函数localtime
、mktime
和strftime
均受到环境变量TZ
的影响。如果定义了该变量,则这些函数将使用其值代替系统默认时区 ??TZ = TIME ZONE? 。如果TZ
定义为空串,则使用协调统一时间UTC。关于TZ
的详细可命令行执行man 3 tzset
查询。