ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi, I wrote the following code which creates a simple shell (like bash). It works fine, can take a command along with arguments and run it or give error if it doesn't exist. However, the strange problem is that it doesn;t execute anything the first time "enter" is hit!! But after that it works perfectly.
I couldn't find the bug, any help would be great. Thanks
---------------------------------------------------------------------------------------------
#include <string.h>
#include <errno.h>
#define TRUE 1
void type_prompt();
void *read_command(char *argv[]);
int n = 0;
int main(int argc, char *argv[], char *envp[])
{
char *command;
int status;
argv[0] = NULL;
while (TRUE) /* repeat forever */
{
type_prompt(); /* display prompt on screen */
read_command(argv); /* read input from terminal */
if (fork() != 0) /* fork off child process */
{
waitpid(-1, &status, 0); /* wait for child to exit */
}
else
{
if (execve(argv[0], argv, envp) == -1) /* execute command */
printf("Ouch, can't execute: %s\n", strerror(errno));
}
}
return 0;
}
void type_prompt()
{
printf("[arajgarh]$ ");
}
void *read_command(char *argv[])
{
n = 0;
char temp[256];
Yes, I tried debugging and temp gives the correct value even the first time. Yet the first time, as I said, the value of temp gets messed up when fork() is called. I do not know why this happens
Well, I don't think the way you're using argv is very reliable. Ideally, you'd create your own array of strings that you can store the user's input in.
You should try getting your code to compile correctly (warning free):
Code:
itsme@dreams:~/C$ gcc -Wall shell.c -o shell
shell.c: In function `main':
shell.c:22: warning: implicit declaration of function `fork'
shell.c:24: warning: implicit declaration of function `waitpid'
shell.c:28: warning: implicit declaration of function `execve'
shell.c:29: warning: implicit declaration of function `printf'
shell.c:12: warning: unused variable `command'
shell.c: In function `read_command':
shell.c:43: parse error before `char'
shell.c:45: warning: implicit declaration of function `gets'
shell.c:45: `temp' undeclared (first use in this function)
shell.c:45: (Each undeclared identifier is reported only once
shell.c:45: for each function it appears in.)
shell.c:50: warning: control reaches end of non-void function
What this function does is bad:
It assigns pointers to the local variable 'temp' to the argv 'owned' by main(). After this function returns, 'temp' doesn't exist anymore, while main() will have its argv[] point to 'temp'... Because local var's like 'temp' are on the stack you didn't get segementation fault crashes. It's more or less coincidence that your argv[] still has values that seem correct after calling read_command().
Even without the error above, I fully agree with itsme86's doubts about the way you are fiddling with argv[]. While it's not necessarily wrong to change argv-strings: e.g. the getopt() library function shuffles them, and some software change argv[0] which reflects in top, ps, etc. But: "argv[0] = NULL" looks very "experimental" to me. I'm not sure if its really wrong to do that, it's "unusual" to say the least. Also, imagine you start your program without any parameters on the command line, so argv[1]....argv[x] will be empty or don't even exist. What would happen if a user of your program enters a command with 1 or more arguments? Then argv[1]...argv[x] will be assinged those arguments, but do argv[1], argv[2] exist, e.g. have memory space allocated for all of them? I don't know, and maybe Linux does allocate space for some argv[]'s for each program even if they were not given on the command line that started the program. But even if Linux does this, how many?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.