用C语言写一个自己的shell-Part Ⅱ--execute commands
创始人
2024-05-28 09:07:07
0

Part Ⅱ–execute commands

Exec

This brings us to the exec family of functions. Namely, it has the following functions:

  • execl
  • execv
  • execle
  • execve
  • execlp
  • execvp

For our needs,we will use execvp whose signature looks like this

int execvp(const char *file, char *const argv[]);

execvp function indicates that,it accepts the name of a file,for which it will search for $PATH variable of the system and an array of arguments to be executed.

A few things to note about the execvp function:

  1. The first argument is the name of the command
  2. The second argument consists of the name of the command and the arguments passed to the command itself. It must also be terminated by NULL.
  3. It also swaps out the current process image with that of the command being executed, but more on that later.

execvp.c

#include int main() {char *argv[] = {"ls","-l","-h","-a",NULL};execvp(argv[0],argv);return 0;
}

If you compile and execute the execvp.c, you will see an output similar to the following:

total 32K
drwxrwxr-x 2 marco marco 4.0K  3月  1 22:07 .
drwxrwxr-x 5 marco marco 4.0K  3月  1 22:04 ..
-rwxrwxr-x 1 marco marco  17K  3月  1 22:07 execvp
-rw-rw-r-- 1 marco marco  123  3月  1 22:07 execvp.c

Which is exactly the same if you manually executels -l -h -a

readline

https://tiswww.case.edu/php/chet/readline/rltop.html

With execvp function,we can perform commands in $PATH but how to accept the string of commands as stdin?

This brings us to the Readline Library.

#include 
#include 
char * readline (const char *prompt);

However,when I used this function,error occured.

Ubuntu that I used doesn’t have the library by default.Hence,the library need to be installed.

sudo apt-get install libreadline-dev

Meanwhile,we should add an another argument to link the library when compiling the File.c ,otherwise you may see an error like

“undefined reference to `readline’
collect2: error: ld returned 1 exit status”.

gcc File.c -o File -lreadline

And here’s the code.

#include 
#include 
#include 
#include 
#include 
#include char **get_input(char *);int main() {//in C,ptr can be used as array.char **command;char *input;pid_t child_pid;int stat_loc;while(1) {input = readline("mysh> ");//with "mysh> " to be a prompt,the function reads a line of input.command = get_input(input);if(!command[0]) {//empty commandsfree(input);free(command);continue;}child_pid = fork();if(child_pid == 0) {//child processexecvp(command[0],command);} else {waitpid(child_pid, &stat_loc, WUNTRACED);}free(input);free(command);}return 0;
}char **get_input(char *input) {char **command = malloc(8 * sizeof(char *));char *separator = " ";char *parsed;int index = 0;parsed = strtok(input, separator);while (parsed != NULL) {command[index] = parsed;index++;parsed = strtok(NULL, separator);}command[index] = NULL;return command;
}

Let’s test it.

在这里插入图片描述

However,the exec family of function can’t perform built-in commands like cd.

在这里插入图片描述

The code with weak robustness should be revised to be more robust and stronger.

  1. Dynamic memory allocation - in char ** get_input(char *input);

    The command variable only malloc 8 sizeof(char *).It’s limited,

    so you will see the following error:

在这里插入图片描述

To handle the error,commandshould malloc dynamic memories.

  1. fork failed - If the OS runs out of memory or reaches the maxmum number of allowed processes,a child process will not be created.We add the following segment to our code:

    		if(child_pid < 0) {perror(command[0]);exit(1);}
    
  2. exev failed - the exev function may fail.We modify the following block to our code:

    			//child processif (execvp(command[0], command) < 0) {perror(command[0]);exit(1);}
    

The revised code is here,written by chatGPT.The AI is amazing!!!

#include 
#include 
#include 
#include 
#include 
#include char **split_input(char *);int main() {//in C,ptr can be used as array.char **command;char *input;pid_t child_pid;int stat_loc;while(1) {input = readline("mysh> ");//with "mysh> " to be a prompt,the function reads a line of input.command = split_input(input);if(!command[0]) {//empty commandsfree(input);free(command);continue;}//fork failed.child_pid = fork();if(child_pid < 0) {perror(command[0]);exit(1);}if(child_pid == 0) {//child processif (execvp(command[0], command) < 0) {perror(command[0]);exit(1);}} else {waitpid(child_pid, &stat_loc, WUNTRACED);}free(input);free(command);}return 0;
}
char **split_input(char *input) {int capacity = 10;char **command = malloc(capacity * sizeof(char *));if (command == NULL) {fprintf(stderr, "Error: memory allocation failed\n");exit(EXIT_FAILURE);}char *token = strtok(input, " ");int i = 0;while (token != NULL) {if (i == capacity - 1) {  // resize the array if it is fullcapacity *= 2;char **new_command = realloc(command, capacity * sizeof(char *));if (new_command == NULL) {fprintf(stderr, "Error: memory allocation failed\n");exit(EXIT_FAILURE);}command = new_command;}command[i] = malloc((strlen(token) + 1) * sizeof(char));if (command[i] == NULL) {fprintf(stderr, "Error: memory allocation failed\n");exit(EXIT_FAILURE);}strcpy(command[i], token);token = strtok(NULL, " ");i++;}command[i] = NULL;  // terminate the array with NULLreturn command;
}

相关内容

热门资讯

雷军宣布小米汽车推出七年低息政... 小米集团创始人、董事长兼CEO雷军1月15日晚在直播中宣布,为进一步降低智能电动汽车的入手门槛,小米...
关于严厉打击“盗抢骗”“黄赌毒... 稷山县公安局 关于严厉打击“盗抢骗”“黄赌毒” “食药环”等突出违法犯罪的 通 告 为深入推进平安稷...
雷军宣布小米YU7推出「7年低... 1月15日,小米创办人,董事长兼CEO雷军在直播中宣布,小米YU7推出7年低息政策。 雷军表示,从...
(粤港澳大湾区)广东多方签署备... 中新社广州1月15日电 (记者 方伟彬)记者15日从广东省人民检察院获悉,日前,该院与广东省高级人民...
技术创新+政策支持,北京青年用... 2025年,北京新能源汽车产业蓬勃发展,产量同比大幅增长,市场渗透率持续领先。在这股绿色浪潮中,北京...
网易云音乐前CEO朱一闻起诉老... 1月15日,天眼查App显示,近日,朱一闻、网易云音乐股份有限公司与杭州网易云音乐科技有限公司相关合...
政策红利持续释放,港股房地产板... 新京报贝壳财经讯(记者段文平)1月15日,港股房地产板块走强。据Wind数据显示,截至当天下午收盘,...
陕建股份(600248)披露公... 截至2026年1月15日收盘,陕建股份(600248)报收于3.59元,较前一交易日下跌0.28%,...