C系统调用 - 执行关闭其文件的进程?

时间:2015-03-24 17:20:14

标签: c exec system-calls file-descriptor

基本上,我在为系统编程课做一些功课时想出了一个奇怪的思想实验。我回来的行为有点令人惊讶,我想知道是否有人可以解释发生了什么。

我有这两个源文件:

prog.c中:

#include <fcntl.h>
#include <stdio.h>

int main()
{
    printf("%d\n", close(3));

    return 0;
}

shell.c:

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

extern char **environ;

int main()
{
    char *args[] = {"prog", NULL};
    int fd = open("prog", O_RDONLY);

    fexecve(fd, args, environ);

    printf("-> %d\n", close(fd));

    return 0;
}

当我运行shell时,它打开prog,它获取文件描述符3.当我运行fexecve时,它调用prog,关闭FD 3,打印返回值,以及退出。基本上,我正在执行文件which does nothing but close itself!

我发现奇怪的是,当我这样做时,第二个打印语句(shell.c:14)永远不会到达,因为 control永远不会返回shell程序。 return 0;中的prog会终止整个过程。我通过gdb进行了调查:

(gdb) break main
Breakpoint 1 at 0x40065e: file shell.c, line 9.
(gdb) r
Starting program: /home/kebertx/shell 

Breakpoint 1, main () at shell.c:9
9           char *args[] = {"prog", NULL};
(gdb) n
10          int fd = open("prog", O_RDONLY);
(gdb) 
12          fexecve(fd, args, environ);
(gdb) 
process 4256 is executing new program: /home/kebertx/prog

Breakpoint 1, main () at prog.c:6
6           printf("%d\n", close(3));
(gdb) 
0
8           return 0;
(gdb) 
9       }
(gdb) 
0x00007ffff7a58800 in __libc_start_main () from /usr/lib/libc.so.6
(gdb) 
Single stepping until exit from function __libc_start_main,
which has no line number information.
[Inferior 1 (process 4256) exited normally]
(gdb) quit

我的直觉让我失望了。 FD 3已成功关闭,但这会导致程序丢失。不应该fexecve在调用堆栈上吗?为什么要让exec找回原来的路径,为什么需要打开子进程的文件?什么是exec函数正在做什么,以及当我像这样打破它时它们无法做什么?

我不认为这对于实际应用来说应该是我需要知道的东西,但我很好奇。任何解释都将不胜感激!

0 个答案:

没有答案