下面C程序的预期行为是将自己的可执行文件复制到一个新的随机命名文件中,然后执行该文件,令人恶心。这应该会创建许多可执行文件的副本。这显然是一个糟糕的想法,但这正是我想要做的
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
int main(int argc, char* argv[]) {
/* Obtain name of current executable */
const char* binName = argv[0];
/* Print message */
printf("Hello from %s!n", binName);
/* Create name of new executable */
char newBinName[] = "tmpXXXXXX";
mkstemp(newBinName);
/* Determine size of current executable */
struct stat st;
stat(binName, &st);
const int binSize = st.st_size;
/* Copy current executable to memory */
char* binData = (char*) malloc(sizeof(char) * binSize);
FILE* binFile = fopen(binName, "rb");
fread(binData, sizeof(char), binSize, binFile);
fclose(binFile);
/* Write executable in memory to new file */
binFile = fopen(newBinName, "wb");
fwrite(binData, sizeof(char), binSize, binFile);
fclose(binFile);
/* Make new file executable */
chmod(newBinName, S_IRUSR | S_IWUSR |S_IXUSR);
/* Run new file executable */
execve(
newBinName,
(char*[]) {
newBinName,
NULL
},
NULL);
/* If this code runs, then there has been an error. */
perror("execve");
return EXIT_FAILURE;
}
相反,输出如下:
Hello from ./execTest
execve: Text file busy
我认为文本文件"正忙",因为./execTest
仍在访问它……但我确实关闭了该文件的文件流。我做错了什么?
来自mkstemp
:的手册页
On success, these functions return the file descriptor of the
temporary file.
您丢弃了mkstemp
返回给您的文件描述符,从而有效地泄漏了它。它可能是一个可写的文件描述符。因此,它将导致execve
与ETXTBSY
一起失败(当打开可写的fds时会发生这种情况)。你能在mkstemp
的返回值上尝试close()
,看看这是否能改善行为吗?
反馈的一般要点:当用C进行编码时,您应该养成查看返回值的习惯。未能遵守它们的含义和错误状态通常表明存在错误