用C实现的UNIX命令 [英] UNIX Commands Implemented in C

查看:79
本文介绍了用C实现的UNIX命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的操作系统类,我有一个作业,该作业建立在先前的作业上.不幸的是,除了我不知道下一个项目需要从哪里开始之外,我的上一个项目无法正常工作.我下面的代码假设是模拟一个简单的UNIX/Linux shell,其中包含一些其他命令无法使用execvp来执行:通过&运算符进行后台处理,'jobs'shell命令:列出所有活动子进程的pid(即不是终止的),僵尸"进程的收割"以及"cd" shell命令:更改外壳的工作目录.

For my Operating Systems class I have an assignment due that is built onto a previous assignment. Unfortunately my previous project doesn't work correctly in addition to me not knowing where I need to start for the next project. The code which I have below is suppose to mimic a simple UNIX/Linux shell with some additional commands that cannot be performed with execvp: background processing via the ampersand operator, the 'jobs' shell command: list the pids of all living child processes (i.e. not ones that have terminated), "reaping" of "zombie" processes, and the 'cd' shell command: change the shell's working directory.

我相信,除了"jobs"命令和"cd"命令之外的所有命令都可以工作,但是我不确定为什么这两个命令不起作用.

I believe, everything but the "jobs" command, and "cd" command work, but I'm not sure why these two don't.

下一个任务是以"mysh $ cmd arg1 arg2 argN> file.out"的形式添加一些I/O重定向,我什至不知道该从哪里真正开始...

The next assignment is to add some I/O redirection in the form of "mysh$ cmd arg1 arg2 argN > file.out" which I don't know where to even really begin...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <wait.h>
#include <signal.h>
#include <sys/types.h>

int main(int argc, char **argv) {
    char bBuffer[BUFSIZ], *pArgs[10], *aPtr = NULL, *sPtr;
    int jobs[100];
    int jobList = 0;
    int background;
    ssize_t rBytes;
    int aCount;
    pid_t pid;
    int status;
    while(!feof(stdin)) {
        pid = waitpid(-1, &status, WNOHANG);
        if (pid > 0)
        printf("waitpid reaped child pid %d\n", pid);
        write(1, "\e[1;31mmyBash \e[1;32m# \e[0m", 27);
        rBytes = read(0, bBuffer, BUFSIZ-1);
        if(rBytes == -1) {
        perror("read");
        exit(1);
    }

    bBuffer[rBytes-1] = '\0';
    if(!strcasecmp(bBuffer, "exit")){ 
        exit(0);
    }

    sPtr = bBuffer;
    aCount = 0;
    do {
        aPtr = strsep(&sPtr, " ");
        pArgs[aCount++] = aPtr;
    } while(aPtr);
        background = (strcmp(pArgs[aCount-2], "&") == 0);
        if (background)
        pArgs[aCount-2] = NULL;

        if (strlen(pArgs[0]) > 1) {
            pid = fork();
            if (pid == -1) {
                perror("fork");
                exit(1);
            } else if (pid == 0) {
                jobs[jobList] = pid;
                jobList++;

                if(!strcasecmp(pArgs[0], "jobs")){                                         
                    for(int i; i<jobList; i++) {
                        if(kill(jobs[i],0)==0){
                            printf(jobs[i]);    
                        }
                        printf("these are jobs\n");
                        exit(1);
                    }
                    if(!strcasecmp(pArgs[0], "cd")){ 
                        int ret;
                        if (!pArgs[1])
                            strcpy(bBuffer, "pwd");
                        ret = chdir(pArgs[1]);
                        strcpy(bBuffer, "pwd");
                        exit(1);
                    }                                
                    fclose(stdin);
                    fopen("/dev/null", "r");
                    execvp(pArgs[0], pArgs);
                    exit(1);
                } else if (!background) {
                    pid = waitpid(pid, &status, 0);
                    if (pid > 0)
                        printf("waitpid reaped child pid %d\n", pid);
                }
        }
    }
    return 0;
}

推荐答案

首先,您将要分析行并检测到需要重定向到文件.因此,假设您使用strsep或其他任何内容,您发现输出将进入file.out或输入来自file.in.

First you;ll want to parse your line and detect that you need to redirect to a file. So let;s say you use strsep or whatever and you found out output is going to file.out or input is coming from file.in.

这时,您想使用dup/dup2重定向输出.例如,要重定向STDOUT:

At this point you want to redirect output using dup / dup2. For example, to redirect STDOUT:

int
do_redirect(int fileno, const char *name)
{
    int newfd;

    switch (fileno) {
    case STDOUT_FILENO:
        newfd = open(name, O_WRONLY | O_CREAT, S_IRUSR | S_IRUSR);
        break;
    }
    if (newfd == -1) {
        perror("open");
        return -1;
    }

    return dup2(fileno, newfd);
}
/* ... */


pid = fork();
do_redirect(STDOUT_FILENO, name);

注意事项:

  • 我没有测试代码-它甚至可能无法编译
  • 我没有做太多的错误检查-您应该(我为open所做的方式)
  • 您需要自己实现STDIN_FILENO重定向
  • 请注意我是如何使用单独的功能的,您的main确实会很大
  • 您的代码具有大约7个缩进级别-曾经听说过箭头代码?
  • I didn't test the code - it might not even compile
  • I didn't do much error-checking - you should (the way I did for open)
  • You need to implement STDIN_FILENO redirection on your own
  • Note how I used a separate function, your main is WAY to large as it is
  • Your code has something like 7 levels of indentation - ever heard about arrow code ?

这篇关于用C实现的UNIX命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆