I implemented a simple shell in programming language C with UNIX system calls. Now it has only following functions, but I will add some functions(Redirection, Pipe, Background running, ...) in future.
- Run inputed commands.
- "exit" command.
Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#define MAX_ARGS 10
#define MAX_LEN 100
void child(int argc, char *argv[MAX_ARGS]);
int main()
{
int argc, n = 0;
int status;
char input[MAX_LEN], *argv[MAX_ARGS], *cp;
const char *delim = " \t\n"; /* delimiters of commands */
while (1) {
/* show a prompt */
++n;
printf("command[%d] ", n);
/* read a line */
if (fgets(input, sizeof(input), stdin) == NULL) {
/* inputed EOF(Ctrl-D) */
printf("Goodbye!\n");
exit(0);
}
/* split the input to commands with blank and Tab */
cp = input;
for (argc = 0; argc < MAX_ARGS; argc++) {
if ((argv[argc] = strtok(cp,delim)) == NULL)
break;
cp = NULL;
}
/* exit this shell when "exit" is inputed */
if(strcmp(argv[0], "exit") == 0) {
printf("Goodbye!\n");
exit(0);
}
pid_t pid = fork();
if(pid == -1) {
/* failed to fork() */
perror("fork");
exit(1);
} else if(pid == 0) {
/* child process */
child(argc, argv);
} else {
/* parent process */
wait(&status);
}
}
}
void child(int argc, char *argv[MAX_ARGS]) {
execvp(argv[0], argv);
}
Result
****@ubuntu-vm:~/work/os$ gcc -Wall s_shell.c
****@ubuntu-vm:~/work/os$ ./a.out
command[1] ls
#ex01.c# execlp0.c fileio1.c~ fileio4.c~ s_shell.c
a.out execve0.c fileio2.c foo system0.c
ex1.c execve0.c~ fileio2.c~ fork0.c wait0.c
ex1.c~ fileio0.c fileio3.c fork0.c~ wait0.c~
ex2.c fileio0.c~ fileio3.c~ hello.c
ex2.c~ fileio1.c fileio4.c httpget.c
command[2] cat hello.c
#include <stdio.h>
int main() {
printf("hello, world!\n");
return 0;
}
command[3] gcc -Wall hello.c
command[4] ./a.out
hello, world!
command[5] exit
Goodbye!
****@ubuntu-vm:~/work/os$
Reference site
Original Text(Japanese)
1 comment:
wow. thanks for posting this. it helped me with my problem regarding execvp(). oh by the way, why did you created a function child() instead of just putting execvp() on the main?
Post a Comment