将数组发送到 pipeline() 时出现 c 管道分段错误
该程序被设置为实现一个外壳。 首先,它从 user( 到 info[4]) 获取输入,然后指示输入是否包含管道,然后按照所需的步骤执行输入中的命令。 当我将 info[4] 初始化放在引号之间,并手动将命令放入 execlp 中时,它可以工作。但如果我不这样做,如果我的输入中甚至没有管道,则会出现分段错误。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include<readline/readline.h>
#include<readline/history.h>
#include <sys/wait.h>
#include <fcntl.h>
#define READ 0
#define WRITE 1
void printDir(){
//display current directory
char cwd[1024];
getcwd(cwd, sizeof(cwd));
printf("\nDir: %s>>", cwd);
}
void scanIn(char* str){
char* buf;
buf=readline(" ");
if(strlen(buf)!=0){
add_history(buf);
strcpy(str,buf);
}
}
int main(){
pid_t childpid;
char* cmdLine;
int status;
char* info[4];//0-first command,1-second command,2-first word of first command,3-first word of second command.
int flag,i;
char* token;
int p[2];
while(1){
flag=0;
i=0;
printDir();//printing current directory
scanIn(cmdLine);//scan input
while(i<strlen(cmdLine)&&flag==0){//check if there's pipeline
if(cmdLine[i]=='|'){
flag++;
}
i++;
}
if(flag == 1){//if pipeline-split to two commands
token=strtok(cmdLine,"|");
if(token){
info[0]=strdup(token);//store the first command
token=strtok(NULL,"|");
info[1]=strdup(token);//store the second command
}
info[2]=strdup(strtok(cmdLine," "));
info[3]=strdup(strtok(token," "));
}
else{
info[0]=strdup(cmdLine);//store the only command
info[2]=strdup(strtok(cmdLine," "));//store the first word
}
if(strcmp(info[2],"exit")==0){//ip entered exit- then exit
exit(0);
}
if(flag==0){/////////////////if no pipeline- fork once
childpid=fork();
if(childpid==0){
execlp(info[2],info[0],NULL);
}
else{
waitpid(childpid,&status,0);
}
}
else{///////////////////if pipeline- make 2 forks
printf("p1_first:%s,p1:%s\n",info[2],info[0]);
printf("p2_first:%s,p2:%s\n",info[3],info[1]);
if(pipe(p)==-1){
perror("pipe");
exit(EXIT_FAILURE);
}
if(fork()==0){
close(p[READ]);
dup2(p[WRITE],WRITE);
execlp(info[2],info[0],NULL);
}
if(fork()==0){
close(p[WRITE]);
dup2(p[READ],READ);
execlp(info[3],info[1],NULL);
}
}
}
return 0;
}
the program is set to implement a shell.
At first, it takes input from user( to info[4]), then it indicates whether the input includes a pipe, and then it follows the needed steps to execute the commands from the input.
When I put the info[4] initiallization between quotes, and put the commands in execlp manually, it works. But if I dont, a segmentation error appears if I dont even have a pipeline in my input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include<readline/readline.h>
#include<readline/history.h>
#include <sys/wait.h>
#include <fcntl.h>
#define READ 0
#define WRITE 1
void printDir(){
//display current directory
char cwd[1024];
getcwd(cwd, sizeof(cwd));
printf("\nDir: %s>>", cwd);
}
void scanIn(char* str){
char* buf;
buf=readline(" ");
if(strlen(buf)!=0){
add_history(buf);
strcpy(str,buf);
}
}
int main(){
pid_t childpid;
char* cmdLine;
int status;
char* info[4];//0-first command,1-second command,2-first word of first command,3-first word of second command.
int flag,i;
char* token;
int p[2];
while(1){
flag=0;
i=0;
printDir();//printing current directory
scanIn(cmdLine);//scan input
while(i<strlen(cmdLine)&&flag==0){//check if there's pipeline
if(cmdLine[i]=='|'){
flag++;
}
i++;
}
if(flag == 1){//if pipeline-split to two commands
token=strtok(cmdLine,"|");
if(token){
info[0]=strdup(token);//store the first command
token=strtok(NULL,"|");
info[1]=strdup(token);//store the second command
}
info[2]=strdup(strtok(cmdLine," "));
info[3]=strdup(strtok(token," "));
}
else{
info[0]=strdup(cmdLine);//store the only command
info[2]=strdup(strtok(cmdLine," "));//store the first word
}
if(strcmp(info[2],"exit")==0){//ip entered exit- then exit
exit(0);
}
if(flag==0){/////////////////if no pipeline- fork once
childpid=fork();
if(childpid==0){
execlp(info[2],info[0],NULL);
}
else{
waitpid(childpid,&status,0);
}
}
else{///////////////////if pipeline- make 2 forks
printf("p1_first:%s,p1:%s\n",info[2],info[0]);
printf("p2_first:%s,p2:%s\n",info[3],info[1]);
if(pipe(p)==-1){
perror("pipe");
exit(EXIT_FAILURE);
}
if(fork()==0){
close(p[READ]);
dup2(p[WRITE],WRITE);
execlp(info[2],info[0],NULL);
}
if(fork()==0){
close(p[WRITE]);
dup2(p[READ],READ);
execlp(info[3],info[1],NULL);
}
}
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论