Re: popen/pclose problem in Linux 2.2.x with vfork/glibc 2.1

Pete Wyckoff (wyckoff@ca.sandia.gov)
Sat, 27 Mar 1999 18:01:06 -0800


--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii

Andreas said:

> Juergen Heinzl reported a bug in the implementation of popen/pclose to
> the glibc maintainers. Looking closer at the bug the problem might be
> in the kernel since the test program runs fine with Linux 2.0.36 but
> fails with Linux 2.2.x. The IMO significant difference is the vfork
> implementation in Linux 2.2 which popen uses with glibc 2.1.
>
> Has anybody an idea what's broken ?
>
>
> Here are some parts of Juergen's reports (the full report is available
> via the bug database as PR 966 and 967 at
> http://www-gnats.gnu.org:8080/cgi-bin/wwwgnats.pl)

No idea about what's broken in the kernel. I had expected the
following version of the test code to create havoc as well. It doesn't
(on 2.2.4). What else is glibc doing in popen() and vfork()?

Compile with "gcc -Wl,-Bstatic -Wall -g -o test test.c fork.S".

-- Pete

--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="test.c"

extern void sleep(int);
extern int pipe(int p[2]);
extern int dup2(int, int);
extern int close(int);
extern int execl(const char *fmt, ...);
extern void printf(const char *fmt, ...);
extern int waitpid(int, int*, int);

int popen(const char *s);
void pclose(int pid, int val);
int fork(void);
int vfork(void);

int
main()
{
int t, f;

f = popen("/bin/false");
sleep(1);
t = popen("/bin/true");
sleep(1);

pclose(t, 0);
pclose(f, 1);
return 0;
}

int
popen(const char *cmd)
{
int p[2], pid;
register int ri;
int i;

ri = 3;
i = 3;
if (pipe(p) < 0) return -1;
pid = vfork();
if (pid < 0) return -1;
if (pid == 0) {
if (dup2(p[1], 1) < 0)
exit(127);
close(p[0]);
close(p[1]);
ri++;
i++;
execl("/bin/sh", "sh", "-c", cmd, 0);
exit(127);
}

close(p[1]);
printf("ri = %d, i = %d\n", ri, i);
return pid;
}

void
pclose(int pid, int val)
{
int s;

if (waitpid(pid, &s, 0) == -1) {
printf("bad waitpid\n");
} else {
if (s & 0xff) {
printf("bad status\n");
} else {
if (((s & 0xff00) >> 8) != val)
printf("wanted %d, returned %04x\n", val, s);
}
}
}

--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fork.S"

.section .text
.globl fork
fork:
movl $2, %eax
int $0x80
ret

.globl vfork
vfork:
popl %ecx
movl $190, %eax
int $0x80
jmp *%ecx
ret

--82I3+IH0IqGh5yIs--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/