problem with gets

J

jorntk

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define MAX 256
#define CMD_MAX 10
char *valid_cmds = " ls ps df ";
int main (void) {
char line_input[MAX], the_cmd[CMD_MAX];
char *new_args[CMD_MAX], *cp;
int i;
while(1) {
printf ("cmd> ");
if (gets(line_input ) != NULL) {
cp = line_input;
i = 0;
if ((new_args =strtok(cp, " " )) != NULL) {
sprintf(the_cmd, "%s ", new_args);
if((strstr(valid_cmds,the_cmd) - valid_cmds) % 4 == 1) {
do {
++i;
cp = NULL;
new_args = strtok(cp, " ");
} while (i < CMD_MAX -1 && new_args != NULL);
new_args =NULL;
switch (fork( )) {
case 0:
execvp(new_args[0], new_args);
perror("exec failure");
exit(1);
case -1:
perror("fork failure");
break;
default:
;
}
} else
printf("huh?\n");
}
}
}
}


the code above is taken from a unix system programming book, i compile
the code in red hat 9 and error message came out. can someone tell me
how to make the code work any help will be appreciated.

make -k shell
cc shell.c -o shell
/tmp/ccOmPIMu.o(.text+0x2f): In function `main':
: the `gets' function is dangerous and should not be used.
 
M

Mike Wahler

Re: problem with gets

'gets()' *is* the problem. Don't use it.
There is no way to use it safely.
Use 'fgets()' instead.

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define MAX 256
#define CMD_MAX 10
char *valid_cmds = " ls ps df ";
int main (void) {
char line_input[MAX], the_cmd[CMD_MAX];
char *new_args[CMD_MAX], *cp;
int i;
while(1) {
printf ("cmd> ");
if (gets(line_input ) != NULL) {
cp = line_input;
i = 0;
if ((new_args =strtok(cp, " " )) != NULL) {
sprintf(the_cmd, "%s ", new_args);
if((strstr(valid_cmds,the_cmd) - valid_cmds) % 4 == 1) {
do {
++i;
cp = NULL;
new_args = strtok(cp, " ");
} while (i < CMD_MAX -1 && new_args != NULL);
new_args =NULL;
switch (fork( )) {
case 0:
execvp(new_args[0], new_args);
perror("exec failure");
exit(1);
case -1:
perror("fork failure");
break;
default:
;
}
} else
printf("huh?\n");
}
}
}
}


the code above is taken from a unix system programming book, i compile
the code in red hat 9 and error message came out. can someone tell me
how to make the code work any help will be appreciated.


I don't think that's an 'error' message, but a 'warning'
message. Did the compiler refuse to translate your code?
make -k shell
cc shell.c -o shell
/tmp/ccOmPIMu.o(.text+0x2f): In function `main':
: the `gets' function is dangerous and should not be used.

This is an accurate assessment. Use 'fgets()' instead.

-Mike
 
M

Malcolm

: the `gets' function is dangerous and should not be used.
Just replacing gets() with fgets() swaps undefined behaviour for incorrect
behaviour, which will shut up the compiler (since it doesn't know the
purpose of the program) but will help no-one.

You need a strategy that will warn the user if the line entered is too
long - presumably if its over 256 characters in length in must be garbage -
and discard it.
 
A

amanayin

all though you should not use the gets function you can still run the program
i get the same message when i use the gets function.
I use it just to see what happens I use suse 8.2
 
C

CBFalconer

Malcolm said:
Just replacing gets() with fgets() swaps undefined behaviour for incorrect
behaviour, which will shut up the compiler (since it doesn't know the
purpose of the program) but will help no-one.

You need a strategy that will warn the user if the line entered is too
long - presumably if its over 256 characters in length in must be garbage -
and discard it.

Simply using ggets retains the simplicity of gets, removes the
trailing \n, but requires the user to realize that the returned
line must be eventually freed. Available at:

<http://cbfalconer.home.att.net/download/>
 
J

jorntk

Malcolm said:
Just replacing gets() with fgets() swaps undefined behaviour for incorrect
behaviour, which will shut up the compiler (since it doesn't know the
purpose of the program) but will help no-one.

You need a strategy that will warn the user if the line entered is too
long - presumably if its over 256 characters in length in must be garbage -
and discard it.

i have try to use fgets and can't make it work, can some one help me with this?
thanks in advance
 
M

Mike Wahler

"Malcolm" <[email protected]> wrote in message

i have try to use fgets and can't make it work, can some one help me with
this?

Sure, many people, including myself, are willing and able
to help you with it. As soon as you show us the code you
need help with. When you post it, remember to ask specific
questions.

-Mike
 
C

CBFalconer

Mike said:
.... snip ...

Sure, many people, including myself, are willing and able
to help you with it. As soon as you show us the code you
need help with. When you post it, remember to ask specific
questions.

He did, and we did.
 
J

jorntk

Mike Wahler said:
Sure, many people, including myself, are willing and able
to help you with it. As soon as you show us the code you
need help with. When you post it, remember to ask specific
questions.

sorry for not making it clear at the first time, the code below should
have executed the ls or ps or df if user enter then, other command
will return huh?.
the problem is that when is run the program all command entered will
return huh?.

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define MAX 256
#define CMD_MAX 10
char *valid_cmds = "ls ps df";
int main (void) {
char line_input[MAX], *l;
char the_cmd[CMD_MAX];
char *new_args[CMD_MAX], *cp;
int i;
while(1) {
printf ("cmd> ");
fgets(line_input, sizeof line_input, stdin);
if((l=strchr(line_input, '\n')) != NULL)
*l='\0';
if (l != NULL) {
cp = l;
i = 0;
if ((new_args =strtok(cp, " " )) != NULL) {
sprintf(the_cmd, "%s ", new_args);
if((strstr(valid_cmds,the_cmd) - valid_cmds) % 4 == 1) {
do {
++i;
cp = NULL;
new_args = strtok(cp, " ");
} while (i < CMD_MAX -1 && new_args != NULL);
new_args =NULL;
switch (fork( )) {
case 0:
execvp(new_args[0], new_args);
perror("exec failure");
exit(1);
case -1:
perror("fork failure");
break;
default:
;
}
} else
printf("huh?\n");
}
}
}
}
 
J

John Bode

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define MAX 256
#define CMD_MAX 10
char *valid_cmds = " ls ps df ";
int main (void) {
char line_input[MAX], the_cmd[CMD_MAX];
char *new_args[CMD_MAX], *cp;
int i;
while(1) {
printf ("cmd> ");
if (gets(line_input ) != NULL) {

Replace the call to gets() with the following:

if (fgets (line_input, sizeof line_input, stdin) != NULL)
{
if (strchr (line_input, '\n'))
*strchr (line_input, '\n') = 0;
else
{
printf ("Command line too long\n");
while (!strchr (line_input, '\n'))
fgets (line_input, sizeof line_input, stdin);
exit(1);
}

Reason: if someone enters a command line longer than MAX, gets() will
write those extra characters to memory following the line_input
buffer, which may cause a crash or weird behavior (worms typically
exploit buffer overruns to propagate). fgets() will cap the number of
characters written to line_input to MAX - 1. Unlike gets(), fgets()
stores the trailing '\n' character to the buffer if there is room, so
we need to check for it using strchr() (be sure to #include
<string.h>). If it's in the buffer, set it to 0 (string terminator).
If not, the line was too long to store in the buffer, so we reject it
and print an error message. The code that consumes the remaining
input isn't strictly necessary if we're just going to exit anyway, but
it's a good practice to clean out the input buffer anyway.
cp = line_input;
i = 0;
if ((new_args =strtok(cp, " " )) != NULL) {
sprintf(the_cmd, "%s ", new_args);
if((strstr(valid_cmds,the_cmd) - valid_cmds) % 4 == 1) {
do {
++i;
cp = NULL;
new_args = strtok(cp, " ");
} while (i < CMD_MAX -1 && new_args != NULL);
new_args =NULL;
switch (fork( )) {
case 0:
execvp(new_args[0], new_args);
perror("exec failure");
exit(1);
case -1:
perror("fork failure");
break;
default:
;
}
} else
printf("huh?\n");
}
}
}
}


the code above is taken from a unix system programming book,


Frankly, that worries me. Using gets() has been *known* to introduce
a point of failure in C code for quite a while now (remember the
Morris worm in 1988?), and it's *still* being presented as a
reasonable practice in system programming books. I can't believe any
book written after 1990 would still use it.

gets() is evil.
 
J

jorntk

the code below will execute ls but not the other two function, what is
wrong with the code?
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define MAX 256
#define CMD_MAX 10
char *valid_cmds = "ls ps df";
int main (void) {
char line_input[MAX], *l;
char the_cmd[CMD_MAX];
char *new_args[CMD_MAX], *cp;
int i;
while(1) {
printf ("cmd> ");
fgets(line_input, sizeof line_input, stdin);
if((l=strchr(line_input, '\n')) != NULL)
*l='\0';
if (l != NULL) {
cp = l;
i = 0;
if ((new_args =strtok(cp, " " )) != NULL) {
sprintf(the_cmd, "%s ", new_args);
if((strstr(valid_cmds,the_cmd) - valid_cmds) % 4 == 1) {
do {
++i;
cp = NULL;
new_args = strtok(cp, " ");
} while (i < CMD_MAX -1 && new_args != NULL);
new_args =NULL;
switch (fork( )) {
case 0:
execvp(new_args[0], new_args);
perror("exec failure");
exit(1);
case -1:
perror("fork failure");
break;
default:
;
}
} else
printf("huh?\n");
}
}
}
}
 
J

jorntk

i have changed some part of the program but it only work for "ls". why
"ps" and "df" does not work?
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define MAX 256
#define CMD_MAX 10
char *valid_cmds = " ls ps df ";
int main (void) {
char line_input[MAX], the_cmd[CMD_MAX];
char *new_args[CMD_MAX], *cp;
int i;
while(1) {
printf ("cmd> ");
fflush(stdout);
if (gets(line_input ) != NULL) {
cp = line_input;
i = 0;
if ((new_args =strtok(cp, " " )) != NULL) {
sprintf(the_cmd, "%s ", new_args);
if((strstr(valid_cmds,the_cmd) - valid_cmds) % 4 == 1) {
do {
++i;
cp = NULL;
new_args = strtok(cp, " ");
} while (i < CMD_MAX -1 && new_args != NULL);
new_args =NULL;
switch (fork( )) {
case 0:
execvp(new_args[0], new_args);
perror("exec failure");
exit(1);
case -1:
perror("fork failure");
break;
default:
;
}
} else
printf("huh?\n");
}
}
}
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,077
Messages
2,570,568
Members
47,204
Latest member
abhinav72673

Latest Threads

Top