荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: bstone (Back to real world!), 信区: Hacker
标  题: unix环境高级编程--第6章 系统数据文件和d?**{F*(L?*(p***
发信站: BBS 荔园晨风站 (Wed Mar 29 08:34:38 2000), 转信

发信人: scircle (yuanyuan), 信区: Security
标  题: unix环境高级编程--第6章 系统数据文件和信息
发信站: BBS 水木清华站 (Mon Mar 27 15:52:37 2000)

第六章〓系统数据文件和信息
61〓引言
有很多操作需要使用一些与系统有关的数据文件,例如,口令字文件/etc/passwc
l和组文件
/etc/group就是经常由多种程序使用的两个文件。用户每次登录入Unix系统时,以
及每次执
行ls-l命令时都要使用口令字文件。
由于历史原因,这些数据文件都是ASCII文本文件,并且使用标准I/O库读这些文件
。但是,
对于较大的系统,顺序扫描口令字文件变得很花费时间,我们想以非ASCII文本格
式存放这
些文件,但仍向应用程序提供一个可以处理任何一种文件格式的界面。对于这些数
据文件的
可移植界面是本章的主题。本章也包括了系统标识函数、时间和日期函数。
62〓口令字文件
Unix口令字文件(POSIX1则将其称为用户数据库)包含了图61中所示的各字段,
这些字段
包含在<pwdh>中定义的passwd结构中。
注意,POSIX1只指定passwd结构中7个字段中的5个。另外2个元素由SVR4和43
注意,POSIX1只指定passwd结构中7个字段中的5个。另外2个元素由SVR4和43
+BSD支持
。P146
图61〓/etc/passwd文件中的字段
由于历史原因,口令字文件是/etc/passwd,而且是一个文本文件。每一行包含图
61中所
示的7个字段,字段之间用冒号相分隔。例如,该文件中可能有下列三行:
root:jheVopR58x9Fx:0:1:The superuser:/:/bin/sh
nobody:*:65534:65534::/:
stevens:3hKVD8R58r9Fx:224:20:Richard Stevens:/home/stevens:/bin/ksh
关于这些记录项请注意下列各点:
·通常有一个记录项,其用户名为root。此记录项的用户ID是O(超级用户)。
·密码口令字字段包含了经单向密码单法处理过的用户口令字副本。因为此算法是
单问的,
所以我们不能从密码口令字猜测到原来的口令字。当前使用的算法(见Morris和Th
ompson〔
1979〕)总是产生13个可打印字符(在64字符集〔a-zA-Z0-91〕中)。因为对
用户名no
b
ody的记录的密码口令字段只包含一个字符(*),所以密码口令字决不会与此值相匹
配。此用
户名可用于网络服务器,这些服务器允许我们登录到一个系统,但其用户ID和组I
D(65534)
D(65534)
,并不提供优先权。以此用户ID和组ID我们可存取的文件只是大家都可读、写的文
件。(这
假定用户ID65534和组ID65534并不拥有任何文件。)在本节稍后部分我们将讨论对
口令字文
件最近所作的更改(阴影口令字)。
·在口令字文件记录中的某些字段可能是空。如果密码口令字段为空,这通常就意
味着该用
户没有口令字。(不希望这样做。)nobody记录有两个空白字段:注释字段和初始s
hell字段
。空白注释字段不产生任何影响。空白shell字段则表示取系统默认值,这通常是
/bin/sh。

·支持finger(1)命令的某些Unix系统支持在注释字段中的附加信息。其中,各部
分之间都
用逗号分隔:用户姓名,办公室地点,办公室电话号码,家庭电话号码。另外,如
果在注释
字段中的用户姓名是一个&,则它被代换为登录名。例如,可以有下列记录:

stevens:3hKVD8R58r9Fx:224:20:Richard &,B232,555-1111,555-2222:/home/ste
vens:/bin
/ksh
即使你所使用的系统并不支持finger命令,这些信息仍可存放在注释字段中,因为
即使你所使用的系统并不支持finger命令,这些信息仍可存放在注释字段中,因为
该字段只
是一个注释,并不由系统公用程序解释。
POXIX1只定义了两个存取口令字文件中信息的函数。在给出用户登录名或数值用
户ID后,
这两个函数就能查看相关记录。
#include <sys/typesh>
include <pwdh>
struct passwd *getpwuid(uid 迹茫模*常病絫 uid);
struct passwd *getpwnaw(const char *name);
Both return:pointer if OK,NULL on error
两个函数反回:看成功为指针,出错为NULL
getpwuid由ls(1)程序使用,以便将包含在一个i-node中的数值用户ID映照为用户
登录名。g
etpwnaw在我们键入登录名时由login(1)程序使用。
这两个函数都返回一个指向passwd结构的指针,该结构已由这两个函数在执行时填
入了所需
的信息。此结构通常是在相关函数内的静态变量,只要调用相关函数,其内容就会
被重写。

如果我们要查看的只是一个登录名或一个用户ID,那么这两个POSIX1函数是能满
足要求的
,但是也有些程序要查看整个口令字文件。下列三个函数则可用于此种目的。
即使你所使用的系统并不支持finger命令,这些信息仍可存放在注释字段中,因为
该字段只
是一个注释,并不由系统公用程序解释。
POXIX1只定义了两个存取口令字文件中信息的函数。在给出用户登录名或数值用
户ID后,
这两个函数就能查看相关记录。
#include <sys/typesh>
include <pwdh>
struct passwd *getpwuid(uid 迹茫模*常病絫 uid);
struct passwd *getpwnaw(const char *name);
Both return:pointer if OK,NULL on error
两个函数反回:看成功为指针,出错为NULL
getpwuid由ls(1)程序使用,以便将包含在一个i-node中的数值用户ID映照为用户
登录名。g
etpwnaw在我们键入登录名时由login(1)程序使用。
这两个函数都返回一个指向passwd结构的指针,该结构已由这两个函数在执行时填
入了所需
的信息。此结构通常是在相关函数内的静态变量,只要调用相关函数,其内容就会
被重写。

如果我们要查看的只是一个登录名或一个用户ID,那么这两个POSIX1函数是能满
足要求的
,但是也有些程序要查看整个口令字文件。下列三个函数则可用于此种目的。
,但是也有些程序要查看整个口令字文件。下列三个函数则可用于此种目的。
#include <sys/typesh>
#include <pwdh>
struct passwd *getpwent(void);
Returns:pointer if OK,NULL on error or end of file
返回:看成功为指针,出错或文件尾为NULL
void setpwent(void);
void endpwent(void);
POXIX1没有定义这三个函数,但它们受到SVR4和43+BSD的支持。
调用getpwent时,它返回口令字文件中的下一个记录。如同上面所述的两个POSIX
1函数一
样,它返回一个由它填写好的passwd结构的指针。每次调用此函数时都重写该结构
。在第一
次调用该函数时,它打开它所使用的各个文件。在使用本函数时,对口令字文件中
各个记录
安排的顺序并无要求。
函数setpwent反绕它所使用的文件,endpwent则关闭这些文件。在使用getpwent查
看完了口
令字文件后,一定要调用endpwent关闭这些文件。getpwent知道什么时间它应当打
开它所使
用的文件(第一次被调用时),但是它并不能知道何时关闭这些文件。
实例
程序61示出了函数getpwnam的一个实现。
程序61示出了函数getpwnam的一个实现。
程序61〓getpwent函数
P148
在程序开始处调用setpwent是保护性的措施,以便在调用者在此之前已经调用过g
etpwent的
情况下,反绕有关文件使它们定位到文件开始处。getpwnaw和getpwuid完成后不应
使有关文
件仍处于打开状态,所以应调用endpwent关闭它们。
63〓阴影口令字(Shadow Passwords)
在上面一节我们曾提及,对Unix口令字通常使用的密码算法是单向算法。给出一个
密码口令
字,我们找不到一种算法可以将其反变换到普通文本口令字。(普通文本口令字是
在Passwor
d:提示后键入的口令字。)但是我们可以对口令字进行猜测,将猜测的口令字经单
向算法变
换成密码形成,然后将其与用户的密码口令字相比较。如果用户口令字是随机选择
的,那么
这种方法并不是很有用的。但是用户往往以非随机方式选择口令字(对偶的姓名、
街名、宠
物名等)。一个经常重复的试验是先得到一份口令字文件,然后用试探方法猜测口
令字。(Ga
rfinkel和Spaftord〔1991〕的第二章对Unix口令字及口令字密码处理方案的
历史情况
历史情况
及细节进行了说明。)
为使企图这样做的人难以获得原始资料(密码口令字),某些系统将密码口令字存放
在另一个
通常称为阴影口令字文件中。该文件至少要包含用户名和密码口令字。与该口令字
相关的其
它信息也可存放在该文件中。例如,具有阴影口令字的系统经常要求用户在一定时
间间隔后
选择一个新口令字。这被称之为口令字时效,要选择新口令字的时间间隔长度经常
也存放在
阴影口令字文件中。
在SVR4中,阴影口令文件是/etc/shadow。在43+BSD中,密码口令字存放在/etc
/master
passwd中。
阴影口令字文件不应是一般用户可以读取的。仅有少数几个程序需要存取密码口令
字文件,
例如login(1)和passwd(1),这些程序常常是设置-用户-ID为root。有了阴影口令
字后,普
通口令字文件/etc/passwd可由各用户自由读取。
64〓组文件
Unix组文件(POSIX1称其为组数据库)包含了图62中所示字段。这些字段包含在
<grph>
中所定义的group结构中。
中所定义的group结构中。
P149
图62〓/etc/group文件中的字段
POSIX1只定义了其中3个字段。另一个字段gr 迹茫模*常病絧asswd则由SVR4和
43+BSD
支持。
字段gr-mem是一个指针数组,其中的指针各指向一个属于该组的用户名。该数组以
空指针(n
ull)结尾。
我们可以用下列两个由posix1定义的函数来查看组名或数值组I。
#include <sys/typesh>
#include <grph>
struct group *getgrgid(gid 迹茫模*常病絫 gid);
struct group *getgrnam(const char *name);
Both return:pointer if OK,NULL on error两个函数返回:若成功为指针,出错
为NULL
如同对口令字文件进行操作的函数一样,这两个函数通常也返回指向一个静态变量
的指针,
在每次调用时都重写该静态变量。
如果需要搜索整个组文件,则须使用另外几个函数。下列三个函数类似于针对口令
字文件的
三个函数。
#include <sys/typesh>
#include <sys/typesh>
#include <grph>
struct group *getgrent(void);
Returns:Pointer if OK,NULL on error or end of file
返回:若成功为指针,出错或文件尾为NULL
void setgrent(void);
void endgrent(void);
这三个函数由SVR4和43+BSD提供POSIX1并末定义这些函数。
setgrent打开组文件(如若它尚末被打开)并反绕它。getgrent从组文件中读下一个
记录,如
若该文件尚末打开则先打开它。endgrent关闭组文件。
65〓添加组ID
在Unix中,组的使用已经作了些更改。在Version7中,每个用户任何时候都只属于
一个组。
当用户登录时,系统就按口令字文件中与其相关记录中的数字组ID,赋给他实际组
ID。我们
可以在任何时候执行newgrp(1)以更改组ID。如果newgrp命令执行成功(关于许可权
规则,请
参阅手册页。),则我们的实际组ID就更改为新的组ID,它将被用于后续的文件存
取许可权
检查。执行不带任何参数的newgrp,则可返回到原来的组。
这种组的成员关系一直维持到1983年左右。此时,42BSD引入了添加组ID的概念
。我们不
#include <sys/typesh>
#include <grph>
struct group *getgrent(void);
Returns:Pointer if OK,NULL on error or end of file
返回:若成功为指针,出错或文件尾为NULL
void setgrent(void);
void endgrent(void);
这三个函数由SVR4和43+BSD提供POSIX1并末定义这些函数。
setgrent打开组文件(如若它尚末被打开)并反绕它。getgrent从组文件中读下一个
记录,如
若该文件尚末打开则先打开它。endgrent关闭组文件。
65〓添加组ID
在Unix中,组的使用已经作了些更改。在Version7中,每个用户任何时候都只属于
一个组。
当用户登录时,系统就按口令字文件中与其相关记录中的数字组ID,赋给他实际组
ID。我们
可以在任何时候执行newgrp(1)以更改组ID。如果newgrp命令执行成功(关于许可权
规则,请
参阅手册页。),则我们的实际组ID就更改为新的组ID,它将被用于后续的文件存
取许可权
检查。执行不带任何参数的newgrp,则可返回到原来的组。
这种组的成员关系一直维持到1983年左右。此时,42BSD引入了添加组ID的概念
。我们不
P 迹茫模*常病組AX为0,则返回0,这并不表示出错。
#include <sys/typesh>
#include <unistdh>
int getgroups(int gidsetsize,gid 迹茫模*常病絫 grouplist[]);

Returns:number of supplementary group IDs if OK,-1 on error
int setgroups(int ngroups,const gid 迹茫模*常病絫 grouplist[]
);
int initgroups(const char *username,gid 迹茫模*常病絫 basegid);

两个函数返回:若成功为0,出错为-1
Both return:0 if OK,-1 on error
作为一种特殊情况,如若giclsetsize为0,则函数只返回添加组ID数,而对数组g
rouplist
则不作修改。(这使调用者可以确定grouplist数组的长度,以便进行分配。)
setgroups可由超级用户调用以便为调用进程设置添加组ID表。grouplist,是组I
D数组,而
ngroups说明了数组中的元素数。
通常,只有initgroups函数调用setgroups,initgroups读整个组文件(用函数getg
rent,setg
rent和endgrent),然后对username确定其组的成员关系。然后,它调用setgroup
s,以便为
该用户初始化添加组ID表。因为initgroups调用setgroups,所以只有超级用户才能
该用户初始化添加组ID表。因为initgroups调用setgroups,所以只有超级用户才能
调用init
groups。除了在组文件中找到username是成员的组,initgroups也在添加组ID表中
包括了ba
segid。basegid是username在口令字文件中的组ID。
initgroups只有少数几个程序调用,例如login(1)程序在用户登录时调用该函数。

66〓其它数据文件
至此我们讨论了两个系统数据文件-口令字文件和组文件。在日常事务操作中,Un
ix系统还
使用很多其它文件。例如,BSD网络软件有一个记录各网络服务器所提供的服务的
数据文件(
/etc/services),有一个记录协议信息是数据文件(/etc/protocols),还有一个则
是记录网
络信息的数据文件(/etc/networks)。幸运的是,对于这些数据文件的界面都与上
述对口令
字文件和组文件的相似。
一般原理是,每个数据文件至少有三个函数:
1 get函数;读下一个记录,如果需要还打开该文件。此种函数通常返回指向一
个结构的
指针。当已达到文件尾端时返回空指针。大多数get函数返回指向一个静态存储类
结构的指
针,如果要保存其内容,则需复制它。
该用户初始化添加组ID表。因为initgroups调用setgroups,所以只有超级用户才能
调用init
groups。除了在组文件中找到username是成员的组,initgroups也在添加组ID表中
包括了ba
segid。basegid是username在口令字文件中的组ID。
initgroups只有少数几个程序调用,例如login(1)程序在用户登录时调用该函数。

66〓其它数据文件
至此我们讨论了两个系统数据文件-口令字文件和组文件。在日常事务操作中,Un
ix系统还
使用很多其它文件。例如,BSD网络软件有一个记录各网络服务器所提供的服务的
数据文件(
/etc/services),有一个记录协议信息是数据文件(/etc/protocols),还有一个则
是记录网
络信息的数据文件(/etc/networks)。幸运的是,对于这些数据文件的界面都与上
述对口令
字文件和组文件的相似。
一般原理是,每个数据文件至少有三个函数:
1 get函数;读下一个记录,如果需要还打开该文件。此种函数通常返回指向一
个结构的
指针。当已达到文件尾端时返回空指针。大多数get函数返回指向一个静态存储类
结构的指
针,如果要保存其内容,则需复制它。
针,如果要保存其内容,则需复制它。
2 set函数:打开相应数据文件(如果尚末打开),然后反绕该文件。如果希望在
相应文件
起始处开始处理,则调用此函数。
3 end函数:关闭相应数据文件。正如前述,在结束了对相应数据文件的读、写
操作后,
总应调用此函数以关闭所有相关文件。
另外,如果数据文件支持某种形式的关键字搜寻,则也提供搜寻具有指定关键字的
记录的例
程。例如,对于口令字文件提供了两个按关键字进行搜寻的程序:getpwnam寻找具
有指定用
户名的记录;getpwuid寻找具有指定用户ID的记录。
图63中列出了一些这样的例程,这些都是SVR4和43+BSD支持的。在图中列出了
针对口令
字文件和组文件的函数,这些已在上面说明过。图中也列出了一些与网络有关的函
数。对图
中列出的所有数据文件都有get、set和end函数。
在SVR4中,图63中最后四个数据文件都是符号连接,连接到目录/e6tc/inet下的
同名文件
上。
SVR4和43+BSD都有类似于图中所列的附加函数,但是这些附加函数都处理系统管
理文件,
专用于各个实现。
通过该函数的参数向其传递一个utsname结构的地址,然后该函数填写此结构。PO
SIX1只
定义了该结构中最少需要的字段(它们都是字符数组),而每个数组的长度则由实现
确定。某
些实现在该结构中提供了另外一些字段。在历史上,系统V为每个数组分配9个字节
,其中有
1个字节用于字符串结束符(null字符)。
struct utsname {
char sysname[9];  /*name of the operating system */操作系统名
char nodename[9];  /* name of this node */ 此节点名
char release[9];  /*current release of operating system */操作系统当前
发行版
char version[9];  /*current version of this release */此发行版的当前版

char machine[9];  /*name of hardware type */硬件类型名
};
在utsname结构中的信息通常可用uname(1)命令打印。
POSIX1警告:nodename元素可能并不适用于在一通信网络上引用宿主机。此函数
来自于系
统V,在较早时期,nodename元素适用于在UUCP网络上引用主机。
也应理解在此结构中并没有给出有关POSIX1版本的信息。这应当使用252节
中所说明
的 迹茫模*常病絇OSIX 迹茫模*常病絍ERSION以获得该信息。最后,此函数给出
的 迹茫模*常病絇OSIX 迹茫模*常病絍ERSION以获得该信息。最后,此函数给出
了一种存
取该结构中信息的方法,至于
如何初始化这些信息,POSIX1没有作任何说明。大多数系统V版本在构造系统核
时通过编
译将这些信息存放在系统核中。
贝克莱类的版本提供gethostname函数,它只返回宿主机名。这通常就是在TCP/IP
网上该宿
主机的名字。
#include <unistdh>
int gethostname(char *name,int namelen);
Returns:0 if OK,-1 on error返回:若成功为0,出错为-1
通过name返回的字符串以null符结尾(除非没有提供足够的空间)。<sys/paramh
>中的常数
MAXHOSTNAMELEN规定了此名字的最大长度(通常是64字节)。如果该宿主机联到TCP
/IP网,则
此宿主机名通常是该宿主机的完整的域名。
hostname(1)命令可用来存取和设置宿主机名。(超级用户用一个类似的函数setho
stname来
设置宿主机名。)宿主机名通常在系统自举时设置,它由/etc/rc取自一个启动文件
。
虽然此函数是贝克莱所特有的,但是,SVR4作为BSD兼容性软件包的一部分提供ge
tbostname
的 迹茫模*常病絇OSIX 迹茫模*常病絍ERSION以获得该信息。最后,此函数给出
了一种存
取该结构中信息的方法,至于
如何初始化这些信息,POSIX1没有作任何说明。大多数系统V版本在构造系统核
时通过编
译将这些信息存放在系统核中。
贝克莱类的版本提供gethostname函数,它只返回宿主机名。这通常就是在TCP/IP
网上该宿
主机的名字。
#include <unistdh>
int gethostname(char *name,int namelen);
Returns:0 if OK,-1 on error返回:若成功为0,出错为-1
通过name返回的字符串以null符结尾(除非没有提供足够的空间)。<sys/paramh
>中的常数
MAXHOSTNAMELEN规定了此名字的最大长度(通常是64字节)。如果该宿主机联到TCP
/IP网,则
此宿主机名通常是该宿主机的完整的域名。
hostname(1)命令可用来存取和设置宿主机名。(超级用户用一个类似的函数setho
stname来
设置宿主机名。)宿主机名通常在系统自举时设置,它由/etc/rc取自一个启动文件
。
虽然此函数是贝克莱所特有的,但是,SVR4作为BSD兼容性软件包的一部分提供ge
tbostname
tbostname
和setbostname函数,以及hostname命令。SVR4也将MAXHOSTNAMELEN扩充为256字节
。
69〓时间和日期例程
由Unix系统核提供的基本时间服务是国际标准时公元197011 00:00:00以来
经过的秒
数。在110节中曾提及这种秒数是以数据类型time-t表示的。我们称它们为日历
时间。日
历时间包括时间和日期。Unix在这方面与其它操作系统的区别是(a)以国际标准时
而非本地
时间计时,(b)可自动进行转换,例如变换到夏日制,(c)将时间和日期作为一个量
值保存。
time函数返回当前时间和日期。
#include <timeh>
time 迹茫模*常病絫 time(time 迹茫模*常病絫 *calptr);
Returns:value of time if OK,-1 on error 返回:若成功为时间值,出错为-1

时间值作为函数值返回。如果参数是非null,则时间值也存放在由calptr指向的单
元内。
在很多贝克莱类的系统中,time(3)只是一个函数,它调用gettime of day(2)系统
调用。
在SVR4中调用stime(2)函数,在贝克莱类的系统中调用settime of day(2)对系统
核中的当
核中的当
前时间设置初始值。
与time和stime函数相比,BSD的gettime of day和settime of day提供了更高的分
辨率(微
秒级)。这对某些应用是很重要的。
一旦取得这种以秒计的很大的时间值后,通常要调用另一个时间函数将其变换为人
们可读的
时间和日期。图64说明了各种时间函数之间的关系。(图中以虚线表示的四个函
数localti
me、mktime、ctime和strftime都受到环境变量TZ的影响。我们将在本节的最后部
分对其进
行说明。)
P156
图64〓各个时间函数之间的关系
两个函数localtime和gmtime将日历时间变换成以年、月、日、时、分、秒、周日
表示的时
间,将这些存放在一个tm结构中。
struct tm {  /* a broken-down time */ 以年、月、日、时、分、秒表示的时间

int tm 迹茫模*常病絪ec;  /* seconds after the minute:[0,61] */秒[0
,61]
int tm 迹茫模*常病絤in;  /* minutes after the hour:[0,59] */分[0
,59]
,59]
int tm 迹茫模*常病絟our; /* hours after midnight:[0,23] */时[0,
23]
int tm 迹茫模*常病絤day; /* day of the month:[1,31] */日[1,31]

int tm 迹茫模*常病絤on; /* month of the year:[0,11] */月[0,11]

int tm 迹茫模*常病統ear; /* years since 1900 */ 1900后的年
int tm 迹茫模*常病絯day; /* days since Sunday:[0,6] */①星期几[0,
6]
int tm 迹茫模*常病統day; /* days since January 1:[0,365] */②自1月1日
经过的天
数[0,365]
int tm 迹茫模*常病絠sdst; /* daylight saving time flag:<0,0,>0 */③夏日
制时间标
志:<0,0,>0
};
秒可以超过59的理由是可以表示润秒。注意,除了月日字段,其它字段的值都以0
开始。如
果夏日制生效,则夏日制标志值为正,如果已非夏日制时间则为零,如果此信息不
可用,则
为负。
#include <timeh>
#include <timeh>
struct tm *gmtime(const time 迹茫模*常病健t—?calptr);
struct tm *localtime(const time 迹茫模*常病絫 *calptr);
Both return:pointer to broken-down time
两个函数返回:指向tm结构的指针
localtime和gmtime之间的区别是:localtime将日历时间变换成本地时间(考虑到本
地时区和
夏日制标志),而gmtime则将日历时间变换成国际标准时的年、月、日、时、分、
秒、周日
。
函数mktime以本地时间的年、月、日等作为参数,将其变换成time-t值。
#include <timeh>
time 迹茫模*常病絫 mktime(struct tm *tmptr); 返回:若成功为日历时间
,出错为
-1
asctime和ctime函数产生下列形式的26字节字符串,这与date(1)命令的系统默认
输出形式
类似:
Tue Jan 14 17:49:03 1992\n\0
#include <timeh>
char *asctime(const struct tm *tmptr);
char *ctime(const time 迹茫模*常病絫 *calptr);
两个函数返回:指向null结尾的字符串
号。与printf函数的不同之处是,每个变换说明产生一个定长输出字符串,在for
mat字符串
中没有字段宽度修饰符。图65中列出了21种ANSIC规定的变换说明。
P158
图65〓strftime
图中第三列的数据来自于在SVR4上,对应于下列时间和日期,执行strftime函数所
得的结果
。
Tue〓Jan〓14〓19:40〓MST〓1992
图65中的大多数格式说明的意义是很明显的。需要略作解释的是%U和%W。%U是相
应日期在
该年中所属因数,包含该年中第一个星期日的周是第一周。%W也是相应日期在该年
中所属的
周数,不同的是包含第一个星期一的周为第一周。
SVR4和43+BSD都对strftime的格式字符串提供另一些扩充支持。
我们曾在前面提及,图64中以虚线表示的四个函数受到环境变量TZ的影响。这四
个函数是
:localtime,mktime,ctime和strftime。如果定义了TZ,则这些函数将使用其值以
代替系统
默认时区。如果TZ定义为空串(亦即TZ=),则使用国际标准时。TZ的值常常类似于
TZ=EST5ED
T,但是POSIX1允许更详细的说明。有关TZ的详细情况请参阅POSIX1标准[IE
EE 1990]
号。与printf函数的不同之处是,每个变换说明产生一个定长输出字符串,在for
mat字符串
中没有字段宽度修饰符。图65中列出了21种ANSIC规定的变换说明。
P158
图65〓strftime
图中第三列的数据来自于在SVR4上,对应于下列时间和日期,执行strftime函数所
得的结果
。
Tue〓Jan〓14〓19:40〓MST〓1992
图65中的大多数格式说明的意义是很明显的。需要略作解释的是%U和%W。%U是相
应日期在
该年中所属因数,包含该年中第一个星期日的周是第一周。%W也是相应日期在该年
中所属的
周数,不同的是包含第一个星期一的周为第一周。
SVR4和43+BSD都对strftime的格式字符串提供另一些扩充支持。
我们曾在前面提及,图64中以虚线表示的四个函数受到环境变量TZ的影响。这四
个函数是
:localtime,mktime,ctime和strftime。如果定义了TZ,则这些函数将使用其值以
代替系统
默认时区。如果TZ定义为空串(亦即TZ=),则使用国际标准时。TZ的值常常类似于
TZ=EST5ED
T,但是POSIX1允许更详细的说明。有关TZ的详细情况请参阅POSIX1标准[IE
EE 1990]
EE 1990]
的811节,SVR4 environ(5)手册页[A T&T 1990e],或43+BSD ctime(3)手
册页。
本节所述的所有时间和日期函数都是由ANSIC标准定义的。在此基础上,POSIX1
只增加了
环境变量TZ。
图64中七个函数中的五个可以回溯到Version7(或更早),它们是:time、local
time、gmt
ime、asctime和ctime。在Unix时间功能方面近期所作的增加大多是处理非US时区
以及夏日
制的更改规则。
610〓摘要
在所有Unix系统上都使用口令字文件和组文件。我们说明了各种读这些文件的函数
。我们也
介绍了阴影口令字,它可以增加系统的安全性。添加组ID正在得到更多应用,它提
供了一个
用户同时可以参办多个组的方法。我们也介绍了大多数系统所提供的存取其它与系
统有关的
数据文件的类似的函数。最后,我们说明了ANSIC和POSIX1提供的与时间和日期
有关的一些函数。

--
※ 来源:·BBS 水木清华站 smth.org·[FROM: 162.105.8.213]

--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: bbs@192.168.28.23]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店