UNIX环境高级编程——系统数据文件和信息

news2025/1/23 13:16:40

6.1 引言

UNIX系统的正常运行需要使用大量与系统有关的数据文件,这些文件都是ASCII文本文件,并且使用标准I/O库读这些文件。

6.2 口令文件

UNIX口令文件是/etc/passwd,每一行包含下图中的各字段,字段之间用冒号分隔,这些字段包含在<pwd.h>中定义的passwd结构中。
在这里插入图片描述
两个获取口令文件项的函数:

#include <pwd.h>

struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
										// 两个函数返回值:若成功,返回指针;若出错,返回NULL
  • 这两个函数都返回一个指向passwd结构的指针,该结构已由这两个函数在执行时填入信息;
  • passwd结构通常是函数内部的静态变量,只要调用任一相关函数,其内容就会被重写。
/* The passwd structure.  */
struct passwd
{
  char *pw_name;		/* Username.  */
  char *pw_passwd;		/* Password.  */
  __uid_t pw_uid;		/* User ID.  */
  __gid_t pw_gid;		/* Group ID.  */
  char *pw_gecos;		/* Real name.  */
  char *pw_dir;			/* Home directory.  */
  char *pw_shell;		/* Shell program.  */
};

下列3个函数用于查看整个口令文件:

#include <pwd.h>

struct passwd *getpwent(void);
										// 返回值:若成功,返回指针;若出错或到达文件尾端,返回NULL
void setpwent(void);
void endpwent(void);
  • getpwent函数返回口令文件中的下一个记录项;
  • setpwent函数用来将getpwent函数的读写地址指向密码文件开头;
  • endpwent函数关闭这些文件,在使用getpwent函数查看完口令文件后,一定要调用endpwent关闭这些文件。

6.3 阴影口令

  • 加密口令是经单向加密算法处理过的用户口令副本,不能从加密口令猜测到原来的口令;
  • 系统将加密口令存放在阴影口令文件(/etc/shadow)中,该文件的主要内容包括如下内容,其中用户登录名加密口令是必需的:
    在这里插入图片描述

下面一组函数用于访问阴影口令文件:

#include <shadow.h>

struct spwd *getspnam(const char* name);
struct spwd *getspent(void);
										// 两个函数返回值:若成功,返回指针;若出错,返回NULL
void setspent(void);
void endspent(void);

6.4 组文件

UNIX组文件(/etc/group)包含下图所示字段,这些字段包含在<grp.h>中所定义的group结构中:
在这里插入图片描述

  • 字段gr_mem是一个指针数组,其中每个指针指向一个属于该组的用户名,该数组以null指针结尾。

可以用下列两个函数来查看组名或数值组ID:

#include <grp.h>

struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
										// 两个函数返回值:若成功,返回指针;若出错,返回NULL
  • 这两个函数返回一个指向静态变量的指针,在每次调用时都重写该静态变量。

下列3个函数用于搜索整个组文件:

#include <grp.h>

struct group *getgrent(void);
										// 返回值:若成功,返回指针;若出错或到达文件尾端,返回NULL
void setgrent(void);
void endgrent(void);
  • setgrent函数打开组文件(如若它尚未打开)并反绕它;
  • getgrent函数从组文件中读下一个记录,如若该文件尚未打开,则先打开它;
  • endgrent函数关闭组文件。

6.5 附属组ID

下面3个函数用于获取和设置附属组ID:

#include <unistd.h>
int getgroups(int gidsetsize, gid_t grouplist[]);
										// 返回值:若成功,返回附属组ID数量;若出错,返回-1

#include <grp.h>	/* on Linux */
#include <unistd.h>	/* on FreeBSD, Mac OS X, and Solaris */
int setgroups(int ngroups, const gid_t grouplist[]);

#include <grp.h>	/* on Linux and Solaris */
#include <unistd.h>	/* on FreeBSD and Mac OS X */
int initgroups(const char *username, gid_t basegid);
										// 两个函数的返回值:若成功,返回0;若出错,返回-1
  • getgroups将进程所属用户的各附属组ID填写到数值grouplist中,填写入该数组的附属组ID数最多为gidsetsize个;实际填写到数组中的附属组ID数由函数返回,若gidsetsize0,则函数只返回附属组ID数,而对数组grouplist则不做修改;
  • setgroups由超级用户调用来为调用进程设置附属组ID表,grouplist是组ID数组,而ngroups说明数组中的元素数,ngroups的值不能大于NGROUPS_MAX
  • initgroups函数调用setgroups,它先读整个组文件,对username确定其组的成员关系;然后,它调用setgroups,为该用户初始化附属组ID表;除了在组文件中找到username的所有组,initgroups也在附属组ID表中包含了basegidbasegidusername在口令文件中的组ID。

6.6 实现区别

6.7 其他数据文件

在这里插入图片描述
一般情况下,对于每个数据文件至少有3个函数:

  • get函数:读下一个记录,如果需要,还会打开该文件。此种函数通常返回指向一个结构的指针。当已达到文件尾端时返回空指针。大多数get函数返回指向一个静态存储类结构的指针,如果要保存其内容,则需复制它;
  • set函数:打开相应数据文件(如果尚未打开),然后反绕该文件。如果希望在相应文件起始处开始处理,则调用此函数;
  • end函数:关闭相应数据文件。在结束了对相应数据文件的读、写操作后,总应调用此函数以关闭所有相应文件。

6.8 登录账户记录

6.9 系统标识

uname函数返回与主机和操作系统有关的信息:

#include <sys/utsname.h>

int uname(struct utsname *name);
										// 返回值:若成功,返回非负值;若出错,返回-1
  • 该函数的参数是一个utsname结构的地址,其内容由函数填写。

gethostname函数只返回主机名,该名字通常就是TCP/IP网络上主机的名字:

#include <unistd.h>

int gethostname(char *name, int namelen);
										// 返回值:若成功,返回0;若出错,返回-1
  • namelen参数指定name缓冲区长度,如若提供足够的空间,则通过name返回的字符串以null字节结尾;如若没有提供足够的空间,则没有说明通过name返回的字符串是否以null结尾;
  • 最大主机名长度是HOST_NAME_MAX

6.10 时间和日期例程

UNIX内核提供的基本时间服务是计算自协调世界时(Coordinated Universal Time,UTC)公元1970年1月1日00:00:00这一特定时间以来经过的秒数,这种秒数是以数据类型time_t表示的,称为日历时间,日历时间包括时间日期

time函数返回当前时间和日期:

#include <time.h>

time_t time(time_t *calptr);
										// 返回值:若成功,返回时间值;若出错,返回-1
  • 时间值作为函数返回;
  • 如果参数非空,则时间值也存放在由calptr指向的单元内。

POSIX.1的实时扩展增加了对多个系统时钟的支持,时钟通过clockid_t类型进行标识,下图给出了标准值:
在这里插入图片描述

clock_gettime函数用于获取指定时钟的时间,返回的时间在timespec结构中,它把时间表示为纳秒

struct timespec {
	__kernel_time_t	tv_sec;			/* seconds */
	long		tv_nsec;		/* nanoseconds */
};
#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函数获取当前时间:

#include <sys/time.h>

int gettimeofday(struct timeval *restrict tp, void *restrict tzp);
										// 返回值:总是返回0
  • gettimeofday函数以距特定时间(1970年1月1日00:00:00)的秒数的方式将当前时间存放在tp指向的timeval结构中,而该结构将当前时间表示为微秒
/* A time value that is accurate to the nearest
   microsecond but also has a range of years.  */
struct timeval
{
  __time_t tv_sec;		/* Seconds.  */
  __suseconds_t tv_usec;	/* Microseconds.  */
};

一旦取得这种从上述特定时间经过的秒数的整型时间值后,通常需要调用函数将其转换成分解的时间结构,然后调用另一个函数生成人们可读的时间和日期,各种时间函数之间的关系如下:
在这里插入图片描述
localtimegmtime将日历时间转换成分解的时间,并将这些存放在一个tm结构中:

/* ISO C `broken-down time' structure.  */
struct tm
{
  int tm_sec;			/* Seconds.	[0-60] (1 leap second) */
  int tm_min;			/* Minutes.	[0-59] */
  int tm_hour;			/* Hours.	[0-23] */
  int tm_mday;			/* Day.		[1-31] */
  int tm_mon;			/* Month.	[0-11] */
  int tm_year;			/* Year	- 1900.  */
  int tm_wday;			/* Day of week.	[0-6] */
  int tm_yday;			/* Days in year.[0-365]	*/
  int tm_isdst;			/* DST.		[-1/0/1]*/

# ifdef	__USE_MISC
  long int tm_gmtoff;		/* Seconds east of UTC.  */
  const char *tm_zone;		/* Timezone abbreviation.  */
# else
  long int __tm_gmtoff;		/* Seconds east of UTC.  */
  const char *__tm_zone;	/* Timezone abbreviation.  */
# endif
};
#include <time.h>

struct tm *gmtime(const time_t *calptr);
struct tm *localtime(const time_t *calptr);
										// 两个函数的返回值:指向分解的tm结构的指针;若出错,返回NULL
  • localtime将日历时间转换成本地时间(考虑到本地时区和夏时令标志);
  • gmtime将日历时间转换成协调统一时间的年、月、日、时、分、秒、周日分解结构。

mktime以本地时间的年、月、日等作为参数,将其变换成time_t值:

#include <time.h>

time_t mktime(struct tm *tmptr);
										// 返回值:若成功,返回日历时间;若出错,返回-1

strftime函数通过可用的多个参数来定制产生的字符串:

#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
  • strftime_l允许调用者将区域指定为参数,除此之外,strftimestrftime_l函数是相同的,strftime使用通过TZ环境变量指定的区域;
  • tmptr参数是要格式化的时间值,由一个指向分解时间值tm结构的指针说明;
  • 格式化结果存放在一个长度为maxsize个字符的buf数组中,如果buf长度足以存放格式化结果及一个null终止符,则该函数返回在buf中存放的字符数(不包括null终止符),否则该函数返回0
  • format参数控制时间值的格式,其转换说明如下:
    在这里插入图片描述
    strptime函数是strftime的反过来版本,把字符串时间转换成分解时间:
#include <time.h>

char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tmptr);
										// 返回值:指向上次解析的字符的下一个字符的指针;否则,返回NULL
  • format参数给出了buf参数指向的缓冲区内字符串的格式,其转换说明如下:
    在这里插入图片描述

6.11 实例代码

chapter6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/413895.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

除了Jira、禅道还有哪些更好的敏捷开发过程管理平台?

无论是从国内的敏捷调研开发调研报告还是从国外的敏捷状态调查&#xff0c;工具支持一直是决定敏捷成功的关键因素之一&#xff0c;它们可以帮助团队提高软件开发的效率、质量、协作和满意度。选择合适的敏捷开发管理工具&#xff0c;并正确地使用它们&#xff0c;是每个敏捷团…

JAVA SMART系统-系统框架设计与开发

SMART系统是一个新型智能在线考试信息管理系统&#xff0c;该系统主要实现了学生在线考试与评估以及教师对学生在线考试信息的管理和维护。本文按照SMART系统的非功能性需求&#xff0c;基于Struts、Spring、Hibernate三种开源技术&#xff0c;构建了一个具有良好的可扩展性、可…

英文译中文翻译-中文英文翻译在线翻译

如果您需要在线翻译英文文本为汉字&#xff0c;您可以使用各种在线翻译服务或应用程序。以下是一些您可以尝试的在线翻译服务&#xff1a; Google翻译&#xff1a; Google翻译是一款广受欢迎的在线翻译服务&#xff0c;可将英语文本翻译成汉字。只需将需要翻译的英文文本复制粘…

MFC动态库封装

1.MVC的设计模式的使用 经典MVC模式中&#xff0c;M是指业务模型&#xff0c;V是指用户界面&#xff0c;C则是控制器&#xff0c;使用MVC的目的是将M和V的实现代码分离&#xff0c;从而使同一个程序可以使用不同的表现形式。其中&#xff0c;View的定义比较清晰&#xff0c;就…

自动化面试题4

1、工业中常见的通信方式都有哪些&#xff0c;各自特点是什么&#xff1f; 2、对于一台新的伺服驱动器来说&#xff0c;需要设置哪几个方面的参数&#xff1f; &#xff08;1&#xff09;参数初始化 &#xff08;2&#xff09;点动测试电机旋转方向 &#xff08;3&#xff09;惯…

神经网络/深度学习(二)

Seq2Seq 模型 Encoder-Decoder Attention 机制 Self-Attention 自注意力机制 Transformer 摘文不一定和目录相关&#xff0c;但是取自该链接 1. Seq2Seq 模型详解 https://baijiahao.baidu.com/s?id1650496167914890612&wfrspider&forpc Seq2Seq 是一种循环神经网…

云原生——容器技术docker基础命令

前言&#xff1a; &#x1f44f;作者简介&#xff1a;我是笑霸final&#xff0c;一名热爱技术的在校学生。 &#x1f4dd;个人主页&#xff1a;个人主页1 || 笑霸final的主页2 &#x1f4d5;系列专栏云原生专栏 &#x1f4e7;如果文章知识点有错误的地方&#xff0c;请指正&…

d2l语言模型--生成小批量序列

对语言模型的数据集处理做以下汇总与总结 目录 1.k元语法 1.1一元 1.2 二元 1.3 三元 2.随机抽样 2.1各bs之间随机 2.2各bs之间连续 3.封装 1.k元语法 1.1一元 tokens d2l.tokenize(d2l.read_time_machine()) # 因为每个⽂本⾏不⼀定是⼀个句⼦或⼀个段落&#xff0…

认识C++指针

目录 前言&#xff1a; 1.指针未初始化的危险性 2.指针与十六进制数字 3.使用new分配内存空间 4.使用delete释放内存 5.使用new来创建动态数组 6.使用动态数组 7.指针运算 前言&#xff1a; 期待已久的指针篇来啦&#xff0c;这篇全都是有关指针的知识&#xff0c;喜欢…

【Matlab算法】粒子群算法求解二维线性优化问题(附MATLAB代码)

MATLAB求解二维线性优化问题前言正文函数实现可视化结果前言 二维线性优化问题指的是在二维空间中&#xff0c;对于一个由线性函数构成的目标函数&#xff0c;通过限制自变量的范围或满足特定的约束条件&#xff0c;寻找一个最优解&#xff08;最小值或最大值&#xff09;。这…

【精华】表格结构识别模型研究进展

表格结构识别模型研究进展 合合信息&#xff1a;表格识别与内容提炼技术理解及研发趋势 OCR之表格结构识别综述 表格识别技术综述 用于表检测和结构识别的深度学习&#xff1a;综述 &#xff08;1&#xff09;PP-Structure 速度提升11倍&#xff0c;一键PDF转Word PP-St…

MATLAB | 这些各种各样的花里胡哨的折线填充图咋画

这些各种各样的花里胡哨的折线填充图咋画&#xff1f; 折线下面填充纯色的话area函数很容易做到&#xff0c;但上面那些各种花里胡哨的填充图就没那么容易做到了&#xff0c;本期就来讲讲这些玩意都是咋画的&#xff1a; 事先说明&#xff0c;为了绘图好看本文绝大多数图像都使…

Vue3步骤条(Steps)

Vue2步骤条&#xff08;Steps&#xff09; 可自定义设置以下属性&#xff1a; 步骤数组&#xff08;steps&#xff09;&#xff0c;类型&#xff1a;Array<{title?: string, description?: string}>&#xff0c;默认 [] 当前选中的步骤&#xff0c;设置 v-model 后&a…

Java13-多线程

一&#xff1a;基本概念&#xff1a;程序&#xff0c;进程&#xff0c;线程 程序&#xff1a; 是完成特定任务&#xff0c;用某种语言编写的一组指令集合&#xff0c;即指一段静态的代码。 进程&#xff1a;是程序的一次执行过程&#xff0c;或是正在运行的一个程序。 线程&…

Linux系统之MobaXterm远程连接centos的GNOME桌面环境

Linux系统之MobaXterm远程连接centos的GNOME桌面环境一、MobaXterm介绍1.MobaXterm简介2.MobaXterm功能特点二、centos安装GNOME桌面1.本地环境介绍2.安装GNOME桌面环境3.本地进入Linux桌面三、MobaXterm远程连接centos1.打开MobaXterm软件2.远程连接本地Linux系统四、远程连接…

如何利用ChatGPT辅助优化刷题性能

根据土著刷题共建群里的一个小伙伴反馈&#xff0c;刷题会出现切题卡顿的情况&#xff0c;有时会出现滑不动的情况。 定位问题 为了定位切题卡顿问题的具体原因&#xff0c;测试了高低端手机&#x1f4f1;、切换2G、3G、4G低网络状态等各种影响切题的现实情况&#xff0c;经过借…

门店零售系统有哪些功能模块?能带来哪些帮助?

门店零售系统是一种用于管理门店销售、库存、采购等业务的软件系统&#xff0c;可以帮助门店提高管理效率、降低操作风险、优化运营决策&#xff0c;从而增强市场竞争力和顾客满意度。 一、门店零售系统的4大功能 1、商品管理 该模块主要用于管理门店的商品信息&#xff0c;包…

arcgis中地理配准之栅格平移

背景 前面写过一篇文章,是针对有两个对应的栅格数据进行配准的 Arcgis地理配准栅格数据 有时候需要没有对应的栅格数据,只有单幅栅格数据,而且知道平移参数,这时候可以通过平移参数来平移栅格,而且在unity中不能直接识别坐标值很大的数据,只能通过平移将坐标值减少,才…

【分布式事务AT模式 SpringCloud集成Seata框架】分布式事务框架Seata详细讲解

前言 上篇文章我们讲述了如何启动seata的本地服务&#xff0c;并且注册到nacos使用&#xff0c;这篇文章将在SpringCloud中整合Seata框架 上篇文章传送门&#xff1a;https://blog.csdn.net/Syals/article/details/130102851?spm1001.2014.3001.5501 本篇主要内容&#xff…

Docker几个概念

Docker几个概念&#xff0c;有不正确地方欢迎指正 一、首先来看一句话&#xff1a;没有Cgroups就没有LXC&#xff0c;没有LXC就没有Docker。 1、什么是Cgroup呢&#xff1f;Cgroup又名Control group&#xff0c;是Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理…