每个进程都有一个当前工作目录,此目录是搜索所有相对路径名的起点(不以斜杠开始的路径名为相对路径名)。当用户登录到UNIX系统时,其当前工作目录通常是口令文件(/etc/passwd)中该用户登录项的第6个字段——用户的起始目录(home directory)。当前工作目录是进程的一个属性,起始目录则是登录名的一个属性。

进程通过调用chdir或fchdir函数可以更改当前工作目录。

#include <unistd.h>
int chdir( const char *pathname );
int fchdir( int filedes );
两个函数的返回值:若成功则返回0,若出错则返回-

在这两个函数中,分别用pathname或打开文件描述符来指定新的当前工作目录。

实例

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

程序清单4-8 chdir函数实例

[root@localhost apue]# cat prog4-.c
#include "apue.h" int
main(void)
{
if(chdir("/tmp") < )
err_sys("chdir failed");
printf("chdir to /tmp succeeded\n");
exit();
}

运行结果:

[root@localhost apue]# pwd
/home/zhu/apue
[root@localhost apue]# ./prog4-
chdir to /tmp succeeded
[root@localhost apue]# pwd
/home/zhu/apue

从中可以看出,执行上面程序的shell的当前工作目录并没有改变,其原因是shell创建了一个子进程,由该子进程具体执行该程序。

因为内核保存有当前工作目录的信息,所以我们应能取其当前值。不幸的是,内核为每个进程只保存指向该目录v节点的指针等目录本身的信息,并不保存该目录的完整路径名。

我们需要一个函数,它从当前工作目录(.目录项),用..目录项找到其上一级的目录,然后读其目录项(上一级目录中肯定有一个目录项是当前工作目录),直到该目录项中的i节点编号与工作目录i节点编号相同,这样就找到了其对应的文件名。按照这种方法,逐层上移,直到遇到根,这样就得到了当前工作目录完整的绝对路径名。很幸运,函数getcwd就提供了这种功能。

#include <unistd.h>
char *getcwd( char *buf, szie_t size );
返回值:若成功则返回buf,若出错则返回NULL

向此函数传递两个参数,一个是缓冲地址buf,另一个是缓冲的长度size(单位:字节)。该缓冲必须有足够的长度以容纳绝对路径名再加上一个null终止字符,否则返回出错。

程序清单4-9 getcwd函数实例

[root@localhost apue]# cat prog4-.c
#include "apue.h"
#include <errno.h>
#include <limits.h> #ifdef PATH_MAX
static int pathmax = PATH_MAX;
#else
static int pathmax = ;
#endif #define SUSV3 200112L static long posix_version = ; /* If PATH_MAX is indeterminate, no guarantee this is adequate */
#define PATH_MAX_GUESS 1024 char *path_alloc(int *sizep); int
main(void)
{
char *ptr;
int size; if(chdir("/home/zhu/test") < )
err_sys("chdir failed"); ptr = path_alloc(&size); /* our own function */
if(getcwd(ptr, size) == NULL)
err_sys("getcwd failed"); printf("cwd = %s\n", ptr);
exit();
} char *
path_alloc(int *sizep) /* also return allocated size, if nonull */
{
char *ptr;
int size; if(posix_version == )
posix_version = sysconf(_SC_VERSION); if(pathmax == ) { /* first time trough */
errno = ;
if((pathmax = pathconf("/", _PC_PATH_MAX)) < ) {
if(errno == )
pathmax = PATH_MAX_GUESS; /* it's indeterminate */
else
err_sys("pathconf error for _PC_PATH_MAX");
} else {
pathmax++; /* add one since it's relative to root */
}
}
if(posix_version < SUSV3)
size = pathmax + ;
else
size = pathmax; if((ptr = malloc(size)) == NULL)
err_sys("malloc error for pathname"); if(sizep != NULL)
*sizep = size;
return(ptr);
}

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

fchdir函数向我们提供了一种完成此任务的便捷方法。在更换到文件系统中的不同位置前,无需调用getcwd函数,而是使用open打开当前工作目录(用open可以打开目录吗???我尝试用open打开一个目录,运行时出现错误:open: Is a directory),然后保存文件描述符。当希望回到原工作目录时,只需简单地将该文件描述符传递给fchdir。

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

文件和目录之chdir、fchdir和getcwd函数的更多相关文章

  1. [APUE]文件和目录(下)

    一.mkdir和rmdir函数 #include <sys/types.h> #include <sys/stat.h> int mkdir(const char *pathn ...

  2. apue chapter 4 文件和目录

    1.文件信息结构体 struct stat{ mode_t st_mode; //file type and permissions ino_t st_ino; //i-node number (se ...

  3. UNIX环境高级编程——文件和目录

    一.获取文件/目录的属性信息 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); in ...

  4. IO系统-文件与目录操作

    1.文件内核数据结构 一个打开的文件在内核中使用三种数据结构表示: (1)文件描述符表 文件描述符标志 文件表项指针 (2)文件表项: 文件状态标志:读.写.追加.同步和非阻塞等状态标志 当前文件偏移 ...

  5. python文件和目录操作方法

    一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法.1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()2.返回指定目录下的所有文件和目 ...

  6. PHP面试 PHP基础知识 七(文件及目录处理)

    文件操作 文件打开函数 fopen()函数 //用来打开一个文件 打开时需要指定打开模式 语法:fopen( filename, mode, include_path, context); filen ...

  7. 函数chdir、fchdir和getcwd

    函数chdir.fchdir和getcwd chdir.fchdir函数     每个进程都有一个当前工作目录,当前目录是进程的一个属性     当用户登录UNIX系统时,其当前工作目录通常是口令文件 ...

  8. [04]APUE:文件与目录

    [a] stat / lstat / fstat #include <sys/stat.h> int stat(const char *restrict pathname, struct ...

  9. Python::OS 模块 -- 文件和目录操作

    os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...

随机推荐

  1. Yii 实现restful

    首先做一下接口的 URL 规划,假设我们要面对的资源是 item ,现在我们暴露5个接口供其他应用调用,分别是: 对于所有 item 列表调用: GET /rest/item 对于某个 item 信息 ...

  2. 2013年最受欢迎的16个HTML5 WordPress主题

    本文中,我整理了16个最新.最受欢迎的WordPress主题,它们一致的特征是支持HTML5, 它们秉承最佳设计理念以及最新的流行趋势,将它们归纳与此,希望对喜欢HTML5,准备用WordPress做 ...

  3. c++模板注意事项

    c++模板类 分类: C++2012-08-20 21:28 7108人阅读 评论(2) 收藏 举报 c++编译器instantiationiostreamlinker编程 c++模板类 分类: 数据 ...

  4. Server.MapPath 的使用方法

    Server.MapPath 的使用方法 用法: 1.Server.MapPath ("/") 应用程序根目录所在的位置 如 C:\Inetpub\wwwroot\ 2.Serve ...

  5. Oracle Form Developer: Folder FRM-99999 Error 14212

    Question: 做FOLDER文件夹功能,打开FORM错误提示: FRM-99999:出现1412错误.有关该错误的详细信息,请参阅发行说明文件(relnotes) Answer: 原因是FOLD ...

  6. Reflector+Reflexil 相结合实现对DLL文件修改

    在工作过程中,我们有可能遇到这样的问题:公司发给客户的软件包突然报错了,但是你知道哪里报错了,而这个代码已经编译成DLL文件了,源代码不在自己这里.怎么办呢?还好现在有Reflexil插件,这个插件只 ...

  7. C#中的cookie编程

    Cookie就是所谓的" 小甜饼" ,他最早出现是在Netscape Navigator 2.0中.Cookie其实就是由Web服务器创建的.将信息存储在计算机上的文件.那么为什么 ...

  8. UVA_11468_Substring_(AC自动机+概率动态规划)

    描述 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  9. windows播放声音

    一般播放MP3常见的有两种方法,一种是自己解码,另外一种用系统的库,比如MCI,当然如果可以用控件直接用个控件会更方便. 1.      使用mci #include <windows.h> ...

  10. zabbix中文配置指南(转)-服务器监控

    一.Zabbix简介 1.1 Zabbix简介 Zabbix是一个企业级的开源分布式监控解决方案,由一个国外的团队持续维护更新,软件可以自由下载使用,运作团队靠提供收费的技术支持赢利.官方网站:htt ...