First off, this a homework assignment so most of the syntax in the code that I'm about to append to this thread is required by my professor. Anywho...I'm having trouble with the piping in my code. Here is what I have:
Code:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <assert.h>
int fg_id = 0;
void sigchldHandler(int sig)
{
int status = 0;
int pid = wait(&status);
if (pid == fg_id)
{
fg_id = 0;
}
}
int main()
{
char* dosCmd[] = {"exit", "dir", "md", "type", "sort", "del", "copy", ">", ">>", "&"};
char* unixCmd[] = {"exit", "ls", "mkdir", "cat", "sort", "rm", "cp", ">", ">>", "&"};
signal(SIGCHLD, sigchldHandler);
while (1)
{
int args = 0;
char* argv[10];
char* delimiter = " \n";
char command[80] = {0};
int redir = 0;
int reder = 0;
bool foreground = true;
printf("terminal@piping> ");
fgets(command, sizeof(command), stdin);
if (command[0] == '\n') continue;
// gather input tokens
argv[args++] = strtok(command, delimiter);
do
{
int z = 0;
for(; (z < 10) && (strcmp(argv[args-1], dosCmd[z]) != 0); ++z);
switch(z)
{
case 0: return 0; break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6: argv[args-1] = unixCmd[z]; break;
case 7: reder = args-1; argv[args-1] = NULL; break;
case 8: redir = args-1; argv[args-1] = NULL; break;
case 9: foreground = false; argv[args-1] = NULL; break;
}
} while ((argv[args] = strtok(NULL, delimiter)) != NULL && (++args < 10));
if (args > 0)
{
int file_des[2];
int new_cid;
pipe(file_des);
if ((new_cid = fork()) == 0)
{
// child process
usleep(10000); // delay for parent to setup semaphore for foreground processes
close(file_des[1]);
assert(dup2(file_des[0], 0) != -1);
int file_ptr = 0;
if (reder)
{
file_ptr = open(argv[reder+1], O_WRONLY | O_CREAT | O_TRUNC, 0666);
}
else if (redir)
{
file_ptr = open(argv[redir+1], O_WRONLY | O_APPEND, 0666);
}
if (file_des[1]) dup2(file_des[1], 1);
execvp(argv[0], argv);
close(file_des[0]);
if (file_ptr) close(file_ptr);
}
else if (foreground)
{
fg_id = new_cid;
while(fg_id) usleep(10000); // don't pound the CPU
}
}
}
return 0;
}
Everything compiles just fine, but for instance when the shell is running I type in "type hunt program5.c | sort" it is supposed to translate DOS commands into Unix commands(which it does correctly) but when I try to cat(or type is the DOS syntax..etc) my program called hunt and program5.c and then pipe it by sorting the two programs it gives me the following prompt
Code:
terminal@piping> type hunt program5.c | sort
#!/bin/csh
# Chad Reynolds - CSC 60 - Section 1
set directoryCount = 0
set fileCount = 0
### Test to see if no arguments get inputted on the command line
if($#argv == 0)then
echo Usage: Missing arguments, please re-execute hunt
else
while(1)
foreach val (`ls`)
if(-d $val) then
### If val is a directory then increment its value to see
### the total amount of directories searched
@ directoryCount = $directoryCount + 1
### Push back to the current directory and add to the stack
pushd $val >> ~/dump
pushd +1 >> ~/dump
else if($val =~ $1) then
### Echo full path
@ fileCount = $fileCount + 1
echo `pwd`/$val
else if(-e $val) then
### Increment file count if val is a file
@ fileCount = $fileCount + 1
endif
### End for
end
### If directory or word count is greater than 1,
### then pop the directory off the stack
if(`dirs | wc -w` > 1) then
popd >> ~/dump
else
### Else, the stack is complete, so output the file count,
### directory count, and delete temp file dump
rm ~/dump
echo Files Searched: $fileCount
echo Directories Searched: $directoryCount
### Infinite loop, so a break statement is needed
break
endif
### End while
end
### End if($#argv == 0)/Else
endif
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <fcntl.h>
#include <assert.h>
int fg_id = 0;
int pid = 0;
int status = 0;
int file_ptr = 0;
int file_des[2];
void sigchldHandler(int sig)
{
pid = wait(&status);
if (pid == fg_id)
{
fg_id = 0;
}
signal(SIGCHLD, sigchldHandler);
}
int main()
{
char* dosCmd[] = {"exit", "dir", "md", "type", "sort", "del", "copy", ">",
">>", "&", "|" };
char* unixCmd[] = {"exit", "ls", "mkdir", "cat", "sort", "rm", "cp", ">",
">>", "&", "|"};
signal(SIGCHLD, sigchldHandler);
while (1)
{
int args = 0;
char* argv[10];
char* delimiter = " \n";
char command[80] = {0};
int redir = 0;
int reder = 0;
bool foreground = true;
printf("terminal@piping> ");
fgets(command, sizeof(command), stdin);
if (command[0] == '\n') continue;
// gather input tokens
argv[args++] = strtok(command, delimiter);
do
{
int z = 0;
for(; (z < 10) && (strcmp(argv[args-1], dosCmd[z]) != 0); ++z);
switch(z)
{
case 0: return 0; break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6: argv[args-1] = unixCmd[z]; break;
case 7: reder = args-1; argv[args-1] = NULL; break;
case 8: redir = args-1; argv[args-1] = NULL; break;
case 9: foreground = false; argv[args-1] = NULL; break;
}
}//end do
while ((argv[args] = strtok(NULL, delimiter)) != NULL && (++args < 10));
if (args > 0)
{
int new_cid;
pipe(file_des);
if ((new_cid = fork()) == 0)
{
// child process
usleep(10000); // delay for parent to setup semaphore for foreground processes
close(file_des[1]);
assert(dup2(file_des[0], 0) != -1);
if (reder)
{
file_ptr = open(argv[reder+1], O_WRONLY | O_CREAT | O_TRUNC, 0666);
}
else if (redir)
{
file_ptr = open(argv[redir+1], O_WRONLY | O_APPEND, 0666);
}
if (file_des[1])
{
dup2(file_des[1], 1);
}
execvp(argv[0], argv);
close(file_des[0]);
if (file_ptr)
{
close(file_ptr);
}
}//end if((new_cid = fork()) == 0)
else if (foreground)
{
fg_id = new_cid;
while(fg_id)
usleep(10000); // don't pound the CPU
}
}//end if(args > 0)
}
return 0;
}
cat: |: No such file or directory
cat: sort: No such file or directory
terminal@piping>
When I type "type hunt" it displays my program hunt's source code just fine but once I try to pipe the programs it doesn't do as I expected. Any suggestions? My apologies if I didn't elaborate very well on my struggles.