代码拉取完成,页面将自动刷新
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<wait.h>
#include<ctype.h>
#include<fcntl.h>
#include<sys/stat.h>
#define NUM 1024
#define SEP " "
#define SIZE 64
#define NoneRedir 0
#define OutputRedir 1
#define AppendRedir 2
#define InputRedir 3
int redir = NoneRedir;
char *filename = NULL;
char cwd[1024];
char enval[1024]; // for test
int lastcode = 0;
//#define debug -1
// 获取环境变量 user,hostname,pwd
char *homepath()
{
char *home= getenv("HOME");
if(home) return home;
else return (char*)".";
}
const char *getUsername()
{
const char *name = getenv("USER");
if(name) return name;
else return "none";
}
const char *getHostname()
{
const char *hostname = getenv("HOSTNAME");
if(hostname) return hostname;
else return "none";
}
const char *getCwd()
{
const char *cwd = getenv("PWD");
if(cwd) return cwd;
else return "none";
}
int getUserCommand(char *command, int num)
{
printf("[%s@%s %s]$ ",getUsername(), getHostname(), getCwd());
char *r = fgets(command, num, stdin); // 最后还是会输入'\n',回车
if(r == NULL) return -1; // TODO
command[strlen(command)-1] = '\0'; // 这里不会越界
return strlen(command);
}
void commandSplit(char *in, char *out[])
{
int argc = 0;
out[argc++] = strtok(in, SEP);
while(out[argc++] = strtok(NULL, SEP));
#ifdef debug
int i = 0;
for(i = 0; out[i]; i++)
{
printf("%d:%s\n", i, out[i]);
}
#endif
}
int execute(char *argv[])
{
pid_t id = fork();
if(id < 0) return -1;
else if(id == 0)
{
int fd = 0;
if(redir == InputRedir)
{
fd = open(filename, O_RDONLY);
dup2(fd, 0);
}
else if(redir == OutputRedir)
{
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
}
else if(redir == AppendRedir)
{
fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0666);
dup2(fd, 1);
}
else{
// do nothing
}
// 子进程
execvp(argv[0], argv);
exit(1);
}
else{
// 父进程
int status = 0;
pid_t rid = waitpid(id, &status, 0);
if(rid > 0)
{
lastcode = WEXITSTATUS(status);
}
}
return 0;
}
#define SkipSpace(pos) do{while(isspace(*pos)) pos++;}while(0)
void checkRedir(char usercommand[], int len)
{
char *end = usercommand + len - 1;
char *start = usercommand;
while(end > start)
{
if(*end == '>')
{
if(*(end-1) == '>')
{
*(end-1) = '\0';
filename = end + 1;
SkipSpace(filename);
redir = AppendRedir;
break;
}
else{
*end = '\0';
filename = end + 1;
SkipSpace(filename);
redir = OutputRedir;
break;
}
}
else if(*end == '<')
{
*end = '\0';
filename = end + 1;
SkipSpace(filename);
redir = InputRedir;
break;
}
else
{
end--;
}
}
}
void cd(const char *pash)
{
chdir(pash);
char tmp[1024];
getcwd(tmp, sizeof(tmp));
sprintf(cwd, "PWD=%s", tmp);
putenv(cwd);
}
int doBuildin(char *argv[])
{
if(strcmp(argv[0], "cd") == 0)
{
char *pash = NULL;
if(argv[1] == NULL) pash = homepath();
else
{
pash = argv[1];
}
cd(pash);
return 1;
}
else if(strcmp(argv[0], "exprot") == 0)
{
if(argv[1] == NULL) return 1;
strcpy(enval, argv[1]);
putenv(enval);
return 1;
}
else if(strcmp(argv[0], "echo") == 0)
{
if(argv[1] == NULL)
{
printf("\n");
return 1;
}
if(*(argv[1]) == '$' && strlen(argv[1]) > 1)
{
char *val = argv[1]+1;
if(strcmp(val, "?") == 0)
{
printf("%d\n", lastcode);
lastcode = 0;
}
else
{
const char *enval = getenv(val);
if(enval) printf("%s\n", enval);
else printf("\n");
}
return 1;
}
else{
printf("%s\n",argv[1]);
return 1;
}
}
return 0;
}
int main()
{
while(1)
{
redir = NoneRedir;
filename = NULL;
char usercommand[NUM];
char *argv[SIZE];
// 获取输入
int n = getUserCommand(usercommand, sizeof(usercommand));
if(n <= 0) continue;
// 检测是否发生重定向
checkRedir(usercommand, strlen(usercommand));
// 分割字符串 (strtok)
commandSplit(usercommand, argv);
// check Buildin
n = doBuildin(argv);
if(n) continue;
// 执行命令
execute(argv);
}
return 0;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。