Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C stdin因文件重定向而损坏?_C_Fork_Stdin_Stdio_Corruption - Fatal编程技术网

C stdin因文件重定向而损坏?

C stdin因文件重定向而损坏?,c,fork,stdin,stdio,corruption,C,Fork,Stdin,Stdio,Corruption,我正在做一项作业,其中包括编写一个迷你shell,使用forks和execvp执行其他程序。当一切似乎都正常工作时,我尝试使用bash上的/myshell0){ my_系统(线路); } //无法释放,因为队列中的行用于显示“历史记录”` //自由线; } 返回0; } char*get_a_行(){ char*buffer=(char*)malloc(buffer_SIZE*sizeof(char)); size\u t len=getline(&buffer,&buffer\u size,

我正在做一项作业,其中包括编写一个迷你shell,使用forks和
execvp
执行其他程序。当一切似乎都正常工作时,我尝试使用bash上的
/myshell
将文件中的命令列表直接传递到shell中,得到了无限*的命令流,这些命令永远无法完成执行

我不确定是什么导致了它,所以我用
gdb
调试了它。令我惊讶的是,当到达文件的最后一行时,从stdin读取的行中又添加了一个字符。此外,以前执行的更多行将返回到提要并重新执行。以下是馈送到shell的文件:

-trimmed for compactness-
chdir file
chdir ../
touch hello.txt index.html app.py
ls
rm hello.txt
ls -1
wc app.py
cat index.html
pwd
history
touch .hidden.txt
ls -a
history
echo preparing to exit
cd ../../
ip route show
ls -R
rm -rf path
invalid command
history

注意,
无效命令
之后是
历史
,带有
/
,然后下一行是
触摸hello.txt index.html app.py
,依此类推。我尝试了多种方法来调试这个问题,将我的readLine函数放到一个单独的文件中并单独测试,但程序在读取最后一行后正确终止。我还在MacOS上编译了shell,令我惊讶的是,这个问题也没有发生。作为参考,该错误发生在运行Ubuntu18.04.3 LTS的系统上

我完全不明白为什么会这样。我假设这可能与我的stdin是由它自身的一个分叉副本编写的有关,但我真的不确定。如能提供一些见解,将不胜感激

*不确定它是否真的是无限的

编辑1:这是我代码的一部分(很抱歉,我无法在不删除该问题的情况下进一步减小其大小,因为我不知道是什么导致了它)

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
char*get_a_line();
字符*提取参数(字符**行,字符分隔符);
int my_系统(字符*行);
//要读取标准数据的缓冲区大小
大小缓冲区大小=256;
//tailq的字符串节点
结构字符串节点{
字符*值;
TAILQ_条目(字符串节点)条目;
};
//用于初始化字符串的节点结构的宏
TAILQ_头(str_列表、string_节点);
结构列表历史;
int main(int argc,字符**argv){
int user_input=isatty(0);
而(1){
如果(用户输入){
printf($);
}
char*line=get_a_line();
if(feof(stdin)){
出口(0);
}
如果(strlen(line)>0){
my_系统(线路);
} 
//无法释放,因为队列中的行用于显示“历史记录”`
//自由线;
}
返回0;
}
char*get_a_行(){
char*buffer=(char*)malloc(buffer_SIZE*sizeof(char));
size\u t len=getline(&buffer,&buffer\u size,stdin);
//将“\n”转换为“\0”以终止字符串
如果(len!=-1&&buffer[len-1]='\n'){
缓冲区[len-1]='\0';
}
返回缓冲区;
}
int解析(字符**行,字符***解析){
//初始化包含参数的字符串列表
结构str_list strings_list;
TAILQ_INIT(&strings_list);
结构字符串节点*tmp节点;
//参数部分的数量
整数计数=0;
char*s;
while((s=extract_参数(行,)!=NULL){
tmp_node=malloc(sizeof(struct string_node));
tmp_节点->值=s;
TAILQ_插入_TAIL(&strings_列表、tmp_节点、条目);
计数++;
}
//将参数保存到字符串数组(字符数组数组)
char**arguments=malloc(sizeof(char**)*(count+1));
int i=0;
while((tmp_节点=TAILQ_第一(&strings_列表))){
参数[i++]=tmp_节点->值;
TAILQ_删除(&strings_列表、tmp_节点、条目);
空闲(tmp_节点);
}
//终止数组
参数[count]=NULL;
//检查终端的类型
*解析=参数;
如果(**行=='|'){
(*行)+=1;
返回1;
}
返回0;
}
//通过malloc分配,从*行开始提取字符串,直到长度
字符*提取字符串(字符**行,整数长度){
char*str=NULL;
如果(长度>0){
str=malloc((长度+1)*sizeof(字符));
strncpy(str,*行,长度);
str[length]='\0';
*行+=(长度);
}
返回str;
}
/*
通过str1上的calloc合并两个字符串str1和str2并释放str2
(prob不应释放此中的str2,但w/e)
*/
字符*strcat_alloc(字符*str1,字符*str2){
如果(str1==NULL){
返回str2;
} 
如果(str2==NULL){
返回str1;
}
尺寸长度1=标准长度(标准长度1);
尺寸长度2=标准长度(标准长度2);
str1=realloc(str1,长度1+2+1);
strcpy(str1+length1,str2);
str1[length1+length2]='\0';
免费(str2);
返回str1;
}
/*
提取行的单个参数,以分隔符结尾
实现基本引号和转义,以支持多字参数
*/
字符*提取参数(字符**行,字符分隔符){
//删除尾随空格
而(**行==''){
(*行)+=1;
}
int right=0;
char*str_p=NULL;
while((*行)[右]!=分隔符&&
(*行)[右]!=EOF&&
(*行)[右]!='\0'&&
(*行)[右]!=“|”)
{
如果((*行)[右]='\\'){
str_p=提取字符串(右行);
//转义字符在“\”之后
*行+=1;
char*c=malloc(sizeof(char));
*c=**行;
*行+=1;
返回strcat_alloc(strcat_alloc(str_p,c),提取参数(行,分隔符));
}
如果((*行)[右]='\''){
str_p=提取字符串(右行);
*行+=1;
char*str\u p2=提取参数(行“\”);
返回strcat_alloc(strcat_alloc(str_p,str_p2),提取参数(行“”);
}如果((*行)[右]='\'',则为else{
str_p=提取字符串(右行);