《unix环境高级编程》 读书笔记 (4)

近来读书,做些笔记,来年好翻翻。

本文所使用的操作系统为 CentOS7.0,如果不想装双系统的可以装虚拟机,可以参考这里:

http://blog.csdn.net/alex_my/article/details/38142229

system data files and infomation


1 password file

终端上输入cat /etc/passwd

可以看见很多相关信息。

也可以通过以下函数:

#include <sys/types.h>

#include <pwd.h>

struct passwd* getpwnam(const char* name);

struct passwd* getpwuid(uid_t uid);

int getpwnam_r(const char* name, struct passwd* pwd, char* buf, size_t buflen, struct passwd** result);

int getpwuid_r(uid_t uid, struct passwd* pwd, char* buf, size_t buflen, struct passwd** result);

结构体passwd(<pwd.h>):

struct passwd

{

char*     pw_name;       /* username */

char*     pw_passwd;     /* user password */

uid_t     pw_uid;        /* user ID */

gid_t     pw_gid;        /* group ID */

char*     pw_gecos;      /* user information */

char*     pw_dir;        /* home directory */

char*     pw_shell;      /* shell program */

};

如果不能理解每个成员的意思,可以通过man 5 passwd查阅。

getpwuid和getpwnam的程序用例:

#include <stdio.h>

#include <pwd.h>

#include <sys/types.h>

#include <unistd.h>

static void PrintfPwd(const passwd* pwdInfo)

{

if(!pwdInfo)

return;

printf("name: \t%s\n", pwdInfo->pw_name);

printf("passwd: \t%s\n", pwdInfo->pw_passwd);

printf("uid: \t%d\n", pwdInfo->pw_uid);

printf("gid: \t%d\n", pwdInfo->pw_gid);

printf("gecos: \t%s\n", pwdInfo->pw_gecos);

printf("dir: \t%s\n", pwdInfo->pw_dir);

printf("shell: \t\%s\n", pwdInfo->pw_shell);

}

int main(int argc, char* argv[])

{

printf("test getpwuid: \n");

uid_t uid = getuid();

printf("uid: %d\n", uid);

// test getpwuid

struct passwd* pwdInfo = getpwuid(uid);

if(!pwdInfo)

return 1;

PrintfPwd(pwdInfo);

// test getpwnam

printf("\n\ntest getpwnam: \n");

struct passwd* pwdInfo2 = getpwnam(pwdInfo->pw_name);

PrintfPwd(pwdInfo2);

return 0;

}

getpwuid_r用例:

#include <stdio.h>

#include <stdlib.h>

#include <pwd.h>

#include <unistd.h>

#include <errno.h>

static void PrintfPwd(const passwd* pwdInfo)

{

if(!pwdInfo)

return;

printf("name: \t%s\n", pwdInfo->pw_name);

printf("passwd: \t%s\n", pwdInfo->pw_passwd);

printf("uid: \t%d\n", pwdInfo->pw_uid);

printf("gid: \t%d\n", pwdInfo->pw_gid);

printf("gecos: \t%s\n", pwdInfo->pw_gecos);

printf("dir: \t%s\n", pwdInfo->pw_dir);

printf("shell: \t\%s\n", pwdInfo->pw_shell);

}

int main(int argc, char* argv[])

{

uid_t uid = getuid();

size_t len = sysconf(_SC_GETPW_R_SIZE_MAX);

if(len == -1)

len = 16384;

char* buffer = new char[len];

if(!buffer)

{

printf("buffer create failed. error[%d]\n", errno);

return 1;

}

struct passwd pwd;

struct passwd* result = NULL;

int ret = getpwuid_r(uid, &pwd, buffer, len, &result);

if(!result)

{

printf("getpwuid failed. ret[%d]\n", ret);

return 1;

}

printf("----------pwd---------- \n");

PrintfPwd(&pwd);

printf("\n\n----------result----------\n");

PrintfPwd(result);

printf("\n\n----------buffer----------\n");

printf("buffer: %s\n", buffer);

return 0;

}

以下三个函数与读取/etc/passwd相关:

#include <sys/types.h>

#include <pwd.h>

struct passwd* getpwent(void);

void setpwent(void);

void endpwent(void);

getpwent: 获取passwd文件中的一个口令,严格的说,是获取下一个口令

setpwent: 将获取口令重置到第一个

endpwent: 关闭由getpwent打开的文件

程序用例:

#include <stdio.h>

#include <pwd.h>

int main(int argc, char* argv[])

{

// 为了测试方便,最多只打印10个口令信息

struct passwd* pwd;

// 设置从头开始读取

setpwent();

int n = 0;

while((pwd = getpwent()) != NULL)

{

printf("name: %s \t uid: %d\n", pwd->pw_name, pwd->pw_uid);

if(++n >= 10)

break;

}

endpwent();

return 0;

}


2 shadow passwords

看着名字就知道它藏的好深。

有以下函数可以操作这个文件:

#include <shadow.h>

struct spwd* getspnam(const char* name);

struct spwd* getspent(void);

void setspent(void);

void endspent(void);

struct spwd*fgetspent(FILE* fp);

struct spwd*sgetspent(const char* s);

int putspent(struct spwd* p, FILE* fp);

int lckpwdf(void);

int ulckpwdf(void);

/* GNU extension */

#include <shadow.h>

int getspent_r(struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);

int getspnam_r(const char* name, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);

int fgetspent_r(FILE* fp, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);

int sgetspent_r(const char* s, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);

其中的struct spwd定义如下:

struct spwd

{

char* sp_namp;     /* Login name */

char* sp_pwdp;     /* Encrypted password */

long  sp_lstchg;   /* Date of last change

(measured in days since

1970-01-01 00:00:00 +0000 (UTC)) */

long  sp_min;      /* Min # of days between changes */

long  sp_max;      /* Max # of days between changes */

long  sp_warn;     /* # of days before password expires

to warn user to change it */

long  sp_inact;    /* # of days after password expires

until account is disabled */

long  sp_expire;   /* Date when account expires

(measured in days since

1970-01-01 00:00:00 +0000 (UTC)) */

unsigned long sp_flag;  /* Reserved */

};

getspnam程序用例:

#include <stdio.h>

#include <shadow.h>

#include <errno.h>

#include <string.h>

int main(int argc, char* argv[])

{

struct spwd* pwd = getspnam("alex_my");

if(!pwd)

{

printf("getspnam failed, error: [%d] [%s]\n", errno, strerror(errno));

return 1;

}

printf("name: %s\t password: %s\n", pwd->sp_namp, pwd->sp_pwdp);

return 0;

}

如果在普通账号下运行,就会发生错误,因为读取文件的权限不够。


3 group file

位于/etc/group

有以下函数可以操作:

#include <sys/types.h>

#include <grp.h>

struct group *getgrnam(const char *name);

struct group *getgrgid(gid_t gid);

int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result);

int getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result);

用法可以参考passwd file

用户在登陆的时候,就会获取到group ID,属于某一个group,可以通过命令来改变所属的组。但总体来说不方便。

于是,出现了supplementary group IDs(附加组ID)。


4 获取本地主机名

#include <unistd.h>

int gethostname(char* name, size_t namelen);

#include <stdio.h>

#include <unistd.h>

int main(int argc, char* argv[])

{

char name[256] = { 0 };

gethostname(name, sizeof(name));

printf("name: %s\n", name);

return 0;

}

时间: 2024-08-10 16:25:38

《unix环境高级编程》 读书笔记 (4)的相关文章

高性能javascript读书笔记(三.DOM 编程1)

第三章DOM Script DOM编程 读书笔记 访问和修改DOM元素 浏览器通常要求DOM实现和JavaScript保持相互独立. <!-- 例如IE中,被称为JScript的JavaScript实现位于库文件jscript.dll中,而DOM实现位于另一个库mshtml.dll(内 部代号Trident).这种分离技术允许其他技术和语言,如VBScript,受益于Trident所提供的DOM功能和渲染功能.Safari使用Webkit的WebCore处理DOM和渲染,具有一个分离的JavaS

数据访问---高性能JavaScript读书笔记(2)

对于任何一种编程语言来说,数据存储的位置关系到访问速度! 在JavaScript中的直接量包括字符串string.数字number.布尔值boolean.对象object.数组array.函数function.正则表达式regular expression.空值null.未定义数组undefined.而数组项则需要通过数组的数字索引来访问,对象通过字符串进行索引来访问其成员(这里顺便提一句因为数组项是通过数字进行索引.对象成员是通过字符串进行索引,所以这也就是为什么访问对象成员比访问数组项更慢的

加载和运行---高性能JavaScript读书笔记(1)

众所周知大多数浏览器是使用单进程处理UI更新和JavaScript运行等多个任务的,而同一时间只能有一个任务被执行,如此说来,JavaScript运行了多长时间就意味着用户得等待浏览器响应需要花多久时间. 从认知上来说,解析器解析一个界面的时候都是从上至下依次解析的,这就是说界面上出现多少个<script>标签(不管是内联还是外部文件),页面下载和解析必须停止等待脚本下载完成并运行完成(注意这里包括运行),这个过程当中,页面解析和用户交互是被完全阻塞的. Javascript第一条定律:将脚本

DOM访问---高性能JavaScript读书笔记(3)

在JavaScript高级程序设计第一章当中就把JavaScript分成三大部分 所以事实上DOM和BOM是两在独立的部分,它们之间的通信是通过相互之间的功能接口来实现的,这样说来两个独立的部分以功能接口必定会带来性能损耗.这也就是为什么大家一致都说尽量少去访问和修改DOM元素(注意我这里说的是访问和修改,为什么包括访问,请继续往下看  哈哈). 下面用一张图来说明它们各自的作用. 1.在修改DOM元素的时候,我们应该尽量使用innerHTML而不是CreateElement再AppendChi

高性能javascript读书笔记(三.DOM 编程2)

重绘和重排版 浏览器下载完所有的HTML标记,Javascript,CSS,图片之后,它解析文件并创建两个内部数据结构 DOM树 表示页面结构渲染树 表示DOM节点如何显示 渲染树中为每个需要显示的DOM树木=节点存放至少一个节点(隐藏DOM元素在选桉树中没有对应节点)渲染树上的节点称为"框"或者"盒",符合CSS模型的定义,将页面元素看作一个具有填充,边距,边框和位置的盒.一 旦DOM树和渲染树构造完毕,浏览器就可以显示(绘制)页面上的元素了. 当DOM改变影响到

Javascript读书笔记:函数定义和函数调用

定义函数 使用function关键字来定义函数,分为两种形式: 声明式函数定义: function add(m,n) { alert(m+n); } 这种方式等同于构造一个Function类的实例的方式: var add = new Function("m", "n", "alert(m+n);"); Function类构造方法的最后一个参数为函数体:"alert(m+n);",前面的都是函数的形参,参数必须是字符串形式的:&

Javascript读书笔记:字符串常用方法

concat() 连接多个字符串,返回合并后的字符串. 1 var s1="a"; 2 var s2="b"; 3 var s3="c"; 4 5 console.log(s1.concat(s2,s3));//abc 数组中的concat():将参数添加为数组的元素,返回新的数组. 1 var arr = [1, 2, 3]; 2 console.log(arr.concat(4, 5));//[1,2,3,4,5] indexOf() 查找子

高性能javascript学习笔记系列(1) -js的加载和执行

这篇笔记的内容主要涉及js的脚本位置,如何加载js脚本和脚本文件执行的问题,按照自己的理解结合高性能JavaScript整理出来的 javascript是解释性代码,解释性代码需要经历转化成计算机指令的过程,这个过程就会带来一定的性能损耗,所以在js中做性能的优化是必须的 javascript的阻塞特性:浏览器在执行js代码的时候,不能做其他的任何事情,因为浏览器使用单一的进程来处理用户界面的刷新和javascript的脚本执行,也就是说什么时候执行js脚本影响着用户对页面的使用体验(之所以js

高性能javascript学习笔记系列(6) -ajax

参考 高性能javascript javascript高级程序设计 ajax基础  ajax技术的核心是XMLHttpRequest对象(XHR),通过XHR我们就可以实现无需刷新页面就能从服务器端读取数据 var xhr = new XMLHttpRequest(); //只支持IE7以及更高的版本 xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if( (xhr.status >= 200 && xh

高性能javascript学习笔记系列(5) -快速响应的用户界面

参考高性能javascript 理解浏览器UI线程  用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程  UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 <button onclick="handleClick()">click</button> <script type="text/javascript"> function handleClick() { var div = do