Hata İletileri
Önceki II. Oylum - Hata Bildirme Sonraki
Hata İletileri
Kütüphane, bir kütüphane çağrısının başarısız olması durumunda yazılımınızda özelleştirilebilir biçimde bilgilendirici hata iletileri oluşturabilmenizi kolaylaştıran işlevler ve değişkenler içerir. strerror ve perror işlevleri belirtilen bir hata kodu için standart hata iletisini verirler. program_invocation_short_name değişkeni ise hatanın saptandığı yazılımın ismine erişebilmenizi sağlar.
char *strerror
(int hatanum)
işlev
strerror işlevi hatanum ile belirtilen hata kodunu bir açıklayıcı hata iletisi dizgesi ile eşleştirir ve bu dizgeye bir gösterici ile döner.
hatanum normalde errno değişkeninden alınır.
strerror ile döndürülen dizgeyi değiştirmemelisiniz. Ayrıca, strerror işlevine daha sonra yapacağınız çağrılar, dizgenin üzerine yazılması ile de sonuçlanabilir. (strerror bir kütüphane işlevi tarafından da çağrılabileceğinden döndürdüğü hata iletisinin sizin istediğiniz hata iletisi olacağının hiçbir garantisi yoktur.)
strerror işlevi string.h başlık dosyasında bildirilmiştir.
char *strerror_r
(int    hatanum,
 char  *tampon,
 size_t n)
işlev
strerror_r işlevi süreçteki tüm evreler (threads) tarafından paylaşılan süreç için ayrılmış durağan bellek içindeki evreye özel hata iletisini döndürmek dışında strerror işlevi gibi çalışır. Hata iletisini tutacak bellek bölgesi kullanıcı tarafından belirlenen ve tampon ile başlayan n bayt uzunlukta bir tampondur.
Bu tampona NULL karakteri de dahil olmak üzere en fazla n karakter yazılabileceğinden yazılımcı bu alanın büyüklüğünü yeterince büyük seçmelidir.
strerror tarafından döndürülen dizgenin gerçekten o anki evrenin son çağrısına karşılık olacağının hiçbir garantisi olmadığından çok evreli (multi-threaded) yazılımlarda daima strerror_r işlevi kullanılmalıdır.
strerror_r işlevi bir GNU oluşumu olup string.h başlık dosyasında bildirilmiştir.
void perror
(const char *ileti)
işlev
Bu işlev standart hataya (stderr) bir hata iletisi basar. Standart hatanın yönünü değiştirmez.
perror işlevini ileti argümanına değer olarak bir boş gösterici ya da bir boş dizge belirterek çağırırsanız o andaki errno değerine karşılık gelen hata iletisini sonuna bir satırsonu karakteri ekleyerek basar.
ileti argümanı boş değilse, perror bu dizgeyi çıktısına önek olarak alır ve arkasına bir iki nokta imi ile boşluk ekledikten sonra errno değerine karşılık gelen hata iletisini sonuna bir satırsonu karakteri ekleyerek basar.
perror işlevi stdio.h başlık dosyasında bildirilmiştir.
strerror ve perror belirtilen hata kodu için tamamen aynı hata iletisini üretir, ancak üretilen ileti sistemden sisteme farklı olabilir. GNU sisteminde iletiler oldukça kısadır; çok satırlı hata iletileri yoktur (Ç.N: çeviriler bu kurala uymayabilir). Her hata iletisi büyük harfle başlar ve sonunda herhangi bir noktalama işareti bulunmaz.
Uyumluluk Bilgisi:
strerror işlevi ISO C89 ile gelmiştir. Eski C sistemlerinin çoğu hala bu işlevi desteklememektedir.
Uçbirimden girdi okumayan yazılımların çoğu bir sistem çağrısı başarısız olduğunda kendini sonlandıracak şekilde tasarlanır. Teamül olarak, böyle bir yazılımın verdiği hata iletileri dizin ismi içermeden yazılımın ismi ile başlamalıdır. Bu isim program_invocation_short_name değişkeninde bulunur. Dizini de içeren tam dosya ismi ise program_invocation_name değişkeninde saklanır.
char *program_invocation_name
değişken
Bu değişkenin değeri o anda çalışmakta olan sürecin çağrıldığı yazılım ismidir. argv[0] ile aynıdır. Bu bir dosya ismi olmak zorunda da değildir. Çoğunlukla da dizin bilgisi içermez.
char *program_invocation_short_name
değişken
Bu değişkenin değeri, dizin isimleri kaldırıldığında o anda çalışmakta olan süreci çağırmakta kullanılan isimdir. Yani program_invocation_name değişkenin değeri olan dizgedeki son bölü çizgisi ve onun solundaki herşey kaldırıldığında kalan isim bu değişkenin değeridir diyebiliriz.
Kütüphane ilklendirme kodu main işlevi çağrılmadan önce bu değişkenlerin her ikisine de değerlerini atar.
Taşınabilirlik Bilgisi:
Bu iki değişken GNU oluşumudur. Yazılımınızın GNU dışı sistemlerde çalışmasını istiyorsanız yazılımın ismini main işlevinin argv[0] argümanının değerinden dizin isimlerini ayıklayarak elde etmelisiniz. main işlevi ile hiç etkileşime girmeden hata bildirme yordamlarında yazılım ismi içeren iletileri kolayca üretmek için bu değişkenleri kütüphaneye koyduk.
Aşağıdaki bir dosya açılamadığında hatayı gösteren bir örnek yeralmaktadır. acil_susam_acil işlevi isim isimli dosyayı okumak için açmayı dener, dosya sorunsuz olarak açılırsa bir akım ile döner. fopen kütüphane işlevi bir sebeple dosyayı açamazsa bir boş gösterici ile döner. Bu durumda acil_susam_acil işlevi strerror işlevini kullanarak bir hata iletisi oluşturur ve süreci sonlandırır. Hata kodunu strerror işlevine aktarmadan önce başka kütüphane çağrıları yapacaksak, onu bir değişkene kaydetmeliyiz, çünkü arada çağırdığımız diğer işlevler errno değerini değiştirebilir.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

FILE *acil_susam_acil (char *isim)
{
  FILE *stream;

  errno = 0;
  stream = fopen (isim, "r");
  if (stream == NULL)
    {
      fprintf (stderr, "%s: %s dosyası açılamadı; %s\n";,
               program_invocation_short_name, isim, strerror (errno));
      exit (EXIT_FAILURE);
    }
  else
    return stream;
}
perror işlevi ISO C standardına uyumlu tüm sistemlerde geçerli olduğundan daha taşınabilirdir. Ancak perror işlevinin ürettiği hata iletisi tam isteneni sağlamaz ve yaptığı işlemi değiştirmek ya da geliştirmek için bir yol yoktur. Örneğin, GNU kodlama standardı, hata iletilerinin yazılımın ismi ile başlamasını ve bazı girdi dosyalarını okuyan yazılımların girdi dosyasının ismi ile dosya okunurken hata oluşturan satırın numarası gibi bilgilerinde hata iletisinde içerilmesini gerektirir. Bu gibi durumlar için GNU projelerinde geniş çapta kullanılan iki işlev vardır. Bu işlevler error.h başlık dosyasında bildirilmiştir.
void error
(int         durum,
 int         hatanum,
 const char *biçim,
 …)
işlev
error işlevi yazılımın çalışması sırasında oluşan genel sorunları bildirmek amacıyla kullanılır. bicim argümanı, printf ailesi işlevlerde olduğu gibi dizgeyi biçimlemekte kullanılır. perror gibi error işlevi de bir hata kodunu metin şeklinde basmak için kullanılabilir. perror işlevinden farklı olarak hatanum argümanıyla işleve hata numarası açıkça belirtilir. İşlevin bu özelliği, yukarıda bahsedilen, arada çağrılan başka işlevlerin errno değerini değiştirebilmesi sorununu ortadan kaldırır.
error işlevi önce yazılımın ismini basar. Eğer yazılım, error_print_progname isimli bir genel değişken tanımlamış ve onu işleve göstermişse, bu işlev yazılımın ismini basmak için çağrılacaktır. Aksi takdirde, program_name kütüphane değişkenindeki dizge kullanılır. Yazılımın isminden sonra iki nokta imi ve bir boşluk gelir. Onun ardına da bicim argümanı ile hazırlanan dizge basılır. hatanum argümanı sıfırdan farklı bir değere sahipse, biçim dizgesinden sonra iki nokta imi ve bir boşluk konduktan sonra bu değere karşılık olan hata iletisi basılır. Her durumda çıktı bir satırsonu karakteri ile sonlandırılır.
Çıktı standart hataya (stderr) yönlendirilir. Eğer standart çıktı çağrı öncesi yönlenimli değilse çağrı sonrası dar yönlenimli (narrow-oriented) olacaktır.
İşlev durum parametresi sıfırdan farklı bir değere sahip olmadıkça bir geridönüş değeri ile dönecektir. Bu durumda işlev exit işlevini parametre olarak durum değerini vererek çağıracak ve bu durumda asla dönmeyecektir. error işlevi bir geridönüş değerine sahipse, bu error_message_count kütüphane değişkeninin değerinin bir arttırılması ile elde edilen o ana kadar bildirilmiş hata iletilerinin sayısına karşılık gelen bir sayı olacaktır.
void error_at_line
(int          durum,
 int          hatanum,
 const char  *dosyaismi,
 unsigned int satırno,
 const char  *biçim,
 …)
işlev
error_at_line işlevi error işlevine çok benzer. Ek olarak dosyaismi ve satırno parametrelerini içerir. Yazılımın ismi ile bicim ile üretilen dizge arasına giren ek bilgiler dışında diğer parametrelerin yorumlanması error işlevindeki gibidir.
Yazılımın isminden sonraki iki nokta iminden sonra dosyaismi ile verilen dosya ismi tekrar bir iki nokta imi ve ardından satırno ile verilen satır numarası ve bir iki nokta imi basılır.
Bu ek çıktı, bir girdi dosyasındaki hatanın yerini belirtmekte kullanılır.
error_one_per_line genel değişkenine sıfırdan farklı bir değer verilirse error_at_line, aynı dosya ve satır için başka hatalar varsa onları basmayacaktır. Hata bir ardardalık arzediyorsa ardarda olmayan tekrarlar yakalanmaz.
error işlevi gibi bu işlevde durum sıfır olduğunda döner. Sıfırdan faklı ise exit çağrılır. İşlev bir geridönüş değerine sahipse, bu error_message_count kütüphane değişkeninin değerinin bir arttırılması ile elde edilen o ana kadar bildirilmiş hata iletilerinin sayısına karşılık gelen bir sayı olacaktır.
Yukarıda değinildiği gibi error ve error_at_line işlevleri error_print_progname isimli bir değişken tanımlanarak özelleştirilebilir.
void (*error_print_progname)
(void)
değişken
error_print_progname değişkenine sıfırdan farklı bir değer atanmışsa, bu değerin gösterdiği yazılım veya işlev error veya error_at_line işlevleri tarafından çağrılır.
İşlevin hatayı standart çıktıya basacağı ve akımın yönünü saptayabileceği umulur.
Değişken geneldir ve tüm evrelerce paylaşılır.
unsigned int error_message_count
değişken
error_message_count değişkeninin değeri error veya error_at_line işlevlerinin her geri dönüşünde bir arttırılır. Değişken geneldir ve tüm evrelerce paylaşılır.
int error_one_per_line
değişken
error_one_per_line değişkeni sadece error_at_line işlevi ile etkilidir. Normalde error_at_line işlevi her çağrı için bir çıktı oluşturur. error_one_per_line değişkenine sıfırdan farklı bir değer atanırsa, error_at_line işlevi aynı dosyanın aynı satırındaki diğer hataların iletilerini basmaz. Değişken geneldir ve tüm evrelerce paylaşılır.
Bir girdi dosyasını okuyan ve hataları bildiren bir yazılım aşağıdakine benzer:
{
  char *satir = NULL;
  size_t boyu = 0;
  unsigned int satirno = 0;

  error_message_count = 0;
  while (! feof_unlocked (fp))
    {
      ssize_t n = getline (&satir, &boyu, fp);
      if (n <= 0)
        /* Dosya sonu ya da hata.  */
        break;
      ++satirno;

      /* Satır işlemleri.  */
      …

      if (Satırdaki hata saptandı)
        error_at_line (0, hatanum, dosyaismi, satirno,
                       "hata iletisi metni %s", bir_degisken);
    }

  if (error_message_count != 0)
    error (EXIT_FAILURE, 0, "%u hata bulundu", error_message_count);
}
error ve error_at_line işlevleri GNU kodlama standardına göre uygulama geliştirmek isteyen yazılımcıların seçimi olmalıdır. GNU libc aynı amaçlar için BSD'de kullanılan işlevleri de içerir. Bu işlevler err.h başlık dosyasında bildirilmiştir. Uyumluluk amacıyla kütüphaneye dahil edildiklerinden, genelde kullanılmamaları önerilir.
void warn
(const char *biçim, …)
işlev
warn işlevi, error işlevinin birlikte çalıştığı genel değişkenleri kullanmaması dışında
  error (0, hatanum, biçim, parametreler)
çağrısına eşdeğerdir.
void vwarn
(const char *biçim,
             va_list)
işlev
vwarn işlevi, warn gibidir, farklı olarak biçim ile belirtilen biçim dizgesinin va_list türünde verilen parametrelerle düzenlenmesini sağlar.
void warnx
(const char *biçim, …)
işlev
warnx işlevi, error işlevinin birlikte çalıştığı genel değişkenleri kullanmaması dışında
  error (0, 0, biçim, parametreler)
çağrısına eşdeğerdir. warn işlevinden farkı ise, hata numarası dizgesinin basılmamasıdır.
void vwarnx
(const char *biçim,
             va_list)
işlev
vwarnx işlevi, warnx gibidir, farklı olarak biçim ile belirtilen biçim dizgesinin va_list türünde verilen parametrelerle düzenlenmesini sağlar.
void err
(int         durum,
 const char *biçim,
 …)
işlev
err işlevi,
  error (durum, hatanum, biçim, parametreler)
çağrısı ile error işlevinin birlikte çalıştığı genel değişkenleri kullanmaması ve durum değişkenine sıfır verildiğinde bile yazılımın çıkması dışında aynıdır.
void verr
(int         durum,
 const char *biçim,
             va_list)
işlev
verr işlevi, err gibidir, farklı olarak biçim ile belirtilen biçim dizgesinin va_list türünde verilen parametrelerle düzenlenmesini sağlar.
void errx
(int         durum,
 const char *biçim,
 …)
işlev
errx işlevi,
  error (durum, 0, biçim, parametreler)
çağrısı ile error işlevinin birlikte çalıştığı genel değişkenleri kullanmaması ve durum değişkenine sıfır verildiğinde bile yazılımın çıkması dışında aynıdır. err işlevinden farkı ise, hata numarası dizgesinin basılmamasıdır.
void verrx
(int         durum,
 const char *biçim,
             va_list)
işlev
verrx işlevi, errx gibidir, farklı olarak biçim ile belirtilen biçim dizgesinin va_list türünde verilen parametrelerle düzenlenmesini sağlar.
Önceki Üst Ana Başlık Sonraki
Hata Kodları Başlangıç III. Oylum - Sanal Bellek Ayırma ve Sayfalama
Bir Linux Kitaplığı Sayfası