From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6713 invoked by alias); 16 Jan 2013 17:42:23 -0000 Received: (qmail 6515 invoked by uid 48); 16 Jan 2013 17:42:07 -0000 From: "ujvari at microsec dot hu" To: glibc-bugs@sourceware.org Subject: [Bug libc/15020] New: wordexp goes into busy loop after child process closes it's output file descriptor Date: Wed, 16 Jan 2013 17:42:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: libc X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: ujvari at microsec dot hu X-Bugzilla-Status: NEW X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact glibc-bugs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: glibc-bugs-owner@sourceware.org X-SW-Source: 2013-01/txt/msg00120.txt.bz2 http://sourceware.org/bugzilla/show_bug.cgi?id=15020 Bug #: 15020 Summary: wordexp goes into busy loop after child process closes it's output file descriptor Product: glibc Version: unspecified Status: NEW Severity: normal Priority: P2 Component: libc AssignedTo: unassigned@sourceware.org ReportedBy: ujvari@microsec.hu CC: drepper.fsp@gmail.com Classification: Unclassified When wordexp is used to execute shell command and run a program in that command the program may close it's output file descriptor before exits. The wordexp function reads the program output (from the read side of a pipe), but when the program closes it output file descriptor (the write side of a pipe), the wrodexp function goes into a busy loop. An strace output when a program uses wordexp and goes into busy loop: > 15:44:38.748956 pipe([5, 8]) = 0 <0.000016> > 15:44:38.749027 clone(Process 20369 attached > child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x42292b48) = 20369 <0.001831> > [pid 30525] 15:44:38.750969 close(8 > [pid 20369] 15:44:38.751074 dup2(8, 1 > [pid 30525] 15:44:38.751098 <... close resumed> ) = 0 <0.000096> > [pid 20369] 15:44:38.751127 <... dup2 resumed> ) = 1 <0.000035> > [pid 30525] 15:44:38.751150 read(5, > [pid 20369] 15:44:38.751180 close(8) = 0 <0.000008> > [pid 20369] 15:44:38.751216 close(2) = 0 <0.000035> > [pid 20369] 15:44:38.751285 open("/dev/null", O_WRONLY) = 2 <0.000018> > [pid 20369] 15:44:38.751347 fstat64(2, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0 <0.000008> > [pid 20369] 15:44:38.751437 close(5) = 0 <0.000007> > [pid 20369] 15:44:38.751477 execve("/bin/sh", ["/bin/sh", "-c", "/usr/bin/stat -c %s /tmp/med30525f000000"], [/* 122 vars */]) = 0 <0.001610> > ... > [pid 20369] 15:44:38.826332 write(1, "11486\n", 6 > [pid 30525] 15:44:38.826473 <... read resumed> "11486\n", 128) = 6 <0.075257> > [pid 20369] 15:44:38.826578 <... write resumed> ) = 6 <0.000173> > [pid 30525] 15:44:38.826661 read(5, > [pid 20369] 15:44:38.826773 close(1 > [pid 30525] 15:44:38.826881 <... read resumed> "", 128) = 0 <0.000121> > [pid 20369] 15:44:38.826962 <... close resumed> ) = 0 <0.000129> > [pid 30525] 15:44:38.827037 waitpid(20369, 0xbffecfc0, WNOHANG) = 0 <0.000008> > [pid 30525] 15:44:38.827182 read(5, "", 128) = 0 <0.000007> > [pid 30525] 15:44:38.827311 waitpid(20369, 0xbffecfc0, WNOHANG) = 0 <0.000008> > [pid 30525] 15:44:38.827431 read(5, "", 128) = 0 <0.000008> > ... > [pid 30525] 15:44:38.997549 read(5, "", 128) = 0 <0.000007> > [pid 30525] 15:44:38.997586 waitpid(20369, 0xbffecfc0, WNOHANG) = 0 <0.000007> > [pid 30525] 15:44:38.997624 read(5, "", 128) = 0 <0.000007> > [pid 30525] 15:44:38.997661 waitpid(20369, 0xbffecfc0, WNOHANG) = 0 <0.000007> > [pid 30525] 15:44:38.997699 read(5, "", 128) = 0 <0.000007> > [pid 30525] 15:44:38.997737 waitpid(20369, > [pid 20369] 15:44:38.997777 <... munmap resumed> ) = 0 <0.131820> > [pid 30525] 15:44:38.997826 <... waitpid resumed> 0xbffecfc0, WNOHANG) = 0 <0.000072> > [pid 20369] 15:44:38.997854 exit_group(0) = ? Process 20369 detached > 15:44:38.997986 read(5, "", 128) = 0 <0.000007> > 15:44:38.998026 waitpid(20369, 0xbffecfc0, WNOHANG) = -1 ECHILD (No child processes) <0.000007> > 15:44:38.998070 read(5, "", 128) = 0 <0.000006> > 15:44:38.998105 close(5) = 0 <0.000013> The corresponding wordexp code: > 951 while (1) > 952 { > 953 if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer, > 954 bufsize))) < 1) > 955 { > 956 if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, WNOHANG)) == 0) > 957 continue; > 958 if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer, > 959 bufsize))) < 1) > 960 break; > 961 } > ... > 968 } (This code snippet is duplicated at lines 981-991.) Wordexp code tries to read from the pipe when it's write side already closed. On the closed pipe the read function does not block, but immediately returns with 0 as the read file handle is already at EOF. Then waitpid is called while the child process has not exited yet, therefore it returns with 0. This loop goes on till the child process has really exited and waitpid returns its PID. -- Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug.