﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-jixuduxing</title><link>http://www.cppblog.com/jixuduxing/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 09:35:35 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 09:35:35 GMT</pubDate><ttl>60</ttl><item><title>linux学习笔记（7）</title><link>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114439.html</link><dc:creator>高磊</dc:creator><author>高磊</author><pubDate>Wed, 05 May 2010 01:41:00 GMT</pubDate><guid>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114439.html</guid><wfw:comment>http://www.cppblog.com/jixuduxing/comments/114439.html</wfw:comment><comments>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114439.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jixuduxing/comments/commentRss/114439.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jixuduxing/services/trackbacks/114439.html</trackback:ping><description><![CDATA[<div>第六章：系统数据文件和信息</div><div>6.2 口令文件</div><div>#include &lt;pwd.h&gt;</div><div>struct passwd * getpwuid(uid_t uid);</div><div>struct passwd * getpwnam(const char * name);</div><div><br></div><div><br></div><div>struct passwd * getpwent(void);</div><div>void setpwent(void);</div><div>void endpwent(void);</div><div>这三个函数用来获取指令文件对应每个用户的信息；</div><div><br></div><div>6.3 阴影文件</div><div>加密口令存放在阴影口令文件中 &nbsp;/etc/shadow</div><div>该文件只有root用户可以访问；</div><div>访问该文件的函数</div><div>#include &lt;shadow.h&gt;</div><div>struct spwd *getspnam(const char * name);</div><div>struct spwd *getspent(void);</div><div><br></div><div>void setspent(void);</div><div>void endspent(void);</div><div><br></div><div>6.4 组文件</div><div>#include &lt;grp.h&gt;</div><div>struct group *getgrgid(gid_t gid)；</div><div>struct group *getgrnam(const char *name)；</div><div><br></div><div>struct group *getgrent(void);</div><div>void setgrent(void);</div><div>void endgrent(void);</div><div><br></div><div>6.5 附加组id</div><div>每个用户可以有多个组</div><div>拥有这些组的权限；</div><div><br></div><div>#include &lt;unistd.h&gt;</div><div><br></div><div>int getgroups(int gidsetsize, gid_t grouplist[]);</div><div><br></div><div>Returns: number of supplementary group IDs if OK, 1 on error</div><div>&nbsp;</div><div>#include &lt;grp.h&gt; &nbsp; &nbsp; /* on Linux */</div><div>#include &lt;unistd.h&gt; &nbsp;/* on FreeBSD, Mac OS X, and</div><div>&nbsp;Solaris */</div><div><br></div><div>int setgroups(int ngroups, const gid_t grouplist[]);</div><div><br></div><div>#include &lt;grp.h&gt; &nbsp; &nbsp; /* on Linux and Solaris */</div><div>#include &lt;unistd.h&gt; &nbsp;/* on FreeBSD and Mac OS X */</div><div><br></div><div>int initgroups(const char *username, gid_t basegid);</div><div><br></div><div><br></div><div><br></div><div>以上</div><div>get方法都表示读下一条记录</div><div>set 表示打开该数据文件；</div><div>end 表示关闭该数据文件；</div><div>6.9</div><div>#include &lt;sys/utsname.h&gt;</div><div><br></div><div>int uname(struct utsname *name);</div><div>获取系统信息</div><div>#include &lt;unistd.h&gt;</div><div><br></div><div>int gethostname(char *name, int namelen);</div><div>获取主机名</div><div><br></div><div>6.10 时间和日期例程</div><div><br></div><div>#include &lt;time.h&gt;</div><div><br></div><div>time_t time(time_t *calptr);</div><div>获取当前时间（相对于1970年1月0日0分）</div><div>#include &lt;sys/time.h&gt;</div><div><br></div><div>int gettimeofday(struct timeval *restrict tp, void</div><div>&nbsp;*restrict tzp);</div><div>获取秒和微妙</div><div><br></div><div>#include &lt;time.h&gt;</div><div><br></div><div>struct tm *gmtime(const time_t *calptr);</div><div>//转化为国际时间</div><div>struct tm *localtime(const time_t *calptr);</div><div>//转化为本地时间</div><div>#include &lt;time.h&gt;</div><div><br></div><div>time_t mktime(struct tm *tmptr);</div><div>//反转</div><div><br></div><div>The asctime and ctime functions produce the familiar 26-byte string that is similar to the default output of the date(1) command:</div><div><br></div><div>&nbsp;&nbsp; &nbsp;Tue Feb 10 18:27:38 2004\n\0</div><div><br></div><div>#include &lt;time.h&gt;</div><div><br></div><div>char *asctime(const struct tm *tmptr);</div><div><br></div><div>char *ctime(const time_t *calptr);</div><div>&nbsp;</div><div><br></div><div>&nbsp;#include &lt;time.h&gt;</div><div><br></div><div>size_t strftime(char *restrict buf, size_t maxsize,</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const char *restrict format,</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const struct tm *restrict tmptr);</div><div>//自定义格式化时间</div><div><div>Chapter 7. Process Environment&nbsp;</div><div>7.2 main函数</div><div>每个进程都是由一个起动例程启动的。</div><div>7.3 程序终止</div><div>#include &lt;stdlib.h&gt;</div><div><br></div><div>void exit(int status);</div><div><br></div><div>void _Exit(int status);</div><div><br></div><div>#include &lt;unistd.h&gt;</div><div><br></div><div>void _exit(int status);</div><div>_exit and _Exit, which return to the kernel immediately 立即进入内核，关闭程序</div><div>exit, which performs certain cleanup processing and then returns to the kernel.</div><div>先做清理处理（执行终止处理程序，关闭所有标准io流等），对于所有的打来的流，执行fclose操作</div><div><br></div><div>大多数unix shell提供一个检查一个进程终止状态的方法，如果a）该函数返回时不带终止状态，b）执行不带返回值的return语句，c）main隐式返回，则该进程的终止状态是未定义的；</div><div><br></div><div><br></div><div>#include &lt;stdlib.h&gt;</div><div><br></div><div>int atexit(void (*func)(void));</div><div>终止处理函数注册函数</div><div>比如 atexit(my_exit2)</div><div><br></div><div>注：main函数中 exit (0)等价于return (0);</div><div>7.4 命令行参数</div><div><br></div><div>7.5 环境表</div><div>Access to specific environment variables is normally through the getenv and putenv functions</div><div><br></div><div>7.6. Memory Layout of a C Program&nbsp;</div><div>c程序的存储空间布局</div><div>Historically, a C program has been composed of the following pieces:</div><div>1、Text segment,&nbsp;</div><div>2、Initialized data segment</div><div>3、Uninitialized data segment</div><div>4、Stack</div><div>5、Heap</div><div><br></div><div>7.7. Shared Libraries&nbsp;</div><div>共享库</div><div>就是动态连接库</div><div>cc -static a.c</div><div>静态编译</div><div><br></div><div>7.8. Memory Allocation&nbsp;</div><div>存储分配</div><div><br></div><div>#include &lt;stdlib.h&gt;</div><div><br></div><div>void *malloc(size_t size);</div><div><br></div><div>void *calloc(size_t nobj, size_t size);</div><div><br></div><div>void *realloc(void *ptr, size_t newsize);</div><div>&nbsp;</div><div>All three return: non-null pointer if OK, NULL on error</div><div>&nbsp;</div><div>void free(void *ptr);</div><div>以上都是在堆中分配</div><div><br></div><div>alloca 在栈中分配</div><div><br></div><div>7.9 环境变量</div><div>&nbsp;&nbsp;#include &lt;stdlib.h&gt;</div><div><br></div><div>&nbsp;&nbsp;int putenv(char *str);</div><div><br></div><div>&nbsp;&nbsp;int setenv(const char *name, const char *value,</div><div>&nbsp;int rewrite);</div><div><br></div><div>&nbsp;&nbsp;int unsetenv(const char *name);</div><div>7.10 setjmp和longjmp</div><div>非局部跳转函数，goto是局部跳转的，无法跨越函数实现跳转</div><div>#include &lt;setjmp.h&gt;</div><div><br></div><div>int setjmp(jmp_buf env);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">	</span>Returns: 0 if called directly, nonzero if returning from a call to longjmp&nbsp;</div><div>&nbsp;</div><div>void longjmp(jmp_buf env, int val);</div><div>val表示第几次调用，传递该参数后，从此处跳转，setjmp会返回对应的val；</div><div>注意：使用的时候，可能会对自动变量，寄存器变量和易失变量产生影响，导致其值&#8220;看情况&#8221;，在使用的时候，必需使用validate属性；</div><div>&nbsp;</div><div>一个文件存储的时候主要包含三块：</div><div>数据块 &nbsp;i节点 &nbsp; 目录项</div><div>i节点是唯一的，对应一个或者几个数据块，同时对应一个或者几个目录块</div><div>对一个文件创建一个硬链接，产生新的目录项，然后这个目录项指向了原来文件对应的i节点</div><div>目录项主要包含两个属性：i节点号和文件名；</div><div><br></div><div>但是对于创建一个软链接来说，不仅产生了新的目录项，也产生了新的i节点和数据块，该数据块存储的</div><div>内容就是原文件的文件名，需要注意的是，不同的命令对符号链接的处理不一样，有些&#8220;跟随&#8221;，有些不</div><div>&#8220;跟随&#8221;；</div><div><br></div><div>1、访问符号链接的效率应该比硬链接要低那么一点点，因为牵扯一个跟随的过程：</div><div>从目录块到i节点，然后到数据块，读取文件内容，然后找到被链接接的文件的目录块，再到i节点，访</div><div>问数据块；但是对于硬链接来说的过程是：目录块-》i节点-》数据块即可，跟访问被连接文件的过程是完全一致的；</div><div>2、硬链接的使用存在限制：只能在一个文件系统之中使用，因为对于一个文件而言，数据库，i节点，目录项必须存在在一个文件系统之中，甚至应该是存在一个文件系统的一个柱面组之中；</div><div>附：硬盘、分区、文件系统的关系：</div><div>硬盘分为N个分区，每个分区包含一个文件系统，文件系统由自举块、超级块和M个柱面组组成，而每个柱面组分为超级副本块、配置信息、i节点图，块位图、i节点数组、数据块数组，数据块中穿插着分布目录块，一个文件就存放在该柱面之中，目录块、数据块、i节点分别存储；这也导致硬链接必须在该柱面之中，方可有链接关系，但是软链接就没有这种限制，因为它是通过文件内容和文件属性来跟随所链接的文件并访问其数据，放在哪里都是一样；</div><div>3、i节点存储的有文件的链接数，这个链接是硬链接，初始为1，每增加一个硬链接，该数+1，删除一个硬链接，该数-1，该数为0时释放数据块；</div><div><br></div><div><div>08 进程控制</div><div>8.2 进程标示</div><div>#include &lt;unistd.h&gt;</div><div><br></div><div>pid_t getpid(void);</div><div>Returns: process ID of calling process</div><div><br></div><div>pid_t getppid(void);</div><div>Returns: parent process ID of calling process</div><div><br></div><div>uid_t getuid(void);</div><div>Returns: real user ID of calling process</div><div>&nbsp;</div><div>uid_t geteuid(void);</div><div><br></div><div>Returns: effective user ID of calling process</div><div>&nbsp;</div><div>gid_t getgid(void);</div><div>Returns: real group ID of calling process</div><div><br></div><div>gid_t getegid(void);</div><div><br></div><div>Returns: effective group ID of calling process</div><div>注;以上函数都没有出错返回</div><div><br></div><div>特殊进程：</div><div>id=0 &nbsp;系统进程（调度进程）（交换进程） &nbsp;内核的一部分，不执行磁盘上的任何程序</div><div>id=1 &nbsp;init进程 在自举过程中由内核调用 &nbsp;相当于初始化进程，不是内核中的系统进程，而是普通的用户进程，以超级用户特权运行，会接管所有的野进程；</div><div>8.3 fork函数</div><div>An existing process can create a new one by calling the fork function.</div><div>#include &lt;unistd.h&gt;</div><div><br></div><div>pid_t fork(void);</div><div><br></div></div></div>
<img src ="http://www.cppblog.com/jixuduxing/aggbug/114439.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jixuduxing/" target="_blank">高磊</a> 2010-05-05 09:41 <a href="http://www.cppblog.com/jixuduxing/archive/2010/05/05/114439.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux学习笔记（6）</title><link>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114438.html</link><dc:creator>高磊</dc:creator><author>高磊</author><pubDate>Wed, 05 May 2010 01:40:00 GMT</pubDate><guid>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114438.html</guid><wfw:comment>http://www.cppblog.com/jixuduxing/comments/114438.html</wfw:comment><comments>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jixuduxing/comments/commentRss/114438.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jixuduxing/services/trackbacks/114438.html</trackback:ping><description><![CDATA[<div>5.2 流和file对象</div><div>流的定向决定了所读、写的字符时单字节或多字节的，当一个流被创建时，并没有定向，若在未定向的流上使用一个多字节i/o函数，则该流的定向设置为宽定向的，若在为定向的流上使用单字节i/o函数，则将该流的定向设置为字节定向的。</div><div>有两个函数可以专门改变流的定向：freopen(清除流的定向)和fwide(设置流的定向)，需要注意fwide只针对未定向的流，已定向流不可直接更改，必需清除之后方可；</div><div><br></div><div>5.3 标准输入、标准输出、标准出错</div><div>STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO</div><div><br></div><div>5.4 缓冲</div><div>全缓冲</div><div>行缓冲</div><div>不带缓冲</div><div><br></div><div>void setbuf(FILE *restrict fp,char * restrict buf);</div><div><br></div><div>int setvbuf(FILE *restrict fp,char *restrict buf,int mode,size_t size);</div><div>mode参数:_IOFBF<span class="Apple-tab-span" style="white-space:pre">	</span>全 _IOLBF 行<span class="Apple-tab-span" style="white-space:pre">	</span>_IONBF 不带</div><div><br></div><div>int fflush(FILE *fp)</div><div>使所有未写的数据都被传送到内核(？啥意思 不太清楚)，如果fp是null，则所有的输出流被冲洗；</div><div><br></div><div>5.5 打开流</div><div><br></div><div>FILE * fopen(const char *restrict pathname，const char *restrict type);</div><div><br></div><div>FILE * freopen(const char *restrict pathname，const char *restrict type);</div><div><br></div><div>FILE * fdopen(int filedes，const char *type);</div><div><br></div><div>1、fopen打开指定的文件；</div><div>2、freopen在一个指定的流上打开一个指定的文件，如若该流已经打开，则先关闭该流。若该流已经定向，则清除该定向。</div><div>3、fdopen获取一个现有的文件描述符，并使一个标准的io流与该描述符相结合</div><div>注：此函数常用于创建管道和网络通信函数返回的描述符。。。。。因为这类函数不能用标准io函数fopen函数打开。</div><div><br></div><div>当以读和写打开一个文件时，具有以下限制：</div><div>1、如果中间没有fflush、fseek、fsetpos或rewind，则在输出的后面不能直接跟随输入；</div><div>2、如果中间没有fseek、fsetpos或rewind，或者一个输入操作没有到达文件尾端，则在输入操作之后不能直接跟随输出；</div><div><br></div><div>5.6 读和写流</div><div>1、每次一个字符</div><div>getc</div><div>fgetc</div><div>getchar=getc(stdin);</div><div><br></div><div>ungetc将字符再压送回流中;</div><div>putc(int c,FILE *fp);</div><div>fputc(int c,FILE *fp);</div><div>putchar(int c);</div><div><br></div><div>5.7 每次一行io</div><div><br></div><div>char *fgets(char *restrict buf,int n,FILE *restrict fp);</div><div>char *gets(char * buf);</div><div><br></div><div>5.8 标准io的效率</div><div>1、行io操作函数是用memccpy实现的，而memccpy是利用汇编语言而非c语言编写，效率要高很多；</div><div>2、消耗时间应该为用户cpu和系统cpu之和，系统cpu的时间基本相同，因为行io、字符io函数对内核提出的读写请求数基本相同，使用标准io例程的一个优点是无需考虑缓冲和最佳io的选择，在使用fgets的时候需要考虑最大行长，但是与选择最佳io长度相比较，要方便的多；</div><div><br></div><div><div>5.09<span class="Apple-tab-span" style="white-space:pre">	</span>二进制io</div><div>针对数组、结构体的应用</div><div>fread</div><div>fwrite</div><div><br></div><div>5.10<span class="Apple-tab-span" style="white-space:pre">	</span>定位流：</div><div>ftell</div><div>fseek v7的时候已经存在，都假定文件的位置可以存放在一个长整形中</div><div>ftello</div><div>fseeko<span class="Apple-tab-span" style="white-space:pre">	</span>single unix specification 引入，可以使文件偏移量不必一定使用长整型，它们使用off_t数据类型代替长整型</div><div>rewind<span class="Apple-tab-span" style="white-space:pre">	</span>将一个流设置到文件的起始位置；</div><div>fgetpos</div><div>fsetpos 它们使用一个抽象数据类型fpos_t记录文件的位置，这种数据类型可以定义为记录一个文件位置所需的长度；</div><div><br></div><div><br></div><div>5.11<span class="Apple-tab-span" style="white-space:pre">	</span>格式化io</div><div>输出</div><div><br></div><div>printf</div><div>fprintf</div><div>sprintf</div><div>snprintf</div><div><br></div><div>输入</div><div><br></div><div>scanf</div><div>fscanf</div><div>sscanf</div><div><br></div><div>5.12<span class="Apple-tab-span" style="white-space:pre">	</span>临时文件</div><div>int fileno(FILE * fp)</div><div>对一个流调用fileno以获得其描述符</div><div><div>5.13<span class="Apple-tab-span" style="white-space:pre">	</span>临时文件</div><div>char * tmpnam(char * ptr)</div><div>FILE * tmpfile();</div><div>tmpnam产生一个与现有文件名不同的一个有效路径名字符串，并存放在一个静态区中，指向该静态区的指针作为函数值返回，下一次调用tmpnam会重写该静态区(这意味着，如果我们调用此函数多次，而且想保存路径名，则我们应该保存该路径名的副本，而不是指针的副本)</div><div><br></div><div>tmpfile创建一个二进制文件，在关闭该文件或程序结束时将自动删除这种文件。</div><div><br></div><div>tmpfile函数经常使用的标准unix技术是先调用tmpname产生一个唯一的路径名，然后用该路径名创建一个文件，并立即unlink它</div><div>注：对一个文件unlink并不会删除其内容，关闭该文件才会。</div><div><br></div><div>char *tempnam(const char * directory,const char *prefix);</div><div>是tmpnam的变体，允许调用者为所产生的路径名指定目录和前缀;</div><div><br></div><div>int mkstemp(char *template)</div><div>类似于tmpfile,是其变体,需要注意的是该函数创建的临时文件不会自动被删除，需要自己unlink</div><div><br></div><div>另注：使用tmpnam和tempnam的一个不足之处是：在返回唯一路径和应用程序用该路径名创建文件之间有一个时间窗口，在该时间窗口期间，另一个进程可能会创建一个同名文件，tempfile和mkstemp函数不会产生此种问题；</div></div></div>
<img src ="http://www.cppblog.com/jixuduxing/aggbug/114438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jixuduxing/" target="_blank">高磊</a> 2010-05-05 09:40 <a href="http://www.cppblog.com/jixuduxing/archive/2010/05/05/114438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux学习笔记（5）</title><link>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114437.html</link><dc:creator>高磊</dc:creator><author>高磊</author><pubDate>Wed, 05 May 2010 01:39:00 GMT</pubDate><guid>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114437.html</guid><wfw:comment>http://www.cppblog.com/jixuduxing/comments/114437.html</wfw:comment><comments>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114437.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jixuduxing/comments/commentRss/114437.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jixuduxing/services/trackbacks/114437.html</trackback:ping><description><![CDATA[<div><div>打开流的几种方式：</div><div>fopen <span class="Apple-tab-span" style="white-space:pre">	</span>打开一个指定的文件</div><div>freopen &nbsp;在一个指定流上打开指定文件<span class="Apple-tab-span" style="white-space:pre">		</span>如果该流已经打开，关闭之，若已定向，则清除之</div><div>fdopen<span class="Apple-tab-span" style="white-space:pre">	</span>获取一个现有的文件描述符；并使一个标准的io流与该描述符相结合；</div><div><br></div><div><br></div><div>当以读和写类型打开一个文件时</div><div>1、如果中间没有fflush、fseek、fsetpos或rewind，则在输出的后面不能直接跟随输入；</div><div>2、如果中间没有fseek、fsetpos或rewind，或者一个输入操作没有到达文件尾端，则在输入操作之后不能直接跟随输出；</div><div><br></div><div><br></div><div>按照系统默认，除非流引用终端设备，流被打开时是全缓冲的，若流引用终端设备，行缓冲，若是标准输入、输出、出错，无缓冲；</div><div><br></div><div><br></div><div>读、写：</div><div>1、每次一个字符：</div><div>getc<span class="Apple-tab-span" style="white-space:pre">		</span>可被实现为宏，</div><div>fgetc<span class="Apple-tab-span" style="white-space:pre">		</span>不能被实现为宏，</div><div>getchar<span class="Apple-tab-span" style="white-space:pre">	</span>=getc(stdin)</div><div><br></div><div>对于这三个函数，不管出错还是到达尾端，三个函数都会返回-1，这时候需要调用ferror或者feof来判断；</div><div><br></div><div>ungetc 把读出的字符压到流中，但是压送的顺序和读出顺序相反；</div><div><br></div><div>以上为输出函数：</div><div>下面输入函数：</div><div>putc</div><div>fputc</div><div>putchar==putc(c,stdout)</div><div><br></div><div>2、每次一行io：</div><div>fgets</div><div>gets</div><div>gets没有读缓冲限制，而且不将换行符存入缓冲区中；</div><div><br></div><div>fputs</div><div>puts</div><div>puts会将换行符写到标准输出中；</div><div><br></div><div><br></div><div>使用标准io的一个优点是无需考虑缓冲以及最佳io长度的选择，在使用fgets时只需要考虑最大行长，但是与选择最佳io长度比较，这要方便的多；</div><div><br></div><div>fgets是使用memccpy实现的，memccpy函数使用的汇编语言而非c语言来实现，所以要高效的多；</div><div><div>文件时间属性</div><div>st_atime 文件数据的最后访问时间</div><div>st_mtime 文件数据的最后修改时间</div><div>st_ctime i节点状态的最后更改时间</div><div><br></div><div>更改文件的权限、用户id、链接数等，都会影响到i节点，i节点的所有信息都是与文件的实际内容分开存放的</div><div><br></div><div><br></div><div>utime(const char *pathname，const struct utimbuf *times)；</div><div>struct utimbuf{</div><div>time_t actime;</div><div>time_t modtime;</div><div>};设置文件的访问时间和内容修改时间；</div></div></div>
<img src ="http://www.cppblog.com/jixuduxing/aggbug/114437.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jixuduxing/" target="_blank">高磊</a> 2010-05-05 09:39 <a href="http://www.cppblog.com/jixuduxing/archive/2010/05/05/114437.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux学习笔记（4）</title><link>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114436.html</link><dc:creator>高磊</dc:creator><author>高磊</author><pubDate>Wed, 05 May 2010 01:39:00 GMT</pubDate><guid>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114436.html</guid><wfw:comment>http://www.cppblog.com/jixuduxing/comments/114436.html</wfw:comment><comments>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114436.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jixuduxing/comments/commentRss/114436.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jixuduxing/services/trackbacks/114436.html</trackback:ping><description><![CDATA[<div>1、link创建一个指向现有文件的链接，该文件的内容跟原文件完全一致，并且当其中一个文件内容改变时，对应的文件打开随之改变，其中一个删除，另一个还可继续访问，文件内容没有随之删除，只有当所有的链接都删除掉之后该文件内容才会被删除；需要注意的是：两个文件占用的空间只是一个文件的空间，文件内容只有一份，并没有被复制</div><div>2、unlink(const char *pathname)，删除目录项,并将pathname所引用文件的链接计数器减一，其他指向该文件的链接，还可以被利用来访问该文件的数据，如果出错，不对该文件做任何更改；</div><div>只有当链接计数达到0时，该文件内容才可能被删除；另外，当进程打开该文件的时候，该文件内容也不能被删除；(这一特性常被用来确保程序崩溃时,程序所创建的临时文件也不会遗留下来,程序打开时调用unlink，程序退出或者文件关闭时该临时文件会被删除)</div><div>以上所述是建立硬链接的方式以及相应的特性，硬链接直接指向文件的i节点(文件系统这块理解还是很吃力)</div><div>明日学习间接链接--符号链接</div><div><div>关于符号链接：</div><div>1、硬链接通常要求链接和文件位于同一文件系统中；</div><div>2、只有超级用户才有创建指向目录的硬链接的权限；</div><div>3、硬链接直接指向文件的i节点，符号链接则不然，文件的属性是普通文件，符号链接是连接文件；</div><div>各个函数对于符号链接的处理：</div><div>函数<span class="Apple-tab-span" style="white-space:pre">		</span>不跟随符号链接<span class="Apple-tab-span" style="white-space:pre">	</span>跟随符号链接</div><div>access &nbsp;<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>chdir<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>chmod<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>chown<span class="Apple-tab-span" style="white-space:pre">		</span>yes<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>creat<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>exec<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>lchown<span class="Apple-tab-span" style="white-space:pre">		</span>yes<span class="Apple-tab-span" style="white-space:pre">		</span>no</div><div>link<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>lstat<span class="Apple-tab-span" style="white-space:pre">		</span>yes<span class="Apple-tab-span" style="white-space:pre">		</span>no</div><div>open<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>opendir<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>pathconf<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>readlink<span class="Apple-tab-span" style="white-space:pre">		</span>yes<span class="Apple-tab-span" style="white-space:pre">		</span>no</div><div>remove<span class="Apple-tab-span" style="white-space:pre">		</span>yes<span class="Apple-tab-span" style="white-space:pre">		</span>no</div><div>rename<span class="Apple-tab-span" style="white-space:pre">		</span>yes<span class="Apple-tab-span" style="white-space:pre">		</span>no</div><div>stat<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>truncate<span class="Apple-tab-span" style="white-space:pre">		</span>no<span class="Apple-tab-span" style="white-space:pre">		</span>yes</div><div>unlink<span class="Apple-tab-span" style="white-space:pre">		</span>yes<span class="Apple-tab-span" style="white-space:pre">		</span>no</div><div><br></div><div>注：一个例外：</div><div>同时用O_CREAT和O_EXCL两者调用open函数，在此情况下，若路径名引用符号链接，open会出错返回，将errno设置为EEXIST，这种处理方式是堵塞一个安全性漏洞，使具有特权的进程不会被诱骗对不适当的文件进行写操作；</div><div>两个函数：</div><div>int symlink(const char *actualpath,const char *sympath)函数创建一个符号链接;</div><div>ssize_t readlink(const char* restrict pathname,char *restrict buf,size_t bufsize);(因为open函数跟随符号链接，所以需要一个方法打开链接本身，并读该链接的名字)</div></div>
<img src ="http://www.cppblog.com/jixuduxing/aggbug/114436.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jixuduxing/" target="_blank">高磊</a> 2010-05-05 09:39 <a href="http://www.cppblog.com/jixuduxing/archive/2010/05/05/114436.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux学习笔记（3）</title><link>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114434.html</link><dc:creator>高磊</dc:creator><author>高磊</author><pubDate>Wed, 05 May 2010 01:38:00 GMT</pubDate><guid>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114434.html</guid><wfw:comment>http://www.cppblog.com/jixuduxing/comments/114434.html</wfw:comment><comments>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114434.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jixuduxing/comments/commentRss/114434.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jixuduxing/services/trackbacks/114434.html</trackback:ping><description><![CDATA[<div>1、新文件的用户组id可能使进程的有效组id，也可能是它所在目录的组id(在所在目录的组id被设置的情况下)</div><div>注:对于目录来说，创建之后的组id规则跟文件创建相同；</div><div>2、修改文件权限不会更改文件的最后修改日期属性；</div><div>3、粘住位：如果可执行文件的该位被设置了，那么在该程序第一次执行并结束时，程序正文部分的一个副本扔被保存在交换区(程序的正文部分是机器指令部分)</div><div>4、粘住位的问题：如果对于一个目录设置了粘住位，则只有对该目录有写权限并且符合如下条件之一的情况下，才可以删除或者更名该目录下的文件：拥有此文件。。拥有此目录。。超级用户。。</div>
<img src ="http://www.cppblog.com/jixuduxing/aggbug/114434.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jixuduxing/" target="_blank">高磊</a> 2010-05-05 09:38 <a href="http://www.cppblog.com/jixuduxing/archive/2010/05/05/114434.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux学习笔记（2）</title><link>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114433.html</link><dc:creator>高磊</dc:creator><author>高磊</author><pubDate>Wed, 05 May 2010 01:37:00 GMT</pubDate><guid>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114433.html</guid><wfw:comment>http://www.cppblog.com/jixuduxing/comments/114433.html</wfw:comment><comments>http://www.cppblog.com/jixuduxing/archive/2010/05/05/114433.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jixuduxing/comments/commentRss/114433.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jixuduxing/services/trackbacks/114433.html</trackback:ping><description><![CDATA[<div>linux下io操作学习：</div><div><br></div><div>close(关闭文件)</div><div>相关函数 &nbsp;open，fcntl，shutdown，unlink，fclose</div><div>&nbsp;</div><div>表头文件 &nbsp;#include&lt;unistd.h&gt;</div><div>&nbsp;</div><div>定义函数 &nbsp;int close(int fd);</div><div>&nbsp;</div><div>函数说明 &nbsp;当使用完文件后若已不再需要则可使用close()关闭该文件，二close()会让数据写回磁盘，并释放该文件所占用的资源。参数fd为先前由open()或creat()所返回的文件描述词。</div><div>&nbsp;</div><div>返回值 &nbsp;若文件顺利关闭则返回0，发生错误时返回-1。</div><div>&nbsp;</div><div>错误代码 &nbsp;EBADF 参数fd 非有效的文件描述词或该文件已关闭。</div><div>&nbsp;</div><div>附加说明 &nbsp;虽然在进程结束时，系统会自动关闭已打开的文件，但仍建议自行关闭文件，并确实检查返回值。</div><div><br></div><div><br></div><div><br></div><div>&nbsp;</div><div>creat（建立文件） &nbsp;</div><div>相关函数 &nbsp;read，write，fcntl，close，link，stat，umask，unlink，fopen</div><div>&nbsp;</div><div>表头文件 &nbsp;#include&lt;sys/types.h&gt;</div><div>#include&lt;sys/stat.h&gt;</div><div>#include&lt;fcntl.h&gt;</div><div>&nbsp;</div><div>定义函数 &nbsp;int creat(const char * pathname, mode_tmode);</div><div>&nbsp;</div><div>函数说明 &nbsp;参数pathname指向欲建立的文件路径字符串。Creat()相当于使用下列的调用方式调用open()</div><div>open(const char * pathname ,(O_CREAT|O_WRONLY|O_TRUNC));</div><div>&nbsp;</div><div>错误代码 &nbsp;关于参数mode请参考open（）函数。</div><div>&nbsp;</div><div>返回值 &nbsp;creat()会返回新的文件描述词，若有错误发生则会返回-1，并把错误代码设给errno。</div><div>EEXIST 参数pathname所指的文件已存在。</div><div>EACCESS 参数pathname 所指定的文件不符合所要求测试的权限</div><div>EROFS 欲打开写入权限的文件存在于只读文件系统内</div><div>EFAULT 参数pathname 指针超出可存取的内存空间</div><div>EINVAL 参数mode 不正确。</div><div>ENAMETOOLONG 参数pathname太长。</div><div>ENOTDIR 参数pathname为一目录</div><div>ENOMEM 核心内存不足</div><div>ELOOP 参数pathname有过多符号连接问题。</div><div>EMFILE 已达到进程可同时打开的文件数上限</div><div>ENFILE 已达到系统可同时打开的文件数上限</div><div>&nbsp;</div><div>附加说明 &nbsp;creat()无法建立特别的装置文件，如果需要请使用mknod()。</div><div><br></div><div><br></div><div>&nbsp;</div><div>lseek（移动文件的读写位置） &nbsp;</div><div>相关函数 &nbsp;dup，open，fseek</div><div>&nbsp;</div><div>表头文件 &nbsp;#include&lt;sys/types.h&gt;</div><div>#include&lt;unistd.h&gt;</div><div>&nbsp;</div><div>定义函数 &nbsp;off_t lseek(int fildes,off_t offset ,int whence);</div><div>&nbsp;</div><div>函数说明 &nbsp;每一个已打开的文件都有一个读写位置，当打开文件时通常其读写位置是指向文件开头，若是以附加的方式打开文件(如O_APPEND)，则读写位置会指向文件尾。当read()或write()时，读写位置会随之增加，lseek()便是用来控制该文件的读写位置。参数fildes 为已打开的文件描述词，参数offset 为根据参数whence来移动读写位置的位移数。</div><div>&nbsp;</div><div>参数 &nbsp;whence为下列其中一种:</div><div>SEEK_SET 参数offset即为新的读写位置。</div><div>SEEK_CUR 以目前的读写位置往后增加offset个位移量。</div><div>SEEK_END 将读写位置指向文件尾后再增加offset个位移量。</div><div>当whence 值为SEEK_CUR 或SEEK_END时，参数offet允许负值的出现。</div><div>下列是教特别的使用方式:</div><div>1) 欲将读写位置移到文件开头时:lseek（int fildes,0,SEEK_SET）；</div><div>2) 欲将读写位置移到文件尾时:lseek（int fildes，0,SEEK_END）；</div><div>3) 想要取得目前文件位置时:lseek（int fildes，0,SEEK_CUR）；</div><div>&nbsp;</div><div>返回值 &nbsp;当调用成功时则返回目前的读写位置，也就是距离文件开头多少个字节。若有错误则返回-1，errno 会存放错误代码。</div><div>&nbsp;</div><div>附加说明 &nbsp;Linux系统不允许lseek（）对tty装置作用，此项动作会令lseek（）返回ESPIPE。</div><div>&nbsp;</div><div>范例 &nbsp;参考本函数说明&nbsp;</div><div><br></div><div>&nbsp;</div><div>flock（锁定文件或解除锁定） &nbsp;</div><div>相关函数 &nbsp;open,fcntl</div><div>&nbsp;</div><div>表头文件 &nbsp;#include&lt;sys/file.h&gt;</div><div>&nbsp;</div><div>定义函数 &nbsp;int flock(int fd,int operation);</div><div>&nbsp;</div><div>函数说明 &nbsp;flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作。此函数只能锁定整个文件，无法锁定文件的某一区域。</div><div>&nbsp;</div><div>参数 &nbsp;operation有下列四种情况:</div><div>LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。</div><div>LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。</div><div>LOCK_UN 解除文件锁定状态。</div><div>LOCK_NB 无法建立锁定时，此操作可不被阻断，马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。</div><div>单一文件无法同时建立共享锁定和互斥锁定，而当使用dup()或fork()时文件描述词不会继承此种锁定。</div><div>&nbsp;</div><div>返回值 &nbsp;返回0表示成功，若有错误则返回-1，错误代码存于errno。</div><div><br></div><div><br></div><div>&nbsp;</div><div>open（打开文件） &nbsp;</div><div>相关函数 &nbsp;read，write，fcntl，close，link，stat，umask，unlink，fopen</div><div>&nbsp;</div><div>表头文件 &nbsp;#include&lt;sys/types.h&gt;</div><div>#include&lt;sys/stat.h&gt;</div><div>#include&lt;fcntl.h&gt;</div><div>&nbsp;</div><div>定义函数 &nbsp;int open( const char * pathname, int flags);</div><div>int open( const char * pathname,int flags, mode_t mode);</div><div>&nbsp;</div><div>&nbsp;&nbsp;#include&lt;unistd.h&gt;</div><div>#include&lt;sys/types.h&gt;</div><div>#include&lt;sys/stat.h&gt;</div><div>#include&lt;fcntl.h&gt;</div><div>main()</div><div>{</div><div>int fd,size;</div><div>char s [ ]=&#8221;Linux Programmer!\n&#8221;,buffer[80];</div><div>fd=open(&#8220;/tmp/temp&#8221;,O_WRONLY|O_CREAT);</div><div>write(fd,s,sizeof(s));</div><div>close(fd);</div><div>fd=open(&#8220;/tmp/temp&#8221;,O_RDONLY);</div><div>size=read(fd,buffer,sizeof(buffer));</div><div>close(fd);</div><div>printf(&#8220;%s&#8221;,buffer);</div><div>}</div><div>&nbsp;</div><div>执行 &nbsp;Linux Programmer!</div><div><br></div><div>read（由已打开的文件读取数据） &nbsp;</div><div>相关函数 &nbsp;readdir，write，fcntl，close，lseek，readlink，fread</div><div>&nbsp;</div><div>表头文件 &nbsp;#include&lt;unistd.h&gt;</div><div>&nbsp;</div><div>定义函数 &nbsp;ssize_t read(int fd,void * buf ,size_t count);</div><div>&nbsp;</div><div>函数说明 &nbsp;read()会把参数fd 所指的文件传送count个字节到buf指针所指的内存中。若参数count为0，则read()不会有作用并返回0。返回值为实际读取到的字节数，如果返回0，表示已到达文件尾或是无可读取的数据，此外文件读写位置会随读取到的字节移动。</div><div>&nbsp;</div><div>附加说明 &nbsp;如果顺利read()会返回实际读到的字节数，最好能将返回值与参数count 作比较，若返回的字节数比要求读取的字节数少，则有可能读到了文件尾、从管道(pipe)或终端机读取，或者是read()被信号中断了读取动作。当有错误发生时则返回-1，错误代码存入errno中，而文件读写位置则无法预期。</div><div>&nbsp;</div><div>错误代码 &nbsp;EINTR 此调用被信号所中断。</div><div>EAGAIN 当使用不可阻断I/O 时（O_NONBLOCK），若无数据可读取则返回此值。</div><div>EBADF 参数fd 非有效的文件描述词，或该文件已关闭。</div><div>&nbsp;</div><div>范例 &nbsp;参考open（）。</div><div>&nbsp;</div><div><br></div><div>&nbsp;</div><div>write（将数据写入已打开的文件内） &nbsp;</div><div>相关函数 &nbsp;open，read，fcntl，close，lseek，sync，fsync，fwrite</div><div>&nbsp;</div><div>表头文件 &nbsp;#include&lt;unistd.h&gt;</div><div>&nbsp;</div><div>定义函数 &nbsp;ssize_t write (int fd,const void * buf,size_t count);</div><div>&nbsp;</div><div>函数说明 &nbsp;write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。当然，文件读写位置也会随之移动。</div><div>&nbsp;</div><div>返回值 &nbsp;如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1，错误代码存入errno中。</div><div>&nbsp;</div><div>错误代码 &nbsp;EINTR 此调用被信号所中断。</div><div>EAGAIN 当使用不可阻断I/O 时（O_NONBLOCK），若无数据可读取则返回此值。</div><div>EADF 参数fd非有效的文件描述词，或该文件已关闭。</div><div>&nbsp;</div><div>范例 &nbsp;请参考open（）。</div><div><br></div><img src ="http://www.cppblog.com/jixuduxing/aggbug/114433.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jixuduxing/" target="_blank">高磊</a> 2010-05-05 09:37 <a href="http://www.cppblog.com/jixuduxing/archive/2010/05/05/114433.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>