You are not logged in.
Pages: 1
Hi all,
I am making a program for my class assignment related to PIPES.
In the project i need to implement a remote shell server which can take 'piping' commands form the user.
eg.
ls | cat => as expected this will take output from ls into cat.
The problem is that i did all the piping etc. But when i finally run the code and 'ls' is executed first and it pipes its data into 'PIPE' (fd=1) and in the next iteration, the forked process which executes CAT also has its stdin as PIPE's fd=0(i used dup2 to do copy the file descriptors).
Now when finally the command is executed, CAT sends back the output as desired to the client but doesnot return for some reason(it just sleeps after sending the last line of output). The task manager in Ubuntu shows that its sleeping.
Because I use wait() for the child process to exit...so my program gets stuck there.
If I kill it from the task manager then the process returns to accept the next command but this problem has other effects which are not letting me finish my F##$#ing assigment.
I am really REALLY stuck and all my work will go down the drain....your help will be very much appreciated.
Where could I have been wrong :|
Thanks.
Pranay
Below is the main function I am using(hope its not that messy )
the struct command *comm -> this has the commands like LS and CAT stored in an array format.
sub_comm_count = number of commands in a single like e.g ls | cat =>2 commands so its value= 1
current_count = -1(at the first call)
void recursive_call(struct command *comm, int sub_comm_count,int current_count)
{
current_count++; // if current_count==sub_comm_count then no more commands to process
int childpid;
if( (childpid=fork()) <0)
errlog("fork error");
else if (childpid==0)
{
/***********************
*child process - Recursive_call()
**********************/
int flag[4];
flag[0]=flag[1]=flag[2]=flag[3]=0;
int read_pipe,fd_prog_to_file,fd_file_to_prog;
read_pipe=read_from_pipe(comm_count);// checks and copies the pipe fd to read pending data from
if(read_pipe==1) flag[0]=1;
if(read_pipe==-1)
{
//No PENDING pipe to read from
/** check for '<' **/
if (comm[current_count].file_to_program!=NULL)
{
if((fd_file_to_prog=open(comm[current_count].file_to_program,O_RDWR))==-1)
{
errlog("error opening 'read' file \n");
exit(0);
}
flag[1]=1;
// copy the file descriptor to the STDIN_FILENO
if(dup2(fd_file_to_prog,STDIN_FILENO)!=STDIN_FILENO)
{
errlog("error in dup2\n");
exit(0);
}
}
}
if(comm[current_count].pipe_level<0)
{
/** check for '>' **/
if (comm[current_count].program_to_file!=NULL)
{
if((fd_prog_to_file=open(comm[current_count].program_to_file,O_WRONLY|O_CREAT, 0644))==-1)
{
errlog("error opening 'write' file \n");
exit(0);
}
flag[2]=1;
// copy the file descriptor to the STDOUT_FILENO
if(dup2(fd_prog_to_file,STDOUT_FILENO)!=STDOUT_FILENO)
{
errlog("cannot dup2\n");
exit(-1);
}
}
else
{
/** OUTPUT TO client SOCKET ==default output **/
///CHANGE HERE SOCKET VALUE ---enter it from the funciton
if( dup2(newsockfd,STDOUT_FILENO)!= STDOUT_FILENO )
{
errlog("dup 2 error");
exit(-1);
}
}
}else{
close(pipe_from[comm[current_count].pipe_level + comm_count ][0]);
/** handle '|' --> STDOUT DATA piped into some PIPE **/
if( dup2(pipe_from[comm[current_count].pipe_level + comm_count ][1],STDOUT_FILENO)!= STDOUT_FILENO )
{
errlog("dup 2 error pipe out\n");
exit(-1);
}
flag[3]=1;
}
/** execute the command **/
execv(comm[current_count].argv1[0],comm[current_count].argv1);
errlog("execv did not work \n");
exit(-1 );
}
/***********************
*Parent process - Recursive_call()
**********************/
int dummy;
wait(&dummy);
if(sub_comm_count>current_count)
{
comm_count++;
recursive_call(comm,sub_comm_count,current_count);
}
else
{
return ;
}
}
Well one more thing it also takes care of commands like
ls > output.txt
or cat < input.txt
but these are not a problem right now
Hi All,
Thanks but my problem has been solved now.
I was not able to get the EOF from the reading process as i had not closed all the write ends of my pipes.
Thanks anyways..
BR
PRanay
static void file_to_stdin(const char *file)
{
int fd = open(file, O_RDONLY);
if (fd == -1){
errlog("error opening 'read' file \n");
exit(1);
}
/* copy the file descriptor to the STDIN_FILENO */
if (dup2(fd, STDIN_FILENO) == -1){
errlog("error in dup2\n");
exit(1);
}
close(fd);
}
static void file_to_stdout(const char *file)
{
int fd = open(file, O_WRONLY|O_CREAT, 0644)
if (fd == -1){
errlog("error opening 'write' file \n");
exit(1);
}
/* copy the file descriptor to the STDOUT_FILENO */
if (dup2(fd, STDOUT_FILENO) == -1){
errlog("cannot dup2\n");
exit(1);
}
close(fd);
}
static void exec_child(struct command *comm, int comm_count)
{
int read_pipe;
int flag[4] = {0};
int fd = -1;
/* checks and copies the pipe fd to read pending data from */
read_pipe = read_from_pipe(comm_count);
if (read_pipe == 1)
flag[0] = 1;
else if (read_pipe == -1){
/* No PENDING pipe to read from. Check for '<' */
if (comm->file_to_program){
file_to_stdin(comm->file_to_program);
flag[1] = 1;
}
}
if (comm->pipe_level < 0){
/* check for '>' */
if (comm->program_to_file){
file_to_stdout(comm->program_to_file);
flag[2] = 1;
} else {
/** OUTPUT TO client SOCKET == default output **/
// CHANGE HERE SOCKET VALUE ---enter it from the funciton
if (dup2(newsockfd, STDOUT_FILENO) == -1){
errlog("dup 2 error");
exit(-1);
}
close(newsockfd);
}
} else {
// This looks a bit dodgy, not sure what's going on here.
int *from_pipe;
from_pipe = pipe_from[comm->pipe_level + comm_count];
/*
* handle '|' --> STDOUT DATA piped into some PIPE
*/
if (dup2(from_pipe[1], STDOUT_FILENO) == -1){
errlog("dup 2 error pipe out\n");
exit(-1);
}
close(from_pipe[0]);
close(from_pipe[1]);
flag[3] = 1;
}
/* execute the command */
execv(comm->argv1[0], comm->argv1);
errlog("execv did not work \n");
exit(-1);
}
void exec_all_cmds(struct command *comm, int sub_comm_count)
{
int childpid;
int current;
int dummy;
for (current = 0; current < sub_comm_count; count++){
childpid = fork();
if (childpid < 0){
errlog("fork error");
exit(1);
} else if (childpid == 0){
return exec_child(comm[current], current);
}
/*
* Parent process
*/
wait(&dummy);
}
}
Offline
Pages: 1