Ayrılmama izin ver.
Bir yürütülebilir dosyayı çalıştırdığınızda, en önemlisi fork()
ve bir dizi sistem çağrısı yürütülür execve()
:
fork()
Her ikisi de hala aynı yürütülebilir dosyayı çalıştıran (üzerine yazılan bellek sayfalarını kullanarak, bu nedenle etkilidir) (çoğunlukla) ebeveynin tam bir kopyası olan çağrı sürecinin alt sürecini oluşturur. İki kez döner: Ebeveynde, alt PID değerini döndürür. Çocukta 0 döndürür. Normalde, çocuk işlemi hemen yürütme çağırır:
execve()
yürütülebilir dosyaya tam bir yol olarak argüman olarak gider ve çağıran işlemi yürütülebilir ile değiştirir. Bu noktada, yeni oluşturulan süreç kendi sanal adres alanını, yani sanal belleği alır ve yürütme giriş noktasında başlar (platform ABI'nin yeni işlemler için kuralları tarafından belirtilen bir durumda).
Bu noktada, çekirdeğin ELF yükleyicisi, sistem çağrısını kullanıyormuşçasına (sırasıyla paylaşılan salt okunur ve özel okuma-yazma eşleşmeleriyle birlikte) çalıştırılabilir metin ve veri bölümlerini belleğe mmap()
eşlemiştir. BSS ayrıca MAP_ANONYMOUS ile eşleştirilir. (BTW, basitlik için buradaki dinamik bağlantıyı görmezden geliyorum: Dinamik bağlayıcı , ana çalıştırılabilir giriş noktasına atlanmadan önce tüm dinamik kitaplıkları open()
s ve mmap()
s.)
Yeni bir exec () ed kendi kodunu çalıştırmaya başlamadan önce sadece birkaç sayfa aslında diskten belleğe yüklenir. İşlem sanal adres alanının bu kısımlarına dokunduğunda / gerektiğinde, gerektiğinde sayfalar talep edilir. (Kullanıcı alanı kodunu çalıştırmaya başlamadan önce herhangi bir kod veya veri sayfasını önceden yüklemek sadece bir performans optimizasyonudur.)
Yürütülebilir dosya inode tarafından alt seviyedeki tanımlanır. Dosya çalıştırılmaya başladıktan sonra, çekirdek dosya içeriğini açık dosya tanımlayıcıları veya dosya destekli bellek eşlemeleri gibi dosya adıyla değil inode referansı ile aynı tutar. Böylece, yürütülebilir dosyayı dosya sisteminin başka bir yerine, hatta farklı bir dosya sisteminde kolayca taşıyabilirsiniz. Bir yan not olarak, sürecin çeşitli stat'lerini kontrol etmek için /proc/PID
(PID verilen işlemin İşlem Kimliğidir) dizine göz atabilirsiniz . Yürütülebilir dosyayı /proc/PID/exe
bile diskten bağlantısı kesilmiş olarak açabilirsiniz .
Şimdi harekete geçelim:
Bir dosyayı aynı dosya sistemi içinde taşıdığınızda rename()
, dosyayı başka bir isimle yeniden adlandıran çalıştırılan sistem çağrısı , dosyanın inode işlevi aynı kalır.
İki farklı dosya sistemi arasında iki şey olur:
Dosyanın içeriği önce ve sonra yeni konuma kopyalanır read()
vewrite()
Bundan sonra, dosya kullanılarak kaynak dizinden bağlantı kaldırılır unlink()
ve dosya açıkça yeni dosya sisteminde yeni bir inode alır.
rm
aslında unlink()
verilen dosyayı dizin ağacından ayırmak, dizinde yazma iznine sahip olmanız, bu dizinden herhangi bir dosyayı çıkarmanız için yeterli hakkı sağlayacaktır.
Şimdi eğlenmek için, iki dosya sistemi arasında dosya taşırken neler olduğunu unlink()
ve dosyaya kaynaktan izin almadığınızı hayal edin.
Peki, dosya ilk başta ( read()
, write()
) hedefe kopyalanacak ve ardından unlink()
yetersiz izin nedeniyle başarısız olacaktır. Böylece, dosya her iki dosya sisteminde de kalacaktır !!