2015-10-21 22 views
5

mount sistem çağrısı perl'den nasıl yapılabilir? Aşağıdaki yer:Perl'den gelen sistem çağrısı yürütme

$ret = syscall(&SYS_mount, "/proc", "/path/to/my/mount/point", 0, 0, 0); 

sonuçları:

Modification of a read-only value attempted at ... 

ben mount programı yeteneğine sahip görünmüyor ki mount() sistem çağrısı yapmak gerekir çünkü system kullanılarak mount programı arayamazsın. Daha spesifik olarak, ben aramam lazım:

mount("/proc", "/path/to/my/mpoint/point", NULL, MS_REC|MS_PRIVATE|MS_BIND, NULL); 

Ama bir ayrıcalığı olmayan paylaşılmamış bağlama linux ad aşağıdaki çalıştırmayı denerseniz: Sonra

mount --make-rprivate --bind /proc /path/to/my/mountpoint 

aşağıdaki hatayı alıyorum:

mount: wrong fs type, bad option, bad superblock on /proc, 
     missing codepage or helper program, or other error 

     In some cases useful info is found in syslog - try 
     dmesg | tail or so. 
strace kullanma

neyi mount program aslında çağırmaya yarar olduğunu ortaya koymaktadır:

mount("/proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND, NULL); 
mount("none", "/path/to/my/mointpoint", NULL, MS_REC|MS_PRIVATE, NULL); 

Ancak bu seçeneklerin ayrılması işe yaramıyor. MS_BIND ve MS_REC|MS_PRIVATE'a, mount sistem çağrısına tek bir çağrıda, ayrıcalıklı olmayan paylaşılmayan mount ad alanında çalışmasına ihtiyacım var.

Peki, ilk sistem çağrımı, salt okunur bir değerin değiştirilmesine yönelik bir girişimde hata iletisi olmadan nasıl perl yapabilirim?

düzenlemek:

Neyse Ikegami perl syscall işlevini kullanmaya çalışırken ben yanlış yaptıklarını işaret hızlı oldu ama imtiyazlı olmayan bir montaj içinden bir dizin monte bağlamak nasıl ararken durumda birileri bu bulur

:

mount --rbind /proc /path/to/my/mountpoint 

Bu da içten aşağıdaki syscall arayacak: sadece mount komut satırı aracıyla birlikte ad, burada nasıl

mount("proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND|MS_REC, 0); 

MS_MGC_VAL bayrağı, yalnızca 2.4'den önceki çekirdek sürümleriyle geriye dönük uyumluluk için görünüyor. Önemli bitler MS_BIND (bağlamanın montajını yapmak için) ve MS_REC (tekrar tekrar yapmak için içeriğindeki diğer bağlarla gizlenen dizinlerin içeriğinin mount ad alanında açığa çıkmaması için yapılır).

Yani şimdi ben bir perl system işlev çağrısı ile gitmek ya da sadece ikisi işin çünkü sadece de mount Bu yüzden sistem yapmak :)

cevap

8

syscall sabit dize tampona gösterici geçmek reddediyor karar vermek zorunda bağımsız değişken char * veya const char * ise hiçbir fikri yoktur.

You can't use a string literal (or other read-only string) as an argument to syscall because Perl has to assume that any string pointer might be written through

Çözüm basittir. Sadece sabiti önce bir değişkene kopyalayın.

my $ret = syscall(&SYS_mount, my $s="/proc", my $t="/path/to/my/mount/point", 0, 0, 0); 

Testi:

$ perl -E' 
    require "syscall.ph"; 
    my $ret = syscall(&SYS_mount, "/proc", "/path/to/my/mount/point", 0, 0, 0); 
    say $ret; 
' 
Modification of a read-only value attempted at -e line 3. 

$ perl -E' 
    require "syscall.ph"; 
    my $ret = syscall(&SYS_mount, my $s="/proc", my $t="/path/to/my/mount/point", 0, 0, 0); 
    say $ret; 
' 
-1 

$ strace perl -e' 
    require "syscall.ph"; 
    syscall(&SYS_mount, my $s="/proc", my $t="/path/to/my/mount/point", 0, 0, 0); 
' 2>&1 | grep mount 
mount("/proc", "/path/to/my/mount/point", NULL, 0, NULL) = -1 ENOENT (No such file or directory) 
+0

Bay/Bayan sadece benim gün yaptı Sen! Şimdi "syscall" in doktorlarının "Bir dizgeyi literal (ya da diğer salt okunur bir dizgeyi) argüman olarak kullanamazsın" diyorum ... aptalca, RTFM yapmalıydım ... Yine de Sadece birçok baş ağrısı kurtardı Size birçok upvotes :) :) – josch

+0

Doh! Bunu da okumadım! Cevabımı biraz geliştirdim. – ikegami

İlgili konular