execvp:错误的地址错误(execvp: bad address error)

编程入门 行业动态 更新时间:2024-10-27 16:30:00
execvp:错误的地址错误(execvp: bad address error)

我正在开发linux来创建一个使用各种命令的shell。 我有不同的内置命令,其中一个是“历史”。 我有一个reshist()函数来重置包含由用户输入的输入的数组。 我也想使用execvp()来启用系统命令,并且还需要多个管道操作。

reshist()函数和多管道操作不在一起时,它们运行良好,但是当我使用它们时,会导致execvp()引发“错误地址”错误。

我知道reshist()函数不能正确地将输入添加到列表中,但这不是什么大问题。 问题是为什么我得到错误。

可能是什么原因? 任何更好的想法,使他们一起工作?

#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> #include <sys/stat.h> #include <fcntl.h> #include <stdbool.h> #include <sys/types.h> #include <signal.h> #include <errno.h> #define MAX_BUFFER 129 // max line buffer #define MAX_ARGS 32 // max # args #define SEPARATORS " \t\n" // token sparators char *args[MAX_ARGS]; int print[16]; int get[16]; int fd[2]; char histarr[10][129]; // History array char histel[129]; void reshist(void) { //HISTORY RESORTING int counter = 0; while (counter < 10) { //shifting all elements by one from the last element of the list if (histarr[counter] == NULL ) { strcpy(histarr[counter], histel); //first element of the history will contain the last command break; } counter++; } if (counter == 10) { counter = 1; while (counter < 10) { strcpy(histarr[counter - 1], histarr[counter]); counter++; } strcpy(histarr[9], histel); } memset(histel, 0, 127); //HISTORY RESORT ENDS } void setup(void) { char buf[MAX_BUFFER]; // line buffer //char * args[MAX_ARGS]; // pointers to arg strings char ** arg; // working pointer thru args char * prompt = "333.sh>"; // shell prompt /* keep reading input until "quit" command or eof of redirected input */ while (!feof(stdin)) { /* get command line from input */ fputs(prompt, stdout); // write prompt if (fgets(buf, MAX_BUFFER, stdin)) { // read a line /* tokenize the input into args array */ arg = args; *arg++ = strtok(buf, SEPARATORS); // tokenize input while ((*arg++ = strtok(NULL, SEPARATORS))) ; // last entry will be NULL strcpy(histel, buf); reshist(); pid_t pid; int print[16]; int get[16]; int fd[2]; int count = 0; int i = 0; while (args[i] != NULL ) { if (0 == strcmp(args[i], "|")) { count++; } i++; } char *arrays[count + 1][i - count]; // array lines bordered as arrays[numberOfPipes+1][numberofArguments-numberOfPipes] i = 0; int x = 0; int y = 0; while (args[i] != NULL ) { if (strcmp(args[i], "|") != 0) { arrays[x][y] = args[i]; //builting arrays that is going to be sent to the each process, each row of the matrix is an array to be sent to another process y++; } else { x++; y = 0; } i++; } int h = 0; int a = 0; int k = 0; for (k = 0; k <= count; k++) { get[k] = -1; print[k] = -1; } //create required number of pipes for (a = 0; a < count; a++) { if (pipe(fd) == -1) { perror("Pipe failure"); continue; } get[a + 1] = fd[0]; print[a] = fd[1]; } for (k = 0; k <= count; k++) { pid = fork(); if (pid < 0) { printf("fork failed\n"); } else if (pid == 0) { if (print[k] != -1) { if (dup2(print[k], 1) == -1) { perror("dup2 error"); exit(1); } } if (get[k] != -1) { if (dup2(get[k], 0) == -1) { perror("dup2read error"); exit(1); } } for (h = 0; h <= count; h++) { close(print[h]); close(get[h]); } if (execvp((const char*) arrays[k][0], arrays[k]) < 1) { perror("error"); exit(1); } exit(0); } else { int stat; close(print[k]); close(get[k]); waitpid(pid, &stat, 0); } } } // system command else ends } } int main(void) { setup(); /** * After reading user input, the steps are: * (1) fork a child process using fork() * (2) the child process will invoke execvp() * (3) if command included &, parent will invoke wait() */ return 0; }

I am working on linux to create a shell serving with various commands. I have different built in commands and one of them is "history". I have a reshist() function to reset the array that contains the inputs entered by user. I also want to enable system commands using execvp() and also multiple pipe operation.

reshist() function and multiple pipe operation works well when they are not together, but when I use them both, it causes execvp() to raise "bad address" error.

I know that reshist() function does not works correct to add inputs to the list, but that is not a big deal. The problem is why I get the error.

What could be the reason? Any better ideas to make them work together?

#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> #include <sys/stat.h> #include <fcntl.h> #include <stdbool.h> #include <sys/types.h> #include <signal.h> #include <errno.h> #define MAX_BUFFER 129 // max line buffer #define MAX_ARGS 32 // max # args #define SEPARATORS " \t\n" // token sparators char *args[MAX_ARGS]; int print[16]; int get[16]; int fd[2]; char histarr[10][129]; // History array char histel[129]; void reshist(void) { //HISTORY RESORTING int counter = 0; while (counter < 10) { //shifting all elements by one from the last element of the list if (histarr[counter] == NULL ) { strcpy(histarr[counter], histel); //first element of the history will contain the last command break; } counter++; } if (counter == 10) { counter = 1; while (counter < 10) { strcpy(histarr[counter - 1], histarr[counter]); counter++; } strcpy(histarr[9], histel); } memset(histel, 0, 127); //HISTORY RESORT ENDS } void setup(void) { char buf[MAX_BUFFER]; // line buffer //char * args[MAX_ARGS]; // pointers to arg strings char ** arg; // working pointer thru args char * prompt = "333.sh>"; // shell prompt /* keep reading input until "quit" command or eof of redirected input */ while (!feof(stdin)) { /* get command line from input */ fputs(prompt, stdout); // write prompt if (fgets(buf, MAX_BUFFER, stdin)) { // read a line /* tokenize the input into args array */ arg = args; *arg++ = strtok(buf, SEPARATORS); // tokenize input while ((*arg++ = strtok(NULL, SEPARATORS))) ; // last entry will be NULL strcpy(histel, buf); reshist(); pid_t pid; int print[16]; int get[16]; int fd[2]; int count = 0; int i = 0; while (args[i] != NULL ) { if (0 == strcmp(args[i], "|")) { count++; } i++; } char *arrays[count + 1][i - count]; // array lines bordered as arrays[numberOfPipes+1][numberofArguments-numberOfPipes] i = 0; int x = 0; int y = 0; while (args[i] != NULL ) { if (strcmp(args[i], "|") != 0) { arrays[x][y] = args[i]; //builting arrays that is going to be sent to the each process, each row of the matrix is an array to be sent to another process y++; } else { x++; y = 0; } i++; } int h = 0; int a = 0; int k = 0; for (k = 0; k <= count; k++) { get[k] = -1; print[k] = -1; } //create required number of pipes for (a = 0; a < count; a++) { if (pipe(fd) == -1) { perror("Pipe failure"); continue; } get[a + 1] = fd[0]; print[a] = fd[1]; } for (k = 0; k <= count; k++) { pid = fork(); if (pid < 0) { printf("fork failed\n"); } else if (pid == 0) { if (print[k] != -1) { if (dup2(print[k], 1) == -1) { perror("dup2 error"); exit(1); } } if (get[k] != -1) { if (dup2(get[k], 0) == -1) { perror("dup2read error"); exit(1); } } for (h = 0; h <= count; h++) { close(print[h]); close(get[h]); } if (execvp((const char*) arrays[k][0], arrays[k]) < 1) { perror("error"); exit(1); } exit(0); } else { int stat; close(print[k]); close(get[k]); waitpid(pid, &stat, 0); } } } // system command else ends } } int main(void) { setup(); /** * After reading user input, the steps are: * (1) fork a child process using fork() * (2) the child process will invoke execvp() * (3) if command included &, parent will invoke wait() */ return 0; }

最满意答案

该代码似乎错过了NULL终止arrays[k] 。 使arrays[k]的最后一项进入NULL 。


更新

这个

if (execvp((const char*) arrays[k][0], arrays[k]) < 1)

应该

if (execvp(arrays[k][0], arrays[k]) == -1)

更直截了当的只是:

execvp(arrays[k][0], arrays[k]); perror("execvp() failed");

因为exec*()函数的成员函数在错误时返回。

The code seems to miss to NULL-terminate arrays[k]. Make the last entry in arrays[k] carry NULL.


Update:

This

if (execvp((const char*) arrays[k][0], arrays[k]) < 1)

should be

if (execvp(arrays[k][0], arrays[k]) == -1)

of even more straight forward just:

execvp(arrays[k][0], arrays[k]); perror("execvp() failed");

as the members of the exec*()-family of functions return on error only.

更多推荐

本文发布于:2023-07-21 09:40:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1209023.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:错误   地址   execvp   error   address

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!