NULL arguments in a shell program
I have written a basic shell program that handles 3 commands: cat, cp, and cryptix for encrypting files. 'cat' and 'cp' act exactly as they do in any normal linux shell. 'cat' can take any number of paths to files as arguments. 'cp' takes 2 arguments (source, destination). And 'cryptix' takes 3 arguments (integer key, source, destination). I use 2 functions outside of main to help parse out the commands and arguments given on the command line. The first is getCommand() which returns an integer that represents one of the commands to determine which command was given. The second is getArgument() which returns a char * that is the argument that is next in line to be read from the command line. If an argument is a path is to a file that doesn't exist, then the program writes an appropriate message to stdout that the file couldn't be found. My only problem comes when a file doesn't exist at the given path. If I give the command "cat file1 file2" and one or both files don't exist, then I end up receiving a segfault error and the program crashes. I am able to read in the argument "file1" but since it can't be found the program crashes, instead of writing a message to stdout that the file doesn't exist. When reading the arguments from the command line I check to see if the argument that was extracted is NULL and if not then I begin to process the command on that argument. If it is NULL then I attempt to write that error message. I guess I'm not checking for valid arguments in the correct way but I really don't know how to go about fixing this because it has stumped me for a few days now.
I have been working remotely on linux through an SSH client, but I can't connect to any linux machines right now. I will post the code that is in question when I am able to get to it. But for now, if anyone has any suggestions as to how to go about correctly identifying when an invalid argument is given, please share your thoughts.
Thanks.
continued with code mentioned before
This is from main:
Code:
if(cmd == 1) //cat command
{
cat_arg = getArgument(args+1, cmdline); //get 1st argument
//args is an int that starts at 0; args+1 represents the 1st...
//...argument after the command given; so the 1st parameter...
//...is the location on the command line
FILE *cat_file; //file to read from
//while there are still arguments
while(cat_arg != NULL)
{
args++;
cat_file = fopen(cat_arg, "r"); //open file
//check if file was opened
if(cat_file != NULL)
{
buffer = fgetc(cat_file); //read a char from the file
while(buffer != EOF)
{
fprintf(stdout, "%c", buffer); //write to stdout
buffer = fgetc(cat_file); //read from the file
}
}
else
fprintf(stderr, "cat: %s: No such file", cat_arg);
fclose(cat_file); //close the file
cat_arg = getArgument(args+1, cmdline); //get next arg
}
args = 0; //reset the argument counter
}
Here is getArgument:
Code:
/*
* char *getArgument(int which,char *command_line)
*
* Given a command string and a position, this function
* returns the argument at that position in the string.
* Counting should begin with the first word after the
* command. For example:
*
* char *arg1 = getArgument(1, "cat file1 file2");
*
* . . . will return "file1". If there are no arguments
* at the position specified by which, then the
* function should return NULL.
*/
char *getArgument(int which, char *command_line)
{
char *cpy_cmdline; //stores a copy of the paramter...
//...command_line
char *cmd; //stores the command given (1st argument in list)
char *arg; //stores an argument from the command line
int argCount = 0; //keeps track of the arguments
//copy the parameter command_line and store it in cpy_cmdline
cpy_cmdline = (char *)malloc(strlen(command_line)+1);
strcpy(cpy_cmdline, command_line);
cmd=strtok(cpy_cmdline, " \n\t"); //store the command
//if there are still arguments to extract
if(argCount < which)
{
//extract the 1st argument
arg = strtok(NULL, " \n\t");
argCount++;
//continue extracting arguments until the correct argument
//has been extracted
while(argCount < which)
{
arg = strtok(NULL, " \n\t");
argCount++;
}
}
return arg;
}