Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1798417
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 系统运维

2012-03-28 14:05:41

每个进程都有一个当前工作目录。这个目录是所有相对路径(不以斜杠开头的路径)开始查找的地方。当一个用户登录一个UNIX系统时,当前工作目录一般从文 件/etc/passwd里的第6个域指定的目录--用户的主目录--开始。当前工作路径是进程的一个属性,主目录是登录名的一个属性。

我们可以用chdir和fchdir函数来改变进程的当前路径。



  1. #include <unistd.h>

  2. int chdir(const char *pathname);

  3. int fchdir(int filedes);

  4. 成功返回0,失败返回-1。


我们可以用路径名或文件描述符来指定一个新的当前工作目录。

fchdir函数不是基本POSIX.1规范的一部分,它是SUS的一个XSI扩展。本文讨论的4个平台都支持fchdir。


下面的代码把当前工作目录改为“/tmp":



  1. #include <unistd.h>

  2. int
  3. main(void)
  4. {
  5.     if (chdir("/tmp") < 0) {
  6.         printf("chdir failed\n");
  7.         exit(1);
  8.     }
  9.     printf("chdir to /tmp succeeded\n");
  10.     exit(0);
  11. }



运行结果为:
$ pwd
/home/tommy/code/c/unix
$ ./a.out
chdir to /tmp succeeded
$ pwd
/home/tommy/code/c/unix

shell的当前工作目录之所以没有改变,是因为当前工作目录是进程的一个属性,进程改变当前工作目录不能影响到其它进程,即使是其父进程。(我们会在第8章更深入讨论进程间的关系。)要改变shell的的当前工作目录,可以使用其内置的cd命令。

因为内核必须维护当前工作目录的信息,我们应该可以得到它的当前值。不幸的是,内核并不维护这个目录的完全路径,而是关于目录的信息,比如指向目录v-node的指针。


我们需要的是一个从当前工作目录(点)开始,并使用点点往上遍历其层次的函数。每进入上一层目录时,函数读取它的目录项,直到找到对应于进入该目录前的目 录的i-node的名字。重复这个过程,直到到达要目录,从而得到当前工作目录的整个绝对路径。幸运的是,已经有一个函数来为我们完成这个任务了。



  1. #include <unistd.h>

  2. char *getcw(char *buf, size_t size);

  3. 成功返回buf,错误返回NULL。


我们必须给这个函数传递一个缓冲区,buf,的地址,以及它的(字节)大小。这个缓冲区必须足够大以容下绝对路径名加一个终止null字节,不然会返回错误。(回想下2.5.5节关于为最大尺寸的路径名分配空间的讨论。)


一些getcwd的早期实现允许第一个参数为NULL。这种情况下,函数调用malloc来动态分配size大小的字节。这不是POSIX.1的部分,也不是SUS的部分,所以应该避免使用。


看下面的代码:



  1. #include <unistd.h>

  2. char *path_calloc(int *);

  3. int
  4. main(void)
  5. {
  6.     char *ptr;
  7.     int size;

  8.     if (chdir("/var/spool/mail") < 0) {
  9.         printf("chdir failed\n");
  10.         exit(1);
  11.     }

  12.     ptr = path_alloc(&size); /* our own funciton */
  13.     if (getcwd(ptr, size) == NULL) {
  14.         printf("getcwd failed\n");
  15.         exit(1);
  16.     }

  17.     printf("cwd = %s\n", ptr);
  18.     exit(0);
  19. }


$ ./a.out
cwd = /var/mail
$ ls -l /var/spool/mail
lrwxrwxrwx 1 root root 7 2011-10-12 16:16 /var/spool/mail -> ../mail

可以看到chdir解析了符号链接,正如我们期望的。getcwd在往上查找的过程中,并不知道/var/mail是一个符号链接指向的目录。这是符号链接的特性。


当我们有一个需要返回到原来的文件系统的位置的程序时,getcwd函数有很有用的。我们可以在改变我们的工作目录之前调用getcwd来保存开始位置。在完成我们的操作后,我们可以把从getcwd得到的路径名传给chdir来返回到我们在文件系统的开始的位置。


fchdir函数提供我们完成这个任务的一个简单方法。不需要使用getcwd,我们可以在进入文件系统别的位置前用open当前目录并保存文件描述符。当我们想要返回我们开始的位置时,我们可以简单地把描述符会给fchdir。

阅读(1236) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~