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。
请告诉我哪里做错了。
所以我终于解决了上面代码中的歧义。我对我的代码进行了两项彻底的更改。
- 不是在声明字符串数组时直接分配参数字符串,
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("%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;
}
- 我的另一个问题是,所有在 execv() 系统调用之前的 printfs 只有在 execv() 被执行后才会被打印出来。正如@MYousefi Sir 评论的那样,这是因为缓冲区未满。并且按照建议,在 printfs 中添加“\n”解决了问题。
我使用 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。
请告诉我哪里做错了。
所以我终于解决了上面代码中的歧义。我对我的代码进行了两项彻底的更改。
- 不是在声明字符串数组时直接分配参数字符串,
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("%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;
}
- 我的另一个问题是,所有在 execv() 系统调用之前的 printfs 只有在 execv() 被执行后才会被打印出来。正如@MYousefi Sir 评论的那样,这是因为缓冲区未满。并且按照建议,在 printfs 中添加“\n”解决了问题。