Unix/Linux编程:getcwd()、chdir()

221 篇文章 37 订阅

一个进程的当前工作目录(current working directory)定义了该进程解析相对路径名的起点。新进程的当前工作目录继承自其父进程

获取当前工作目录

进程可使用 getcwd()来获取当前工作目录

       #include <unistd.h>

       char *getcwd(char *buf, size_t size);

       char *getwd(char *buf);

       char *get_current_dir_name(void);

  • getcwd()函数将内含当前工作目录决定路径的字符串(包括结尾空字符)置于buf指向的已分配缓冲区中。调用者必须为buf缓冲区分配至少size个字节的空间(通常,buf的大小与PATH_MAX常量相当)
  • 一旦调用成功,getcwd()将返回一枚指向buf的指针。如果当前工作目录的路径名长度超过size个字节,那么getcwd()会返回 NULL,并将 errno 置为 ERANGE。
  • 若 cwdbuf 为 NULL,且 size 为 0,则 glibc 封装函数会为 getcwd()按需分配一个缓冲区,并将指向该缓冲区的指针作为函数的返回值。为避免内存泄漏,调用者之后必须调用 free()来释放这一缓冲区。对可移植性有所要求的应用程序应当避免依赖该特性。大多数其他实现则针对 SUSv3 规范提供了一个更为简单的扩展。如果 buf 是 NULL,那么 getcwd()将分配一个大小为 size 字节的缓冲区,用于向调用者返回结果。glibc 的 getcwd()也实现了这一特性。

GNU C 函数库还为获取当前工作目录提供了另外两个函数。派生自 BSD 的 getwd(path)函数容易引起缓冲区溢出,因为该函数无法为返回的路径名长度设定上限。get_current_dir_name()函数也会返回包含当前工作目录名的一个字符串。虽然该函数易于使用,但却不具有可移植性。考虑到安全性和可移植性,getcwd()无疑是不二之选(前提是避免使用 GNU 扩展功能)

在Linux/x86-32系统中,getcwd()返回指针所指向的字符串最长长度可达4096个字节。如果当前工作目录(以及 buf和 size)突破了这一限制,那么就会直接对路径名做截断处理,移去始于起点的整个目录前缀(字符串仍以空字符结尾)。换言之,当当前工作目录的绝对路径超出这一限制时,getcwd()的行为也不再可靠。

实际上,Linux 的 getcwd()系统调用为要返回的路径名在内部分配了一个虚拟内存页。x86-32 架构的页大小为 4096 字节,而在页尺寸更大的架构中(比如,Alpha 的页大小为 8192字节),getcwd()能返回更长的路径名

只要具有合适的权限(大体要求是,身为进程属主或者具有 CAP_SYS_PTRACE 能力),就可通过读取(readlink())Linux 专有符号链接/proc/PID/cwd 的内容来确定任何进程的当前工作目录

看个例子:

    char *buffer;
    if((buffer = getcwd(NULL, 0)) == NULL)
    {
        perror("getcwd error");
    }
    else
    {
        printf("----%s\n", buffer);
    }

在这里插入图片描述

改变当前工作目录

NAME
       chdir, fchdir - change working directory

SYNOPSIS
       #include <unistd.h>

       int chdir(const char *path);
       int fchdir(int fd);

chdir()系统调用将调用进程的当前工作目录改变为由 pathname 指定的相对或绝对路径名(如属于符号链接,还会对其解除引用)

fchdir()系统调用与 chdir()作用相同,只是在指定目录时使用了文件描述符,而该描述符是之前调用 open()打开相应目录时获得的

以下代码片段所示为使用 fchdir()将进程的当前工作目录变为另一位置,然后再改回原始位置:
在这里插入图片描述
使用 chdir()达到同等效果的代码如下所示

在这里插入图片描述

看个例子

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//chdir和fchdir函数头文件
#include <unistd.h>
 
#define LENTH 255
 
int main(int argc,char *argv[])
{
	int ret;
	char pwd[LENTH];
 
//检测参数	
	if(argc <3){
		printf("\nPlease input file path\n");
		return 1;
	}
	
//getcwd函数获取当前目录		
	if(!getcwd(pwd,LENTH)){
		perror("getcwd");
		return 1;
	}
	printf("\ngetcwd pwd is %s\n",pwd);
	
//使用chdir函数转入其他目录
	ret = chdir(argv[1]);
	if(ret){
		printf("Please make sure file path\n");
		return 1;
	}
	printf("chdir %s is success!\n",argv[1]);
	
//转入其他目录,完成操作
//使用rmdir函数删除目录
	ret = rmdir(argv[2]);
	if(ret<0){
		printf("rmdir %s failed!\n",argv[2]);
		return 1;
	}
	printf("rmdir %s is success!\n",argv[2]);
	
//再次使用chdir回到pwd保存的目录
	ret = chdir(pwd);
	if(ret){
		printf("Please make sure file path\n");
		return 1;
	}
	printf("chdir %s is success!\n",pwd);
 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值