【发布时间】:2013-04-16 07:46:05
【问题描述】:
我一直致力于编写一个简单的 shell,我已经设法获得了一些非常基本的功能,但是对于其中一个阶段,它要求我获取和设置环境。这是任务的详细信息。
第 4 阶段:获取和设置路径 - 10 分
保持原路径
这是必要的原因是因为我们希望将路径恢复到最初退出 shell 时的路径。这很重要,因为您对 shell 环境所做的任何更改(即上面的 setenv() 函数)不仅会影响 shell 本身,还会影响之后将从同一终端执行的任何其他程序。因此,最好将事情恢复到退出时的状态。
一个字符串就足以保留原始路径。
保存路径应该是你的 shell 在启动时做的第一件事。
打印和更改路径——内置命令
在 C 程序中,我们可以使用 getenv() 函数访问环境,也可以使用 setenv() 函数更改环境。如果您查看 setenv() 的手册页,您会发现它是如何工作的(即所需的参数和返回值)以及使用它需要包含的内容。
getpath – 打印系统路径 & setpath – 设置系统路径
这两个命令是关于环境参数PATH的。第一个只是获取并打印它的值,而第二个将路径(冒号分隔的目录列表的字符串)作为参数并使其成为 PATH 的值。为此,您可以分别使用 getenv() 和 setenv()。
恢复路径
您只需将 PATH 环境参数更改为其原始值(即您在 shell 启动时保存的那个)。
如果你的 shell 在它退出之前做的最后一件事,恢复路径。
第 4 阶段:测试
首先,确保您为第 3 阶段执行的所有测试仍然有效。不过要小心,因为我们现在正在更改路径,这将影响外部程序的执行。
要检查附加功能,您应该首先检查路径的保存和恢复是否有效。这里的一个好主意是在您在 shell 执行开始时保存路径时打印路径,然后在最后退出时再次打印。在这两种情况下,打印的路径应该完全相同!
接下来你应该检查当 getpath 被调用时你打印当前路径,它应该与原始路径相同。
那么你应该专注于测试setpath。首先,将路径设置为新值并测试 getpath 打印它,然后尝试查看更改路径如何真正影响外部命令的执行(例如,将路径设置为仅 '.' 并尝试 'ls' 或尝试外壳本身等)。
这是我的代码:
/* S.NO:201148541 Simple Shell Example
Completed upto Stage 3 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define BUFFER_SIZE 1<<16
#define ARR_SIZE 1<<16
void parse_args(char *buffer, char** args,
size_t args_size, size_t *nargs)
{
char *buf_args[args_size];
char **cp;
char *wbuf;
size_t i, j;
wbuf=buffer;
buf_args[0]=buffer;
args[0] =buffer;
for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){
if ((*cp != '\0') && (++cp >= &buf_args[args_size]))
break;
}
for (j=i=0; buf_args[i]!=NULL; i++){
if(strlen(buf_args[i])>0)
args[j++]=buf_args[i];
}
*nargs=j;
args[j]=NULL;
}
int main(int argc, char *argv[], char *envp[]){
char buffer[BUFFER_SIZE];
char *args[ARR_SIZE];
int *ret_status;
size_t nargs;
pid_t pid;
char curDir[100];
while(1){
getcwd(curDir, 100);
printf("%s->", curDir);
fgets(buffer, BUFFER_SIZE, stdin);
parse_args(buffer, args, ARR_SIZE, &nargs);
if (nargs==0) continue;
if(strcmp(args[0], "cd") == 0){
chdir(args[1]);
}
else if (!strcmp(args[0], "exit" )) exit(0);
pid = fork();
if (pid){
pid = wait(ret_status);
printf("finished\n", pid);
}
else {
if( execvp(args[0], args)) {
puts(strerror(errno));
exit(127);
}
}
}
}
return 0;
}
我真的很茫然,任何指导都会有所帮助。
【问题讨论】:
-
你能说得更具体点吗?你有什么问题?
-
我试图实现 2 个函数以获取环境 PATH 并设置环境,我真的不确定我应该如何去做,从我的作业中它指出使用 getenv 和 setenv 函数我可以这样做,但是我不确定如何开始。例如,它只是我编写的一个函数,然后在用户输入获取特定输入时调用它吗? (就像我对 exit 和 cd 命令所做的那样)
-
sn-p 代码是你写的还是作业中给出的?它不包含任何路径设置代码!