繁体   English   中英

zsh 非法硬件指令 c

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM