在C中实现的UNIX命令

对于我的操作系统类,我有一个分配到期的任务。 不幸的是,我以前的项目不能正常工作,除了我不知道我需要从哪里开始下一个项目。 下面的代码假设模仿一个简单的UNIX / Linuxshell,其中一些额外的命令不能用execvp来执行:通过&符号操作符的后台处理,'jobs'shell命令:列出所有活着的subprocess的pid即不是终止的),“僵尸”进程的“收获”和“cd”shell命令:更改shell的工作目录。

我相信,除了“工作”命令和“cd”命令之外的所有东西都可以工作,但我不确定为什么这两个都不行。

下一个任务是以“mysh $ cmd arg1 arg2 argN> file.out”的forms添加一些I / Oredirect,我不知道哪里真的开始了…

#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; } 

Solutions Collecting From Web of "在C中实现的UNIX命令"

首先你要分析你的行,并检测到你需要重定向到一个文件。 所以,让我们说你使用strsep或其他什么,你发现输出是去file.out或输入来自file.in

此时你想用dup / dup2重定向输出。 例如,重定向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级缩进 – 听说过箭头代码 ?

由于这是作业,我不会直接给你代码。

dupdup2freopen都可以用来查看输入/输出重定向。

fork启动并发进程(&符号)

你在正确的轨道上使用waitpid来获取子进程。