C 存在分叉过程和'\n';?
我有一个简单的shell程序,可以在交互和非交互模式下工作。我已经尽可能地简化了代码来提出我的问题,但是它仍然有点长,所以很抱歉C 存在分叉过程和'\n';?,c,shell,printf,fork,C,Shell,Printf,Fork,我有一个简单的shell程序,可以在交互和非交互模式下工作。我已经尽可能地简化了代码来提出我的问题,但是它仍然有点长,所以很抱歉 #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> /** *main-entry poin
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/**
*main-entry point for gbk
*Return: returns the index of 0 on sucess
*/
int main(void)
{
char *cmd = malloc(1 * sizeof(char)), *cmdargs[2];
size_t cmdlen = 0;
int childid, len;
struct stat cmdinfo;
while (1)
{
printf("#cisfun$ ");
len = getline(&cmd, &cmdlen, stdin);
if (len == -1)
{
free(cmd);
exit(-1);
}
/*replace the ending new line with \0*/
cmd[len - 1] = '\0';
cmdargs[0] = cmd;
cmdargs[1] = NULL;
childid = fork();
if (childid == 0)
{
if (stat(*cmdargs, &cmdinfo) == 0 && cmdinfo.st_mode & S_IXUSR)
execve(cmdargs[0], cmdargs, NULL);
else
printf("%s: command not found\n", *cmdargs);
exit(0);
}
else
wait(NULL);
}
free(cmd);
exit(EXIT_SUCCESS);
}
#包括
#包括
#包括
#包括
#包括
#包括
/**
*gbk的主要入口点
*Return:成功返回0的索引
*/
内部主(空)
{
char*cmd=malloc(1*sizeof(char)),*cmdargs[2];
大小\u t cmdlen=0;
int childid,len;
struct stat cmdinfo;
而(1)
{
printf(“#cisfun$”);
len=getline(&cmd,&cmdlen,stdin);
如果(len==-1)
{
免费(cmd);
出口(-1);
}
/*将结束的新行替换为\0*/
cmd[len-1]='\0';
cmdargs[0]=cmd;
cmdargs[1]=NULL;
childid=fork();
if(childid==0)
{
if(stat(*cmdargs,&cmdinfo)==0&&cmdinfo.st\u mode&S\u IXUSR)
execve(cmdargs[0],cmdargs,NULL);
其他的
printf(“%s:找不到命令\n”,*cmdargs);
出口(0);
}
其他的
等待(空);
}
免费(cmd);
退出(退出成功);
}
为了总结此程序的功能,它将首先打印提示符#cisfun$
,在交互模式下等待输入,并在非交互模式下获取管道值,创建子进程,子进程检查传递的字符串是否为有效的可执行二进制文件,如果是,它以另一种方式执行,打印一条“未找到命令”消息并再次提示
我已经让这个程序在交互模式下的大多数场景下都能正常工作,但是当我在非交互模式下运行它时,各种疯狂(意外)的事情开始发生
例如,当我运行echo”/bin/ls“|/a.out
,(a.out
是编译程序的名称)
您首先希望打印#cisfun$
消息,因为这是while循环中执行的第一件事,然后是/bin/ls
命令的输出,最后是#cisfun$
提示符,但实际情况并非如此。下面是发生的情况
ls
命令甚至在第一条打印消息之前就运行了。一、 起初,我们认为有一些线程化
正在进行,并且printf
比执行ls命令的子进程慢。但我不确定这是不是真的,因为我是个笨蛋。而且,如果我在打印一条消息时,在末尾加上'\n'
,而不仅仅是一个字符串,事情也会变得有点疯狂。(如果我将printf(“#cisfun$”)
更改为printf(“#cisfun$\n”)
),则会发生以下情况:'\n'
,fork
和printf
的速度之间的关系。简言之,对此有何解释
ctr+D
相同,我认为是通过getline
功能退出的。但是我不明白为什么要在第二个提示符中插入EOF
1.输出通常是行缓冲的,这就是为什么添加换行符会使提示出现在ls的输出之前。实际上,请始终在@Peter Thank you之前调用,但很抱歉,您可以对行缓冲的含义稍微友好一点。@EHM:如果有数据可读取,
getline
将读取它。如果没有数据,但写入程序仍打开管道,getline
将阻塞,直到有数据为止。如果没有数据且管道的另一端已关闭,getline
表示EOF。我不知道你说的“两个包”是什么意思。@EHM:但这和你在终端上阅读时看到的行为是一样的getline
无法在一次返回中同时返回数据和指示EOF。你必须再打一次电话才能知道EOF已经达到。