实现mypwd&mybash&myod&读者写者


目录:
一、mypwd
二、mybash
三、myod
四、读者、写者


一、实现mypwd

  • 学习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 ;  
}  

结果截图:

返回目录


二、实现mybash:

  • 使用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

posted @ 2018-11-22 06:13  21-CarpeDiem  阅读(144)  评论(0编辑  收藏  举报