Bir dosya tanıtıcısının çoğullanmasının ana amacı girdi ve çıktı yönlendirmedir: bu, bir dosya ya da boruyu kendisi ile ilgili başka bir dosya tanıtıcısı ile değiştirmek anlamındadır.
Çoğullama işlemini fcntl işlevini F_DUPFD komutu ile kullanarak yapabileceğiniz gibi dosya tanıtıcıları çoğullayan dup ve dup2 işlevleri ile de yapabilirsiniz.
fcntl işlevi ve seçenekleri
fcntl.h başlık dosyasında bildirilmişken,
dup ve
dup2 işlevlerinin prototipleri
unistd.h başlık dosyasında bulunur.
Bu işlev eski dosya tanıtıcısını kullanılabilir (o an açık olmayan) ilk dosya tanıtıcı numarasına kopyalar. Bu işlem
fcntl (eski, F_DUPFD, 0) çağrısına eşdeğerdir.
int dup2 | (int eski,
int yeni) |
işlev
Bu işlev eski tanıtıcıyı yeni tanıtıcıya kopyalar.
eski geçersiz bir tanıtıcı ise dup2 hiçbir şey yapmaz; yeni'yi de kapatmaz. Aksi takdirde, eski tanıtıcısı, zaten bir tanıtıcı olan yeni tanıtıcısı kapatıldıktan sonra yeni tanıtıcısına kopyalanır.
eski ve yeni farklı numaralarsa ve eski geçerli bir tanıtıcı numarası ise, dup2 şu koda eşdeğerdir:
close (yeni);
fcntl (eski, F_DUPFD, yeni)
Bununla birlikte, dup2 bunu atomik olarak yapar; dup2 çağrısının ortasında yeni'nin kapatıldığı ama henüz eski'nin kopyası yapılmadığı bir an yoktur.
Bu makro fcntl işlevinin komut argümanında kullanıldığında işlevin ilk argümanında belirtilen dosya tanıtıcıyı kopyalar.
Bu çağrı şöyle yapılır:
fcntl (eski, F_DUPFD, sonraki_tanıtıcı)
sonraki_tanıtıcı argümanı int türünde olmalı ve döndürülecek dosya tanıtıcısı bu değerde ya da bu değerden büyük kullanılabilir ilk dosya tanıtıcı olacak şekilde belirtilmelidir.
Böyle bir fcntl çağrısının normal dönüş değeri yeni dosya tanıtıcısının değeridir. Dönüş değeri -1 ise bu bir hata oluştuğunu gösterir. Aşağıdaki errno hata durumları bu komut için tanımlanmıştır:
- EBADF
eski argümanı geçersiz
- EINVAL
sonraki_tanıtıcı argümanı geçersiz
- EMFILE
Kullanılabilir başka tanıtıcı yok--yazılımınız olanı zaten kullanmış. BSD ve GNU'da bu değerin alabileceği azami değeri belirten özkaynak sınırı değiştirilebilir;
RLIMIT_NOFILE sınırı hakkında daha ayrıntılı bilgi almak için
Özkaynak Kullanımın Sınırlanması bölümüne bakınız.
EMFILE hata durumu dup2 işlevinde oluşmaz çünkü dup2 tanıtıcıyı yeni bir dosya açılışı olarak oluşturmaz, mevcut birini kapattıktan sonra ona kopyalama yapar.
Aşağıdaki örnekte yönlendirme için
dup2 işlevinin nasıl kullanıldığı gösterilmiştir. Genellikle, standart akımların (
stdin gibi) yönlendirilmesi kabuk tarafından ya da kabuk benzeri bir yazılım tarafından yeni bir yazılımın ya da bir alt sürecin
çalıştırılması için bir
exec çağrısı yapılmadan önce yapılır. Yeni bir yazılım çalıştırıldığında,
main işlevi çalıştırılmadan önce, standart akımlar kendileriyle ilgili dosya tanıtıcılarla oluşturulur ve ilklendirilir.
Standart girdinin bir dosyaya yönlendirilmesi kabuk tarafından şöyle yapılabilirdi:
pid = fork ();
if (pid == 0)
{
char *dosyaismi;
char *program;
int dosya;
…
dosya = TEMP_FAILURE_RETRY (open (dosyaismi, O_RDONLY));
dup2 (dosya, STDIN_FILENO);
TEMP_FAILURE_RETRY (close (dosya));
execv (program, NULL);
}
İşlerin Başlatılması bölümünde, süreçlerin bir boruhattının bağlamı içinde yönlendirilmesinin gerçekleştirildiği daha ayrıntılı bir örnek vardır.