Full Code of vvy/wshell for AI

master 328695314a7a cached
10 files
21.0 KB
6.0k tokens
13 symbols
1 requests
Download .txt
Repository: vvy/wshell
Branch: master
Commit: 328695314a7a
Files: 10
Total size: 21.0 KB

Directory structure:
gitextract_6f06dpcs/

├── .gitignore
├── README.md
├── builtin_command.c
├── makefile
├── parsing.c
├── read_command.c
├── test.c
├── type_prompt.c
├── wshell.c
└── wshell.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.[oa]
*~


================================================
FILE: README.md
================================================
# Introduction
A simple simulation of shell in Linux for learning.
A blog (in Chinese) of introduction and how to build it :http://www.cnblogs.com/wuyuegb2312/p/3399566.html

# Usage
type

  make wshell

for wshell read input by fgets() or

  make wshell_r
  

for wshell with readline lib.It need to install libreadline5-dev first.


## Attention

  Because of the lack of support for regular expressions , typing file's names such as "*.c" are not support.
  

# File List
### wshell.c
  main program

### type_prompt.c
  print out the prompt of wshell including path,hostname

### read_command.c
  read command input, and analyse the command and parameter(s).

### builtin_command.c
  support some built-in command,such as exit,quit,about, and cd.

### test.c
  a test program, helloworld, which can be executed in wshell.

### parsing.c
  analyses user's input line and tell them to wshell.
  
# Update log

## 2015
### 11.08
    -Make the README.md be a real markdown file.
    -Bug fix1:
        Redirection operator ">>" will append a file, not trunc it to 0-size.
As noted by [caiminfeng](http://www.cnblogs.com/caiminfeng/) .

    -Bug fix2:
        When inputed "cd", it would be core dump before.
As noted by [guokesong](https://github.com/guokesong) in [issues2](https://github.com/vvy/wshell/issues/2).

## 2014
### 05.14

    -Bug fix:

        In readline mode, the spaces alloced by readline() was freed only once.Now they are all freed in the end of read_command().

As noted by [xingfe123](http://home.cnblogs.com/u/614123/) 

 

### 04.14

    -Bug fix:

        Add handler of SIGCHLD. Earlier wshell would ignore the zombie process in background.

        The handler only process the background process whose pid are saved in a array.

     -Adjust some indents, although they are not errors.

 

## 2013

### 12.8

    -Bug fix:

        Output redirect function was not completed. '>' still is for make new file,but '>>' append to any file now.

 

### 11.3
    -Implemented a simple parsing function parse() to analyses the user input.
    -Support I/O redirect, background running, and pipe. 
    -Bug fix:
        Typing ctrl+d will normal exit wshell. before, segment fault when using readline lib.

        Lack of free() somewhere, which may lead to memory leak.

 

### 11.1
    -Implemented some builtin command,such as exit/quit, about, and, cd.
    -Bug fix:
        Never free the memory of command and parameters before, which may cause memory leak.
        To solve it, read_command() has been rewrited, and is more like the one in Linux.
    -Rewrite read_command():
        There is no need to malloc for command and parameters any more.
        All these just are pointers now.
    -Supply two versions:
        Using readline lib and not.the former need installing readline lib.
        Type "make wshell_r" to make the former,and "make wshell" for another.


### 10.31
    -Use execvp() instead of execve() to handle with commands like ls.
    -Detect whether the shell is executed as root by geteuid()
    -Bug fix:
        execv()'s arg[0] usually is the name of command without path.
        earlier version is not correct.
    -Plan to do:
        a built-in cd command.

##10.16
    -A shell with basic function: get input and execute the test program(hello world).


# 简介
为了学习而编写的Linux下shell的简单模拟实现。
介绍如何一步一步编写该程序的博客:http://www.cnblogs.com/wuyuegb2312/p/3399566.html

# 用法
输入

  make wshell

构建使用fgets()接收命令的wshell

  make wshell_r
  

构建使用readline接收命令的wshell。需要安装libreadline5-dev或其他类似的库。


## 注意

  由于不支持正则表达式,含有通配符如"*.c"这样的文件名是不支持的。
    不存在的命令不会提示。
  

# 文件列表
### wshell.c
  主程序

### type_prompt.c
  拼接当前路径、主机名的提示符。

### read_command.c
  读取输入的命令,并分离出其中的参数。

### builtin_command.c
  提供对基本内建命令的支持,含exit、quit、about、cd等。

### test.c
  用来在wshell中执行的测试程序。

### parsing.c
  分析用户输入(是否使用了管道、重定向、后台执行等)。
  
# 更新记录

## 2015
### 11.08
    -让README.md成为了真正的markdown文件
    -调整部分缩进
    -Bug修复1:
        重定向符">>"将正确地在文件存在时做追加,而非把它变成0大小的文件。
感谢[caiminfeng](http://www.cnblogs.com/caiminfeng/) 的指出。

    -Bug修复2:
       当输入不带参数的 `cd`时,会导致崩溃。
感谢 [guokesong](https://github.com/guokesong) 在 [issues2](https://github.com/vvy/wshell/issues/2) 指出。

## 2014
### 05.14

    -Bug修复:

        在readline模式下, readline()申请的内存不会被释放。

感谢[xingfe123](http://home.cnblogs.com/u/614123/) 指出。

 

### 04.14

    -Bug修复:

        增加了SIGCHLD信号的处理器。较早版本的wshell不会处理后台的僵尸进程。

        但是该处理器只会处理事先保存了pid的子进程。

    -调整了不会导致错误的缩进。

 

## 2013

### 12.08

    -Bug修复:

        输出重定向尚未完成。 '>' 仍然会创建新文件,但是'>>'会往文件末尾追加。

 

### 11.03
    -实现了用于分析用户输入的函数parse()。
    -支持输入输出重定向、管道、后台运行。
    -Bug修复:
        输入ctrl+d会正常退出wshell了。此前,在使用readline库时会段错误。

        由于某处缺少free(), 会内存泄漏。

 

### 11.01
    -实现了一些内建命令,包括`exit` 、 `quit` 、 `about` 、 `cd`。
    -Bug修复:
        从未释放命令和参数的空间,导致内存泄漏。
        重写read_command()以解决这个问题,现在的行为更像Linux的了。
    -重写read_command():
        现在没必要为command和parameter释放内存了,它们只是指针。
    -提供了两个版本:
        使用readline库和不使用的。前者需要事先安装这个库。
        输入"make wshell_r"可以生成前者,而"make wshell"会生成后者。


### 10.31
    -用execvp()代替execve()处理 `ls` 这种命令。
    -通过geteuid()判断shell是否执行在root用户下。
    -Bug修复:
        execv()'的arg[0]一般是不含路径的命令,上一个版本处理有误。
    -下一步计划:
        支持内建命令 `cd`。

##10.16
    -一个具有基本功能的shell: 获取输入并执行测试程序(hello world).

================================================
FILE: builtin_command.c
================================================
/*
 * =====================================================================================
 *       Filename:  builtin_command.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2013.11.01 15h31m28s
 *         Author:  wuyue (wy), vvuyve@gmail.com
 *        Company:  UESTC
 * =====================================================================================
 */
#include "wshell.h"

int builtin_command(char *command, char **parameters)
{
	extern struct passwd *pwd;
    if(strcmp(command,"exit")==0 || strcmp(command,"quit")==0)
        exit(0);
    else if(strcmp(command,"about") == 0)
    {
        printf("This is a simulation of shell (bash) in Linux.\n");
        return 1;
    }
    else if(strcmp(command,"cd")==0)
    {
        char *cd_path = NULL;

        if(parameters[1] == NULL)
        //make "cd" to "cd .." as in bash
        {
            parameters[1] = malloc(3 * sizeof(char));
            parameters[1][0]= '.';
            parameters[1][1]= '.';
            parameters[1][2]= '\0';
        }
        if(parameters[1][0] == '~')
        {
            cd_path = malloc(strlen(pwd->pw_dir)+strlen(parameters[1]));
            //'~' makes length 1 more,but instead of '\0'
            if(cd_path == NULL)
            {
                printf("cd:malloc failed.\n");
            }
            strcpy(cd_path,pwd->pw_dir);
            strncpy(cd_path+strlen(pwd->pw_dir),parameters[1]+1,strlen(parameters[1]));
			//printf("path with ~:\n%s\n",cd_path);
        }
        else
        {
            cd_path = malloc(strlen(parameters[1]+1));
            if(cd_path == NULL)
            {
                printf("cd:malloc failed.\n");
            }
            strcpy(cd_path,parameters[1]);
        }
        if(chdir(cd_path)!= 0)
            printf("-wshell: cd: %s:%s\n",cd_path,strerror(errno));
        free(cd_path);
    }
    return 0;
}


================================================
FILE: makefile
================================================
wshell: wshell.h wshell.c type_prompt.c read_command.c builtin_command.c parsing.c test
	gcc wshell.c type_prompt.c read_command.c builtin_command.c parsing.c -o wshell

wshell_r: wshell.h wshell.c type_prompt.c read_command.c builtin_command.c parsing.c test
	gcc wshell.c type_prompt.c read_command.c builtin_command.c parsing.c -o wshell -D READLINE_ON -I /usr/include -lreadline -ltermcap

test: test.c
	gcc test.c -o test

clean:
	rm -f wshell test


================================================
FILE: parsing.c
================================================
/*
 * =====================================================================================
 *       Filename:  parsing.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2013.11.02 15h44min23s
 *         Author:  wuyue (wy), vvuyve@gmail.com
 *        Company:  UESTC
 * =====================================================================================
 */
#include "wshell.h"

int parse_info_init(struct parse_info *info)
{
    info->flag = 0;
    info->in_file = NULL;
    info->out_file = NULL;
    info->command2 = NULL;
    info->parameters2 = NULL;
    return 0;
}

int parsing(char **parameters,int ParaNum,struct parse_info *info)
{
    int i;
    parse_info_init(info);
    if(strcmp(parameters[ParaNum-1],"&") ==0)
    {
        info->flag |= BACKGROUND;
        parameters[ParaNum-1] = NULL;
        ParaNum--;
    }
    for(i=0;i<ParaNum;)
    {
        if(strcmp(parameters[i],"<<")==0 || strcmp(parameters[i],"<")==0)
        {
            info->flag |= IN_REDIRECT;
            info->in_file = parameters[i+1];
            parameters[i] = NULL;
            i+=2;
        }
        else if(strcmp(parameters[i],">")==0)
        {
            info->flag |= OUT_REDIRECT;
            info->out_file = parameters[i+1];
            parameters[i] = NULL;
            i+=2;
        }
        else if(strcmp(parameters[i],">>")==0)
        {
            info->flag |= OUT_REDIRECT_APPEND;
            info->out_file = parameters[i+1];
            parameters[i] = NULL;
            i+=2;
        }
        else if(strcmp(parameters[i],"|")==0)
        {
            char* pCh;
            info->flag |= IS_PIPED;
            parameters[i] = NULL;
            info->command2 = parameters[i+1];
            info->parameters2 = &parameters[i+1];
            for(pCh = info->parameters2[0]+strlen(info->parameters2[0]);
                    pCh!=&(info->parameters2[0][0]) && *pCh!='/';pCh--)
                ;
            if(*pCh == '/')
                pCh++;
            info->parameters2[0] = pCh;
            break;
        }
        else
            i++;
    }
#ifdef DEBUG
	printf("\nbackground:%s\n",info->flag&BACKGROUND?"yes":"no");
	printf("in redirect:");
	info->flag&IN_REDIRECT?printf("yes,file:%s\n",info->in_file):printf("no\n");
	printf("out redirect:");
	info->flag&OUT_REDIRECT?printf("yes,file:%s\n",info->out_file):printf("no\n");
	printf("pipe:");
	info->flag&IS_PIPED?printf("yes,command:%s %s %s\n",info->command2,info->parameters2[0],info->parameters2[1]):printf("no\n");
#endif
    return 1;
}


================================================
FILE: read_command.c
================================================
/*
 * =====================================================================================
 *       Filename:  read_command.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2013.10.21 14h12min24s
 *         Author:  wuyue (wy), vvuyve@gmail.com
 *        Company:  UESTC
 * =====================================================================================
 */
#include "wshell.h"
#ifdef READLINE_ON
#include <readline/readline.h>
#include <readline/history.h>
#endif

//return value: number of parameters
//0 represents only command without any parameters
//-1 represents wrong input
int read_command(char **command,char **parameters,char *prompt)
{
#ifdef READLINE_ON
    free(buffer);
    buffer = readline(prompt);
    if(feof(stdin)) {
        printf("\n");
        exit(0);
    }

#else
    printf("%s",prompt);
    char* Res_fgets = fgets(buffer,MAXLINE,stdin);
    if(Res_fgets == NULL)
    {
        printf("\n");
        exit(0);
    }		
#endif

    if(buffer[0] == '\0')
        return -1;
    char *pStart,*pEnd;
    int count = 0;
    int isFinished = 0;
    pStart = pEnd = buffer;
    while(isFinished == 0)
    {
        while((*pEnd == ' ' && *pStart == ' ') || (*pEnd == '\t' && *pStart == '\t'))
        {
            pStart++;
            pEnd++;
        }

        if(*pEnd == '\0' || *pEnd == '\n')
        {
            if(count == 0)
                return -1;
            break;
        }

        while(*pEnd != ' ' && *pEnd != '\0' && *pEnd != '\n')
            pEnd++;


        if(count == 0)
        {
            char *p = pEnd;
            *command = pStart;
            while(p!=pStart && *p !='/')
                p--;
            if(*p == '/')
                p++;
            //else //p==pStart
            parameters[0] = p;
            count += 2;
#ifdef DEBUG
            printf("\ncommand:%s\n",*command);
#endif
        }
        else if(count <= MAXARG)
        {
            parameters[count-1] = pStart;
            count++;
        }
        else
        {
            break;
        }

        if(*pEnd == '\0' || *pEnd == '\n')
        {
            *pEnd = '\0';
            isFinished = 1;
        }
        else
        {
            *pEnd = '\0';
            pEnd++;
			pStart = pEnd;
        }
    }

    parameters[count-1] = NULL;

#ifdef DEBUG
    /*input analysis*/
    printf("input analysis:\n");
    printf("pathname:[%s]\ncommand:[%s]\nparameters:\n",*command,parameters[0]);
    int i;
    for(i=0;i<count-1;i++)
        printf("[%s]\n",parameters[i]);
#endif

    return count;
}


================================================
FILE: test.c
================================================
/*
 * =====================================================================================
 *       Filename:  test.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2013.10.16 20h40m39s
 *         Author:  wuyue (wy), vvuyve@gmail.com
 *        Company:  UESTC
 * =====================================================================================
 */
#include <stdio.h>
int main()
{
    printf("Hello world!\n");
    return 0;
}


================================================
FILE: type_prompt.c
================================================
/*
 * =====================================================================================
 *       Filename:  type_prompt.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2013.10.16 20h18min28s
 *         Author:  wuyue (wy), vvuyve@gmail.com
 *        Company:  UESTC
 * =====================================================================================
 */
//#include <sys/utsname.h>
#include "wshell.h"
const int max_name_len = 256;
const int max_path_len = 1024;

void type_prompt(char *prompt)
{
    extern struct passwd *pwd;
    char hostname[max_name_len];
    char pathname[max_path_len];
    int length;
    pwd = getpwuid(getuid());
    getcwd(pathname,max_path_len);
    if(gethostname(hostname,max_name_len)==0)
        sprintf(prompt,"[Wshell]%s@%s:",pwd->pw_name,hostname);
    else
        sprintf(prompt,"[Wshell]%s@unknown:",pwd->pw_name);
    //printf("pathname: %s,length:%d\npw_dir:%s,length:%d\n",
    //pathname,strlen(pathname),pwd->pw_dir,strlen(pwd->pw_dir));
    length = strlen(prompt);
    if(strlen(pathname) < strlen(pwd->pw_dir) || 
            strncmp(pathname,pwd->pw_dir,strlen(pwd->pw_dir))!=0)
        sprintf(prompt+length,"%s",pathname);
    else
        sprintf(prompt+length,"~%s",pathname+strlen(pwd->pw_dir));
    length = strlen(prompt);
    if(geteuid()==0)
        sprintf(prompt+length,"#");
    else
        sprintf(prompt+length,"$");
    return;
}

//int main()
//{
//    type_prompt();
//    return 0;
//}


================================================
FILE: wshell.c
================================================
/*
 * =====================================================================================
 *       Filename:  wshell.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2013.10.16 17h12min19s
 *         Author:  wuyue (wy), vvuyve@gmail.com
 *        Company:  UESTC
 * =====================================================================================
 */
#include "wshell.h"
#define TRUE 1
#define MAXPIDTABLE 1024

pid_t BPTable[MAXPIDTABLE];

void sig_handler(int sig)
{
    pid_t pid;
    int i;
    for(i=0;i<MAXPIDTABLE;i++)
        if(BPTable[i] != 0) //only handler the background processes
        {
            pid = waitpid(BPTable[i],NULL,WNOHANG);
            if(pid > 0)
            {
                printf("process %d exited.\n",pid);
                BPTable[i] = 0; //clear
            }
            else if(pid < 0)
            {
	if(errno != ECHILD)
                    perror("waitpid error");
            }
            //else:do nothing.
            //Not background processses has their waitpid() in wshell.
         }
    return;
}

void proc(void)
{
    int status,i;
    char *command = NULL;
    char **parameters;
    int ParaNum;
    char prompt[MAX_PROMPT];
    struct parse_info info;
    pid_t ChdPid,ChdPid2;
    parameters = malloc(sizeof(char *)*(MAXARG+2));
    buffer = malloc(sizeof(char) * MAXLINE);
    if(parameters == NULL || buffer == NULL)
    {
        printf("Wshell error:malloc failed.\n");
        return;
    }
	//arg[0] is command
	//arg[MAXARG+1] is NULL

    if(signal(SIGCHLD,sig_handler) == SIG_ERR)
        perror("signal() error");

    while(TRUE)
    {
        int pipe_fd[2],in_fd,out_fd;
        type_prompt(prompt);
        ParaNum = read_command(&command,parameters,prompt);
        if(-1 == ParaNum)
            continue;
        ParaNum--;//count of units in buffer
        parsing(parameters,ParaNum,&info);
        if(builtin_command(command,parameters))
            continue;
        if(info.flag & IS_PIPED) //command2 is not null
        {                
            if(pipe(pipe_fd)<0)
            {
                printf("Wshell error:pipe failed.\n");
                exit(0);
            }
        }  
        if((ChdPid = fork())!=0) //wshell
        {
            if(info.flag & IS_PIPED)
            {
                if((ChdPid2=fork()) == 0) //command2
                {
                    close(pipe_fd[1]);
                    close(fileno(stdin)); 
                    dup2(pipe_fd[0], fileno(stdin));
                    close(pipe_fd[0]); 
                    execvp(info.command2,info.parameters2);
                }
                else
                {
                    close(pipe_fd[0]);
                    close(pipe_fd[1]);
                    waitpid(ChdPid2,&status,0); //wait command2
                }
            }

            if(info.flag & BACKGROUND)
            {
                printf("Child pid:%u\n",ChdPid);
                int i;
                for(i=0;i<MAXPIDTABLE;i++)
                    if(BPTable[i]==0)
                        BPTable[i] = ChdPid; //register a background process
                if(i==MAXPIDTABLE)
                    perror("Too much background processes\nThere will be zombine process");                    
            }
            else
            {          
                waitpid(ChdPid,&status,0);//wait command1
            } 
        }
        else //command1
        {
			
            if(info.flag & IS_PIPED) //command2 is not null
            {                
                if(!(info.flag & OUT_REDIRECT) && !(info.flag & OUT_REDIRECT_APPEND)) // ONLY PIPED
	           {
                    close(pipe_fd[0]);
                    close(fileno(stdout)); 
                    dup2(pipe_fd[1], fileno(stdout));
                    close(pipe_fd[1]);
                }
                else //OUT_REDIRECT and PIPED
	           {
                    close(pipe_fd[0]);
                    close(pipe_fd[1]);//send a EOF to command2
                    if(info.flag & OUT_REDIRECT)
    	               out_fd = open(info.out_file, O_WRONLY|O_CREAT|O_TRUNC, 0666);
                    else
    	               out_fd = open(info.out_file, O_WRONLY|O_APPEND|O_TRUNC, 0666);
                    close(fileno(stdout)); 
                    dup2(out_fd, fileno(stdout));
                    close(out_fd);	        
                }
            }
            else
            {
                if(info.flag & OUT_REDIRECT) // OUT_REDIRECT WITHOUT PIPE
	           {
                    out_fd = open(info.out_file, O_WRONLY|O_CREAT|O_TRUNC, 0666);
                    close(fileno(stdout)); 
                    dup2(out_fd, fileno(stdout));
                    close(out_fd);
                }
                if(info.flag & OUT_REDIRECT_APPEND) // OUT_REDIRECT_APPEND WITHOUT PIPE
	           {
                    out_fd = open(info.out_file, O_WRONLY|O_CREAT|O_APPEND, 0666);
                    close(fileno(stdout)); 
                    dup2(out_fd, fileno(stdout));
                    close(out_fd);
                }
            }
            
            if(info.flag & IN_REDIRECT)
            {
                in_fd = open(info.in_file, O_CREAT |O_RDONLY, 0666);
                close(fileno(stdin)); 
                dup2(in_fd, fileno(stdin));
                close(in_fd); 
            }
            execvp(command,parameters);
        }
    }
    free(parameters);
	free(buffer);
}

int main() {
    int i;
    //init the BPTable
    for(i=0;i<MAXPIDTABLE;i++)
        BPTable[i] = 0;
    proc();
    return 0;
}


================================================
FILE: wshell.h
================================================
/*
 * =====================================================================================
 *       Filename:  wshell.h
 *    Description:  
 *        Version:  1.0
 *        Created:  2013.10.16 20h15min26s
 *         Author:  wuyue (wy), vvuyve@gmail.com
 *        Company:  UESTC
 * =====================================================================================
 */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h> 
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h> 
#define MAX_PROMPT 1024
#define MAXLINE 4096 //the length of all args is ARG_MAX
#define MAXARG 20

struct parse_info;
struct passwd *pwd;
char *buffer;

void type_prompt(char*);
int read_command(char **,char **,char*);
int builtin_command(char *,char **);
int parsing(char **,int,struct parse_info *);
void proc(void);
void sig_handler(int sig);



#ifndef STRUCT_PARSE_INFO
#define STRUCT_PARSE_INFO
#define BACKGROUND 			1
#define IN_REDIRECT 		2
#define OUT_REDIRECT 		4
#define OUT_REDIRECT_APPEND	8
#define IS_PIPED 			16
struct parse_info 
{
    int flag;
    char* in_file;
    char* out_file;
    char* command2;
	char** parameters2;
};
#endif
Download .txt
gitextract_6f06dpcs/

├── .gitignore
├── README.md
├── builtin_command.c
├── makefile
├── parsing.c
├── read_command.c
├── test.c
├── type_prompt.c
├── wshell.c
└── wshell.h
Download .txt
SYMBOL INDEX (13 symbols across 7 files)

FILE: builtin_command.c
  function builtin_command (line 13) | int builtin_command(char *command, char **parameters)

FILE: parsing.c
  function parse_info_init (line 13) | int parse_info_init(struct parse_info *info)
  function parsing (line 23) | int parsing(char **parameters,int ParaNum,struct parse_info *info)

FILE: read_command.c
  function read_command (line 20) | int read_command(char **command,char **parameters,char *prompt)

FILE: test.c
  function main (line 12) | int main()

FILE: type_prompt.c
  function type_prompt (line 16) | void type_prompt(char *prompt)

FILE: wshell.c
  function sig_handler (line 17) | void sig_handler(int sig)
  function proc (line 41) | void proc(void)
  function main (line 174) | int main() {

FILE: wshell.h
  type parse_info (line 26) | struct parse_info
  type passwd (line 27) | struct passwd
  type parse_info (line 33) | struct parse_info
  type parse_info (line 46) | struct parse_info
Condensed preview — 10 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (24K chars).
[
  {
    "path": ".gitignore",
    "chars": 10,
    "preview": "*.[oa]\n*~\n"
  },
  {
    "path": "README.md",
    "chars": 5238,
    "preview": "# Introduction\nA simple simulation of shell in Linux for learning.\nA blog (in Chinese) of introduction and how to build "
  },
  {
    "path": "builtin_command.c",
    "chars": 1887,
    "preview": "/*\n * =====================================================================================\n *       Filename:  builtin_"
  },
  {
    "path": "makefile",
    "chars": 454,
    "preview": "wshell: wshell.h wshell.c type_prompt.c read_command.c builtin_command.c parsing.c test\n\tgcc wshell.c type_prompt.c read"
  },
  {
    "path": "parsing.c",
    "chars": 2542,
    "preview": "/*\n * =====================================================================================\n *       Filename:  parsing."
  },
  {
    "path": "read_command.c",
    "chars": 2564,
    "preview": "/*\n * =====================================================================================\n *       Filename:  read_com"
  },
  {
    "path": "test.c",
    "chars": 451,
    "preview": "/*\n * =====================================================================================\n *       Filename:  test.c\n "
  },
  {
    "path": "type_prompt.c",
    "chars": 1480,
    "preview": "/*\n * =====================================================================================\n *       Filename:  type_pro"
  },
  {
    "path": "wshell.c",
    "chars": 5598,
    "preview": "/*\n * =====================================================================================\n *       Filename:  wshell.c"
  },
  {
    "path": "wshell.h",
    "chars": 1253,
    "preview": "/*\n * =====================================================================================\n *       Filename:  wshell.h"
  }
]

About this extraction

This page contains the full source code of the vvy/wshell GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 10 files (21.0 KB), approximately 6.0k tokens, and a symbol index with 13 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!