C语言中的简单Shell
我正在做一个学校项目,基本上是在UNIX中创建一个简单的shell。 但我的项目中有历史部分,关于历史部分的解释如下: 历史记录–此命令用于维护以前发出的命令的历史记录 o历史记录-在shell中最多打印10条最近输入的命令 啊!编号-用户应能够重复先前由发出的命令 打字!数字,其中数字指示要重复的命令 注意!1用于重复由返回的命令列表中编号为1的命令 历史,还有-1用于重复最后一个命令 我的代码历史部分在这里:C语言中的简单Shell,c,bash,shell,unix,C,Bash,Shell,Unix,我正在做一个学校项目,基本上是在UNIX中创建一个简单的shell。 但我的项目中有历史部分,关于历史部分的解释如下: 历史记录–此命令用于维护以前发出的命令的历史记录 o历史记录-在shell中最多打印10条最近输入的命令 啊!编号-用户应能够重复先前由发出的命令 打字!数字,其中数字指示要重复的命令 注意!1用于重复由返回的命令列表中编号为1的命令 历史,还有-1用于重复最后一个命令 我的代码历史部分在这里: #include <stdio.h> #include <uni
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <limits.h>
#include <malloc.h>
#include <string.h>
#include <termios.h>
#include <errno.h>
#define CREATE_FLAGS (O_WRONLY | O_CREAT | O_APPEND)
#define CREATE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define CREATE_FLAG (O_WRONLY| O_CREAT| O_TRUNC)
#define MAXCHARNUM 128
#define MAXARGNUM 32
char *argsexec[MAXARGNUM];
char str[MAXCHARNUM];
char *path;
char *name;
struct Node
{
pid_t pid;
char *pname;
int index;
struct Node *nextPtr;
};
typedef struct Node Node;
typedef struct Node *NodePtr;
NodePtr list = NULL;
void addJob(NodePtr *currentPtr, pid_t pid, char *name, int indx)
{
NodePtr newPtr, prePtr, curPtr;
newPtr = malloc(sizeof(Node));
if (newPtr != NULL )
{
newPtr->pid = pid;
newPtr->pname = name;
newPtr->index = indx;
newPtr->nextPtr = NULL;
prePtr = NULL;
curPtr = *currentPtr;
while (curPtr != NULL )
{
prePtr = curPtr;
curPtr = curPtr->nextPtr;
}
if (prePtr == NULL )
{
newPtr->nextPtr = *currentPtr;
*currentPtr = newPtr;
}
else
{
prePtr->nextPtr = newPtr;
newPtr->nextPtr = curPtr;
}
}
}
void printJob(NodePtr curPtr)
{
if (curPtr == NULL )
{
printf("Running: List is empty.\n");
printf("Terminated: List is empty.\n");
}
else
{
printf("Running:\n");
while (curPtr != NULL )
{
printf("[%d] --> %s\n", curPtr->index, curPtr->pname);
curPtr = curPtr->nextPtr;
}
printf("Finished:\n");
while (curPtr != NULL )
{
printf("[%d] --> %s (pid = %d)\n", curPtr->index, curPtr->pname,
curPtr->pid);
curPtr = curPtr->nextPtr;
}
}
}
void ioredirection()
{
int input = -1, output = -1, append = -1;
int k, d, fdinput, fdoutput;
for (k = 0; argsexec[k] != NULL ; k++)
{
if (strcmp(argsexec[k], "<") == 0)
{
argsexec[k] = NULL;
input = k;
d = 1;
}
else if (strcmp(argsexec[k], ">") == 0)
{
argsexec[k] = NULL;
output = k;
d = 2;
}
else if (strcmp(argsexec[k], ">>") == 0)
{
argsexec[k] = NULL;
append = k;
d = 3;
}
if (d == 1)
{
fdinput = open(argsexec[input + 1], O_RDONLY, 0);
dup2(fdinput, STDIN_FILENO);
close(fdinput);
execvp(argsexec[0], argsexec);
}
if (d == 2)
{
int x, y;
char buffer[1024];
fdinput = open(argsexec[output - 1], O_RDONLY);
fdoutput = open(argsexec[output + 1], CREATE_FLAG, CREATE_MODE);
dup2(fdoutput, STDOUT_FILENO);
x = read(fdinput, buffer, 1024);
write(fdoutput, buffer, x);
close(fdinput);
close(fdoutput);
for (y = output; y < MAXARGNUM - 2; y++)
argsexec[y] = argsexec[y + 2];
argsexec[MAXARGNUM - 2] = NULL;
}
if (d == 3)
{
int x, y;
char buffer[1024];
fdinput = open(argsexec[output - 1], O_RDONLY);
fdoutput = open(argsexec[output + 1], CREATE_FLAGS, CREATE_MODE);
x = read(fdinput, buffer, 1024);
write(fdoutput, buffer, x);
close(fdinput);
close(fdoutput);
}
}
}
void add_path(char **dir, const char *begin, const char *end) //do the memory allocations, and add to the specified arrays.
{
if (end == begin)
{
begin = " ";
end = begin + 1;
}
size_t len = end - begin;
*dir = malloc(len + 1);
memmove(*dir, begin, len);
(*dir)[len] = '\0';
}
size_t tokenize(const char *path, char **dirs, size_t max_dirs, char delim) //tokenize the given input, with the given delimiter
{ //returns the size of the splitted parts of the string.
const char *begin = path;
const char *end;
size_t num_dirs = 0;
while (num_dirs < max_dirs && (end = strchr(begin, delim)) != 0)
{
add_path(&dirs[num_dirs++], begin, end);
begin = end + 1;
}
if (num_dirs < max_dirs && *begin != '\0')
add_path(&dirs[num_dirs++], begin, begin + strlen(begin));
return num_dirs;
}
void clearArgs()
{
int i;
for (i = 0; i < MAXARGNUM; ++i)
{
argsexec[i] = NULL;
}
}
int Ampersand()
{
int i;
for (i = 0; argsexec[i] != NULL ; i++)
{
if (strcmp(argsexec[i], "&") == 0)
{
return 1;
}
else
{
return 0;
}
}
}
void Setup()
{
while (1)
{
path = malloc((MAXCHARNUM + 1) * sizeof(char));
clearArgs();
fprintf(stderr, "333sh: ", NULL );
gets(str); //get the next commands
while (strlen(str) == 0)
{ //if the user enters empty string or space, ignore this input, read again.
fprintf(stderr, "333sh: ", NULL );
gets(str);
}
size_t commands = tokenize(str, argsexec, MAXARGNUM, ' ');
const char *path = getenv("PATH"); //get the system's path
ioredirection();
char * const arguments[] =
{ argsexec[0], argsexec[1], argsexec[2], argsexec[3], argsexec[4],
argsexec[5], argsexec[6], argsexec[7], (void*) NULL };
name = argsexec[0];
pid_t pid = fork();
wait(NULL );
if (Ampersand())
{
if (pid == 0)
{
int in = 1;
addJob(&list, pid, name, in);
}
}
if (pid == 0)
{
if (!Ampersand())
{
if (path == NULL )
{ //execl part
execl(path, argsexec[0], argsexec[1], argsexec[2], argsexec[3],
argsexec[4], argsexec[5], argsexec[6], argsexec[7], NULL );
}
else if (strcmp(argsexec[0], "dir") == 0 && argsexec[1] == NULL )
{
system("ls");
}
else if (strcmp(argsexec[0], "clr") == 0)
{
system("clear");
}
else if (strcmp(argsexec[0], "cd") == 0 && argsexec[1] == NULL )
{
system("pwd");
}
else if (strcmp(argsexec[0], "list_jobs") == 0 && argsexec[1] == NULL )
{
printJob(list);
}
else
{ //execvp part
execvp(argsexec[0], arguments);
}
}
}
}
}
int main(int argc, char const *argv[])
{
Setup();
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义创建标志(O_WRONLY | O_CREATE | O_APPEND)
#定义创建模式(S|u IRUSR | S|u IWUSR | S|u IRGRP | S|IROTH)
#定义创建标志(O_WRONLY | O_CREATE | O_TRUNC)
#定义MAXCHARNUM 128
#定义MAXARGNUM 32
char*argsexec[MAXARGNUM];
char str[MAXCHARNUM];
字符*路径;
字符*名称;
结构体类型
{
pid_t pid;
char*pname;
整数指数;
结构节点*nextPtr;
};
typedef结构节点;
typedef结构节点*NodePtr;
NodePtr list=NULL;
void addJob(NodePtr*currentPtr,pid\u t pid,char*name,int indx)
{
NodePtr newPtr、prePtr、curPtr;
newPtr=malloc(sizeof(Node));
如果(newPtr!=NULL)
{
新建PTR->pid=pid;
newPtr->pname=名称;
newPtr->index=indx;
newPtr->nextPtr=NULL;
prePtr=NULL;
curPtr=*currentPtr;
while(curPtr!=NULL)
{
prePtr=curPtr;
curPtr=curPtr->nextPtr;
}
if(prePtr==NULL)
{
newPtr->nextPtr=*当前ptr;
*currentPtr=newPtr;
}
其他的
{
prePtr->nextPtr=newPtr;
newPtr->nextPtr=curPtr;
}
}
}
无效打印作业(NodePtr curPtr)
{
如果(curPtr==NULL)
{
printf(“正在运行:列表为空。\n”);
printf(“已终止:列表为空。\n”);
}
其他的
{
printf(“正在运行:\n”);
while(curPtr!=NULL)
{
printf(“[%d]-->%s\n”,curPtr->index,curPtr->pname);
curPtr=curPtr->nextPtr;
}
printf(“完成:\n”);
while(curPtr!=NULL)
{
printf(“[%d]-->%s(pid=%d)\n”,curPtr->index,curPtr->pname,
curPtr->pid);
curPtr=curPtr->nextPtr;
}
}
}
void ioredirection()
{
int-input=-1,output=-1,append=-1;
int k,d,fdinput,fdoutput;
对于(k=0;argsexec[k]!=NULL;k++)
{
if(strcmp(argsexec[k],“”)=0)
{
argsexec[k]=NULL;
输出=k;
d=2;
}
else if(strcmp(argsexec[k],“>>”==0)
{
argsexec[k]=NULL;
追加=k;
d=3;
}
如果(d==1)
{
fdinput=open(argsexec[input+1],仅限ordu,0);
dup2(fdinput,标准文件号);
关闭(FDI输入);
execvp(argsexec[0],argsexec);
}
如果(d==2)
{
int x,y;
字符缓冲区[1024];
fdinput=open(argsexec[output-1],仅限Ordu);
fdoutput=open(argsexec[output+1],创建_标志,创建_模式);
dup2(fdoutput,标准输出文件号);
x=读取(FDI输入,缓冲区,1024);
写入(输出、缓冲区、x);
关闭(FDI输入);
关闭(FD输出);
对于(y=输出;y