системный вызов execv выполняется не так, как хотелось

#linux #g #system-calls #execv

#linux #g #системные вызовы #execv

Вопрос:

Я использую Linux и при компиляции любого файла c или cpp я использую gcc или g соответственно в терминале. Общий синтаксис : g program.cpp

Но теперь я хочу скомпилировать файлы с использованием флагов. Например: g -Wall -Wextra -std=c 11 program.cpp я буду использовать более 10 флагов для компиляции моей программы. Но я не хочу запоминать и вводить это во время компиляции в терминале.

Теперь я хочу создать программу на c с участием системных вызовов (exec), чтобы выполнить свою работу, используя приведенный ниже синтаксис: ./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("%st %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("%st %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. Печать не выполняется, потому что буфер не заполнен для принудительной очистки, и вы также не используете » n».

2. Есть ли особая причина, по которой «makefile» не подходит?

3. Сэр, не могли бы вы подробнее рассказать об использовании » n»? Может быть, то, что вы говорите, в какой-то степени правильно, но я не понимаю:-(

4. Научитесь использовать GNU make , GCC и GDB

5. Да, я пытался. Но это смутило меня больше, чем помогло мне. Как конкурентоспособному программисту, мне нужен минимальный подход, чтобы выполнить работу только с помощью терминала.

Ответ №1:

Итак, я, наконец, решил двусмысленность в приведенном выше коде. Я внес два радикальных изменения в свой код.

  1. Вместо прямого назначения строк аргументов при объявлении string array,
 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("%st %sn",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.cppn");
        }
        return 0;
}
 
  1. Еще один вопрос, который у меня возник, заключался в том, что все файлы printf, которые были до системного вызова execv(), будут напечатаны только после выполнения execv() . И, как прокомментировал @MYousefi Sir, это произошло из-за того, что буфер не был заполнен. И, как было предложено, добавление » n» в printfs решило проблему.