Re: fork/execv - how to get errno to the parent



Kasper Dupont wrote:
Douglas O'Neal wrote:

Try changing foobar to sleep and rerunning your strace. sh is called
because foobar is a shell script.


It doesn't start with #! so it is not really a shell script.
Besides it does the same with any file. Try using a binary file,
it still calls /bin/sh, but then the shell reports an error
which the parent process has no chance of detecting.


You might have tried my suggestion. The strace is listed below and no
reference to /bin/sh is anywhere in the trace.

You are correct in that your "foobar" is not a shell script, but
'man execlp' returns the following quote describing the actions
of execlp() and execvp():

"If the header of a file isn't recognized (the attempted execve()
returned ENOEXEC), these functions will execute the shell with the
path of the file as its first argument."

If your argument to execlp is a binary or, for instance, an awk
script, /bin/sh will never be invoked. If the argument is a sh
script or an unknown file, then you will see /bin/sh.

Doug

oneal@caffeine ~ $ uname -rs
Linux 2.6.9-gentoo-r13
oneal@caffeine ~ $ cat > ssleep.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
char *c="sleep";
execlp(c,c,NULL);
perror(c);
return EXIT_FAILURE;
}
oneal@caffeine ~ $ cc -o ssleep ssleep.c
oneal@caffeine ~ $ strace ./ssleep
execve("./ssleep", ["./ssleep"], [/* 45 vars */]) = 0
uname({sys="Linux", node="caffeine", ...}) = 0
brk(0) = 0x804a000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=136299, ...}) = 0
mmap2(NULL, 136299, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fc9000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\271U\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1167904, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fc8000
mmap2(NULL, 1113396, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7eb8000
mprotect(0xb7fc1000, 27956, PROT_NONE) = 0
mmap2(0xb7fc2000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x109) = 0xb7fc2000
mmap2(0xb7fc6000, 7476, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fc6000
close(3) = 0
mprotect(0xb7fc2000, 4096, PROT_READ) = 0
mprotect(0xb8000000, 4096, PROT_READ) = 0
munmap(0xb7fc9000, 136299) = 0
open("/dev/urandom", O_RDONLY) = 3
read(3, "\265K\2044", 4) = 4
close(3) = 0
brk(0) = 0x804a000
brk(0x806b000) = 0x806b000
execve("/usr/local/bin/sleep", ["sleep"], [/* 45 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/bin/sleep", ["sleep"], [/* 45 vars */]) = 0
uname({sys="Linux", node="caffeine", ...}) = 0
brk(0) = 0x804d000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=136299, ...}) = 0
mmap2(NULL, 136299, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fc9000
close(3) = 0
open("/lib/libm.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0P4\0\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=149144, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fc8000
mmap2(NULL, 135328, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7fa6000
mmap2(0xb7fc6000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1f) = 0xb7fc6000
close(3) = 0
open("/lib/librt.so.1", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\33"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=34552, ...}) = 0
mmap2(NULL, 77400, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7f93000
mmap2(0xb7f9a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6) = 0xb7f9a000
mmap2(0xb7f9c000, 40536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f9c000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\271U\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1167904, ...}) = 0
mmap2(NULL, 1113396, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e83000
mprotect(0xb7f8c000, 27956, PROT_NONE) = 0
mmap2(0xb7f8d000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x109) = 0xb7f8d000
mmap2(0xb7f91000, 7476, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f91000
close(3) = 0
open("/lib/libpthread.so.0", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220B\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=141323, ...}) = 0
mmap2(NULL, 332928, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e31000
mmap2(0xb7e3f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xd) = 0xb7e3f000
mmap2(0xb7e41000, 267392, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7e41000
close(3) = 0
mprotect(0xb7e3f000, 4096, PROT_READ) = 0
mprotect(0xb7f8d000, 4096, PROT_READ) = 0
mprotect(0xb8000000, 4096, PROT_READ) = 0
munmap(0xb7fc9000, 136299) = 0
brk(0) = 0x804d000
brk(0x806e000) = 0x806e000
brk(0) = 0x806e000
set_thread_area({entry_number:-1 -> 6, base_addr:0x804d8c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
getpid() = 23431
rt_sigaction(SIGRTMIN, {0xb7e393dc, [], 0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0xb7e39521, [RTMIN], 0}, NULL, 8) = 0
rt_sigaction(SIGRT_2, {0xb7e396fc, [], 0}, NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [RTMIN], NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1], NULL, 8) = 0
_sysctl({{CTL_KERN, KERN_VERSION}, 2, 0xbfffef78, 35, (nil), 0}) = 0
open("/dev/urandom", O_RDONLY) = 3
read(3, "\237\220\2109", 4) = 4
close(3) = 0
write(2, "sleep: ", 7sleep: ) = 7
write(2, "too few arguments", 17too few arguments) = 17
write(2, "\n", 1
) = 1
write(2, "Try `sleep --help\' for more info"..., 41Try `sleep --help' for more information.
) = 41
exit_group(1) = ?
.



Relevant Pages