c - execvp在C中跳过某些代码
问题描述
这个程序做了两件事:1)复制shell的动作2)记录用户输入到一个tmp.log文件
这里的问题是在我的子进程中, printf("ABC"); 什么也没做。输出日志文件工作正常,但它只是不打印。
为什么会这样?
我知道 execvp 应该替换当前进程,但这并不能解释为什么它会执行输出而不是打印。我看到了下面的链接,但这并没有回答我的问题。 exevp 跳过所有代码,直到在 c 中等待调用
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <wordexp.h>
void execute(char *user_input)
{
pid_t pid;
int state_loc;
if( (pid = fork()) == -1){
printf("fork failed\n");
exit(1);
}
else if(pid == 0){
FILE *f;
//open the file and append. Create if not there.
f = fopen("tmp.log", "a+");
if (f == NULL) { printf("Something is wrong");}
struct tm *p;
struct tm buf;
char timestring[100];
time_t ltime = time(NULL);
if (NULL != (p=localtime_r(<ime, &buf))){
strftime(timestring, sizeof(timestring),"** %c: ", p);
fprintf(f, "%s %s \n", timestring, user_input);
}
fclose(f);
char* separator = " ";
char* argv[64];
int argc = 0;
char* tmp;
argv[argc] = strtok_r(user_input, separator, &tmp);
while( argv[argc] != NULL){
argc+=1;
argv[argc] = strtok_r(NULL, separator, &tmp);
}
printf("ABC"); //why doesn't this print??
execvp(argv[0],argv);
}
else{
wait(&state_loc);
}
}
int main ()
{
while(1)
{
char user_input[1024];
printf("recsh>> ");
//empty the buffer right scanf
scanf("%[^\n]", user_input);
//calls each character in the user input, repeat until it reaches the terminating \n
while( getchar() != '\n');
if(strcmp(user_input, "exit") == 0){
printf("Exiting\n");
break;
}
else{
execute(user_input);
}
}
return 0;
}
解决方案
该调用printf
在子进程调用之前在子进程中执行execvp
。
由于默认情况下stdout
是行缓冲的,并且打印的文本不构成一行(因为没有换行符),所以它留在输出缓冲区中。当图像被替换时,该输出缓冲区与原始可执行文件的其余部分一起消失execvp
。
道德:始终以换行符 ( \n
) 终止您的输出。
推荐阅读
- kotlin - Jackson 从 Kotlin 值类中生成无效的字段名称
- python - Django 将 BinaryField 下载为 CSV 文件
- node.js - 如何修复 Parse-MS 无法在 Discord.js v12 上运行
- c++ - 我可以使用某种类型的动态数组的空间来构造其他类型的对象吗?
- node.js - NodeJS v3 GetObject 的 .Body 属性不包括数据缓冲区
- hadoop - HiveAccessControlException 权限被拒绝:用户 [hive] 在 [hdfs://sandbox-....:8020/user/..] 上没有 [ALL] 权限(状态=42000,代码=40000)
- wso2 - WSO2IS 5.3.0 - 联合 SAML 和启用身份验证请求签名
- java - Jersey 在启动时失败并出现以下堆栈跟踪。我在 Cent Os 7.9 上,在 Tomcat 9 上运行 openjdk 8
- android - 从 https://dl.google.com/ 在 macos 上下载失败的原因可能是什么
- batch-file - 批处理文件过滤 ping 结果并附加 .csv