[英]zsh illegal hardware instruction c
我正在做一个多次执行 cmd arguments 传递的命令的练习。
练习的描述是:“程序必须逐行读取文件,每行执行一次命令行中指定的命令,在命令行中每次出现“@”时替换当前行的内容的文件。 ”
但是,一旦我执行./file_exec esempio.txt cat @
cli 就会向我显示此错误zsh illegal hardware instruction
。
我把我创建的各种文件放在这里:
主要.c
#include "file_exec.h"
int main(int argc, char **argv) {
if(argc < 3) {
fprintf(stderr,
"Specificare il file di testo e il comando da eseguire.\n");
return 1;
}
char *filename = argv[1];
int cmdargc = argc - 2;
char **opz = argv + 2;
char *cmd = argv[2];
char *line = (char *)malloc(sizeof(char) * BUZZ_SIZE);
int statusLine = 0;
FILE *file = fopen(filename, "r");
if(file == NULL) {
fprintf(stderr, "%s: Impossibile aprire %s: %s\n",
argv[0], argv[1], strerror(errno));
return 2;
}
int size = 1024;
do{
statusLine = fileReadLine(line, file, size); // leggo la singola linea
if(statusLine == 2){
size += 1024;
}
if(strlen(line) != 0){
int ris = executeLine(cmdargc, cmd, opz);
if(ris == -1){
fprintf(stderr, "Impossibile eseguire il comando: %s\n", cmd);
return -1;
}
}
}while(statusLine != -1);
fclose(file);
return 0;
}
file_exec.c
#include "file_exec.h"
int fileReadLine(char *line, FILE *file, int size){
if(!feof(file) && (int)strlen(line) < size){
fgets(line, size, file);
}else if((int)strlen(line) == size){
line = realloc(line, size*2);
return 2;
}else{
free(line);
return -1;
}
return 1;
}
int executeLine(int nOpz, char *cmd, char **opz){
char *pathCmd = strcat("/bin/",cmd);
pid_t pidSon = fork();
opz = addArguments(nOpz, cmd, opz);
switch(pidSon) {
case -1:
perror("fork() failed");
free(opz);
return 1;
case 0:
printf("Esecuzione di ls...\n");
execl(pathCmd, cmd, opz, NULL);
perror("exec failed");
free(opz);
return 1;
default:
wait(NULL);
printf("%s completed\n",cmd);
}
free(opz);
return 0;
}
char **addArguments(int cmdargc, char *line, char **cmdargv){
char **newArgs = (char **)malloc((cmdargc + 1) * sizeof(char *));
for(int i = 0; i < cmdargc; i++){
if(strcmp(cmdargv[i], "@") == 0){
newArgs[i] = line;
}else{
newArgs[i] = cmdargv[i];
}
}
newArgs[cmdargc] = NULL;
return newArgs;
}
file_exec.h
#ifndef FILEEX_H__
#define FILEEX_H__
#define BUZZ_SIZE 1024
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
int fileReadLine(char *, FILE *, int);
int executeLine(int, char *, char **);
char **addArguments(int, char *, char **);
#endif
esmpio.txt文件
file1.txt
file2.txt
file3.txt
文件1.txt
Hello
文件2.txt
I'm
文件3.txt
italian
Makefile
file_exec: file_exec.o main.o
gcc -Wall -Werror -Wextra -std=c99 file_exec.o main.o -o file_exec
file_exec.o: file_exec.h file_exec.c
gcc -Wall -Werror -Wextra -std=c99 -c file_exec.c
main.o: file_exec.h main.c
gcc -Wall -Werror -Wextra -std=c99 -c main.c
clean:
rm -f *.o main
(我在 Intel Mac 上)
该程序应通过此命令显示此 output ./file_exec esempio.txt cat @
:
Hello
I'm
italian
我刚刚尝试在 main.c 上的第一个 if 语句之后放置一些调试 printf 但它被忽略并且没有执行。
您以错误的方式使用strcat
char *pathCmd = strcat("/bin/",cmd);
正在将 cmd 添加到字符串的末尾(char 常量数组) "/bin"
。 然后返回这个数组。 更准确地说,它所做的是到达地址"/bin"
——是的,这是一个地址——1 1 地迭代这个地址,直到它找到终端 0,即字符串的末尾。 并将地址cmd
的内容复制到那里。 显然,你不能那样做。 不是从语言的角度。 根据需要, "/bin"
和cmd
都是指向 char 的指针。 而且"/bin"
是一个常量字符数组这一事实也不是真正的问题,因为strcat
不会更改它:它只会更改其内容。 但是该字符串"/bin"
存储在您的程序不应该尝试写入的区域 memory 中。 当它尝试在/bin/
的第二个/
之后复制cmd
时,它会这样做。 因此执行错误。
您需要为pathCmd
分配 memory 并在那里连接
char pathCmd[1024];
strcpy(pathCmd, "/bin/");
strcat(pathCmd, cmd);
好吧,实际上,您也不应该那样做。 它是不安全的(如果 cmd 溢出我在这里分配的 1024 字节)。 所以你应该使用strncat
char pathCmd[1024];
strcpy(pathCmd, "/bin/");
strncat(pathCmd, cmd, 1024-5); // 5 bytes already used by "/bin/"
或者,您可以使用 snprintf
char pathCmd[1024];
snprintf(pathCmd, 1024, "/bin/%s", cmd);
(它少了 1 行代码,并且您不需要计算 1024-5 限制,因为该限制是针对整个目标的)
请注意,这与zsh
无关。 zsh
只是一个抱怨,因为你可能在 zsh 脚本中调用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.