gpt4 book ai didi

c - 用 C 实现的 UNIX 命令

转载 作者:太空狗 更新时间:2023-10-29 12:20:48 24 4
gpt4 key购买 nike

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

我相信,除了“jobs”命令和“cd”命令之外的所有命令都有效,但我不确定为什么这两个命令不起作用。

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

#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 .

此时您想使用 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 级缩进 - 听说过 arrow code

关于c - 用 C 实现的 UNIX 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9339472/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com