Girdi ve Çıktı İlkelleri
Önceki XIII. Oylum - Düşük Seviyeli Girdi ve Çıktı Sonraki
Girdi ve Çıktı İlkelleri
Bu kısımda dosya tanıtıcılar üzerinde düşük seviyeli girdi ve çıktı işlemlerini gerçekleştiren read, write ve lseek işlevlerinden bahsedilecektir. Bu işlevler unistd.h başlık dosyasında bildirilmiştir.
ssize_t
veri türü
Bu veri türü tek bir işlem olarak okunup yazılabilen veri parçalarınını uzunluğunu göstermekte kullanılır. size_t türüne benzemekle birlikte bu bir işaretsiz bir türdür.
ssize_t read
(int    dosyatanıtıcı,
 void  *tampon,
 size_t boyut)
işlev
read işlevi dosyatanıtıcı tanıtıcılı dosyadan boyut baytlık okuma yapar ve sonucu tampon içinde döndürür. (Bunun bir karakter dizgesi olması gerekmediği gibi sonlandırıcı boş karakter de eklenmez.)
İşlevin normal dönüş değeri okunan baytların sayısıdır. Bu boyut bayttan küçük olabilir; örneğin dosyada kalan baytlar boyut bayttan az olabilir ya da o an için bu dosyada bu kadar bayt olmayabilir. Davranış aslında dosyanın çeşidine bağlıdır. boyut bayttan daha az verinin okunmuş olmasının bir hata olarak değerlendirilmediğini unutmayın.
Sıfır dönüş değeri dosyasonunu belirtir (boyut argümanının sıfır olduğu durum dışında). Bu bir hata olarak sayılmaz. Dosya sonunda read çağrısı yapmayı sürdürürseniz, işlev de başka bir şey yapmadan sıfır döndürmeye devam eder.
read çağrısı ile zaten tek bir karakter döndürüyorsanız dosya sonuna eriştiğinizde bunu anlayamayacaksınız. Ancak dosya sonunda, sonraki read çağrıları hep sıfır döndürecektir.
Bir hata durumunda işlev -1 ile döner. Aşağıdaki errno hata durumları bu işlev için tanımlanmıştır:
EAGAIN
Normalde, bir girdi yoksa read girdi varolana kadar bekler. Fakat dosya için O_NONBLOCK seçeneği etkinse (bkz. Dosya Durum Seçenekleri), böyle bir durumda read hiç veri okumadan hemen döner ve bunu bu hatayla raporlar.
Uyumluluk Bilgisi
BSD Unix'lerin çoğu sürümü bunun için farklı bir hata kodu kullanır: EWOULDBLOCK. GNU kütüphanesinde EWOULDBLOCK, EAGAIN için bir takma addır, dolayısıyla hangi ismi kullandığınızın bir önemi yoktur.
Bazı sistemlerde, çekirdek kullanıcı sayfaları için yeterli fiziksel bellek bulamazsa, bir karakter özel dosyasından büyük miktarda veri okunması da EAGAIN hata koduna sebep olur. Bu, kullanıcı belleğine doğrudan bellek erişimi ile iletim yapan aygıtlarla sınırlıdır. Bunlar uçbirimleri kapsamaz, çünkü uçbirimler için çekirdek içinde daima ayrı tamponlar vardır. GNU kütüphanesinde böyle bir sorunla asla karşılaşmayacaksınız.
EAGAIN ile sonuçlanabilecek bir durumda istenenden daha az bayt döndürerek read başarılı olabilir. Hemen ardından yapılan bir read çağrısı EAGAIN ile sonuçlanırdı.
EBADF
dosyatanıtıcı argümanı geçerli bir dosya tanıtıcı değil ya da okumak için açılmamış
EINTR
read çağrısı girdi beklerken bir sinyal ile durduruldu. Bkz. Sinyallerle Kesilen İlkeller. Bir sinyalin read çağrısının EINTR döndürmesine sebep olması şart değildir; istenenden daha az bayt döndürerek read başarılı olabilir.
EIO
Çoğu aygıt ve disk dosyası için bu hata kodu bir donanım hatasına işaret eder.
EIO ayrıca, bir artalan süreci denetim uçbiriminden okuma yapmaya çalışırken ve sürecin bir SIGTTIN sinyali gönderilerek durdurulmasında normal eylemin çalışmaması durumunda oluşabilir. Bu SIGTTIN sinyalinin engellenmesi ya da yoksayılmasından kaynaklanabileceği gibi süreç grubunun öksüz kalması nedeniyle de olabilir. Sinyaller hakkında daha fazla bilgi almak için Sinyal İşleme bölümüne ve iş denetimi için İş Denetimi bölümüne bakabilirsiniz.
EINVAL
Bazı sistemlerde bir karakter veya blok aygıtından okuma yapılırken, konum ve boyut başlangıçları belli bir blok boyuna hizalanmalıdır. Bu hata başlangıçların gerektiği gibi hizalanmadığını belirtir.
read64 isminde bir işlevin olmadığını unutmayın. İşlev olası geniş dosya konumlarını işlemek ya da değiştirmek için bir işlem yapmadığından bu gerekli değidir. Çekirdek gerekeni kendi içinde hallettiğinden read işlevi her durumda kullanılabilir.
Bu işlev çok evreli yazılımlarda bir iptal noktasıdır. read çağrısı sırasında evre bazı özkaynakları (bellek, dosya tanıtıcı, semafor, vb.) ayırdığında bu bir sorun olur. Evre tam bu anda bir iptal alırsa ayrılan özkaynaklar yazılım sonlanana kadar ayrılmış olarak kalır. Bu tür read çağrılarından kaçınmak için iptal eylemcileri kullanılarak korunulmalıdır.
read işlevi, akımlardan okuma yapan fgetc gibi işlevlerin düşük seviyedeki karşılığıdır.
ssize_t pread
(int    dosyatanıtıcı,
 void  *tampon,
 size_t boyut,
 off_t  konum)
işlev
pread işlevi ilk üç argümanının ve dönüş değeri ile hata durumlarının aynı olmasıyla read işlevine çok benzer.
Fark dördüncü argümanda ve onun elde edilişindedir. Okuma işlemi dosyatanıtıcı dosya tanıtıcısının o anki konumundan değil, konum ile belirtilen konumdan başlar ve dosya tanıtıcısının konumu bu işlemden etkilenmez; değeri çağrı öncesindeki değerinde kalır.
Kaynak dosyası _FILE_OFFSET_BITS == 64 ile derlenmişse pread işlevi aslında 2^63 bayta kadar dosyalarla çalışabilen ve 64 bitlik off_t türünde olan pread64 işlevi olur.
pread işlevinin normal dönüş değeri okunan baytların sayısıdır. Hata durumunda read gibi -1 ile döndüğü gibi hata kodları aşağıdakiler dışında aynıdır:
EINVAL
konum değeri negatif dolayısıyla kuraldışı
ESPIPE
dosyatanıtıcı bir boru ya da FIFO ile ilişkili ve bu aygıtlar dosya içinde konum belirtilmesine izin vermez.
İşlev Unix Tek Belirtiminin 2. sürümünde tanımlı bir oluşumdur.
ssize_t pread64
(int      dosyatanıtıcı,
 void    *tampon,
 size_t   boyut,
 off64_t  konum)
işlev
Bu işlev pread işlevinin benzeridir. Farkı konum parametresinin 2^31 bayta kadar dosyalar için olan off_t türünde değil, 2^63 bayta kadar dosyalar için olan off64_t türünde olmasıdır. Bu işlev için kullanılan dosyatanıtıcı tanıtıcısının open64 ile açılması önemlidir. Aksi takdirde, küçük dosya kipinde açılmış dosya tanıtıcılarla off64_t türündeki dosya konumları hatalara yol açacaktır.
Kaynak dosyası _FILE_OFFSET_BITS == 64 ile derlenmişse 32 bitlik sistemlerde bu işleve pread ismiyle erişilir. Yani 32 bitlik arayüz 64 bitlik olanıyla değiştirilir.
ssize_t write
(int    dosyatanıtıcı,
 void  *tampon,
 size_t boyut)
işlev
write işlevi dosyatanıtıcı tanıtıcılı dosyaya tampon tamponundaki boyut baytı yazar. tampon içindeki veri bir karakter dizgesi olması gerekmediği gibi bir boş karakter de sıradan bir karakter olarak ele alınır.
İşlevin normal dönüş değeri yazılabilen baytların sayısıdır. Bu boyut sayıda olabileceği halde hep daha küçük olur. Yazılımınızda işlevi, tüm veriyi yazana kadar tekrarlanan write çağrıları şeklinde bir döngü içinde kullanmalısınız.
write döndükten hemen sonra kuyruklanan veri okunabilir. Bunun için verinin kalıcı bir saklama alanına yazılması şart değildir. Devam etmeden önce verinin kalıcı saklama alanına yazılmasını sağlamak için fsync kullanablirsiniz. (Yazma işlemini peşpeşe çağrılar şeklinde bir defada gerçekleştirip saklama alanına yazma işini sisteme bırakmak daha verimlidir. Normalde bu veri diske bir dakikadan daha geç yazılmaz.) Günümüz sistemlerinde fdatasync adında bir işlev daha vardır ve bununla dosya verisinin bütünlüğü garanti edilmiştir ve daha hızlıdır. Dosyayı O_FSYNC kipinde açarsanız write çağrıları veri diske yazılmadan dönmeyecektir; bkz. G/Ç İşlem Kipleri.
Hata durumunda işlev -1 ile döner. Aşağıdaki errno hata durumları bu işlev için tanımlanmıştır:
EAGAIN
Normalde, yazma işlemi tamamlanana kadar write dönmez. Fakat O_NONBLOCK seçeneği etkinse (bkz. Dosyalar Üzerindeki Denetim İşlemleri), hiçbir veri yazılmadan işlev hemen bu hata durumu ile döner. Bu duruma bir örnek vermek gerekirse, sürecin bir STOP karakteri aldığında, akış denetimini destekleyen bir uçbirim aygıtına çıktının yazılmasını engellemesi verilebilir.
Uyumluluk Bilgisi
BSD Unix'in çoğu sürümü bu hata kodu için farklı bir hata kodu kullanır: EWOULDBLOCK. GNU kütüphanesinde EWOULDBLOCK, EAGAIN için bir takma addır, dolayısıyla hangi ismin kullanıldığının bir önemi yoktur.
Bazı sistemlerde, çekirdek kullanıcı sayfaları için yeterli fiziksel bellek bulamazsa, bir karakter özel dosyasına büyük miktarda veri yazılması da EAGAIN hata koduna sebep olur. Bu, kullanıcı belleğine doğrudan bellek erişimi ile iletim yapan aygıtlarla sınırlıdır. Bunlar uçbirimleri kapsamaz, çünkü uçbirimler için çekirdek içinde daima ayrı tamponlar vardır. GNU kütüphanesinde böyle bir sorunla asla karşılaşmayacaksınız.
EBADF
dosyatanıtıcı argümanı geçerli bir dosya tanıtıcı değil ya da yazma amacıyla açılmamış
EFBIG
Dosya boyutu gerçeklemenin desteklediğinden büyük
EINTR
write işlemi tamamlanmadan önce bir sinyal tarafından durduruldu. Bir sinyal her zaman write işlevinin EINTR döndürmesine sebep olmaz; istenenden daha az baytı yazarak da işlev başarılı olabilir. Bkz. Sinyallerle Kesilen İlkeller.
EIO
Çoğu aygıt ve disk dosyası için bu hata kodu bir donanım hatasını işaret eder.
ENOSPC
Aygıtın dosyası dolu.
EPIPE
Bu hata bir süreç tarafından okumak için açılmamış bir boru ya da FIFO'ya yazmaya çalışırsanız oluşur. Bu oluştuğu zaman sürece bir SIGPIPE sinyali gönderilir; bkz. Sinyal İşleme.
EINVAL
Bazı sistemlerde bir karakter veya blok aygıtından okuma yapılırken, konum ve boyut başlangıçları belli bir blok boyuna hizalanmalıdır. Bu hata başlangıçların gerektiği gibi hizalanmadığını belirtir.
EINTR başarısızlıklarından korunmak için bir düzenleme yapmadıkça, her başarısız write çağrısından sonra errno değişkenine bakmalı ve bu EINTR hatası ise çağrıyı tekrarlamalısınız. Bkz. Sinyallerle Kesilen İlkeller. Bunu yapmanın kolay bir yolu TEMP_FAILURE_RETRY makrosunu kullanmaktır:
nbytes = TEMP_FAILURE_RETRY (write (desc, buffer, count));
write64 isminde bir işlevin olmadığını unutmayın. İşlev olası geniş dosya konumlarını işlemek ya da değiştirmek için bir işlem yapmadığından bu gerekli değidir. Çekirdek gerekeni kendi içinde hallettiğinden write işlevi her durumda kullanılabilir.
Bu işlev çok evreli yazılımlarda bir iptal noktasıdır. write çağrısı sırasında evre bazı özkaynakları (bellek, dosya tanıtıcı, semafor, vb.) ayırdığında bu bir sorun olur. Evre tam bu anda bir iptal alırsa ayrılan özkaynaklar yazılım sonlanana kadar ayrılmış olarak kalır. Bu tür write çağrılarından kaçınmak için iptal eylemcileri kullanılarak korunulmalıdır.
write işlevi, akımlardan okuma yapan fputc gibi işlevlerin düşük seviyedeki karşılığıdır.
ssize_t pwrite
(int         dosyatanıtıcı,
 const void *tampon,
 size_t      boyut,
 off_t       konum)
işlev
pwrite işlevi ilk üç argümanının ve dönüş değeri ile hata durumlarının aynı olmasıyla write işlevine çok benzer.
Fark dördüncü argümanda ve onun elde edilişindedir. Yazma işlemi dosyatanıtıcı dosya tanıtıcısının o anki konumundan değil, konum ile belirtilen konumdan başlar ve dosya tanıtıcısının konumu bu işlemden etkilenmez; değeri çağrı öncesindeki değerinde kalır.
Kaynak dosyası _FILE_OFFSET_BITS == 64 ile derlenmişse pwrite işlevi aslında 2^63 bayta kadar dosyalarla çalışabilen ve 64 bitlik off_t türünde olan pwrite64 işlevi olur.
pwrite işlevinin normal dönüş değeri yazılan baytların sayısıdır. Hata durumunda write gibi -1 ile döndüğü gibi hata kodları aşağıdakiler dışında aynıdır:
EINVAL
konum değeri negatif dolayısıyla kuraldışı
ESPIPE
dosyatanıtıcı bir boru ya da FIFO ile ilişkili ve bu aygıtlar dosya içinde konum belirtilmesine izin vermez.
İşlev Unix Tek Belirtiminin 2. sürümünde tanımlı bir oluşumdur.
ssize_t pwrite64
(int         dosyatanıtıcı,
 const void *tampon,
 size_t      boyut,
 off64_t     konum)
işlev
Bu işlev pwrite işlevinin benzeridir. Farkı konum parametresinin 2^31 bayta kadar dosyalar için olan off_t türünde değil, 2^63 bayta kadar dosyalar için olan off64_t türünde olmasıdır. Bu işlev için kullanılan dosyatanıtıcı tanıtıcısının open64 ile açılması önemlidir. Aksi takdirde, küçük dosya kipinde açılmış dosya tanıtıcılarla off64_t türündeki dosya konumları hatalara yol açacaktır.
Kaynak dosyası _FILE_OFFSET_BITS == 64 ile derlenmişse 32 bitlik sistemlerde bu işleve pwrite ismiyle erişilir. Yani 32 bitlik arayüz 64 bitlik olanıyla değiştirilir.
Önceki Üst Ana Başlık Sonraki
Dosyaların Açılması ve Kapatılması Başlangıç Dosya Konumu İlkeli
Bir Linux Kitaplığı Sayfası