20155228 2017-11-19 实现mypwd(选做,加分)

时间:2023-03-09 15:51:31
20155228 2017-11-19 实现mypwd(选做,加分)

20155228 2017-11-19 实现mypwd(选做,加分)

题目和要求

  1. 学习pwd命令
  2. 研究pwd实现需要的系统调用(man -k; grep),写出伪代码
  3. 实现mypwd
  4. 测试mypwd

分析和设计

PWD命令

pwd [ -L | -P ]

描述

pwd 命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用 /(斜线)分隔。第一个 / 表示根目录,最后一个目录是当前目录。

参数

  • -L:如果 PWD 环境变量包含了不包含文件名 .(点)或 ..(点点)的当前目录的绝对路径名,则显示 PWD 环境变量的值。否则,-L 标志与 -P 标志一样运行。
  • -P:显示当前目录的绝对路径名。与 -P 标志一起显示的绝对路径不包含在路径名的绝对路径中涉及到符号链接类型的文件的名称。
  • 退出状态:该命令返回以下出口值:0 成功完成;>0 发生错误。

使用man和grep研究pwd涉及的系统调用

  • man -k pwd:没有找到任何系统调用

    20155228 2017-11-19 实现mypwd(选做,加分)

  • man -k current directory:以pwd的描述作为关键字进行查找

    20155228 2017-11-19 实现mypwd(选做,加分)

  • man -k current directory | grep 2:筛选系统调用命令,发现一个叫做getcwd的系统调用,从描述来看,完全符合需求

    20155228 2017-11-19 实现mypwd(选做,加分)

系统调用命令:Getcwd

头文件和参数
#include <unistd.h>

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

These functions return a null-terminated string containing an absolute pathname that is thecurrent working directory of the calling process. The pathname is returned as the functionresult and via the argument buf, if present.If the current directory is not below the root directory of the current process (e.g., becausethe process set a new filesystem root using chroot(2) without changing its current directoryinto the new root), then, since Linux 2.6.36, the returned path will be prefixed with thestring "(unreachable)". Such behavior can also be caused by an unprivileged user by changingthe current directory into another mount namespace. When dealing with paths from untrustedsources, callers of these functions should consider checking whether the returned path startswith '/' or '(' to avoid misinterpreting an unreachable path as a relative path.

这些函数返回一个以null结尾的字符串,其中包含绝对路径名调用进程的当前工作目录。 路径名作为函数返回结果和通过参数buf,如果存在。如果当前目录不在当前进程的根目录下(例如,因为该进程使用chroot(2)设置新的文件系统根目录,而不更改其当前目录进入新的根目录),那么,从Linux 2.6.36开始,返回的路径将以前缀字符串“(无法访问)”。 这种行为也可能是由非特权用户通过改变而引起的将当前目录转换为另一个挂载名称空间。 处理来自不受信任的路径来源,这些函数的调用者应该考虑检查返回的路径是否开始用'/'或'('来避免将不可达路径误解为相对路径。

代码和测试

  • 代码编写
#include "unistd.h"
#include "stdio.h"
int main(void)
{
printf("%s\n",getcwd(NULL,0));
return 0;
}
#include<stdio.h>
#include<sys/stat.h>
#include<dirent.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
void printpath();
char *inode_to_name(int);
int getinode(char *);
int main()
{
printpath();
putchar('\n');
return ;
}
void printpath()
{
int inode,up_inode;
char *str;
inode = getinode(".");
up_inode = getinode("..");
chdir("..");
str = inode_to_name(inode);
if(inode == up_inode) {
// printf("/%s",str);
return;
}
printpath();
printf("/%s",str);
}
int getinode(char *str)
{
struct stat st;
if(stat(str,&st) == -1){
perror(str);
exit(-1);
}
return st.st_ino;
}
char *inode_to_name(int inode)
{
char *str;
DIR *dirp;
struct dirent *dirt;
if((dirp = opendir(".")) == NULL){
perror(".");
exit(-1);
}
while((dirt = readdir(dirp)) != NULL)
{
if(dirt->d_ino == inode){
str = (char *)malloc(strlen(dirt->d_name)*sizeof(char));
strcpy(str,dirt->d_name);
return str;
}
}
perror(".");
exit(-1);
}
  • 测试截图

    20155228 2017-11-19 实现mypwd(选做,加分)

参考资料

pwd (Unix命令)

Linux下用C语言实现pwd命令显示当前工作目录(再次修正)