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
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 <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
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__
#define __EXEC_H__
int forkExec(char **args);
int commandExec(char **args);
#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 <stdio.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_
#define _LINE_H_
#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 <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
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_
#define _LOOP_H_
int loop();

10
main.c
View file

@ -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[]) {