实现mypwd&mybash&myod&读者写者
目录:
一、mypwd
二、mybash
三、myod
四、读者、写者
- 学习pwd命令
- 研究pwd实现需要的系统调用(man -k; grep),写出伪代码
- 实现mypwd
- 测试mypwd
1、pwd命令学习
pwd(print working directory) 作用:打印出当前路径全名
symlink :符号链接
2、研究pwd实现需要的系统调用(man -k; grep),写出伪代码
由上可以看出:
系统调用命令:Getcwd
头文件和参数
#include <unistd.h>
char *getcwd(char *buf, size_t size);
1、用“.”当前目录的inode;
2、用“..”获取父级目录的up_inode;
3、判断当前目录和上级目录的inode-number是否一样;
4、如果两个inode-number一样则说明到达根目录,输出完整路径,退出程序;
5、如果两个inode-number不一样,切换至父级目录,根据步骤1获取的inode-number,在父级目录中搜索对应的文件名记录,返回步骤1。
3、实现mypwd
#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 *);
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);
}
int main()
{
printpath();
putchar('\n');
return ;
}
结果截图:
- 使用fork,exec,wait实现mybash
- 写出伪代码,产品代码和测试代码
- 发表知识理解,实现过程和问题解决的博客
前:bash是大多数Linux系统以及Mac OS X默认的shell
fork:
(duplicate:重复的(adj)副本(n) 复制(v)calling:调用)
与之相关的头文件&函数
#include <unistd.h>
pid_t fork(void);
exec:
(macro:宏观 glibc:linux系统中最底层的api)
与之相关的头文件&函数
#include <unistd.h>
int execv(const char *path, char *const argv[]);
wait:
与之相关的头文件&函数
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
实现过程:
伪代码:
用户输入命令;
创建子进程;
执行命令;
产品代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#define MAX 128
void eval(char *cmdline);
int parseline(char *buf, char **argv);
int builtin_command(char **argv);
int main()
{
char cmdline[MAX];
printf("This is 20165327yjt's bash!\n");
while(1)
{
printf("> ");
fgets(cmdline, MAX, stdin);
if(feof(stdin))
exit(0);
eval(cmdline);
}
}
void eval(char *cmdline)
{
char *argv[MAX];
char buf[MAX];
int bg;
pid_t pid;
strcpy(buf,cmdline);
bg = parseline(buf,argv);
if(argv[0]==NULL)
return;
if(!builtin_command(argv))
{
if((pid=fork()) == 0)
{
if(execvp(argv[0],argv) < 0)
{
printf("%s : Command not found.\n",argv[0]);
exit(0);
}
}
}
if(!bg)
{
int status;
if(waitpid(-1,&status,0) < 0)
printf("waitfg: waitpid error!");
}
else
{
printf("%d %s",pid, cmdline);
return;
}
}
int builtin_command(char **argv)
{
if(!strcmp(argv[0], "quit"))
exit(0);
if(!strcmp(argv[0],"&"))
return 1;
return 0;
}
int parseline(char *buf,char **argv)
{
char *delim;
int argc;
int bg;
buf[strlen(buf)-1]=' ';
while(*buf && (*buf == ' '))
buf++;
argc=0;
while( (delim = strchr(buf,' ')))
{
argv[argc++] = buf;
*delim= '\0';
buf = delim + 1;
while(*buf && (*buf == ' '))
buf++;
}
argv[argc] = NULL;
if(argc == 0)
return 1;
if((bg=(*argv[argc-1] == '&')) != 0)
argv[--argc] = NULL;
return bg;
}
测试代码:
ls
ls -a
ls -l
运行截图:
返回目录
三、myod