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
|
CC=gcc
|
||||||
CFLAGS= -O3 -Wall
|
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 <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
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__
|
#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
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 "line.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.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_
|
#ifndef _LINE_H_
|
||||||
#define _LINE_H_
|
#define _LINE_H_
|
||||||
#define LINE_BUF_SIZE 1024
|
#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 <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
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_
|
#ifndef _LOOP_H_
|
||||||
#define _LOOP_H_
|
#define _LOOP_H_
|
||||||
int loop();
|
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 <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[]) {
|
||||||
|
|
Loading…
Reference in a new issue