Kullanıcı ve Grup ID’leri İle İlgili POSIX Fonksiyonları
Normal, etkin kullanıcı ve grup ID’leri aşağıdaki fonksiyonlarla alınabilir.
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
Bu fonksiyonların dışında set etme işlemi için aşağıdaki fonksiyonlar vardır.
int setuid(uid_t uid);
int setgid(gid_t gid);
dup ve dup2 Fonksiyonları
Aynı dosya iki kez open fonksiyonuyla açıldığında iki ayrı dosya betimleyicisi ve dosya
nesnesi oluşturulur. Bilindiği gibi dosya göstericisinin konumu, open fonksiyonunda belirtilen
açma modu dosya nesnesi içerisinde tutulmaktadır. Ancak bir dosyayı iki kez açmak yerine
eğer dosyaya ilişkin iki tane dosya betimleyicisi isteniyorsa aynı dosya nesnesini gören farklı
betimleyiciler kullanılır. Bu işlem dup fonksiyonuyla yapılır.
int dup(int oldfd);
Fonksiyonun parametresi çoğaltılacak betimleyici değeridir. Fonksiyon geri dönüş değeri
olarak aynı dosya nesnesine ilişkin yeni bir betimleyici verir. Fonksiyonun ilk boş
betimleyiciyi verdiği garanti altına alınmıştır. Örneğin;
int fd;
fd = open(....);
close(1);
dup(fd);
Burada önce stdout dosyasına ilişkin 1 numaralı betimleyici kapatılmıştır. Sonra açılan dosya
dup fonksiyonu ile 1 numaralı slota yazdırılmıştır.
Burada stdout başka bir dosyaya yönlendirilmiştir. dup fonksiyonunun geri dönüş değerine
bakılmamıştır. Gerçi dup fonksiyonu başka nedenlerden başarısız olabilir. dup fonksiyonu
başarılıysa 1 değerine geri dönecektir. Bu işlemden geri dönüş de mümkündür. Yani
programcı 1 numaralı betimleyicinin yine ekrana ilişkin olmasını sağlayabilir. Örneğin;
close(1);
dup(2);
gibi bir işlemle stderr’den faydalanılarak yeniden eski duruma dönüş yapılabilir.
dup eğer dosya betimleyici tablosu doluysa başarısız olur ve –1 değerine geri döner.
Fonksiyonun prototipi <unistd.h> dosyası içerisindedir.
Sınıf çalışması: close, dup, fork ve exec fonksiyonlarını kullanarak başka bir programı
çalıştırınız, ama çalıştırılan programdaki stdout çalıştıran programda belirlenen dosyaya
yönlensin. Program aşağıdaki gibi çalıştırılacaktır.
direct<çalıştırılcak_dosya_ismi><stdout_yönlendirmesi_yapılacak_dosya_ismi>
Yönlendirilecek dosya önce açılır. Daha sonra,
close(1);
dup(fd);
uygulanır. Daha sonra fork ve exec yapılır. Sonra çalıştırılan programın sonlanması beklenir.
Anahtar notlar: Bir dosya fopen standart C fonksiyonuyla açılmış olsun. Eğer programcı
aşağı seviyeli çalışmaya geçecekse fileno fonksiyonuyla dosya betimleyici değerini alabilir.
int fileno(FILE *fp);
Şüphesiz betimleyici değeri (handle değeri) FILE yapısı içerisinde tutulmaktadır. Standart C
fonksiyonlarıyla çalışırken eğer tamponlamasız modda değilsek fork ve exec işlemlerinden
önce fflush yapılması gerekmektedir.
/* direct.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
int fd;
FILE *fp;
pid_t pid;
fp = fopen("den.dat", "wb");
if (fp == NULL) {
fprintf(stderr, "Cannot open file...\n");
exit(0);
}
fd = fileno(fp);
close(1);
dup(fd);
if ((pid = fork()) == -1) {
perror("fork");
exit(0);
}
if (pid == 0) {
if (execlp(argv[1], argv[1]) < 0) {
perror("exec");
exit(0);
}
}
wait(NULL);
return 0;
}
close ve dup fonksiyonları yerine önce close, sonra open fonksiyonları kullanılabilir. Çünkü
open fonksiyonu da boş en küçük dosya betimleyici değerine döner.
dup fonksiyonu öncesinde close kullanılırken işlemlerin atomik olmamasından dolayı bazı
uygulamalarda signal problemi oluşabilir. Yani close ile dup arasında oluşan signal
mekanizmayı bozabilir. dup2 fonksiyonu close ve dup işlemini yapan ve atomik olan bir
fonksiyondur.
int dup2(int oldfd, int newfd);
Bu fonksiyon ikinci parametresiyle belirtilen dosyayı kapatarak birinci parametresiyle
belirtilen dosya betimleyicisinin kopyasından çıkartır. Elde edilen betimleyicinin ikinci
parametresiyle belirtilen betimleyici olduğu garanti altına alınmıştır. Örneğin;
dup2(fd1, fd2);
Burada önce fd2 kapatılır. Sonra fd1’in kopyası fd2 slotu kullanılarak çıkartılır. Fonksiyon
başarılıysa fd2 değeriyle, başarısızsa –1 değeriyle geri döner. fd2’nin kapatılması ve yeni
betimleyicinin oluşturulması atomik işlemlerdir. Yani herhangi bir kesilme oluşmaz.