From 885bd34da32ade734baa37b89e27a704d1b01a22 Mon Sep 17 00:00:00 2001 From: Dm1tr1y147 Date: Sat, 18 Jul 2020 20:34:20 +0500 Subject: [PATCH] Added setting environment variables with APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL=trueCHROME_DESKTOP=code-oss.desktopCOLORTERM=truecolorDBUS_SESSION_BUS_ADDRESS='unix:path=/run/user/1000/bus'DISPLAY=:0GIT_ASKPASS=/usr/lib/code/extensions/git/dist/askpass.shGTK_MODULES=canberra-gtk-moduleHOME=/home/dshI3SOCK=/run/user/1000/i3/ipc-socket.521LANG=en_US.UTF-8LESS=-RLESSHISTFILE=-LESSPROMPT='?f%f .?ltLine %lt:?pt%pt\%:?btByte %bt:-...'LESS_TERMCAP_mb=$'\C-[[31m'LESS_TERMCAP_md=$'\C-[[31m'LESS_TERMCAP_me=$'\C-[[0m'LESS_TERMCAP_se=$'\C-[[0m'LESS_TERMCAP_so=$'\C-[[47;30m'LESS_TERMCAP_ue=$'\C-[[0m'LESS_TERMCAP_us=$'\C-[[32m'LOGNAME=dshLS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:'MAIL=/var/spool/mail/dshMANWIDTH=120MOZ_PLUGIN_PATH=/usr/lib/mozilla/pluginsNO_AT_BRIDGE=1OLDPWD=/mnt/hdd/Work/Development/C/myshellPATH=/home/dsh/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perlPWD=/mnt/hdd/Work/Development/C/myshellSHELL=/bin/zshSHLVL=3TERM=xterm-256colorTERM_PROGRAM=vscodeTERM_PROGRAM_VERSION=1.46.1USER=dshVSCODE_GIT_ASKPASS_MAIN=/usr/lib/code/extensions/git/dist/askpass-main.jsVSCODE_GIT_ASKPASS_NODE=/usr/lib/electron7/electronVSCODE_GIT_IPC_HANDLE=/run/user/1000/vscode-git-55765a537b.sockWINDOWPATH=1XAUTHORITY=/home/dsh/.XauthorityXDG_CONFIG_HOME=/home/dsh/.configXDG_RUNTIME_DIR=/run/user/1000XDG_SEAT=seat0XDG_SESSION_CLASS=userXDG_SESSION_ID=1XDG_SESSION_TYPE=ttyXDG_VTNR=1 and before command locally --- README.md | 9 ++--- include/shell.h | 12 ++++--- src/execute.c | 94 +++++++++++++++++++++++++++++++----------------- src/line_parce.c | 27 +++++++++++--- src/main.c | 1 - src/shell.c | 3 ++ 6 files changed, 100 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index fe82c0b..c582c82 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,14 @@ Work is still in porgress, buf when you will see a "finished" topic assigned to * Save history into file and access recent command in another instance of shell * `$ENVIRONMENT_VARIABLES` expansion * Own `execvpe` implimentation as `mexecvpe` with commands getting from `$PATH` +* Setting environment variables with `export` and locally before command # Builtin commands * `cd`: changes current working directory to the one specified by user. If no arguments provided, shows error. -* `exit`: exits shell * `exec`: executes entered command and exits +* `export`: sets environment variable +* `exit`: exits shell # TODO -* `Ctrl+Z` running programm with `fd` -* `$()` subcommands -* Setting environment variables with `export` and before commands +* ~~`Ctrl+Z` running programm with `fd`~~ +* ~~`$()` subcommands~~ \ No newline at end of file diff --git a/include/shell.h b/include/shell.h index 8298912..4d73686 100644 --- a/include/shell.h +++ b/include/shell.h @@ -67,6 +67,9 @@ typedef struct commands cmd_pipe *pipe; ssize_t pipes_am; + char **envs; + ssize_t envs_am; + struct status stat; struct commands *next; cmd_sep sep_next; @@ -75,12 +78,12 @@ typedef struct commands typedef struct { struct history hist; - char **envs; int last_status; } t_; //Globals defenition extern t_ term; +extern char **environ; extern char *builtin[]; // shell.c file @@ -96,13 +99,14 @@ int expand_wildcatrd(char ***arr, char *input); // execute.c file int execute_with_pipes(cmds_p *command); -int execute(cmd_pipe *command); -int launch(cmd_pipe *command); +int execute(cmd_pipe *command, char **envp); +int launch(cmd_pipe *command, char **envp); int mexecvpe(char *file, char **argv, char **envp); int sh_cd(char **args); +int sh_exec(char **args, char **envp); +int sh_export(char **args); int sh_exit(char **args); -int sh_exec(char **args); void redirect_fd(int old, int new); diff --git a/src/execute.c b/src/execute.c index bc134a1..4c990a4 100644 --- a/src/execute.c +++ b/src/execute.c @@ -5,13 +5,15 @@ /* Global definitions */ char *builtin[] = { "cd", - "exit", - "exec"}; + "exec", + "export", + "exit"}; int (*builtin_func[])(char **) = { &sh_cd, - &sh_exit, - &sh_exec}; + &sh_exec, + &sh_export, + &sh_exit}; /** * @brief Redirects command input/output and executes it @@ -36,12 +38,12 @@ int execute_with_pipes(cmds_p *command) curr->pipefd[1] = tmp_fd[1]; curr->next->pipefd[0] = tmp_fd[0]; - status = execute(curr); + status = execute(curr, command->envs); curr = curr->next; } - status = execute(curr); + status = execute(curr, command->envs); return status; } @@ -52,7 +54,7 @@ int execute_with_pipes(cmds_p *command) * @param args * @return int */ -int execute(cmd_pipe *command) +int execute(cmd_pipe *command, char **envp) { if (command->args[0] == NULL) return 1; @@ -69,7 +71,7 @@ int execute(cmd_pipe *command) if (strcmp(args[0], builtin[i]) == 0) return (*builtin_func[i])(args); - return launch(command); + return launch(command, envp); } /** @@ -78,7 +80,7 @@ int execute(cmd_pipe *command) * @param args * @return int */ -int launch(cmd_pipe *command) +int launch(cmd_pipe *command, char **envp) { pid_t pid, wpid; int status; @@ -91,7 +93,7 @@ int launch(cmd_pipe *command) redirect_fd(command->pipefd[1], STDOUT_FILENO); - sh_exec(command->args); + sh_exec(command->args, envp); } else if (pid < 0) { @@ -132,6 +134,54 @@ int sh_cd(char **args) return 0; } +/** + * @brief Shell builtin command. Executes command replacing shell with it + * + * @param args + * @return int + */ +int sh_exec(char **args, char **envp) +{ + change_mode(0); + signal(SIGINT, SIG_DFL); + + if (strcmp(args[0], "exec") == 0) + args = slice_array(args, 1, -1, 1); + + if (mexecvpe(args[0], args, envp) < 0) + { + perror("mshell"); + } + + exit(EXIT_FAILURE); +} + +int sh_export(char **args) +{ + if (args[1] == NULL) + { + for (int i = 0; environ[i] != NULL; i++) + printf("declare -x %s\n", environ[i]); + + return 0; + } + + for (int i = 1; args[i] != NULL; i++) + { + char *name = strtok(args[i], "="), *val = strtok(NULL, "="); + + if (name == NULL || val == NULL) + { + fprintf(stderr, "export: wrong arguments\n"); + return 1; + } + + setenv(name, val, true); + + printf("Set %s variable to %s\n", name, getenv(name)); + } +} + /** * @brief Shell builtin command. Exits shell * @@ -143,28 +193,6 @@ int sh_exit(char **args) exit(0); } -/** - * @brief Shell builtin command. Executes command replacing shell with it - * - * @param args - * @return int - */ -int sh_exec(char **args) -{ - change_mode(0); - signal(SIGINT, SIG_DFL); - - if (strcmp(args[0], "exec") == 0) - args = slice_array(args, 1, -1, 1); - - if (mexecvpe(args[0], args, NULL) < 0) - { - perror("mshell"); - } - - exit(EXIT_FAILURE); -} - void redirect_fd(int old, int new) { if (old > 0) @@ -194,7 +222,7 @@ int mexecvpe(char *file, char **argv, char **envp) char buff[file_len + path_len + 1], *subp; - for (char *p = path; ; p = subp) + for (char *p = path;; p = subp) { subp = strchr(p, ':'); memcpy(buff, p, subp - p); diff --git a/src/line_parce.c b/src/line_parce.c index 0363fdf..9a9dfea 100644 --- a/src/line_parce.c +++ b/src/line_parce.c @@ -227,14 +227,25 @@ cmds_p *process_line(char *line) int j = i; for (; j < line_size; j++) - if (line[j] == ' ') + if (line[j] == ' ' || line[j] == ';' || line[j] == '&' || line[j] == '|' || line[j] == '>' || line[j] == '<') break; free_tmp[j] = '\0'; - char *msg = getenv(tmp); - if (msg != NULL) - append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, "\n"); + char *msg = NULL; + + for (int k = 0; k < curr_cmd->envs_am; k++) + if (strncmp(curr_cmd->envs[k], tmp, strlen(tmp)) == 0) + msg = strchr(curr_cmd->envs[k], '=') + 1; + + if (msg == NULL) + { + msg = getenv(tmp); + + if (msg == NULL) + msg = "\n"; + } + append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, msg); tmp += j - i + 1; i = j; @@ -243,6 +254,14 @@ cmds_p *process_line(char *line) { free_tmp[i] = '\0'; + if (curr_cmd->pipe->args[0] == NULL && strchr(tmp, '=')) + { + append_to_str_arr(&curr_cmd->envs, &curr_cmd->envs_am, tmp); + tmp += strlen(curr_cmd->envs[curr_cmd->envs_am - 1]) + 1; + + continue; + } + char *ap_string = trim_string(tmp, false), **exp = calloc(0, sizeof(char *)); int sz = expand_wildcatrd(&exp, ap_string); diff --git a/src/main.c b/src/main.c index 871e8dd..284d8e9 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,6 @@ int main() // Init t_ init_term() { - // Entering raw mode change_mode(1); diff --git a/src/shell.c b/src/shell.c index 8d51f40..2e84429 100644 --- a/src/shell.c +++ b/src/shell.c @@ -66,6 +66,9 @@ cmds_p *new_cmd() new->pipe = new_cmd_pipe(); new->pipes_am = 1; + new->envs = calloc(0, sizeof(char *)); + new->envs_am = 0; + new->stat.s = 0; new->sep_next = NO_SEP; new->stat.invert = false;