unix环境高级编程-文件和目录(1)

stat、fstat和lstat函数:

一旦给出pathname,stat函数返回与此函数命令文件有关的信息结构。第二个参数buf是指针,指向一个我们必须提供的结构体。该结构体的基本结构是:


文件类型:

1 普通文件(regular file):最常见的文件类型

2 目录文件(directory file):包含了其他文件的名字以及指向这些文件有关信息的指针,只有内核可以直接写目录文件

3 块特殊文件:提供对设备带缓冲的访问

4 字符特殊文件:提供对设备不带缓冲的访问

5 FIFO:用于进程通信,,有时也称为管道命令

6 套间字(socket):用于进程之间网络通信

7 符号连接:指向另一个文件

这些文件类型信息包含在stat结构的st_mode成员中

源代码:对每个命令行参数打印文件类型

#include "apue.h"

int
main(int argc, char *argv[])
{
	int			i;
	struct stat	buf;
	char		*ptr;

	for (i = 1; i < argc; i++) 
              {
		printf("%s: ", argv[i]);
		if (lstat(argv[i], &buf) < 0) {       //lstat函数,给出了路径名argv,就返回与此命令文件有关的信息结构,也就是返回给stat类型的buf
			err_ret("lstat error");
			continue;
		}
		if (S_ISREG(buf.st_mode))    //得到stat结构的buf中的st_mode,接下来用各种文件类型宏进行判断,输出对应信息
			ptr = "regular";
		else if (S_ISDIR(buf.st_mode))
			ptr = "directory";
		else if (S_ISCHR(buf.st_mode))
			ptr = "character special";
		else if (S_ISBLK(buf.st_mode))
			ptr = "block special";
		else if (S_ISFIFO(buf.st_mode))
			ptr = "fifo";
		else if (S_ISLNK(buf.st_mode))
			ptr = "symbolic link";
		else if (S_ISSOCK(buf.st_mode))
			ptr = "socket";
		else
			ptr = "** unknown mode **";
		printf("%s\n", ptr);
	}
	exit(0);
}

新文件和目录的所有权

当用open或creat创建新文件时,并没有说明赋予的用户ID和组ID是什么,新文件的用户ID设置为进程的有效用户ID,组ID可以是进程的有效组ID,也可以是所在目录的组ID


access函数:

用open函数打开文件,以进程的有效用户ID和有效组ID为基础执行访问,access是按照实际用户ID和实际组ID进行访问权限设置的


chmod和fchmod函数:


两个函数可以让我们更改现有文件的访问权限。chmod在指定文件上进行操作,fchmod则对已打开的文件进行操作。而为了改变一个文件的权限位,进程的有效用户ID必须等于文件的所有者ID


chown,fchown和lchown函数

下列几个chown函数可用于更改文件的用户ID和组ID


文件的时间:

要注意数据最后修改时间和i节点最后更改时间的区别,前者是文件内容修改,后者是i节点内容修改,而很多操作会修改i节点,比如更改文件的访问权限,用户ID,连接数等。

但是并没有修改文件的实际内容。

而系统管理员常会删除哪些一段时间没有访问过的文件,最常见的比如a.out  ,find命令常用在这些操作。

下表表示了各种函数对于这三种时间的影响


chdir,fchdir,getcwd函数

每个进程都有一个当前目录,当用户登陆unix系统时,当前目录一般是用户的起始目录(home),调用chdir和fchdir可以改变当前工作目录

因为当前工作目录是进程的一个属性,所以它只影响chdir本身,而不影响其他进程。

源代码;

#include "apue.h"
int main(void)
{
 if (chdir("/tmp")<0)
     err_sys("chdir faileed");
      printf("chdir to /tmp succeeded");
    exit(0);

}

运行结果执行这个程序的shell的当前工作目录并没有改变,原因是shell创建了一个子进程,由该子进程执行这个程序,由此可见,为了改变shell进程自己的工作目录,shell应该直接调用chdir函数,因此这个命令的执行程序应该直接包含在shell中。

可以采用getcwd函数来实现

当一个应用程序需要在文件系统中返回到其工作的起点时,getcwd是有用的。在更换工作目录 之前,用getcwd保存起来,在完成处理后,可将从getcwd获得的路径名作为调用参数传送给chdir。

#include "apue.h"
int main(void)
{
 char *ptr;
 int size;
 if (chdir("/usr/spool/uucppbulic")<0)    
      err_sys("chdir failed");

  ptr = path_alloc(&size);
  if(getcwd(ptr,size) == NULL)
    err_sys("getcwd failed");

   printf("cwd = %s\n", ptr);
   exit(0);

}

设备特殊文件:

st_dev和st_rdev这两个字段经常引起混淆,每个文件系统所在的储存设备都有主,次设备号表示,主设备号标识设备驱动程序,次设备号标识特定的子设备。

源代码:打印st_dev和st_rdev值

传递给程序的前两个参数是目录(/和/home/sar),后两个是设备名/dev/tty[01],也就是tty0和tty1,这两个设备是字符特殊设备。

从程序的输出可见,根目录和/home/sar目录的设备号不同,这表示他们位于不同的文件系统中。而两个终端设备是字符特殊文件,次设备号分别为4/0和4/1.


posted on 2016-07-26 20:11  sichenzhao  阅读(174)  评论(0编辑  收藏  举报

导航