From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.2 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by inbox.vuxu.org (OpenSMTPD) with SMTP id 35b96810 for ; Sat, 8 Feb 2020 07:45:37 +0000 (UTC) Received: (qmail 30339 invoked by uid 550); 8 Feb 2020 07:45:35 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 30316 invoked from network); 8 Feb 2020 07:45:34 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bell-sw-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=aUyuLWaDbBG2YiyRKrj+HiwIzzkd3p96goR3lPaQlvY=; b=dhjao1hNRCEWbKm30yQySEP9C1RHKZn9ySxv4lo8NVlB4giKZ7Gbo9KJLQcEfz9fdi ykDlDlTsotJNhe44t8wL7tQZ+K1mCAC08HpFlYnGGbzQ3BXUNZV1z8Wh3nMh7WKeavzg P6EfioqbW2xpqmRMeYBUhXUfsnmcs5LpwCFb2n8M0jULF6qDgblQCFE5G3TpjO+Jxspy wEUamVXEpztSuZ03Y2dKxuVHV3JxxASBhKL+WYaKLUkbnapT51N3JoVz0iVSjnKLzHev 4n+gmwZPuRnOwd9lqLy3N7h4xb6YVYWn7t0YYEhQn0jdv/w6GoVGA3BGvSn1JRfH4Kvo YGfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=aUyuLWaDbBG2YiyRKrj+HiwIzzkd3p96goR3lPaQlvY=; b=Kar39g5PZtLJa+2RnR5AnAg1FP5ltRHVX8xMYoYFlgFDmD7+33xbjrGEn2QQmDR/Lm hie7pJNw50YLuXxj7t1lTZd7Vkj9wghIXfUl43X0WdwsD2M4o8ePHOkxvIgpoN37x0hw ifdUxdTQp43enzeD28es9ueGq3G91VqkDlvykj8EMC6Xcycxq3+2naVLdJWa+c+Eo7Rq Z62/jl5hUJZCHshzOWSvVSom9RSWqmi73guHpsmzJsZzD6XDD4j2ibH6TzW1KcemGgbG saTZcyhGHaSHQKcOyqy47IGYY+bMHW/6RXNjfjNZDIF9cvUeThjN4oFsxpLX6/4hyQYf Z93g== X-Gm-Message-State: APjAAAVqlF72+WaBYmHiBRcje08tFLiIgx4jdr0Hz8Cz9PV40NtRieXP 4CNsTbv8v0ltQRPlcT9yvcX3cnuO7ib6zJIgYN5sNKwhUIE= X-Google-Smtp-Source: APXvYqykRMmYNJEoDalpCFN0Uus1J0G4acOMduvU2otujTA3VppjR5IQZgX8jWmaSoTNztJbQv1fqB4H/ljCYy6P4RU= X-Received: by 2002:ad4:59c2:: with SMTP id el2mr1841389qvb.152.1581147921503; Fri, 07 Feb 2020 23:45:21 -0800 (PST) MIME-Version: 1.0 References: <20200207210331.GK1663@brightrain.aerifal.cx> In-Reply-To: <20200207210331.GK1663@brightrain.aerifal.cx> From: Alexander Scherbatiy Date: Sat, 8 Feb 2020 10:45:10 +0300 Message-ID: To: musl@lists.openwall.com Content-Type: multipart/alternative; boundary="00000000000032eb7f059e0bb010" Subject: Re: [musl] fopen with "e" mode to close file descriptor in exec... functions --00000000000032eb7f059e0bb010 Content-Type: text/plain; charset="UTF-8" Below are steps to reproduce it in docker, logs from docker and strace log. > docker run --rm -it alpine:3.11.3 ash > apk add gcc > apk add libc-dev Copy the posix_spawn_sample.c code below (note it uses "ash" in 'char *argv[] = {"ash", ,,,}' for posix_spawn on Alpine Linux ) > gcc -o posix_spawn_sample posix_spawn_sample.c > ./posix_spawn_sample --- output --- / # ./posix_spawn_sample Child pid: 17 PID=17 1 /bin/busybox /dev/pts/0 1 /bin/busybox /dev/pts/0 1 /bin/busybox /dev/pts/0 1 /bin/busybox /dev/tty 16 /posix_spawn_sample /dev/pts/0 16 /posix_spawn_sample /dev/pts/0 16 /posix_spawn_sample /dev/pts/0 16 /posix_spawn_sample /test.log ---------------- Note that "test.log" file is listed by "lsof -p PID" command. ---------- posix_spawn_sample.c ---------- #include #include #include #include #include #include extern char **environ; int main() { FILE* file = fopen("test.log", "ae"); fprintf(file, "test line\n"); pid_t pid; // use "ash" for Alpine Linux and "bash" for Ubuntu char *argv[] = {"ash", "-c", "echo PID=$$ && lsof -p $$", NULL}; int status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ); printf("Child pid: %i\n", pid); waitpid(pid, &status, 0); fclose(file); return 0; } -------------------------- The full output step by step: -------------------------------------- > docker run --rm -it alpine:3.11.3 ash / # apk add gcc fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz (1/10) Installing libgcc (9.2.0-r3) (2/10) Installing libstdc++ (9.2.0-r3) (3/10) Installing binutils (2.33.1-r0) (4/10) Installing gmp (6.1.2-r1) (5/10) Installing isl (0.18-r0) (6/10) Installing libgomp (9.2.0-r3) (7/10) Installing libatomic (9.2.0-r3) (8/10) Installing mpfr4 (4.0.2-r1) (9/10) Installing mpc1 (1.1.0-r1) (10/10) Installing gcc (9.2.0-r3) Executing busybox-1.31.1-r9.trigger OK: 101 MiB in 24 packages / # apk add libc-dev (1/2) Installing musl-dev (1.1.24-r0) (2/2) Installing libc-dev (0.7.2-r0) OK: 111 MiB in 26 packages / # gcc -o posix_spawn_sample posix_spawn_sample.c / # ./posix_spawn_sample Child pid: 17 PID=17 1 /bin/busybox /dev/pts/0 1 /bin/busybox /dev/pts/0 1 /bin/busybox /dev/pts/0 1 /bin/busybox /dev/tty 16 /posix_spawn_sample /dev/pts/0 16 /posix_spawn_sample /dev/pts/0 16 /posix_spawn_sample /dev/pts/0 16 /posix_spawn_sample /test.log -------------------------------------- strace log -------------------------------------- / # strace -f ./posix_spawn_sample execve("./posix_spawn_sample", ["./posix_spawn_sample"], 0x7ffd951eb318 /* 6 vars */) = 0 arch_prctl(ARCH_SET_FS, 0x7f0fa33d6d48) = 0 set_tid_address(0x7f0fa33d731c) = 31 mprotect(0x7f0fa33d3000, 4096, PROT_READ) = 0 mprotect(0x55e26cf7b000, 4096, PROT_READ) = 0 open("test.log", O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC, 0666) = 3 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fcntl(3, F_GETFL) = 0x8401 (flags O_WRONLY|O_APPEND|O_LARGEFILE) ioctl(3, TIOCGWINSZ, 0x7ffd87e838a8) = -1 ENOTTY (Not a tty) pipe2([4, 5], O_CLOEXEC) = 0 rt_sigprocmask(SIG_BLOCK, ~[], [], 8) = 0 clone(child_stack=0x7ffd87e838b8, flags=CLONE_VM|CLONE_VFORK|SIGCHLDstrace: Process 32 attached [pid 32] close(4) = 0 [pid 32] fcntl(5, F_SETFD, FD_CLOEXEC) = 0 [pid 32] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 32] execve("/bin/sh", ["ash", "-c", "echo PID=$$ && lsof -p $$"], 0x7ffd87e83998 /* 6 vars */ [pid 31] <... clone resumed>) = 32 [pid 32] <... execve resumed>) = 0 [pid 31] close(5 [pid 32] arch_prctl(ARCH_SET_FS, 0x7f1a19d9ed48 [pid 31] <... close resumed>) = 0 [pid 31] read(4, [pid 32] <... arch_prctl resumed>) = 0 [pid 31] <... read resumed>"", 4) = 0 [pid 32] set_tid_address(0x7f1a19d9f31c [pid 31] close(4 [pid 32] <... set_tid_address resumed>) = 32 [pid 31] <... close resumed>) = 0 [pid 32] mprotect(0x7f1a19d9b000, 4096, PROT_READ [pid 31] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 32] <... mprotect resumed>) = 0 [pid 31] ioctl(1, TIOCGWINSZ, {ws_row=40, ws_col=155, ws_xpixel=0, ws_ypixel=0}) = 0 [pid 32] mprotect(0x556eae13a000, 16384, PROT_READ [pid 31] writev(1, [{iov_base="Child pid: 32", iov_len=13}, {iov_base="\n", iov_len=1}], 2 [pid 32] <... mprotect resumed>) = 0Child pid: 32 [pid 31] <... writev resumed>) = 14 [pid 31] wait4(32, [pid 32] getuid() = 0 [pid 32] getpid() = 32 [pid 32] rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 8) = 0 [pid 32] rt_sigaction(SIGCHLD, {sa_handler=0x556eae0b9dfc, sa_mask=~[RTMIN RT_1 RT_2], sa_flags=SA_RESTORER, sa_restorer=0x7f1a19d500d4}, NULL, 8) = 0 [pid 32] rt_sigaction(SIGHUP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a19d500d4}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 32] getppid() = 31 [pid 32] stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 32] stat(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 32] rt_sigaction(SIGINT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 32] rt_sigaction(SIGINT, {sa_handler=0x556eae0b9dfc, sa_mask=~[RTMIN RT_1 RT_2], sa_flags=SA_RESTORER, sa_restorer=0x7f1a19d500d4}, NULL, 8) = 0 [pid 32] rt_sigaction(SIGQUIT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 32] rt_sigaction(SIGQUIT, {sa_handler=SIG_IGN, sa_mask=~[RTMIN RT_1 RT_2], sa_flags=SA_RESTORER, sa_restorer=0x7f1a19d500d4}, NULL, 8) = 0 [pid 32] rt_sigaction(SIGTERM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 32] wait4(-1, 0x7fff4e3ea22c, WNOHANG, NULL) = -1 ECHILD (No child process) [pid 32] write(1, "PID=32\n", 7PID=32 ) = 7 [pid 32] stat("/usr/local/sbin/lsof", 0x7fff4e3ea170) = -1 ENOENT (No such file or directory) [pid 32] stat("/usr/local/bin/lsof", 0x7fff4e3ea170) = -1 ENOENT (No such file or directory) [pid 32] stat("/usr/sbin/lsof", 0x7fff4e3ea170) = -1 ENOENT (No such file or directory) [pid 32] stat("/usr/bin/lsof", {st_mode=S_IFREG|0755, st_size=841288, ...}) = 0 [pid 32] brk(NULL) = 0x556eaf7c5000 [pid 32] brk(0x556eaf7c6000) = 0x556eaf7c6000 [pid 32] execve("/usr/bin/lsof", ["lsof", "-p", "32"], 0x556eae13ed80 /* 6 vars */) = 0 [pid 32] arch_prctl(ARCH_SET_FS, 0x7fe42bc41d48) = 0 [pid 32] set_tid_address(0x7fe42bc4231c) = 32 [pid 32] mprotect(0x7fe42bc3e000, 4096, PROT_READ) = 0 [pid 32] mprotect(0x55d56c79b000, 16384, PROT_READ) = 0 [pid 32] getuid() = 0 [pid 32] open("/proc", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 3 [pid 32] fcntl(3, F_SETFD, FD_CLOEXEC) = 0 [pid 32] getdents64(3, /* 67 entries */, 2048) = 1984 [pid 32] readlink("/proc/1/exe", "/bin/busybox", 80) = 12 [pid 32] getpid() = 32 [pid 32] open("/proc/1/fd/", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 4 [pid 32] fcntl(4, F_SETFD, FD_CLOEXEC) = 0 [pid 32] brk(NULL) = 0x55d56dac0000 [pid 32] brk(0x55d56dac1000) = 0x55d56dac1000 [pid 32] getdents64(4, /* 6 entries */, 2048) = 144 [pid 32] readlink("/proc/1/fd/0", "/dev/pts/0", 80) = 10 [pid 32] ioctl(1, TIOCGWINSZ, {ws_row=40, ws_col=155, ws_xpixel=0, ws_ypixel=0}) = 0 [pid 32] writev(1, [{iov_base="1\t/bin/busybox\t/dev/pts/0", iov_len=25}, {iov_base="\n", iov_len=1}], 21 /bin/busybox /dev/pts/0 ) = 26 [pid 32] readlink("/proc/1/fd/1", "/dev/pts/0", 80) = 10 [pid 32] writev(1, [{iov_base="1\t/bin/busybox\t/dev/pts/0", iov_len=25}, {iov_base="\n", iov_len=1}], 21 /bin/busybox /dev/pts/0 ) = 26 [pid 32] readlink("/proc/1/fd/2", "/dev/pts/0", 80) = 10 [pid 32] writev(1, [{iov_base="1\t/bin/busybox\t/dev/pts/0", iov_len=25}, {iov_base="\n", iov_len=1}], 21 /bin/busybox /dev/pts/0 ) = 26 [pid 32] readlink("/proc/1/fd/10", "/dev/tty", 80) = 8 [pid 32] writev(1, [{iov_base="1\t/bin/busybox\t/dev/tty", iov_len=23}, {iov_base="\n", iov_len=1}], 21 /bin/busybox /dev/tty ) = 24 [pid 32] getdents64(4, /* 0 entries */, 2048) = 0 [pid 32] close(4) = 0 [pid 32] readlink("/proc/28/exe", "/usr/bin/strace", 80) = 15 [pid 32] getpid() = 32 [pid 32] open("/proc/28/fd/", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 4 [pid 32] fcntl(4, F_SETFD, FD_CLOEXEC) = 0 [pid 32] getdents64(4, /* 5 entries */, 2048) = 120 [pid 32] readlink("/proc/28/fd/0", "pipe:[89317]", 80) = 12 [pid 32] writev(1, [{iov_base="28\t/usr/bin/strace\tpipe:[89317]", iov_len=31}, {iov_base="\n", iov_len=1}], 228 /usr/bin/strace pipe:[89317] ) = 32 [pid 32] readlink("/proc/28/fd/1", "pipe:[89318]", 80) = 12 [pid 32] writev(1, [{iov_base="28\t/usr/bin/strace\tpipe:[89318]", iov_len=31}, {iov_base="\n", iov_len=1}], 228 /usr/bin/strace pipe:[89318] ) = 32 [pid 32] readlink("/proc/28/fd/2", "/dev/pts/0", 80) = 10 [pid 32] writev(1, [{iov_base="28\t/usr/bin/strace\t/dev/pts/0", iov_len=29}, {iov_base="\n", iov_len=1}], 228 /usr/bin/strace /dev/pts/0 ) = 30 [pid 32] getdents64(4, /* 0 entries */, 2048) = 0 [pid 32] close(4) = 0 [pid 32] readlink("/proc/31/exe", "/posix_spawn_sample", 80) = 19 [pid 32] getpid() = 32 [pid 32] open("/proc/31/fd/", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 4 [pid 32] fcntl(4, F_SETFD, FD_CLOEXEC) = 0 [pid 32] getdents64(4, /* 6 entries */, 2048) = 144 [pid 32] readlink("/proc/31/fd/0", "/dev/pts/0", 80) = 10 [pid 32] writev(1, [{iov_base="31\t/posix_spawn_sample\t/dev/pts/"..., iov_len=33}, {iov_base="\n", iov_len=1}], 231 /posix_spawn_sample /dev/pts/0 ) = 34 [pid 32] readlink("/proc/31/fd/1", "/dev/pts/0", 80) = 10 [pid 32] writev(1, [{iov_base="31\t/posix_spawn_sample\t/dev/pts/"..., iov_len=33}, {iov_base="\n", iov_len=1}], 231 /posix_spawn_sample /dev/pts/0 ) = 34 [pid 32] readlink("/proc/31/fd/2", "/dev/pts/0", 80) = 10 [pid 32] writev(1, [{iov_base="31\t/posix_spawn_sample\t/dev/pts/"..., iov_len=33}, {iov_base="\n", iov_len=1}], 231 /posix_spawn_sample /dev/pts/0 ) = 34 [pid 32] readlink("/proc/31/fd/3", "/test.log", 80) = 9 [pid 32] writev(1, [{iov_base="31\t/posix_spawn_sample\t/test.log", iov_len=32}, {iov_base="\n", iov_len=1}], 231 /posix_spawn_sample /test.log ) = 33 [pid 32] getdents64(4, /* 0 entries */, 2048) = 0 [pid 32] close(4) = 0 [pid 32] readlink("/proc/32/exe", "/bin/busybox", 80) = 12 [pid 32] getpid() = 32 [pid 32] getdents64(3, /* 0 entries */, 2048) = 0 [pid 32] close(3) = 0 [pid 32] exit_group(0) = ? [pid 32] +++ exited with 0 +++ <... wait4 resumed>[{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 32 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32, si_uid=0, si_status=0, si_utime=0, si_stime=0} --- writev(3, [{iov_base="test line\n", iov_len=10}, {iov_base=NULL, iov_len=0}], 2) = 10 close(3) = 0 exit_group(0) = ? +++ exited with 0 +++ -------------------------------------- Thanks, Alexander. On Sat, Feb 8, 2020 at 12:03 AM Rich Felker wrote: > On Fri, Feb 07, 2020 at 09:22:01PM +0300, Alexander Scherbatiy wrote: > > Hello, > > > > Below is a simple program without any errors handling that uses > > fopen with "ae" mode to open a "test.log" file with append access > > and call posix_spawn to create a child process and list all open files > for > > the child process. > > > > The program output shows that the child process has "test.log" file as > open. > > I used docker with Alpine Linux 3.11.3 (musl libc x86_64 1.1.24). > > Is it an expected behaviour for Alpine Linux? > > > > The same program on my Ubuntu 19.10 (with "ash" changed to "bash") shows > > that > > the child process doesn't have "test.log" file as open. > > > > Thanks, > > Alexander. > > > > ---------- posix_spawn_sample.c ---------- > > #include > > #include > > #include > > > > #include > > #include > > #include > > > > extern char **environ; > > > > int main() > > { > > FILE* file = fopen("test.log", "ae"); > > fprintf(file, "test line\n"); > > > > pid_t pid; > > char *argv[] = {"bash", "-c", "echo PID=$$ && lsof -p $$", NULL}; > > int status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ); > > printf("Child pid: %i\n", pid); > > waitpid(pid, &status, 0); > > > > fclose(file); > > return 0; > > } > > -------------------------- > > I can't reproduce this. I had to change /bin/sh to /bin/bash to be > able to run the test at all, and the lsof I have (busybox) doesn't > support -p, but I can't see any indication that the child has the log > file open. I also tried changing it to run "ls -l /proc/$$/fd" in the > child, and a fd 3 shows up there but prints an error because fd 3 is > the directory fd for listing /proc/$$/fd and it's closed before trying > to stat it -- apparently ash execs ls rather than running it as a > child. Indeed adding "; echo" makes that go away. > > If you're still having the problem, could you attach a log of running > your test under "strace -f"? > > Rich > --00000000000032eb7f059e0bb010 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Below are steps to reproduce it in docker, logs from = docker and strace log.

> docker run --rm -i= t alpine:3.11.3 ash
> apk add gcc
> apk add libc-= dev
Copy the posix_spawn_sample.c code below (note it uses "= ash" in 'char *argv[] =3D {"ash", ,,,}' for posix_sp= awn on Alpine Linux )

> gcc -o posix_spawn_= sample posix_spawn_sample.c
> ./posix_spawn_sample
<= br>
--- output ---
/ # ./posix_spawn_sample
Child pid: 17=
PID=3D17
1 /bin/busybox /dev/pts/0
1 /bin/busybox /dev/pts/0
1= /bin/busybox /dev/pts/0
1 /bin/busybox /dev/tty
16 /posix_spawn_samp= le /dev/pts/0
16 /posix_spawn_sample /dev/pts/0
16 /posix_spawn_sampl= e /dev/pts/0
16 /posix_spawn_sample /test.log
----------------
Note that "test.log" file is listed by "lsof -p= PID" command.

---------- =C2=A0posix_spawn_s= ample.c ----------
#include <stdlib.h>
#include <stdi= o.h>
#include <string.h>

#include <unistd.h>
#i= nclude <spawn.h>
#include <sys/wait.h>

extern char **= environ;

int main()
{
=C2=A0 =C2=A0 FILE* file =3D fopen("= ;test.log", "ae");
=C2=A0 =C2=A0 fprintf(file, "test= line\n");

=C2=A0 =C2=A0 pid_t pid;
=C2=A0 =C2=A0 // use &qu= ot;ash" for Alpine Linux and "bash" for Ubuntu
=C2=A0 =C2= =A0 char *argv[] =3D {"ash", "-c", "echo PID=3D$$ = && lsof -p $$", NULL};
=C2=A0 =C2=A0 int status =3D posix_s= pawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
=C2=A0 = =C2=A0 printf("Child pid: %i\n", pid);
=C2=A0 =C2=A0 waitpid(p= id, &status, 0);

=C2=A0 =C2=A0 fclose(file);
=C2=A0 =C2=A0 re= turn 0;
}
--------------------------

= The full output step by step:
-----------------------------------= ---
> docker run --rm -it alpine:3.11.3 ash
/ # apk add gcc
fetch http://dl-cdn.alpinelinux.org/alpine/v3.1= 1/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpin= elinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
(1/10) Inst= alling libgcc (9.2.0-r3)
(2/10) Installing libstdc++ (9.2.0-r3)
(3/10= ) Installing binutils (2.33.1-r0)
(4/10) Installing gmp (6.1.2-r1)
(5= /10) Installing isl (0.18-r0)
(6/10) Installing libgomp (9.2.0-r3)
(7= /10) Installing libatomic (9.2.0-r3)
(8/10) Installing mpfr4 (4.0.2-r1)<= br>(9/10) Installing mpc1 (1.1.0-r1)
(10/10) Installing gcc (9.2.0-r3)Executing busybox-1.31.1-r9.trigger
OK: 101 MiB in 24 packages
/ # apk add libc-dev
(1/2) Installing musl-dev (1.1.24-r0)
(2/2) I= nstalling libc-dev (0.7.2-r0)
OK: 111 MiB in 26 packages
/ #=C2=A0 gc= c -o posix_spawn_sample posix_spawn_sample.c
/ # ./posix_spawn_sa= mple
Child pid: 17
PID=3D17
1 /bin/busybox /dev/pts/0
1 /bin/bu= sybox /dev/pts/0
1 /bin/busybox /dev/pts/0
1 /bin/busybox /dev/tty16 /posix_spawn_sample /dev/pts/0
16 /posix_spawn_sample /dev/pts/0
= 16 /posix_spawn_sample /dev/pts/0
16 /posix_spawn_sample /test.log
--------------------------------------

st= race log
--------------------------------------
/ # str= ace -f ./posix_spawn_sample
execve("./posix_spawn_sample", [&q= uot;./posix_spawn_sample"], 0x7ffd951eb318 /* 6 vars */) =3D 0
arch= _prctl(ARCH_SET_FS, 0x7f0fa33d6d48) =3D 0
set_tid_address(0x7f0fa33d731c= ) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 31
mprotect(0x7f0fa33d3000, 4096, PROT= _READ) =3D 0
mprotect(0x55e26cf7b000, 4096, PROT_READ) =3D 0
open(&qu= ot;test.log", O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC, 0666) =3D 3
fcnt= l(3, F_SETFD, FD_CLOEXEC) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0
fcntl= (3, F_SETFD, FD_CLOEXEC) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0
fcntl(= 3, F_GETFL) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =3D 0x8401 (flags O_WRONLY|O_APPEND|O_LARGEFILE)
ioctl(3, = TIOCGWINSZ, 0x7ffd87e838a8) =C2=A0 =C2=A0=3D -1 ENOTTY (Not a tty)
pipe2= ([4, 5], O_CLOEXEC) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =3D 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8) =C2=A0 =3D 0
clone(child_= stack=3D0x7ffd87e838b8, flags=3DCLONE_VM|CLONE_VFORK|SIGCHLDstrace: Process= 32 attached
=C2=A0<unfinished ...>
[pid =C2=A0 =C2=A032] close= (4) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =3D 0
[pid =C2=A0 =C2=A032] fcntl(5, F_SETFD, FD_CLOEXEC) =3D 0
[pid = =C2=A0 =C2=A032] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) =3D 0
[pid =C2= =A0 =C2=A032] execve("/bin/sh", ["ash", "-c",= "echo PID=3D$$ && lsof -p $$"], 0x7ffd87e83998 /* 6 vars= */ <unfinished ...>
[pid =C2=A0 =C2=A031] <... clone resumed&g= t;) =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 32
[pid =C2=A0 =C2=A032] <... exec= ve resumed>) =C2=A0 =C2=A0 =C2=A0 =3D 0
[pid =C2=A0 =C2=A031] close(5= <unfinished ...>
[pid =C2=A0 =C2=A032] arch_prctl(ARCH_SET_FS, 0x= 7f1a19d9ed48 <unfinished ...>
[pid =C2=A0 =C2=A031] <... close = resumed>) =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0
[pid =C2=A0 =C2=A031] read= (4, =C2=A0<unfinished ...>
[pid =C2=A0 =C2=A032] <... arch_prct= l resumed>) =C2=A0 =3D 0
[pid =C2=A0 =C2=A031] <... read resumed&g= t;"", 4) =C2=A0 =C2=A0=3D 0
[pid =C2=A0 =C2=A032] set_tid_addr= ess(0x7f1a19d9f31c <unfinished ...>
[pid =C2=A0 =C2=A031] close(4 = <unfinished ...>
[pid =C2=A0 =C2=A032] <... set_tid_address res= umed>) =3D 32
[pid =C2=A0 =C2=A031] <... close resumed>) =C2=A0= =C2=A0 =C2=A0 =C2=A0=3D 0
[pid =C2=A0 =C2=A032] mprotect(0x7f1a19d9b000= , 4096, PROT_READ <unfinished ...>
[pid =C2=A0 =C2=A031] rt_sigpro= cmask(SIG_SETMASK, [], NULL, 8) =3D 0
[pid =C2=A0 =C2=A032] <... mpro= tect resumed>) =C2=A0 =C2=A0 =3D 0
[pid =C2=A0 =C2=A031] ioctl(1, TIO= CGWINSZ, {ws_row=3D40, ws_col=3D155, ws_xpixel=3D0, ws_ypixel=3D0}) =3D 0[pid =C2=A0 =C2=A032] mprotect(0x556eae13a000, 16384, PROT_READ <unfin= ished ...>
[pid =C2=A0 =C2=A031] writev(1, [{iov_base=3D"Child p= id: 32", iov_len=3D13}, {iov_base=3D"\n", iov_len=3D1}], 2 &= lt;unfinished ...>
[pid =C2=A0 =C2=A032] <... mprotect resumed>= ) =C2=A0 =C2=A0 =3D 0Child pid: 32

[pid =C2=A0 =C2=A031] <... wri= tev resumed>) =C2=A0 =C2=A0 =C2=A0 =3D 14
[pid =C2=A0 =C2=A031] wait4= (32, =C2=A0<unfinished ...>
[pid =C2=A0 =C2=A032] getuid() =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0
[pid= =C2=A0 =C2=A032] getpid() =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0=3D 32
[pid =C2=A0 =C2=A032] rt_sigprocmask(SIG_UNB= LOCK, [RT_1 RT_2], NULL, 8) =3D 0
[pid =C2=A0 =C2=A032] rt_sigaction(SIG= CHLD, {sa_handler=3D0x556eae0b9dfc, sa_mask=3D~[RTMIN RT_1 RT_2], sa_flags= =3DSA_RESTORER, sa_restorer=3D0x7f1a19d500d4}, NULL, 8) =3D 0
[pid =C2= =A0 =C2=A032] rt_sigaction(SIGHUP, {sa_handler=3DSIG_DFL, sa_mask=3D[], sa_= flags=3DSA_RESTORER|SA_RESTART, sa_restorer=3D0x7f1a19d500d4}, {sa_handler= =3DSIG_DFL, sa_mask=3D[], sa_flags=3D0}, 8) =3D 0
[pid =C2=A0 =C2=A032] = getppid() =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =3D 31
[pid =C2=A0 =C2=A032] stat("/", {st_mode=3DS_IFDIR|0755= , st_size=3D4096, ...}) =3D 0
[pid =C2=A0 =C2=A032] stat(".", = {st_mode=3DS_IFDIR|0755, st_size=3D4096, ...}) =3D 0
[pid =C2=A0 =C2=A03= 2] rt_sigaction(SIGINT, NULL, {sa_handler=3DSIG_DFL, sa_mask=3D[], sa_flags= =3D0}, 8) =3D 0
[pid =C2=A0 =C2=A032] rt_sigaction(SIGINT, {sa_handler= =3D0x556eae0b9dfc, sa_mask=3D~[RTMIN RT_1 RT_2], sa_flags=3DSA_RESTORER, sa= _restorer=3D0x7f1a19d500d4}, NULL, 8) =3D 0
[pid =C2=A0 =C2=A032] rt_sig= action(SIGQUIT, NULL, {sa_handler=3DSIG_DFL, sa_mask=3D[], sa_flags=3D0}, 8= ) =3D 0
[pid =C2=A0 =C2=A032] rt_sigaction(SIGQUIT, {sa_handler=3DSIG_IG= N, sa_mask=3D~[RTMIN RT_1 RT_2], sa_flags=3DSA_RESTORER, sa_restorer=3D0x7f= 1a19d500d4}, NULL, 8) =3D 0
[pid =C2=A0 =C2=A032] rt_sigaction(SIGTERM, = NULL, {sa_handler=3DSIG_DFL, sa_mask=3D[], sa_flags=3D0}, 8) =3D 0
[pid = =C2=A0 =C2=A032] wait4(-1, 0x7fff4e3ea22c, WNOHANG, NULL) =3D -1 ECHILD (No= child process)
[pid =C2=A0 =C2=A032] write(1, "PID=3D32\n", 7= PID=3D32
) =C2=A0 =C2=A0 =3D 7
[pid =C2=A0 =C2=A032] stat("/usr/= local/sbin/lsof", 0x7fff4e3ea170) =3D -1 ENOENT (No such file or direc= tory)
[pid =C2=A0 =C2=A032] stat("/usr/local/bin/lsof", 0x7fff= 4e3ea170) =3D -1 ENOENT (No such file or directory)
[pid =C2=A0 =C2=A032= ] stat("/usr/sbin/lsof", 0x7fff4e3ea170) =3D -1 ENOENT (No such f= ile or directory)
[pid =C2=A0 =C2=A032] stat("/usr/bin/lsof", = {st_mode=3DS_IFREG|0755, st_size=3D841288, ...}) =3D 0
[pid =C2=A0 =C2= =A032] brk(NULL) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D 0x556eaf7c5000
[pid =C2=A0 =C2=A032] brk(0x556eaf7c6000) =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =3D 0x556eaf7c6000
[pid =C2=A0 =C2=A032] execve= ("/usr/bin/lsof", ["lsof", "-p", "32&quo= t;], 0x556eae13ed80 /* 6 vars */) =3D 0
[pid =C2=A0 =C2=A032] arch_prctl= (ARCH_SET_FS, 0x7fe42bc41d48) =3D 0
[pid =C2=A0 =C2=A032] set_tid_addres= s(0x7fe42bc4231c) =3D 32
[pid =C2=A0 =C2=A032] mprotect(0x7fe42bc3e000, = 4096, PROT_READ) =3D 0
[pid =C2=A0 =C2=A032] mprotect(0x55d56c79b000, 16= 384, PROT_READ) =3D 0
[pid =C2=A0 =C2=A032] getuid() =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0
[pid =C2=A0 = =C2=A032] open("/proc", O_RDONLY|O_CLOEXEC|O_DIRECTORY) =3D 3
= [pid =C2=A0 =C2=A032] fcntl(3, F_SETFD, FD_CLOEXEC) =3D 0
[pid =C2=A0 = =C2=A032] getdents64(3, /* 67 entries */, 2048) =3D 1984
[pid =C2=A0 =C2= =A032] readlink("/proc/1/exe", "/bin/busybox", 80) =3D = 12
[pid =C2=A0 =C2=A032] getpid() =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 32
[pid =C2=A0 =C2=A032] open("/= proc/1/fd/", O_RDONLY|O_CLOEXEC|O_DIRECTORY) =3D 4
[pid =C2=A0 =C2= =A032] fcntl(4, F_SETFD, FD_CLOEXEC) =3D 0
[pid =C2=A0 =C2=A032] brk(NUL= L) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0x55d= 56dac0000
[pid =C2=A0 =C2=A032] brk(0x55d56dac1000) =C2=A0 =C2=A0 =C2=A0= =C2=A0 =3D 0x55d56dac1000
[pid =C2=A0 =C2=A032] getdents64(4, /* 6 entr= ies */, 2048) =3D 144
[pid =C2=A0 =C2=A032] readlink("/proc/1/fd/0&= quot;, "/dev/pts/0", 80) =3D 10
[pid =C2=A0 =C2=A032] ioctl(1,= TIOCGWINSZ, {ws_row=3D40, ws_col=3D155, ws_xpixel=3D0, ws_ypixel=3D0}) =3D= 0
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"1\t/bin/busybox\t/= dev/pts/0", iov_len=3D25}, {iov_base=3D"\n", iov_len=3D1}], = 21 /bin/busybox /dev/pts/0
) =3D 26
[pid =C2=A0 =C2=A032] readlink(&q= uot;/proc/1/fd/1", "/dev/pts/0", 80) =3D 10
[pid =C2=A0 = =C2=A032] writev(1, [{iov_base=3D"1\t/bin/busybox\t/dev/pts/0", i= ov_len=3D25}, {iov_base=3D"\n", iov_len=3D1}], 21 /bin/busybox /d= ev/pts/0
) =3D 26
[pid =C2=A0 =C2=A032] readlink("/proc/1/fd/2&q= uot;, "/dev/pts/0", 80) =3D 10
[pid =C2=A0 =C2=A032] writev(1,= [{iov_base=3D"1\t/bin/busybox\t/dev/pts/0", iov_len=3D25}, {iov_= base=3D"\n", iov_len=3D1}], 21 /bin/busybox /dev/pts/0
) =3D 2= 6
[pid =C2=A0 =C2=A032] readlink("/proc/1/fd/10", "/dev/t= ty", 80) =3D 8
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"1= \t/bin/busybox\t/dev/tty", iov_len=3D23}, {iov_base=3D"\n", = iov_len=3D1}], 21 /bin/busybox /dev/tty
) =3D 24
[pid =C2=A0 =C2=A032= ] getdents64(4, /* 0 entries */, 2048) =3D 0
[pid =C2=A0 =C2=A032] close= (4) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =3D 0
[pid =C2=A0 =C2=A032] readlink("/proc/28/exe", "/us= r/bin/strace", 80) =3D 15
[pid =C2=A0 =C2=A032] getpid() =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 32
[pid = =C2=A0 =C2=A032] open("/proc/28/fd/", O_RDONLY|O_CLOEXEC|O_DIRECT= ORY) =3D 4
[pid =C2=A0 =C2=A032] fcntl(4, F_SETFD, FD_CLOEXEC) =3D 0
= [pid =C2=A0 =C2=A032] getdents64(4, /* 5 entries */, 2048) =3D 120
[pid = =C2=A0 =C2=A032] readlink("/proc/28/fd/0", "pipe:[89317]&quo= t;, 80) =3D 12
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"28\t/u= sr/bin/strace\tpipe:[89317]", iov_len=3D31}, {iov_base=3D"\n"= ;, iov_len=3D1}], 228 /usr/bin/strace pipe:[89317]
) =3D 32
[pid =C2= =A0 =C2=A032] readlink("/proc/28/fd/1", "pipe:[89318]",= 80) =3D 12
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"28\t/usr/= bin/strace\tpipe:[89318]", iov_len=3D31}, {iov_base=3D"\n", = iov_len=3D1}], 228 /usr/bin/strace pipe:[89318]
) =3D 32
[pid =C2=A0 = =C2=A032] readlink("/proc/28/fd/2", "/dev/pts/0", 80) = =3D 10
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"28\t/usr/bin/s= trace\t/dev/pts/0", iov_len=3D29}, {iov_base=3D"\n", iov_len= =3D1}], 228 /usr/bin/strace /dev/pts/0
) =3D 30
[pid =C2=A0 =C2=A032]= getdents64(4, /* 0 entries */, 2048) =3D 0
[pid =C2=A0 =C2=A032] close(= 4) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D= 0
[pid =C2=A0 =C2=A032] readlink("/proc/31/exe", "/posix= _spawn_sample", 80) =3D 19
[pid =C2=A0 =C2=A032] getpid() =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 32
[pi= d =C2=A0 =C2=A032] open("/proc/31/fd/", O_RDONLY|O_CLOEXEC|O_DIRE= CTORY) =3D 4
[pid =C2=A0 =C2=A032] fcntl(4, F_SETFD, FD_CLOEXEC) =3D 0[pid =C2=A0 =C2=A032] getdents64(4, /* 6 entries */, 2048) =3D 144
[pi= d =C2=A0 =C2=A032] readlink("/proc/31/fd/0", "/dev/pts/0&quo= t;, 80) =3D 10
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"31\t/p= osix_spawn_sample\t/dev/pts/"..., iov_len=3D33}, {iov_base=3D"\n&= quot;, iov_len=3D1}], 231 /posix_spawn_sample /dev/pts/0
) =3D 34
[pi= d =C2=A0 =C2=A032] readlink("/proc/31/fd/1", "/dev/pts/0&quo= t;, 80) =3D 10
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"31\t/p= osix_spawn_sample\t/dev/pts/"..., iov_len=3D33}, {iov_base=3D"\n&= quot;, iov_len=3D1}], 231 /posix_spawn_sample /dev/pts/0
) =3D 34
[pi= d =C2=A0 =C2=A032] readlink("/proc/31/fd/2", "/dev/pts/0&quo= t;, 80) =3D 10
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"31\t/p= osix_spawn_sample\t/dev/pts/"..., iov_len=3D33}, {iov_base=3D"\n&= quot;, iov_len=3D1}], 231 /posix_spawn_sample /dev/pts/0
) =3D 34
[pi= d =C2=A0 =C2=A032] readlink("/proc/31/fd/3", "/test.log"= ;, 80) =3D 9
[pid =C2=A0 =C2=A032] writev(1, [{iov_base=3D"31\t/pos= ix_spawn_sample\t/test.log", iov_len=3D32}, {iov_base=3D"\n"= , iov_len=3D1}], 231 /posix_spawn_sample /test.log
) =3D 33
[pid =C2= =A0 =C2=A032] getdents64(4, /* 0 entries */, 2048) =3D 0
[pid =C2=A0 =C2= =A032] close(4) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0=3D 0
[pid =C2=A0 =C2=A032] readlink("/proc/32/exe",= "/bin/busybox", 80) =3D 12
[pid =C2=A0 =C2=A032] getpid() =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 32[pid =C2=A0 =C2=A032] getdents64(3, /* 0 entries */, 2048) =3D 0
[pid = =C2=A0 =C2=A032] close(3) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0=3D 0
[pid =C2=A0 =C2=A032] exit_group(0) =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D ?
[pid =C2=A0 =C2=A032] +++ e= xited with 0 +++
<... wait4 resumed>[{WIFEXITED(s) && WEXI= TSTATUS(s) =3D=3D 0}], 0, NULL) =3D 32
--- SIGCHLD {si_signo=3DSIGCHLD, = si_code=3DCLD_EXITED, si_pid=3D32, si_uid=3D0, si_status=3D0, si_utime=3D0,= si_stime=3D0} ---
writev(3, [{iov_base=3D"test line\n", iov_l= en=3D10}, {iov_base=3DNULL, iov_len=3D0}], 2) =3D 10
close(3) =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0
exit_group(0) =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D ?+++ exited with 0 +++
--------------------------------------=

Thanks,
Alexander.
=

On Sat, Feb 8, 2020 at 12:03 AM Rich Felker <dalias@libc.org> wrote:
On Fri, Feb 07, 2020 at 09:22:01PM +0300, = Alexander Scherbatiy wrote:
> Hello,
>
> Below is a simple program without any errors handling that uses
> fopen with "ae" mode to open a "test.log" file wit= h append access
> and call posix_spawn to create a child process and list all open files= for
> the child process.
>
> The program output shows that the child process has "test.log&quo= t; file as open.
> I used docker with Alpine Linux 3.11.3 (musl libc x86_64 1.1.24).
> Is it an expected behaviour for Alpine Linux?
>
> The same program on my Ubuntu 19.10 (with "ash" changed to &= quot;bash") shows
> that
> the child process doesn't have=C2=A0 "test.log" file as = open.
>
> Thanks,
> Alexander.
>
> ----------=C2=A0 posix_spawn_sample.c ----------
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
>
> #include <unistd.h>
> #include <spawn.h>
> #include <sys/wait.h>
>
> extern char **environ;
>
> int main()
> {
>=C2=A0 =C2=A0 =C2=A0FILE* file =3D fopen("test.log", "ae= ");
>=C2=A0 =C2=A0 =C2=A0fprintf(file, "test line\n");
>
>=C2=A0 =C2=A0 =C2=A0pid_t pid;
>=C2=A0 =C2=A0 =C2=A0char *argv[] =3D {"bash", "-c",= "echo PID=3D$$ && lsof -p $$", NULL};
>=C2=A0 =C2=A0 =C2=A0int status =3D posix_spawn(&pid, "/bin/sh&= quot;, NULL, NULL, argv, environ);
>=C2=A0 =C2=A0 =C2=A0printf("Child pid: %i\n", pid);
>=C2=A0 =C2=A0 =C2=A0waitpid(pid, &status, 0);
>
>=C2=A0 =C2=A0 =C2=A0fclose(file);
>=C2=A0 =C2=A0 =C2=A0return 0;
> }
> --------------------------

I can't reproduce this. I had to change /bin/sh to /bin/bash to be
able to run the test at all, and the lsof I have (busybox) doesn't
support -p, but I can't see any indication that the child has the log file open. I also tried changing it to run "ls -l /proc/$$/fd" in= the
child, and a fd 3 shows up there but prints an error because fd 3 is
the directory fd for listing /proc/$$/fd and it's closed before trying<= br> to stat it -- apparently ash execs ls rather than running it as a
child. Indeed adding "; echo" makes that go away.

If you're still having the problem, could you attach a log of running your test under "strace -f"?

Rich
--00000000000032eb7f059e0bb010--