/* * DISCLAIMER: THIS CODE IS FOR EDUCATIONAL PURPOSES ONLY. USE AT YOUR OWN RISKS. * * This code shows the basic workings of a shell. * * Append "/path/to/dashell" to /etc/shells, to make it a valid shell: * sudo echo "/path/to/dashell" >> /etc/shells * * Change your "username"'s shell. "username" should have execute permission for the shell: * chsh --shell /path/to/dashell username * */#include <unistd.h>#include <string.h>#include <stddef.h>#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <sys/signal.h>#define STDIN 0#define STDOUT 1#define STDERR 2#define BUFFER_SIZE 1024voidparse_arguments(charbuffer[],int*args_count,char*args[]){char*delimiters=" \r\n";char*token;*args_count=0;// "abc def ghi" => {"abc", "def", "ghi"}while(token=strsep(&buffer,delimiters)){args[*args_count]=token;(*args_count)++;}}intmain(intargc,constchar*argv[]){// The weird characters are used to format the text's appearance.// See http://en.wikipedia.org/wiki/ANSI_escape_codecharprompt[]="\033[1mdashell\033[2m>\033[0m ";charexec_error[]="Cannot execute program %s.\n";charbuffer[BUFFER_SIZE+1];intargs_count;char*args[BUFFER_SIZE];intn;while(1){write(STDOUT,prompt,strlen(prompt)+1);n=read(STDIN,buffer,BUFFER_SIZE);// Read from STDIN (keyboard input)buffer[n]='\0';// Null character to indicate string end// "abc def ghi" => {"abc", "def", "ghi"}parse_arguments(buffer,&args_count,args);// No argumentsif(args_count==0||strcmp(args[0],"")==0)continue;// Argument = exitif(strcmp(args[0],"exit")==0)exit(0);pid_tchild_pid=fork();// Duplicate processif(child_pid==0){// Childif(execvp(args[0],args)<0){// Replace executable code by command passedfprintf(stderr,exec_error,args[0]);}}else{// Parent// Wait for child to finishwait();}}}