execv 系统调用未按要求 运行

execv system call not running as desired

我使用 Linux 并且在编译任何 c 或 cpp 文件时,我在终端中分别使用 gcc 或 g++。 常用语法:g++ program.cpp

但现在我想使用标志编译文件。 例如:g++ -Wall -Wextra -std=c++11 program.cpp 我将使用更多 10 个标志来编译我的程序。但我不想在终端中编译时记住并键入它。

现在我想创建一个涉及系统调用 (exec) 的 c 程序,以使用以下语法完成我的工作: ./compile program.cpp

但是在我下面的代码中使用 exec 时出现了一些问题

#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
int main(int args, char* argv[]){
    char* arguments[10]={"-std=c++11","-Wall","-Wextra","-pedantic","-Wshadow","-fsanitize=address","-fsanitize=undefined","-fstack-protector"}; //consists of flags with which i will compile the program passed as argument
    printf("%s\t %s",argv[0],argv[1]);
    if(args==2){
        arguments[8]=argv[1];
        arguments[9]=(char*)NULL;
    }else{
        printf("only one argument allowed!");// just to check if i pass arguments correctly
    }
    printf("%s\t %s",arguments[8],arguments[9]);// just to check if my arguments array is correct
    if(execv("/bin/g++",arguments)==-1){ // to my suprise this line runs before above printing lines. What is the reason/solution?
        perror("execv failed!");
        exit(1);
    }
    
    return 0;
}

以上代码编译成功,没有报错。 但我认为 execv 甚至在我将传递的参数插入参数数组之前就运行了。 因此,程序运行时出现错误 execv failed: no such file or directory 其次是printfs。 请告诉我哪里做错了。

所以我终于解决了上面代码中的歧义。我对我的代码进行了两项彻底的更改。

  1. 不是在声明字符串数组时直接分配参数字符串,
char* arguments[10]={"-std=c++11","-Wall","-Wextra","-pedantic","-Wshadow","-fsanitize=address","-fsanitize=undefined","-fstack-protector"};

我选择了一个一个地分配字符串。

char* arguments[10];
        arguments[0]="g++";
        arguments[1]="-Wall";
        arguments[2]="-Wextra";
and so on

这修复了我代码中的分段错误。

  1. 这次我使用了 execvp() 而不是 execv() 系统调用,因此我不需要显式声明命令的完整路径 usr/bin/g++ 等等。在 execvp 中,只有命令名称就足够了。 所以我的新代码如下所示:
#include<stdio.h>
//#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
int main(int args, char* argv[]){
        char* arguments[10];
        //printf("%s\t %s\n",argv[0],argv[1]); 
        arguments[0]="g++";
        arguments[1]="-Wall";
        arguments[2]="-Wextra";
        arguments[3]="-pedantic";
        arguments[4]="-Wshadow";
        arguments[5]="-fsanitize=address";
        arguments[6]="-fsanitize=undefined";
        arguments[7]="-fstack-protector";// to add more flags make changes in this array.
        if(args==2){
                arguments[8]=argv[1];
                arguments[9]=(char*)NULL;
                if(execvp(arguments[0],arguments)==-1){
                        perror("execv failed!");
                        exit(1);
                }

        }else{
                printf("->Only one argument(c/cpp file) allowed.\n->Requtired syntax: ./compile program.cpp\n");
        }
        return 0;
}
  1. 我的另一个问题是,所有在 execv() 系统调用之前的 printfs 只有在 execv() 被执行后才会被打印出来。正如@MYousefi Sir 评论的那样,这是因为缓冲区未满。并且按照建议,在 printfs 中添加“\n”解决了问题。