This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug stdio/23151] New: A forked process with unclosed file does lseek before exit and can cause infinite loop in parent I/O
- From: "jonathan.leffler at gmail dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Wed, 09 May 2018 06:12:02 +0000
- Subject: [Bug stdio/23151] New: A forked process with unclosed file does lseek before exit and can cause infinite loop in parent I/O
- Auto-submitted: auto-generated
https://sourceware.org/bugzilla/show_bug.cgi?id=23151
Bug ID: 23151
Summary: A forked process with unclosed file does lseek before
exit and can cause infinite loop in parent I/O
Product: glibc
Version: unspecified
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: stdio
Assignee: unassigned at sourceware dot org
Reporter: jonathan.leffler at gmail dot com
Target Milestone: ---
See Stack Overflow Q&A:
*
https://stackoverflow.com/questions/50110992/why-does-forking-my-process-cause-the-file-to-be-read-infinitely
*
https://stackoverflow.com/questions/50244579/unwanted-child-processes-being-created-while-file-reading
As the accepted answer to the "why does forking my process" question shows,
when the child process exits, it seeks on the file descriptor towards the
beginning of the file, thus changing the position of the read position in the
(shared) open file description, potentially leading to an infinite loop in the
parent process as it never encounters EOF.
The output from strace (strace -ff -o st-out -- neof97) for the children shows:
$ cat st-out.80833
lseek(0, -63, SEEK_CUR) = 21
exit_group(0) = ?
+++ exited with 0 +++
$ cat st-out.80834
lseek(0, -42, SEEK_CUR) = -1 EINVAL (Invalid argument)
exit_group(0) = ?
+++ exited with 0 +++
$ cat st-out.80835
lseek(0, -21, SEEK_CUR) = 0
exit_group(0) = ?
+++ exited with 0 +++
$ cat st-out.80836
exit_group(0) = ?
+++ exited with 0 +++
$
One version of the code that shows the problem is (neof97.c). It limits the
'infinite input' to 30 lines.
#include "posixver.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
enum { MAX = 100 };
int main(void)
{
if (freopen("input.txt", "r", stdin) == 0)
return 1;
char s[MAX];
for (int i = 0; i < 30 && fgets(s, MAX, stdin) != NULL; i++)
{
// Commenting out this region fixes the issue
int status;
pid_t pid = fork();
if (pid == 0)
{
exit(0);
}
else
{
waitpid(pid, &status, 0);
}
// End region
printf("%s", s);
}
return 0;
}
The file input.txt can be any text; 4 lines of 20 random characters each is
sufficient to show the bug.
If the file is explicitly closed in the child, the lseek() does not occur which
avoids the problem.
The problem was reproduced in a Ubuntu 16.04 LTS system running as a VM under
VMWare Fusion on a MacBook Pro running macOS 10.13.4 (High Sierra). When the
same code was recompiled and run on the macOS host operating system, the
problem was not exhibited.
--
You are receiving this mail because:
You are on the CC list for the bug.