文件和目录之chdir、fchdir和getcwd函数
每个进程都有一个当前工作目录,此目录是搜索所有相对路径名的起点(不以斜杠开始的路径名为相对路径名)。当用户登录到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函数的更多相关文章
- [APUE]文件和目录(下)
一.mkdir和rmdir函数 #include <sys/types.h> #include <sys/stat.h> int mkdir(const char *pathn ...
- apue chapter 4 文件和目录
1.文件信息结构体 struct stat{ mode_t st_mode; //file type and permissions ino_t st_ino; //i-node number (se ...
- UNIX环境高级编程——文件和目录
一.获取文件/目录的属性信息 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); in ...
- IO系统-文件与目录操作
1.文件内核数据结构 一个打开的文件在内核中使用三种数据结构表示: (1)文件描述符表 文件描述符标志 文件表项指针 (2)文件表项: 文件状态标志:读.写.追加.同步和非阻塞等状态标志 当前文件偏移 ...
- python文件和目录操作方法
一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法.1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()2.返回指定目录下的所有文件和目 ...
- PHP面试 PHP基础知识 七(文件及目录处理)
文件操作 文件打开函数 fopen()函数 //用来打开一个文件 打开时需要指定打开模式 语法:fopen( filename, mode, include_path, context); filen ...
- 函数chdir、fchdir和getcwd
函数chdir.fchdir和getcwd chdir.fchdir函数 每个进程都有一个当前工作目录,当前目录是进程的一个属性 当用户登录UNIX系统时,其当前工作目录通常是口令文件 ...
- [04]APUE:文件与目录
[a] stat / lstat / fstat #include <sys/stat.h> int stat(const char *restrict pathname, struct ...
- Python::OS 模块 -- 文件和目录操作
os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...
随机推荐
- ruby 模块 的引入
module My NA="China" def My.set_name(name) @name=name end def My.get_name return @name end ...
- Android:MD5加密
/** * @author gongchaobin * * MD5加密 * * @version 2013-8-22 */ public class MD5Util { // 用来将字节转换成 16 ...
- ORACLE查看锁(lock)情况
SELECT /*+ RULE */ ls.osuser os_user_name, ls.username user_name, DECODE ...
- Android开发之通过Intent启动其他App的Service
在Android5.0以前可以通过隐式Intent方式启动其他App的Service,就跟Activity启动隐式Intent一样的. 但是在5.0以后,只能使用显示的Intent方式启动了. 启动其 ...
- shutdown,init,halt,poweroff,reboot的区别和联系, pkill -kill -t tty7注销
前言 最近这些天,每天晚上关机前,都会在osc上发一条动弹,“我要init 0了,各位晚安啊”,这是一件再正常不过的事情了. 看似很平常的一件事情,不过在昨晚就被一位同学的回复给难住了,到底是什么样的 ...
- bzoj1922
首先机器人是并行的: 很容易想到到某个点的最短用时 =max(到这个点的最短路,max(到保护这个点结界所在点的最短用时)) 所以我们在做dij的时候,d[j]维护最短路,w[j]维护所有保护这个点结 ...
- Oracle.ManagedDataAccess.Client注意事项
OracleConnection m_DbConnection = new OracleConnection(connectionString); if (m_DbConnection.State = ...
- Linux Kernel‘ieee80211_radiotap_iterator_init()’函数拒绝服务漏洞
漏洞名称: Linux Kernel‘ieee80211_radiotap_iterator_init()’函数拒绝服务漏洞 CNNVD编号: CNNVD-201312-041 发布时间: 2013- ...
- Linux中的syslog 入门学习教程
syslog是linux系统中默认的日志守护进程,默认的syslog配置文件是/etc/syslog.conf文件.程序.守护进程和内核提供了访问系统的日志信息.任何希望生成日志信息的程序都可以向sy ...
- Android学习笔记(1)—Android Studio安装
Android Studio 是一个全新的 Android 开发环境,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工 ...