Linux getcwd()的实现【转】

转自:http://www.cnblogs.com/alan-forever/p/3721908.html

通过getcwd()可以获取当前工作目录。

1 #include <unistd.h>
2
3 char *getcwd(char *cwdbuf, size_t size);

成功调用返回指向cwdbuf的指针,失败返回NULL。

getcwd()的实现是《Linux/Unix系统编程手册》的练习18.5,题目如下:

实现一个功能与getcwd()相当的函数。提示:要获取当前工作目录的名称,可调用opendir()和readdir()来遍历其父目录(..)中的各个条目,查找其中与当前工作目录具有相同i-node编号及设备号的一项。如此这般,沿着目录树层层拾级而上(chdir(..))并进行扫描,就能构建出完整的目录路径。当前目录与当前工作目录相同时,就结束遍历。无论调用该函数成功与否,都应将调用者遣回其起始目录(使用open()和fchdir()能方便地实现这一功能)

1、通过stat获取文件信息,根据文件信息中的i-node编号和设备号来找到正确的目录

2、运用opendir()、readdir()来获取目录的信息,目录不能通过read()来获取信息。

PS:tlpi_hdr.h头文件为《Linux/Unix系统编程手册》的头文件,可以去作者的网站下载,其中的errExit()为错误处理函数。。。。

  1 /*
  2  * =====================================================================================
  3  *
  4  *       Filename:  18.5.c
  5  *
  6  *    Description:
  7  *
  8  *        Version:  1.0
  9  *        Created:  2014年05月11日 14时04分35秒
 10  *       Revision:  none
 11  *       Compiler:  gcc
 12  *
 13  *         Author:  alan (), [email protected]
 14  *   Organization:
 15  *
 16  * =====================================================================================
 17  */
 18
 19 #include <sys/stat.h>
 20 #include <fcntl.h>
 21 #include <dirent.h>
 22 #include <sys/types.h>
 23 #include "tlpi_hdr.h"
 24
 25 #define BUF_MAX 4096
 26
 27 extern int errno;
 28
 29 char *Getcwd(char *cwdbuf, size_t size){
 30     char path[BUF_MAX], cwd[BUF_MAX];
 31     DIR *dirp;
 32     struct dirent *dp;
 33     struct stat sb, sb_d, sb_1;
 34     dev_t dev;
 35     ino_t ino;
 36
 37     while(1){
 38         //获取当前目录的文件信息
 39         if(stat(".", &sb) == -1)
 40             errExit("stat");
 41         dev = sb.st_dev;
 42         ino = sb.st_ino;
 43
 44         //获取父目录的对应的目录流和父目录的文件信息
 45         if((dirp = opendir("..")) == NULL)
 46             errExit("opendir");
 47         if(stat("..", &sb_1) == -1)
 48             errExit("stat");
 49
 50         //判断当前目录是否与父目录相同
 51         if(sb_1.st_dev == dev && sb_1.st_ino == ino)
 52             break;
 53
 54         errno = 0;
 55
 56         //在父目录对应的目录流读取条目
 57         while((dp = readdir(dirp)) != NULL){
 58             snprintf(path, BUF_MAX, "../%s", dp->d_name);
 59
 60             if(stat(path, &sb_d) == -1)
 61                 errExit("stat");
 62
 63             //得到当前目录对应的条目并将目录逐渐完善
 64             if(dev == sb_d.st_dev && ino == sb_d.st_ino){
 65                 memset(cwd, 0, sizeof(cwd));
 66                 if(strcat(cwd, "/") == NULL)
 67                     errExit("strcat");
 68                 if(strcat(cwd, dp->d_name) == NULL)
 69                     errExit("strcat");
 70                 if(strcat(cwd, cwdbuf) == NULL)
 71                     errExit("strcat");
 72
 73                 if(strncpy(cwdbuf, cwd, BUF_MAX) == NULL)
 74                     errExit("strncpy");
 75                 break;
 76             }
 77
 78         }
 79
 80         if(dp == NULL && errno != 0)
 81             errExit("readdir");
 82
 83         closedir(dirp);
 84         chdir("..");      //改变当前目录
 85     }
 86
 87     return cwdbuf;
 88 }
 89
 90 int main(int argc, char *argv[]){
 91     char buf[BUF_MAX];
 92     char t_buf[BUF_MAX];
 93     char *p;
 94     int fd;
 95
 96     if((fd = open(".", O_RDONLY)) == -1)
 97         errExit("open");
 98
 99     if(argc != 1)
100         usageErr("%s", argv[0]);
101
102     p = Getcwd(buf, BUF_MAX);
103     if(p == NULL)
104         errExit("My getcwd");
105     printf("My getcwd: %s\n", p);
106     fchdir(fd);    //遣回最初的目录
107
108     p = getcwd(t_buf, BUF_MAX);
109     if(p == NULL)
110         errExit("getcwd");
111     printf("getcwd: %s\n", p);
112
113     exit(EXIT_SUCCESS);
114 }

测试结果:

[email protected]:~/Code/tlpi$ pwd
/home/lancelot/Code/tlpi
[email protected]:~/Code/tlpi$ ./18.5
My getcwd: /home/lancelot/Code/tlpi
getcwd: /home/lancelot/Code/tlpi
时间: 2024-10-15 01:18:24

Linux getcwd()的实现【转】的相关文章

C/C++ Windows移植到Linux

近期写了有关Socket的程序,需要从windows移植到linux.现把有用的东东收集整理记录下来. 1.头文件windows下winsock.h或winsock2.h:linux下netinet/in.h(大部分都在这儿),unistd.h(close函数在这儿),sys/socket.h(在in.h里已经包含了,可以省了). 2.初始化windows下需要用WSAStartup启动Ws2_32.lib,并且要用#pragma comment(lib,"Ws2_32")来告知编译器

Linux gcc getcwd()的实现 zhuan

通过getcwd()可以获取当前工作目录. 1 #include <unistd.h> 2 3 char *getcwd(char *cwdbuf, size_t size); Linux gcc getcwd()的实现 zhuan

Linux总结

1 Linux第一天==================================================================================== 2 一.基础命令 3 1.history 查看历史命令,此终端自安装至现在的所有. 4 2.命令解析器: 5 1)shell. 针对Unix操作系统 6 2)bash. 针对Linux操作系统 7 3)工作方式: 用户在终端输入命令, 命令解析器搜索(通过环境变量中的路径)对应的路径,查找同名命令,如果找到了

Linux服务器程序规范

除了网络通信外,服务器程序还必须考虑许多其他细节问题,零碎,但基本上时模板式的. ---引 Linux服务器程序一般以后台形式运行.后台程序又称守护进程.它没有控制终端,因而也不会意外接受用户输入.守护进程的父进程一般是init进程(pid=1). Linux服务器程序通常有一套日志系统,它至少能输出日志到文件,有的高级服务器可以输出日志到专门的UDP服务器.大部分后台进程都在/var/log下有自己的日志目录. Linux服务器程序一般以某个专门的非root身份运行.mysqld, httpd

python 常用对linux系统文件及目录的操作

目录 1.取得当前目录——os.getcwd() >>> import os >>> s=os.getcwd()#获得当前运行脚本所在目录 >>> s 'C:\\Python27' 比如运行test.py,那么输入该命令就会返回脚本所在的文件夹位置. 例如将test.py放入A文件夹.并且希望不管将A文件夹放在硬盘的哪个位置,都可以在A文件夹内生成一个新文件夹.且文件夹的名字根据时间自动生成. >>> import os >&g

linux 文件操作编程

Linux中所有的设备和文件的操作都使用文件描述符来进行. 文件描述符是一个非负的整数,它是一个索引值,指向内核中每个进程打开的记录表. 当打开一个文件或者创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件的时候,就要把文件描述符作为参数传递给相应的函数. 一个进程时,都会打开3个文件:标准输入.标准输出和标准出错处理.分别对应文件描述符的0.1.2. rename函数 #include <stdio.h> int rename(const char *oldpath, cons

编程实现Linux下的ls -l

头文件 #ifndef __FUNC_H__ #define __FUNC_H__ #include<stdio.h> #include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #inc

Linux 程序设计学习笔记----POSIX 文件及目录管理

转载请注明:http://blog.csdn.net/suool/article/details/38141047 问题引入 文件流和文件描述符的区别 上节讲到ANSI C 库函数的实现在用户态,流的相应资源也在用户空间,但无论如何实现最终都需要通过内核实现对文件的读写控制.因此fopen函数必然调用了对OS的系统调用.这一调用在LINUX下即为open, close, read, write等函数.这些都遵循POSIX标准. so,在linux系统中是如何通过POSIX标准实现对文件的操作和目

linux基础的一些常见问题总结_学习笔记

平时自己的总结(miscellaneous) oracle无法实现远程用户连接:  解决办法:       #sqlplus /nolog     SQL> connect / as sysdba    SQL> alter system set local_listener = '(ADDRESS = (PROTOCOL=TCP)(HOST=192.168.0.2)(PORT=1521)(SID=orcl))' scope=spfile;        SQL> shutdown im