feat(builtin): add built-in command

This commit is contained in:
iridiumR 2022-09-18 14:46:23 +08:00
parent d78af54b6c
commit bbec5fbc2e
No known key found for this signature in database
GPG key ID: 5574BE4450D55618
11 changed files with 141 additions and 3 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.o
dish

View file

@ -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 CC=gcc
CFLAGS= -O3 -Wall CFLAGS= -O3 -Wall

53
builtin.c Normal file
View 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
View 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
View file

@ -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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include "builtin.h"
extern int (*builtin_func[]) (char **);
extern char* builtin_cmd[];
int forkExec(char **args) { int forkExec(char **args) {
pid_t pid; pid_t pid;
@ -20,9 +31,29 @@ int forkExec(char **args) {
/* fork error */ /* fork error */
perror("dish"); perror("dish");
} else { } else {
extern char volatile isWaiting;
isWaiting = 1;
/* parent process: wait child process*/ /* parent process: wait child process*/
pid=wait(&status); pid=wait(&status);
isWaiting = 0;
} }
return WEXITSTATUS(status); 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
View file

@ -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__ #ifndef __EXEC_H__
#define __EXEC_H__ #define __EXEC_H__
int forkExec(char **args); int forkExec(char **args);
int commandExec(char **args);
#endif #endif

6
line.c
View file

@ -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 "line.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

6
line.h
View file

@ -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_ #ifndef _LINE_H_
#define _LINE_H_ #define _LINE_H_
#define LINE_BUF_SIZE 1024 #define LINE_BUF_SIZE 1024

9
loop.c
View file

@ -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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -9,11 +15,10 @@ int loop() {
char *line; char *line;
char **args; char **args;
int status = 1;
printf("> "); printf("> ");
line = readLine(); line = readLine();
args = splitLine(line); args = splitLine(line);
status = forkExec(args); commandExec(args);
free(line); free(line);
free(args); free(args);
return 0; return 0;

6
loop.h
View file

@ -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_ #ifndef _LOOP_H_
#define _LOOP_H_ #define _LOOP_H_
int loop(); int loop();

10
main.c
View file

@ -1,13 +1,23 @@
/*
* @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 <signal.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include "loop.h" #include "loop.h"
char volatile isWaiting = 0;
void intHandler(int dummy) { void intHandler(int dummy) {
if (isWaiting) {
return;
printf("\nSIGINT exit.\n"); printf("\nSIGINT exit.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {