Çekirdeğin ve glibc'nin aynı sürümlerini çalıştıran iki RHEL 6 sistemimiz var (glibc – 2.12–1.90.el6_3.6). Çekirdek yürütülebilir bir dosya örneğin ELF olarak yürütülebilir biçimde değil belirlerse, POSIX standardı ve Linux kılavuz sayfalarına göre ve bir shebang (yok #!
) hattını, fonksiyonlar execl
, execlp
, execle
, execv
, execvp
, ve execvpe
(ama not execve
) bu dosyayı Linux'ta olan bir POSIX kabuğu kullanarak yürütmeye çalışacaktır /bin/sh
.
Ancak, sistemlerden birinde, ilk satırı işlevi :
kullanan bir kabuk komut dosyasının yürütülmesi execvp
başarısız olurken, diğer makinede /bin/sh
beklendiği gibi komut dosyası kullanılarak yürütülür . Özellikle, bu test programlarını kullanıyoruz; /tmp/test_script
çalıştırılabilir hale getirildi:
xc:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> dıştaki char ** ortam; int main () { char * argv [] = {"/ tmp / test_script", NULL}; char * progname = argv [0]; if (execvp (progname, argv) == -1) { perror ( "execvp"); dönüş -1; } }
/ Tmp / test_script:
: yankı "Denenen komut dosyası" Çıkış 0
Glibc'nin kurulu sürümü için kaynak RPM'yi aradık ve kesinlikle istenen davranışı uygular (execvp execvpe etrafında önemsiz bir sarıcıdır):
POSIX / execvpe.c:
if (strchr (dosya, '/')! = NULL) { / * Eğik çizgi içerdiğinde arama yapmayın. * / __execve (dosya, argv, envp); eğer (errno == ENOEXEC) { / * Argümanları say. * / int argc = 0; while (argv [argc ++]) ; size_t len = (argc + 1) * sizeof (char *); char ** script_argv; void * ptr = NULL; if (__libc_use_alloca (len)) script_argv = alloca (len); Başka script_argv = ptr = malloc (len); if (script_argv! = NULL) { scripts_argv (dosya, argv, argc, script_argv); __execve (script_argv [0], script_argv, envp); serbest (ptr); } } } Başka ︙
Burada, argüman listesine hazırlanan ve glibc üzerinden kullanıcı alanına maruz kalan ile aynı olan scripts_argv
basit bir işlevdir ./bin/sh
__execve
execve
Bu konuda Linux'ta başka biriyle karşılaştı mı? Davranış denedim diğer tüm sistemlerde doğrudur.