Write its own shell

shell

What is a shell?
shell is like a matchmaker in linux, we have to shell command, shell to tell the system what we need to do, for us to pull strings, call the operating system available to achieve our interface, shell provides communication between you and the operating system the way.
linux kernel (kernel), we can not directly touched, but through the shell, shell is the outermost layer of the operating system. the interaction between the shell and manage your operating system: waiting for your input, to the operating system interprets your input, processing and output of a variety of operating systems results, explain it to you.
The following diagram circled in red to show something that is in the form of a shell in front of us.
shell

Write your own simple shell preparations

fork () function creates the child process

fork function running program is divided into two (almost) exactly the same process, each process started a thread begins execution of code from the same location. These two threads in the process to continue, as if two users simultaneously launched two copies of the application.
fork()For example please move on my blog process

wait () function

Prototype:

	pid_t wait(int* status);
	pid_t waitpid(pid_t pid, int* status, int options);

wait(): Wait for any one child process exits, if no child process exits, the blocking has been waiting for
waitpid(): the specified child process can wait, can wait for any one child process exits, can be set to a non-blocking wait for
blocking: In order to complete a function to initiate a function call If this function is not complete functions have been suspended to wait before returning to complete
a non-blocking: in order to complete a function to initiate a function call, if we do not have the conditions to complete, then immediately return without waiting
options:

  1. WNOHANG If no child process exits, then immediately return an error if there is recovery resources
  2. WUNTRACED if the child enters the suspend state, immediately returned, but the end state of the child process is not to be ignored

Acquisition process exit status code: Exit Reason parameter is stored in the sub-process and wait in the exit code, but only the parameters of the lower 16 bits used to store two bytes of information
in which the low 16 bits, the upper eight bits the exit code is stored, the program has finished running, quit will have low storage 7 is an abnormal situation, the eight core dump is a sign
Write pictures described here
how to get
WIFEXITED and generally used in conjunction with WEXITSTATUS

WIFEXTED(status) 这个宏用来获取是否正常退出,正常退出获得true
WEXITSTATUS(status) 该宏只可在WIFEXITED为true时使用,获取正常退出的状态码

WIFSIGNALED and WTERMSIG

WIFSIGNALED(status) 这个宏用来获取是否异常退出,异常退出获得true
WTERMSIG(status) 该宏只可在WIFSIGNALED为true时使用,获取异常退出的状态码

Replace the code in the child class function --exec

exec family of functions is the role of program replacement if the replacement is successful, the exec source code will not run unless an error, which means that if you write printf after exec, will not have any output

int execl(const char* path, const char* arg, ...);
int execlp(const char* file, const char* arg, ...);
int execle(const char* path, const char* arg, ..., char* envp[]);
int execv(const char* path, char* const argv[]);
int execvp(const char* file, char* const argv[]);
int execve(const char* path, char* const argv[], char *const envp[]);

The six function names and parameters are similar, using them is almost the same, in which the 'l' (list) represents the parameter list, 'v' (vector) represents a parameter array, 'p' (path) indicate automatically searches the environment variables PATH, 'e' (env) expressed the need to maintain their own environment variables:

  1. Parameter const char* path, you need to tell the operating system, program files full path
    parameters are const char* filenot required to tell the path, only the file name will automatically find the path to the next PATH
  2. execle and execve not inherit environment variables from the parent process, organized by the user environment variables
    other functions (functions that do not end e) inherited from the parent process environment variables
  3. three functions execl more in line with our usual habits, in order to ls -l, for example, when using the input int execlp("ls", "ls", "-l");
    three functions execv is in the form of an array of pointers with

Carding process execution of shell

  1. Get input terminal
  2. Parse input
  3. Create a child process, child processes replacement program
  4. The parent process waits for the child process has finished running, corpses

Code

Thank big brother Sun Yu Mo pointed out bug, the code has been modified to learn Gangster

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int argc = 0;
char* argv[32] = {NULL};

int div_commond(char* buf)
{
	if (buf == NULL)
		return -1;
	argc = 0;
	char* front = buf;
	char* back = buf;
	//不断分割命令成指针数组
	while (1)
	{
		while (*front == ' ')
			front++;
		if (*front == '\0')
			break;
		back = front;
		while (*back != ' ' && *back != '\0')
			back++;
		if (*back == '\0')
		{
			argv[argc++] = front;
			break;
		}
		*back = '\0';
		argv[argc++] = front;
		front = back + 1;
	}
	argv[argc++] = NULL;
	if (argc == 1)
		return -1;
	return 0;
}

int exec_cmd()
{
	int pid = fork();
	if (pid < 0)
	{
		perror("fork failed");
		return -1;
	}
	else if (pid == 0)
	{
		//替换进程
		execvp(argv[0], argv);
		exit(0);
	}
	else
	{
		//wait用法,等待子进程退出,退出后一个状态码会存入statu
		//用WIFEXITED这个宏来获取退出值是否是正常退出
		int status;
		wait(&status);
		if (WIFEXITED(status) == 1)
			printf("%s\n", strerror(WEXITSTATUS(status)));
	}
	return 0;
}
	
int main()
{
	char buf[1024];
	while (1)
	{
		memset(buf, 0x00, 1024);
		printf("------shell>>>>>>");
		//读取到\n为止,删除缓冲区数据
		scanf("%[^\n]%*c", buf);
		if (div_commond(buf) != 0)
		{
			char black_hall[100];
			fgets(black_hall, 100, stdin);
			printf("wrong commond\n");
			continue;
		}
		exec_cmd();
	}
	return 0;
}

Implementation of the results

shell demo

Published 89 original articles · won praise 96 · views 90000 +

Guess you like

Origin blog.csdn.net/Boring_Wednesday/article/details/81952551