- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在 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;
}
最佳答案
代码似乎错过了 NULL
-terminate 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*()
函数家族的成员仅返回错误。
关于c - execvp : bad address error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20449182/
reqwest v0.9 将 serde v1.0 作为依赖项,因此实现 converting serde_json errors into reqwest error . 在我的代码中,我使用 se
我有这个代码: let file = FileStorage { // ... }; file.write("Test", bytes.as_ref()) .map_err(|e| Mu
我只是尝试用angular-cli创建一个新项目,然后运行服务器,但是它停止并显示一条有趣的消息:Error: No errors。 我以这种方式更新了(希望有帮助):npm uninstall -g
我从我的 javascript 发送交易 Metamask 打开传输对话框 我确定 i get an error message in metamask (inpage.js:1 MetaMask -
这个问题在这里已经有了答案: How do you define custom `Error` types in Rust? (3 个答案) How to get a reference to a
我想知道两者之间有什么大的区别 if let error = error{} vs if error != nil?或者只是人们的不同之处,比如他们如何用代码表达自己? 例如,如果我使用这段代码: u
当我尝试发送超过 50KB 的图像时,我在 Blazor 服务器应用程序上收到以下错误消息 Error: Connection disconnected with error 'Error: Serv
我有一个error-page指令,它将所有异常重定向到错误显示页面 我的web.xml: [...] java.lang.Exception /vi
我有这样的对象: address: { "phone" : 888, "value" : 12 } 在 WHERE 中我需要通过 address.value 查找对象,但是在 SQL 中有函数
每次我尝试编译我的代码时,我都会遇到大量错误。这不是我的代码的问题,因为它在另一台计算机上工作得很好。我尝试重新安装和修复,但这没有帮助。这是整个错误消息: 1>------ Build starte
在我的代码的类部分,如果我写一个错误,则在不应该的情况下,将有几行报告为错误。我将'| error'放在可以从错误中恢复的良好/安全位置,但是我认为它没有使用它。也许它试图在某个地方恢复中间表情? 有
我遇到了 csv 输入文件整体读取故障的问题,我可以通过在 read_csv 函数中添加 "error_bad_lines=False" 来删除这些问题来解决这个问题。 但是我需要报告这些造成问题的文
在 Spring 中,验证后我们在 controller 中得到一个 BindingResult 对象。 很简单,如果我收到验证错误,我想重新显示我的表单,并在每个受影响的字段上方显示错误消息。 因此
我不知道出了什么问题,因为我用 Java 编程了大约一年,从来没有遇到过这个错误。在一分钟前在 Eclipse 中编译和运行工作,现在我得到这个错误: #A fatal error has been
SELECT to_char(messages. TIME, 'YYYY/MM/DD') AS FullDate, to_char(messages. TIME, 'MM/DD
我收到这些错误: AnonymousPath\Anonymized.vb : error BC30037: Character is not valid. AnonymousPath\Anonymiz
我刚刚安装了 gridengine 并在执行 qstat 时出现错误: error: commlib error: got select error (Connection refused) erro
嗨,我正在学习 PHP,我从 CRUD 系统开始,我在 Windows 上安装了 WAMP 服务器,当我运行它时,我收到以下错误消息。 SCREAM: Error suppression ignore
我刚刚开始一个新项目,我正在学习核心数据教程,可以找到:https://www.youtube.com/watch?v=zZJpsszfTHM 我似乎无法弄清楚为什么会抛出此错误。我有一个名为“Exp
当我使用 Jenkins 运行新构建时,出现以下错误: "FilePathY\XXX.cpp : fatal error C1853: 'FilePathZ\XXX.pch' precompiled
我是一名优秀的程序员,十分优秀!