C孩子读到“资源暂时不可用”

发布于 2024-08-31 11:43:42 字数 1419 浏览 1 评论 0原文

所以我有一个从父进程到子进程的文件流 - 大多数时候它工作正常。然而,当快速多次读取时,使用 fgets() 将返回 NULL,并且错误被设置为“资源暂时不可用”。该问题是间歇性的 - 运行执行读取的脚本有时会使 fgets 返回 NULL,有时则不会。

谁能帮我阻止这个错误的发生?谢谢!

编辑:这是一些代码..我不确定还有哪些其他代码会有帮助? 根据要求,有很多

// this is the bit that gets a line from the child
if( fgets( line, MAX_LINE_LENGTH, fpin ) == NULL ) {
    if( ferror(fpin) ) {
        perror("error on stream fpin");
    }
    free( line );
    return FAIL;
}

打开管道并处理子进程的代码。

// set up pipes
int readPipe[2]; // child -> parent communication
int writePipe[2]; // parent -> child communication
int errorPipe[2]; // child -> parent, to check for errors in exec

/* create pipe */
pipe( readPipe ); // error if return val < 1 for any
pipe( writePipe );
pipe( errorPipe );
pid_t pid; /* process id when we fork */
pid = fork(); /* create new child */

if( pid == 0 ) { /* pid == 0 indicates child process */

    // close unused fds
    close( PARENT_READ );
    close( PARENT_WRITE );
    close( errorPipe[0] );

    dup2( CHILD_READ, 0 ); // replace stdin with pipe in
    dup2( CHILD_WRITE, 1 ); // replace stdout with pipe out

    /* replace child process with program to run */
    execvp(args[0], args);

    // if we get here, exec failed so inform the parent
    char *error_message = "exec failed";
    write( errorPipe[1], error_message, strlen(error_message)+1 );
    exit(-1);

} 

So I have a file stream from a parent process to a child - and most of the time it works fine. However, when reading from it multiple times quickly, using fgets() will return NULL and the error is set to "resource temporarily unavailable". The problem is intermittent - and running the script that does the reads will sometimes have fgets return NULL and sometimes wont.

Could anyone help me stop this error from happening? Thanks!

Edit: here is some code.. I'm not sure what other code would be helpful? there's quite a bit

// this is the bit that gets a line from the child
if( fgets( line, MAX_LINE_LENGTH, fpin ) == NULL ) {
    if( ferror(fpin) ) {
        perror("error on stream fpin");
    }
    free( line );
    return FAIL;
}

As requested, code that opens pipe and deals with child process..

// set up pipes
int readPipe[2]; // child -> parent communication
int writePipe[2]; // parent -> child communication
int errorPipe[2]; // child -> parent, to check for errors in exec

/* create pipe */
pipe( readPipe ); // error if return val < 1 for any
pipe( writePipe );
pipe( errorPipe );
pid_t pid; /* process id when we fork */
pid = fork(); /* create new child */

if( pid == 0 ) { /* pid == 0 indicates child process */

    // close unused fds
    close( PARENT_READ );
    close( PARENT_WRITE );
    close( errorPipe[0] );

    dup2( CHILD_READ, 0 ); // replace stdin with pipe in
    dup2( CHILD_WRITE, 1 ); // replace stdout with pipe out

    /* replace child process with program to run */
    execvp(args[0], args);

    // if we get here, exec failed so inform the parent
    char *error_message = "exec failed";
    write( errorPipe[1], error_message, strlen(error_message)+1 );
    exit(-1);

} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜还是长夜 2024-09-07 11:43:42

这意味着有人已将标准输入文件描述符设置为非阻塞。

资源暂时不可用EAGAIN / EWOULDBLOCK对应的错误消息,仅由read()返回当选择非阻塞 IO 并且没有数据可读取时)。

请注意,父进程可能在执行子进程之前将文件描述符设置为非阻塞。

进一步调查的一些想法:

  • 如果您 strace() 子进程,哪个系统调用返回 EAGAIN?在哪个文件描述符编号上?

  • 在失败的 fgets() 之前,printf("%d\n", fcntl(fileno(fpin), F_GETFL)); 的输出是什么?< /p>

That means that someone has set the standard input file descriptor as non-blocking.

(Resource temporarily unavailable is the error message corresponding to EAGAIN / EWOULDBLOCK, which is returned by read() only when non-blocking IO has been selected and there is no data to read).

Note that it's possible that the parent process set the file descriptor nonblocking before exec-ing your child process.

Some ideas for further investigation:

  • If you strace() the child process, which system call is returning EAGAIN? On which file descriptor number?

  • What's the output of printf("%d\n", fcntl(fileno(fpin), F_GETFL)); right before the failing fgets()?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文