#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:
Итак, я, наконец, решил двусмысленность в приведенном выше коде. Я внес два радикальных изменения в свой код.
- Вместо прямого назначения строк аргументов при объявлении 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
И это исправило ошибки сегментации в моем коде.
- На этот раз я использовал 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;
}
- Еще один вопрос, который у меня возник, заключался в том, что все файлы printf, которые были до системного вызова execv(), будут напечатаны только после выполнения execv() . И, как прокомментировал @MYousefi Sir, это произошло из-за того, что буфер не был заполнен. И, как было предложено, добавление » n» в printfs решило проблему.