feat(builtin): add built-in command
This commit is contained in:
parent
d78af54b6c
commit
bbec5fbc2e
11 changed files with 141 additions and 3 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.o
|
||||
dish
|
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
|||
OBJ=main.o line.o loop.o exec.o
|
||||
OBJ=main.o line.o loop.o exec.o builtin.o
|
||||
CC=gcc
|
||||
CFLAGS= -O3 -Wall
|
||||
|
||||
|
|
53
builtin.c
Normal file
53
builtin.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:16:19
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:28:01
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int dish_cd(char **args);
|
||||
int dish_help(char **args);
|
||||
int dish_exit(char **args);
|
||||
|
||||
char* builtin_cmd[] = {
|
||||
"cd",
|
||||
"help",
|
||||
"exit"
|
||||
};
|
||||
|
||||
int (*builtin_func[]) (char **) = {
|
||||
&dish_cd,
|
||||
&dish_help,
|
||||
&dish_exit
|
||||
};
|
||||
|
||||
int dish_cd(char **args)
|
||||
{
|
||||
if (args[1] == NULL) {
|
||||
fprintf(stderr, "dish: expected argument to \"cd\"\n");
|
||||
} else {
|
||||
if (chdir(args[1]) != 0) {
|
||||
perror("dish");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dish_help(char **args)
|
||||
{
|
||||
fprintf(stdout, "Yet another Shell with C.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dish_exit(char **args)
|
||||
{
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int getBuiltinNum() {
|
||||
return sizeof(builtin_cmd) / sizeof(char *);
|
||||
}
|
12
builtin.h
Normal file
12
builtin.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:15:44
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:41:38
|
||||
*/
|
||||
#ifndef _BUILTIN_H_
|
||||
#define _BUILTIN_H_
|
||||
|
||||
int getBuiltinNum();
|
||||
|
||||
#endif
|
31
exec.c
31
exec.c
|
@ -1,7 +1,18 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:14:23
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:44:37
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "builtin.h"
|
||||
|
||||
extern int (*builtin_func[]) (char **);
|
||||
extern char* builtin_cmd[];
|
||||
|
||||
int forkExec(char **args) {
|
||||
pid_t pid;
|
||||
|
@ -20,9 +31,29 @@ int forkExec(char **args) {
|
|||
/* fork error */
|
||||
perror("dish");
|
||||
} else {
|
||||
extern char volatile isWaiting;
|
||||
isWaiting = 1;
|
||||
/* parent process: wait child process*/
|
||||
pid=wait(&status);
|
||||
isWaiting = 0;
|
||||
|
||||
}
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
int commandExec(char **args) {
|
||||
int i;
|
||||
|
||||
if (args[0] == NULL) {
|
||||
/* empty command */
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < getBuiltinNum(); i++) {
|
||||
if (strcmp(args[0], builtin_cmd[i]) == 0) {
|
||||
return (*builtin_func[i])(args);
|
||||
}
|
||||
}
|
||||
|
||||
return forkExec(args);
|
||||
}
|
||||
|
|
7
exec.h
7
exec.h
|
@ -1,4 +1,11 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:13:40
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:13:40
|
||||
*/
|
||||
#ifndef __EXEC_H__
|
||||
#define __EXEC_H__
|
||||
int forkExec(char **args);
|
||||
int commandExec(char **args);
|
||||
#endif
|
6
line.c
6
line.c
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:14:05
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:14:05
|
||||
*/
|
||||
#include "line.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
6
line.h
6
line.h
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:14:28
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:14:28
|
||||
*/
|
||||
#ifndef _LINE_H_
|
||||
#define _LINE_H_
|
||||
#define LINE_BUF_SIZE 1024
|
||||
|
|
9
loop.c
9
loop.c
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:13:53
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:13:53
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -9,11 +15,10 @@ int loop() {
|
|||
|
||||
char *line;
|
||||
char **args;
|
||||
int status = 1;
|
||||
printf("> ");
|
||||
line = readLine();
|
||||
args = splitLine(line);
|
||||
status = forkExec(args);
|
||||
commandExec(args);
|
||||
free(line);
|
||||
free(args);
|
||||
return 0;
|
||||
|
|
6
loop.h
6
loop.h
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:14:19
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:14:19
|
||||
*/
|
||||
#ifndef _LOOP_H_
|
||||
#define _LOOP_H_
|
||||
int loop();
|
||||
|
|
10
main.c
10
main.c
|
@ -1,12 +1,22 @@
|
|||
/*
|
||||
* @Author: 1ridic
|
||||
* @Date: 2022-09-18 14:13:59
|
||||
* @Last Modified by: 1ridic
|
||||
* @Last Modified time: 2022-09-18 14:21:48
|
||||
*/
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "loop.h"
|
||||
|
||||
char volatile isWaiting = 0;
|
||||
void intHandler(int dummy) {
|
||||
if (isWaiting) {
|
||||
return;
|
||||
printf("\nSIGINT exit.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
|
Loading…
Reference in a new issue