PDA

View Full Version : redirection problems


mile1982
10-19-2004, 06:53 AM
hey there

when i execute the following command: 'ls -lt > pero' a file is created but with a space eg: ' pero' - > supposed to save it as 'pero'.

and when i execute the command 'cat < glob' the program does not do anything.

can someone help please

heres the code:

this is my redirect function


// redirects a command
// fileid is an integer, if it is 0 then its STDIN, if 1 STDOUT
int runCommandAsRedirect(command* a, int fileId) {


int pid, fid, status;

if ((pid = fork()) < 0) {

printf("Error: Fork failed.\n");
return 1;
}

if (pid == 0) {

// child process

if (fileId == STDIN) {

fid = open(a->redirect_in, O_RDONLY);
}

else if (fileId == STDOUT) {

fid = open(a->redirect_out, O_CREAT | O_TRUNC | O_WRONLY, 0600);
}

dup2(fid, fileId);
close(fid);

execvp(a->com_name, a->argv);
printf("Error: execvp failed.\n");
return 1;
}

else {

// parent process
while (wait(&status) != pid);
}
return;
}



this is how i call it the function :


if ((a->redirect_out != NULL) || (a->redirect_in != NULL)) {

runCommandAsRedirect(a, redirection);
return;
}


this is the code that searches for > and < in the command line


/*
* This function parses the commands isolated from the command line string in
* other functions. It searches the string looking for input and output
* redirection characters. The simple commands found are sent to
* process_simple_comd(). The redirection information is stored in the result
* command structure.
*
* Arguments :
* cmd - the command string to be processed.
* result - the command structure to store the results in.
*
* Returns :
* None.
*
*/

void process_cmd(char *cmd, command *result) {

char *pc, *mc;
char *simple_cmd = NULL;

/*If no redirection found, then only a simple command present. */
if ((pc = index(cmd, '<')) == NULL) {

if ((pc = index(cmd, '>')) == NULL) {

process_simple_cmd(cmd, result);
result->redirect_in = NULL;
result->redirect_out = NULL;
}
else { /*Output Redirection in place */

pc = strtok(cmd, ">");
printf(" pc = %s ", pc);

redirection = STDOUT;
simple_cmd = strdup(pc);
printf(" \n simple command %s ", simple_cmd);

pc = strtok(NULL, "\0");
process_simple_cmd(simple_cmd, result);
result->redirect_out = strdup(pc);
}
}
else { /*Input Redirection */

pc = strtok(cmd, "<");

redirection = STDIN;
simple_cmd = strdup(pc);
printf(" \n simple command %s ", simple_cmd);
pc = strtok(NULL, "\0");

/*Output redirection may have been missed because input is checked
* first.*/
if ((mc = index(simple_cmd, '>')) != NULL)
process_cmd(simple_cmd, result);
if ((mc = index(pc, '>')) != NULL)
process_cmd(pc, result);

process_simple_cmd(simple_cmd, result);
result->redirect_in = strdup(pc);
}

free(simple_cmd);
return;
} /*End of process_cmd() */


// ----------------------------------------------------------


im really having trouble figuring out what the problem is so if anyone can help, would appreciate it a lot.

cheers
mile1982

RobSeace
10-19-2004, 02:11 PM
Um, I would think the problem and solution would be obvious,
just based on the results you mention... The fact that the space
is left in front of the filename means your parsing is broken... You
are leaving the typed space that separates the ">" or "<" from the
filename, and incorrectly considering it part of the filename...

Basically, if you want to parse up a command-line of any sort
like that, you really should first and foremost parse the whole thing
up into separate tokens/words, by splitting it up at whitespace (or,
whatever $IFS chars you want to use)... Then, once you have
those, you can move on to checking each separate token/word
for special chars and things like "<" or ">", and I think they'll be a
lot easier to deal with then...

Oh, and I really wouldn't recommend strtok()... For one thing, it's
not thread-safe... For another, it's really just ugly and horrible... ;-)
You're much better off just writing your own parsing code... It's
not that hard... Just spin through the buffer, char by char: if the
curent char is a whitespace (or whatever $IFS you're using), null
it out, and skip past it; if it's non-whitespace, then either begin a
new token/word at this point (if the previous char you saw was a
whitespace, or this is the first char you've seen), or just skip past
it... This will also allow you to easily add special handling for things
like quoted strings to be treated as a single token/word: if a new
token starts with " or ', just jump to the next matching " or ', and
consider everything within a single token...

mile1982
10-19-2004, 05:39 PM
thanks for the advice man. helped me out .

cheers
mile1982