代码之家  ›  专栏  ›  技术社区  ›  fnclovers

在fork和(失败)exec之后更改C文件指针

  •  5
  • fnclovers  · 技术社区  · 7 年前

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main(void) {
        FILE *fp = fopen("sm.c", "r");
        char buf[1000];
        char *args[] = {"invailid_command", NULL};
    
        fgets(buf, sizeof(buf), fp);
        printf("I'm one %d %ld\n", getpid(), ftell(fp));
        if (fork() == 0) {
            execvp(args[0], args);
            exit(EXIT_FAILURE);
        }
        wait(NULL);
        printf("I'm two %d %ld\n", getpid(), ftell(fp));
    } 
    

    此输出

    I'm one 21500 20
    I'm two 21500 -1
    

    printf 电话。

    execvp 失败?

    2 回复  |  直到 7 年前
        1
  •  3
  •   John Bollinger    7 年前

    感谢乔纳森·莱弗勒为我们指明了正确的方向。

    fork )。以下是一些摘录 the relevant section

    open() pipe() 使用诸如 fopen() popen() .

    涉及任何一个句柄的函数调用的结果

    在最后一次使用 句柄(未来的活动句柄)。然后第二个手柄变成

    要应用这些规则,句柄不需要处于同一进程中。

    fork() 应用程序应确保,如果两个手柄都可以 先激活句柄。[在符合上述资格的情况下,]申请应准备 由其中一个进程执行的是exec函数之一,或者 _exit() exit()

    • 如果流是以允许读取的模式打开的,并且底层的打开文件描述引用了能够 fflush()

    • 如果以前的任何活动句柄已被显式更改文件偏移量的函数使用,除非上面对 lseek() fseek()

    stdin fseek()。 (不访问流)而不是

    使用时,实现应确保应用程序,甚至一个

    然而,值得注意的是


    我很感激,仅仅听到你对项目行为的期望没有被相关的标准所证明是合理的,这可能有些令人不满意,但事实上这就是全部。父进程和子进程确实有一些相关的共享数据,这些数据以公共的打开文件描述的形式出现(它们有单独的关联句柄),并且这可能是 对于意外的(和未定义的)行为,但是没有基础来预测您所看到的特定行为,对于同一个程序,也没有基础来预测我所看到的不同行为。

        2
  •  0
  •   dbush    7 年前

    exit

    出口

    在ATEXIT(3)和出口(3)上注册的所有功能都是 对于这些函数中的一个,使用ATEXIT(3)或ON U EXIT(3)来 不返回(例如,它调用退出(2),或使用 被抛弃了。如果函数已注册多次 它已经注册了。

    exit_failure,它可以传递到exit()以指示成功或

    出口 FILE fp .

    出口

    _exit 文件 ftell _退出 atexit 处理程序。