İngilizceFransızcaİspanyolca

Ad


OnWorks favicon'u

açıklama_lca2010 - Bulutta Çevrimiçi

Açıkla_lca2010'u Ubuntu Online, Fedora Online, Windows çevrimiçi emülatörü veya MAC OS çevrimiçi emülatörü üzerinden OnWorks ücretsiz barındırma sağlayıcısında çalıştırın

Bu, Ubuntu Online, Fedora Online, Windows çevrimiçi emülatörü veya MAC OS çevrimiçi emülatörü gibi birden fazla ücretsiz çevrimiçi iş istasyonumuzdan birini kullanarak OnWorks ücretsiz barındırma sağlayıcısında çalıştırılabilen açıklayıcı_lca2010 komutudur.

Program:

ADI


açıklama_lca2010 - Ortam bulunamadı: okumaya çalışmayı bırakma zamanı geldiğinde korku(3)'ler
akıl.

MOTİVASYON


Libexplain fikri 1980'lerin başında aklıma geldi. Ne zaman bir sistem çağrısı
bir hata döndürür, çekirdek tam olarak neyin yanlış gittiğini bilir ... ve bunu sıkıştırır
8 bitten daha az hata. Kullanıcı alanı, çekirdek ile aynı verilere erişime sahiptir.
kullanıcı alanının hatayı tetikleyecek tam olarak ne olduğunu anlaması mümkün olmalıdır
geri dönün ve bunu iyi hata mesajları yazmak için kullanın.

Bu kadar basit olabilir mi?

Hata mesajları as incelik
İyi hata mesajları, genellikle zamanlama yapıldığında bırakılan "yüzde bir" görevlerdir.
baskı projenizi sıkıştırır. Ancak, iyi bir hata mesajı çok büyük bir
kullanıcı korkuya kapıldığında, kullanıcı deneyiminde orantısız iyileştirme
bilinmeyen bölge genellikle karşılaşılmaz. Bu kolay bir iş değil.

Bir larva programcısı olarak, yazar (tamamen doğru) hatayla ilgili sorunu görmedi
bunun gibi mesajlar:
kayan istisna (çekirdek boşaltıldı)
alternatif programcı olmayan yoruma dikkat çekilene kadar. Ama bu değil
Unix hata mesajlarında yanlış olan tek şey. Aşağıdaki gibi hata mesajlarını ne sıklıkla görüyorsunuz:
$ ./Aptal
dosya açılamıyor
$
Bu noktada bir geliştirici için iki seçenek vardır:

1.
gibi bir hata ayıklayıcı çalıştırabilirsiniz. gdb(1) veya

2.
kullanabilirsiniz iz(1) veya demet(1) içine bakmak için.

· Kullanıcılarınızın bu araçlara erişiminin bile olmayabileceğini unutmayın.
onları kullanmak için. (çok uzun zaman oldu Unix acemi "sadece yazdı" demek bir
aygıt sürücüsü".)

Ancak bu örnekte, iz(1) ortaya çıkarır
$ iz -e iz=açık ./Aptal
open("some/file", O_RDONLY) = -1 ENOENT (Böyle bir dosya veya dizin yok)
dosya açılamıyor
$
Bu, hata mesajının sağladığından çok daha fazla bilgidir. Tipik olarak,
aptal kaynak kodu buna benziyor
int fd = açık("bir şey", O_RDONLY);
eğer (fd < 0)
{
fprintf(stderr, "dosya açılamıyor\n");
çıkış(1);
}
kullanıcıya söylenmedi hangi dosya ve ayrıca kullanıcıya söyleyemiyor hangi hata. dosya mıydı
orada bile? Bir izin sorunu mu oldu? açmaya çalıştığını söylüyor.
dosya, ama bu muhtemelen kazayla oldu.

İpucu çubuğunu al ve onunla larva programlayıcısını yen. ona anlat hata(3).
Programı bir sonraki kullanışınızda farklı bir hata mesajı görürsünüz:
$ ./Aptal
açık: Böyle bir dosya veya dizin yok
$
İlerleme, ancak beklediğimiz gibi değil. Hata mesajı gelirse kullanıcı sorunu nasıl çözebilir?
ona sorunun ne olduğunu söylemiyor mu? Kaynağa baktığımızda görüyoruz.
int fd = açık("bir şey", O_RDONLY);
eğer (fd < 0)
{
pererror("açık");
çıkış(1);
}
İpucu çubuğuyla başka bir koşu zamanı. Bu sefer hata mesajı bir adım atıyor
ileri ve bir adım geri:
$ ./Aptal
bir şey: Böyle bir dosya ya da dizin yok
$
Artık açmaya çalıştığı dosyayı biliyoruz, ancak artık dosyanın açıldığı konusunda bilgilendirilmiyoruz. açık(2)
bu başarısız oldu. Bu durumda muhtemelen önemli değildir, ancak aşağıdakiler için önemli olabilir.
diğer sistem çağrıları. Olabilirdi creat(2) bunun yerine, bunu ima eden bir işlem
farklı izinler gereklidir.
const char *dosya adı = "bir şey";
int fd = open(dosya adı, O_RDONLY);
eğer (fd < 0)
{
pererror(dosya adı);
çıkış(1);
}
Yukarıdaki örnek kod maalesef larva olmayan programcılar için de tipiktir. Zaman
padawan öğrencimize anlatmak için korku(3) sistem çağrısı.
$ ./Aptal
açık bir şey: Böyle bir dosya ya da dizin yok
$
Bu, kullanıcıya sunulabilecek bilgileri en üst düzeye çıkarır. Kod benziyor
bu:
const char *dosya adı = "bir şey";
int fd = open(dosya adı, O_RDONLY);
eğer (fd < 0)
{
fprintf(stderr, "%s aç: %s\n", dosya adı, strerror(errno));
çıkış(1);
}
Artık sistem çağrısına, dosya adına ve hata dizesine sahibiz. Bu tüm içerir
bilgi iz(1) basılı. Bu kadar iyi.

Yoksa öyle mi?

Sınırlamalar of hata ve korku
Yazarın 1980'lerde gördüğü sorun, hata mesajının eksik olmasıydı.
“Böyle bir dosya veya dizin yok” ifadesi “biraz” dizinine veya “şey" dosyasında
biraz” dizini?

için man sayfasına hızlı bir bakış korku(3) anlatıyor:
strerror - hata numarasını açıklayan dizeyi döndürür
İyi not edin: hatayı açıklıyor numara, hata değil.

Öte yandan, çekirdek bilir hata neydi. belirli bir nokta vardı
çekirdek kodunun dallandığı ve "hayır" dediği belirli bir durumun neden olduğu çekirdek kodu.
Bir kullanıcı alanı programı belirli durumu çözebilir ve daha iyi bir hata yazabilir mi?
mesaj?

Ancak sorun daha da derinleşiyor. Sorun şu süre içinde ortaya çıkarsa ne olur? okumak(2) sistem
aramak yerine, açık(2) çağrı? İle ilişkili hata mesajı için basittir.
açık(2) dosya adını eklemek için, tam orada. Ancak bir dosya adı ekleyebilmek için
ile ilgili hatada okumak(2) sistem çağrısı, dosya adının tamamını iletmeniz gerekir
dosya tanıtıcısının yanı sıra çağrı yığınının aşağısındaki yol.

Ve işte dikkat çeken kısım: çekirdek, dosyanın hangi dosya adını zaten biliyor.
tanımlayıcı ile ilişkilidir. Bir programcı neden tüm gereksiz verileri iletmek zorunda olsun ki?
asla verilmeyen bir hata mesajını iyileştirmek için çağrı yığınından aşağı inen yol? İçinde
Gerçekte, birçok programcı rahatsız etmez ve sonuçta ortaya çıkan hata mesajları daha kötüdür.
bunu.

Ancak bu, sınırlı kaynaklara ve paylaşılan kütüphanelere sahip olmayan bir PDP1980'de 11'lerdi. Geri
o zaman, Unix'in hiçbir tadı dahil değildir / proc hatta ilkel biçimde ve of(1) programı
on yıldan fazla uzaktaydı. Böylece fikir pratik olmadığı için rafa kaldırıldı.

seviye Sonsuzluk Destek
Seviye sonsuzluk desteği olduğunuzu hayal edin. İş tanımınız, asla
hiç kullanıcılarla konuşmak zorunda. O halde neden hala sürekli bir insan akışı var?
Siz, yerel Unix gurusu, başka bir hata mesajını deşifre etmek için mi?

Garip bir şekilde, 25 yıl sonra, basit bir izin sistemine rağmen, eksiksiz olarak uygulandı.
tutarlılık, çoğu Unix kullanıcısının hala “Böyle bir dosya veya dizin yok” kodunun nasıl çözüleceği hakkında hiçbir fikri yok,
veya her gün gördükleri diğer şifreli hata mesajlarından herhangi biri. Veya, en azından, şifreli
Onları.

Birinci seviye teknik desteğin hata mesajlarının deşifre edilmesine ihtiyacı olmasa iyi olmaz mıydı?
Kullanıcıların aramadan anlayabileceği hata mesajları olması güzel olmaz mıydı?
teknik Destek?

Bugünlerde / proc Linux'ta, kodun çözülmesi için gerekli bilgileri sağlamaktan daha fazlasıdır.
hata mesajlarının büyük çoğunluğunu oluşturur ve kullanıcıyı hatalarının en yakın nedenine yönlendirir.
sorun. Sınırlı sistemlerde / proc uygulama, of(1) komut doldurabilir
boşlukların çoğu.

2008'de, çeviri istekleri akışı yazarın başına çok sık geldi. Öyleydi
25 yıllık fikri yeniden incelemenin zamanı geldi ve sonuç libexplain.

KULLANMA L' KÜTÜPHANE


Kitaplığın arayüzü, mümkün olduğunca tutarlı olmaya çalışır. Bir ile başlayalım
kullanarak örnek korku(3):
if (yeniden adlandır(eski_yol, yeni_yol) < 0)
{
fprintf(stderr, "%s %s adını değiştir: %s\n", old_path, new_path,
strerror(hata));
çıkış(1);
}
libexplain'in arkasındaki fikir, bir korku(3) eşdeğer her sistem çağrısı,
daha ayrıntılı bir hata sağlayabilmesi için özel olarak bu sistem çağrısına uyarlanmıştır
bölümünün “HATALAR” başlığı altında gördüğünüz bilgilerin çoğunu içeren mesaj
2 ve 3 adam gerçek koşullar, gerçek argüman hakkında bilgilerle desteklenen sayfalar
değerler ve sistem limitleri.

The Basit dava
The korku(3) değiştirme:
if (yeniden adlandır(eski_yol, yeni_yol) < 0)
{
fprintf(stderr, "%s\n", açıklama_rename(eski_yol, yeni_yol));
çıkış(1);
}

The Hata dava
Açık bir şekilde geçmek de mümkündür hata(3) değer, önce biraz yapmanız gerekiyorsa
rahatsız edecek işleme hata, hata kurtarma gibi:
if (yeniden adlandır(eski_yol, yeni_yol < 0))
{
int eski_errno = hatano;
...kod o rahatsız ediyor hata...
fprintf(stderr, "%s\n", açıklama_errno_rename(eski_errno,
eski_yol, yeni_yol));
çıkış(1);
}

The Çoklu dizin Olgular
Bazı uygulamalar çok iş parçacıklıdır ve bu nedenle libexplain'in dahili bilgilerini paylaşamazlar.
tampon. kullanarak kendi arabelleğinizi sağlayabilirsiniz.
if (bağlantıyı kaldır(yol adı))
{
karakter mesajı[3000];
açıklamak_message_unlink(mesaj, sizeof(mesaj), yol adı);
hata_diyaloğu(İleti);
dönüş -1;
}
Ve bütünlük için, her ikisi de hata(3) ve iş parçacığı için güvenli:
ssize_t nbytes = read(fd, veri, sizeof(veri));
if (nbayt < 0)
{
karakter mesajı[3000];
int eski_errno = hatano;
...hata kurtarma...
açıklamak_message_errno_read(mesaj, sizeof(İleti),
old_errno, fd, veri, sizeof(veri));
hata_diyaloğu(İleti);
dönüş -1;
}

Bunlar için yedekler strerror_r(3), sahip olduğu sistemlerde.

arayüzey Şeker
Programcıların
libexplain kitaplığı, yazarın en sık kullanılan libexplain işlevleri olduğu ortaya çıktı.
komut satırı programları:
int fd =expla_creat_or_die(dosyaadı, 0666);
Bu işlev, yeni bir dosya oluşturmaya çalışır. Yapamazsa, bir hata mesajı yazdırır ve
EXIT_FAILURE ile çıkar. Hata yoksa yeni dosya tanıtıcısını döndürür.

İlgili bir işlev:
int fd =expla_creat_on_error(dosyaadı, 0666);
başarısızlık durumunda hata mesajını yazdırır, ancak aynı zamanda orijinal hata sonucunu da döndürür ve
hata(3) aynı zamanda rahatsız edilmemiştir.

Türkiye the diğer sistem aramalar
Genel olarak, her sistem çağrısının kendi içerme dosyası vardır.
#Dahil etmekisim.h>
altı işlev için işlev prototiplerini tanımlayan:

· açıklamak_isim,

· açıkla_errno_isim,

· açıklama_mesajı_isim,

· açıklama_mesaj_errno_isim,

· açıklamak_isim_or_die ve

· açıklamak_isim_on_hata.

Her fonksiyon prototipinin Doxygen dokümantasyonu vardır ve bu dokümantasyon is değil elimden
içerme dosyaları yüklendiğinde.

The beklemek(2) sistem çağrısının (ve arkadaşların) arızayı da yorumlayan bazı ekstra değişkenleri vardır
EXIT_SUCCESS olmayan bir çıkış durumu olmak. Bu .... için geçerlidir sistem(3) ve kapatmak(3) olarak
iyi.

Kapsama 221 sistem çağrısı ve 547 ioctl isteği dahildir. daha bir çok sistem var
henüz uygulamaya yönelik çağrılar. Asla geri gelmeyen sistem çağrıları, örneğin çıkış(2), mevcut değil
kütüphanede ve asla olmayacak. bu exec sistem çağrıları ailesi vardır destekleniyor çünkü
bir hata olduğunda geri dönerler.

Kedi
Tam hata raporlamasıyla, varsayımsal bir "kedi" programı böyle görünebilir,
libexplain'i kullanarak.
#Dahil etmek
#Dahil etmek
#Dahil etmek
Libexplain için bir tane artı olağan şüpheliler var. (Eğer azaltmak istiyorsanız,
önişlemci yükü, belirli kullanabilirsinizisim.h> içerir.)
Statik boşluk
süreç(DOSYA *fp)
{
için (;;)
{
karakter arabelleği[4096];
size_t n =açıklama_fread_or_die(arabellek, 1, sizeof(arabellek), fp);
eğer (!n)
break;
açıkla_fwrite_or_die(arabellek, 1, n, stdout);
}
}
The süreç işlevi, bir dosya akışını standart çıktıya kopyalar. Bir hata oluşursa
okuma veya yazma için rapor edilir (ve yol adı,
error) ve komut EXIT_FAILURE ile çıkar. İzlemekten bile endişelenmiyoruz.
yol adları veya bunları çağrı yığınından geçirme.
int
main(int argc, karakter **argv)
{
için (;;)
{
int c = getopt(argc, argv, "o:");
eğer (c == EOF)
break;
anahtar (c)
{
'o' durumu:
açıklamak_freopen_or_die(optarg, "w", stdout);
break;
Bu kodun eğlenceli yanı, libexplain'in hataları bildirebilmesidir. dahil olmak üzere the yol adı Üstelik
eğer değil mi burada yapıldığı gibi açıkça stdout'u yeniden açın. endişelenmiyoruz bile
dosya adını izleme.
Varsayılan:
fprintf(stderr, "Kullanım: %ss [ -o ] ...\n",
argv[0]);
EXIT_FAILURE döndür;
}
}
eğer (isteğe bağlı == argc)
süreç(stdin);
başka
{
while (optind < argc)
{
DOSYA *fp = açıkla_fopen_or_die(argv[optind]++, "r");
süreç(fp);
açıkla_fclose_or_die(fp);
}
}
Standart çıktı örtük olarak kapatılacaktır, ancak bir hata raporunun alınması için çok geç olacaktır.
yayınlandı, bu yüzden arabelleğe alınmış G/Ç'nin henüz bir şey yazmamış olması durumunda bunu burada yapıyoruz ve
ENOSPC hatası veya başka bir şey var.
açıklamak_fflush_or_die(stdout);
EXIT_SUCCESS döndür;
}
Bu kadar. Tam hata raporlama, kodu temizle.

Rusty ölçek of arayüzey Iyilik
Bilmeyenler için, Rusty Russel'ın “Bunu Kötüye Kullanmayı Nasıl Zorlaştırırım?”
sayfa, API tasarımcıları için mutlaka okunması gereken bir sayfadır.
http://ozlabs.org/~rusty/index.cgi/tech/2008-03-30.html

10 O bulunuyor imkânsız için almak yanlış.

Hedefler yüksek, hırslı bir şekilde yüksek belirlenmelidir, yoksa onları başarıp başaracağınızı düşünmezsiniz.
sen yokken bitti.

libexplain kitaplığı, sahte işaretçileri ve diğer birçok sahte sistem çağrı parametresini algılar,
ve genellikle en zorlu koşullarda bile segfault'lardan kaçınmaya çalışır.

libexplain kitaplığı iş parçacığı için güvenli olacak şekilde tasarlanmıştır. Daha fazla gerçek dünya kullanımı muhtemelen
bunun geliştirilebileceği yerleri ortaya çıkarın.

En büyük sorun, gerçek işlev adlarının kendileriyle ilgilidir. Çünkü C yok
ad boşluklarında, libexplain kitaplığı her zaman bir açıklama_ ad öneki kullanır. bu
sembol çakışmalarını önlemek için bir sahte isim-alanı yaratmanın geleneksel yolu.
Bununla birlikte, bazı doğal olmayan isimlerle sonuçlanır.

9. The derleyici or bağlantılar olmaz izin sen almak it yanlış.

Yaygın bir hata, açıklanan_open_or_die'nin amaçlandığı yerde açıklama_open kullanmaktır.
Neyse ki, derleyici bu noktada genellikle bir tür hatası verir (Örneğin atanamaz
const char * değerini bir int değerine çevirir).

8. The derleyici irade uyarmak if sen almak it yanlış.

açıklamak_rename_or_die amaçlandığında kullanılırsa, bu, diğer
sorunlar. GCC'nin kullanışlı bir warn_unused_result işlevi özelliği vardır ve libexplain
kitaplık onu tüm açıklamaya ekler_isim yaptığınızda bir uyarı üretmek için işlev çağrıları
bu hatayı yap. Bunu şununla birleştir gcc -Whata bunu 9. seviye iyiliğe yükseltmek için.

7. The Açık kullanım is (muhtemelen) the doğru bir.

İşlev adları anlamlarını iletmek için seçilmiştir, ancak bu her zaman geçerli değildir.
başarılı. açıklarken_isim_or_öl ve açıkla_isim_on_error oldukça açıklayıcıdır,
daha az kullanılan iş parçacığı güvenli varyantların kodunu çözmek daha zordur. İşlev prototipleri,
derleyiciyi anlamaya yöneliktir ve başlık dosyalarındaki Doxygen yorumları kullanıcıya yardımcı olur
anlamaya yönelik.

6. The isim anlatır sen Nasıl için kullanım bunu.

Açıklamayı okumak özellikle önemlidir_isim_or_die "açıkla (isim yada öl)".
Tutarlı bir açıklama_ ad alanı öneki kullanmanın bazı talihsiz yan etkileri vardır.
barizlik departmanı da.

İsimlerdeki kelimelerin sırası, argümanların sırasını da gösterir. Argüman
her zaman listeler son sistem çağrısına iletilen aynı argümanlarla; herşey of onları. Eğer
Adında _errno_ görünür, argümanı her zaman sistem çağrısı argümanlarından önce gelir. Eğer
Adında _message_ görünür, iki argümanı her zaman önce gelir.

5. Do it krallar gibi yaşamaya or it irade kırılma at Çalışma süresi.

libexplain kitaplığı, sahte işaretçileri ve diğer birçok sahte sistem çağrı parametresini algılar,
ve genellikle en zorlu koşullarda bile segfault'lardan kaçınmaya çalışır. Olması gerekiyor
çalışma zamanında asla kırılmaz, ancak daha fazla gerçek dünya kullanımı şüphesiz bunu iyileştirecektir.

Bazı hata mesajları, son kullanıcılardan ziyade geliştiricilere ve bakımcılara yöneliktir, çünkü bu
hata çözümüne yardımcı olabilir. "Çalışma zamanında ara" kadar "bilgilendirici olun"
çalışma zamanı” (sistem çağrısı barfs'den sonra).

4. Takip Edin ortak kongre ve Eğer olacak almak it sağ.

C'de ad boşlukları olmadığı için, libexplain kitaplığı her zaman bir açıklama_ adı kullanır.
önek. önlemek için bir sözde ad-alanı yaratmanın geleneksel yoludur.
sembol çakışmaları

Tüm libexplain çağrısının takip eden argümanları, sistem çağrısı ile aynıdır.
tarif ediyorlar. Bu, aşağıdakilerle ortak tutarlı bir sözleşme sağlamayı amaçlamaktadır.
sistem kendilerini çağırıyor.

3. Okumak the belgeleme ve Eğer olacak almak it sağ.

libexplain kitaplığı, her biri için eksiksiz Doxygen belgelerine sahip olmayı amaçlar.
genel API çağrısı (ve dahili olarak da).

MESAJ İÇERİK


libexplain üzerinde çalışmak, arabanız açıkken alt tarafına bakmak gibidir.
tamircideki vinç. Altında çirkin şeyler var, ayrıca çamur ve pislik ve
kullanıcılar nadiren görür. İyi bir hata mesajının bilgilendirici olması gerekir, hatta
alt tarafa çok sık bakmak zorunda kalmayacak kadar şanslı ve ayrıca
telefonda kullanıcının açıklamasını dinleyen tamirci için bilgilendirici. Bu
kolay iş yok.

İlk örneğimizi tekrar ziyaret edersek, kod libexplain kullanıyorsa şunu ister:
int fd =açıklama_open_or_die("bir şey/bir şey", O_RDONLY, 0);
bunun gibi bir hata mesajıyla başarısız olacak
open(pathname = "some/file", flags = O_RDONLY) başarısız oldu, Böyle bir dosya veya dizin yok
(2, ENOENT) çünkü geçerli dizinde "bazı" dizin yok
Bu üç parçaya ayrılıyor
sistem çağrısı başarısız oldu, Sistem hatası Çünkü
açıklama

önce Çünkü
Mesajın “çünkü”den önceki kısmını aşırı teknikten teknik olmayana kadar görmek mümkündür.
teknik kullanıcılar, çoğunlukla sistemin doğru bir şekilde yazdırılmasının bir sonucu olarak
hata mesajının başlangıcı. Ve benziyor iz(1) çıkış, bonus geek için
puan.
open(pathname = "some/file", flags = O_RDONLY) başarısız oldu, Böyle bir dosya veya dizin yok
(2, ENOENT)
Hata mesajının bu kısmı, kodu yazarken geliştirici için çok önemlidir.
ve hata raporlarını okuması ve içindeki hataları düzeltmesi gereken bakıcı için eşit derecede önemlidir.
kod. Tam olarak neyin başarısız olduğunu söylüyor.

Bu metin kullanıcıya sunulmazsa, kullanıcı onu kopyalayıp yapıştıramaz.
hata raporu ve eğer hata raporunda değilse, bakıcı gerçekte ne olduğunu bilemez
yanlış.

Sıklıkla teknik personel kullanacak iz(1) veya demet(1) bu kesin bilgiyi almak için, ancak
hata raporları okunurken bu cadde açık değildir. Hata bildiricinin sistemi çok uzak
uzakta ve şimdiye kadar çok farklı bir durumda. Bu nedenle, bu bilgilerin dosyada olması gerekir.
hata raporu, yani hata mesajında ​​olması gerektiği anlamına gelir.

Sistem çağrısı gösterimi ayrıca mesajın geri kalanına bağlam sağlar. Gerekirse
ortaya çıkarsa, rahatsız edici sistem çağrısı argümanına açıklamada ismiyle atıfta bulunulabilir.
"çünkü"den sonra. Ek olarak, tüm dizeler tamamen alıntılanır ve C dizelerinden kaçınılır, bu nedenle
gömülü yeni satırlar ve yazdırılmayan karakterler, kullanıcının terminalinin gitmesine neden olmaz
samanlık.

The Sistem hatası içinden ne çıkıyor korku(2), artı hata sembolü. sabırsız ve
uzman sistem yöneticileri bu noktada okumayı bırakabilir, ancak yazarın bugüne kadarki deneyimi
daha fazla okumanın ödüllendirici olduğunu. (Eğer ödüllendirici değilse, muhtemelen
geliştirilebilir libexplain. Elbette kod katkıları memnuniyetle karşılanmaktadır.)

Sonra Çünkü
Bu, teknik olmayan kullanıcılara yönelik hata mesajının bir kısmıdır. ötesinde görünüyor
basit sistem çağrı argümanları ve daha spesifik bir şey arar.
geçerli dizinde "bazı" dizin yok
Bu kısım, hatanın yakın nedenini sade bir dille açıklamaya çalışır ve
uluslararasılaşmanın gerekli olduğu buradadır.

Genel olarak politika, kullanıcının mümkün olduğunca fazla bilgi içermesidir.
aramaya gitmesi gerekmez (ve hata raporunun dışında bırakmaz).

Uluslararasılaşma
libexplain kitaplığındaki hata mesajlarının çoğu uluslararası hale getirildi. Orası
Henüz yerelleştirme yok, bu nedenle açıklamaları ana dilinizde istiyorsanız,
lütfen katkıda bulunun.

Yukarıdaki "çoğu" niteleyicisi, kavram kanıtının
uygulama uluslararasılaştırma desteğini içermiyordu. Kod tabanı oluyor
genellikle mesajların yeniden düzenlenmesinin bir sonucu olarak aşamalı olarak gözden geçirilir, böylece her hata
mesaj dizisi kodda tam olarak bir kez görünür.

Bölümlerini bir araya getirmesi gereken diller için hazırlık yapılmıştır.
sistem çağrısı başarısız oldu, Sistem hatası Çünkü açıklama
yerelleştirilmiş hata mesajlarında doğru dilbilgisi için farklı sıralarda.

Postmortem
Bir programın libexplain'i henüz kullanmadığı ve kullanamayacağınız zamanlar vardır. iz(1)
herhangi biri. bir açıklamak(1) için kullanılabilecek libexplain ile birlikte verilen komut
Temel sistemin durumu çok fazla değişmediyse, hata mesajlarını deşifre edin.
$ açıklamak adını değiştirmek foo /tmp/bar/baz -e ENOENT
rename(oldpath = "foo", newpath = "/tmp/bar/baz") başarısız oldu, Böyle bir dosya veya dizin yok
(2, ENOENT) çünkü yeni yolda "bar" dizini yok "/ Tmp" dizin
$
Sistem çağrısı bağımsız değişken adını kullanarak yol belirsizliğinin nasıl çözüldüğünü not edin. Nın-nin
Tabii ki, hatayı ve sistem çağrısını bilmeniz gerekir. açıklamak(1) faydalı olmak. olarak
bir yana, bu, libexplain otomatik test takımının bunu doğrulamak için kullandığı yollardan biridir.
libexplain'de çalışıyor

Felsefe
"Bana aramayı bilmediğim şeyler de dahil her şeyi anlat."

Kitaplık, statik olarak bağlandığında yalnızca
aslında kullanım bağlantılı olacaktır. Bu, kaynak dosya başına bir işleve sahip olarak elde edilir,
mümkün olduğunda.

Daha fazla bilgi sağlamak mümkün olduğunda, libexplain bunu yapacaktır. kullanıcı ne kadar az
kendilerinin izini sürmeli, o kadar iyi. Bu, UID'lere aşağıdakilerin eşlik ettiği anlamına gelir:
kullanıcı adı, GID'lere grup adı eşlik eder, PID'lere süreç eşlik eder
ad, dosya tanımlayıcıları ve akışlara yol adı eşlik eder, vb.

Yolları çözerken, bir yol bileşeni yoksa, libexplain benzer arayacaktır.
isimler, yazım hatalarına alternatifler önermek için.

libexplain kitaplığı mümkün olduğu kadar az yığın kullanmaya çalışır ve genellikle hiç kullanmaz. Bu
bazen mümkün olsa da, süreç durumunu bozmaktan kaçınmak için
kaçınılmaz.

libexplain kitaplığı, global değişkenlerden kaçınarak iş parçacığı güvenli olmaya çalışır.
mümkün olduğunca yığın üzerinde durum. Tek bir ortak mesaj arabelleği vardır ve
onu kullanan işlevlerin iş parçacığı için güvenli olmadığı belgelenmiştir.

libexplain kitaplığı, bir işlemin sinyal işleyicilerini rahatsız etmez. Bu yapar
bir işaretçinin bir meydan okumayı ayırıp ayırmayacağını belirlemek, ancak imkansız değil.

Bilgi bir sistem çağrısı yoluyla mevcut olduğunda ve ayrıca bir / proc
giriş, sistem çağrısı tercih edilir. Bu, sürecin durumunu bozmamak içindir.
Dosya tanımlayıcıların bulunmadığı zamanlar da vardır.

libexplain kitaplığı, büyük dosya desteği ile derlenmiştir. büyük/küçük yok
şizofreni. Bunun API'deki argüman türlerini etkilediği ve hatanın verileceği durumlarda
gerekli büyük dosya tanımları yoksa.

DÜZELTME: Dosya sistemi kotalarının kodda işlendiğinden emin olmak için çalışma gerekiyor. Bu
bazıları için geçerlidir getrlimit(2) sınırları da.

Akraba yollarının bilgilendirici olmadığı durumlar vardır. Örneğin: sistem cinleri,
sunucular ve arka plan işlemleri. Bu durumlarda, hatada mutlak yollar kullanılır.
Açıklamalar.

PATH Çözüm


Kısa versiyon: bkz. yol_çözünürlüğü(7).

Uzun versiyon: Çoğu kullanıcı hiç duymadı yol_çözünürlüğü(7) ve birçok ileri düzey kullanıcı
hiç okumadım. İşte açıklamalı bir sürüm:

adım 1: Başlama of the çözüm süreç
Yol adı eğik çizgi (“/”) karakteriyle başlıyorsa, başlangıç ​​arama dizini
çağıran işlemin kök dizini.

Yol adı eğik çizgi ("/") karakteriyle başlamıyorsa, başlangıç ​​araması
çözümleme sürecinin dizini, sürecin geçerli çalışma dizinidir.

adım 2: yürüyüş boyunca the yol
Geçerli arama dizinini, başlangıç ​​arama dizinine ayarlayın. Şimdi, her olmayan için
bir bileşenin eğik çizgi ("/") ile sınırlandırılmış bir alt dize olduğu yol adının son bileşeni
karakter, bu bileşen geçerli arama dizininde aranır.

İşlemin geçerli arama dizininde arama izni yoksa, bir EACCES
hata döndürülür ("İzin reddedildi").
open(pathname = "/home/archives/.ssh/private_key", flags = O_RDONLY) başarısız oldu,
İşlemin arama izni olmadığı için izin reddedildi (13, EACCES)
"/home/archives/.ssh" dizinine, işlem etkin GID 1000
"pmiller", dizin sahibi 1001 "arşivleri" ile eşleşmiyor, bu nedenle sahip
"rwx" izin modu yok sayılır, diğer izin modu "---" ve
işlem ayrıcalıklı değil (DAC_READ_SEARCH özelliğine sahip değil)

Bileşen bulunamazsa, bir ENOENT hatası döndürülür ("Böyle bir dosya veya dizin yok").
unlink(pathname = "/home/microsoft/rubbish") başarısız oldu, Böyle bir dosya veya dizin yok (2,
ENOENT) çünkü yol adında "microsoft" dizini yok "/ Ana Sayfa" dizin

Ayrıca, yol adlarını yanlış yazdıklarında, önerilerde bulunduklarında kullanıcılar için bir miktar destek vardır.
ENOENT döndürülür:
open(pathname = "/user/include/fcntl.h", flags = O_RDONLY) başarısız oldu, Böyle bir dosya yok veya
dizin (2, ENOENT) çünkü "/" yol adında "kullanıcı" dizini yok
dizini, bunun yerine "usr" dizini mi demek istediniz?

Bileşen bulunursa, ancak bir dizin veya sembolik bir bağlantı değilse, bir ENOTDIR
hata döndürülür ("Bir dizin değil").
open(pathname = "/home/pmiller/.netrc/lca", flags = O_RDONLY) başarısız oldu, Değil
dizin (20, ENOTDIR) çünkü yol adındaki ".netrc" normal dosyası
"/home/pmiller" dizini değilken dizin olarak kullanılıyor

Bileşen bulunursa ve bir dizinse, mevcut arama dizinini buna ayarlarız.
dizini ve sonraki bileşene gidin.

Bileşen bulunursa ve bir sembolik bağ (symlink) ise, önce bu semboliği çözeriz.
bağlantı (geçerli arama dizini başlangıç ​​arama dizini olarak). Hata üzerine, bu
hata döndürülür. Sonuç bir dizin değilse, bir ENOTDIR hatası döndürülür.
unlink(pathname = "/tmp/dangling/rubbish") başarısız oldu, Böyle bir dosya veya dizin yok (2,
ENOENT) çünkü yol adındaki "sarkan" sembolik bağ "/ Tmp" dizin
var olmayan "hiçbir yerde" anlamına gelir
Sembolik bağlantının çözümü başarılıysa ve bir dizin döndürürse, geçerli
bu dizine dizini arayın ve sonraki bileşene gidin. Şuna dikkat edin:
Buradaki çözüm süreci özyinelemeyi içerir. Çekirdeği yığına karşı korumak için
taşma ve ayrıca hizmet reddine karşı koruma sağlamak için maksimum limitler vardır.
özyineleme derinliği ve takip edilen maksimum sembolik bağlantı sayısı. Bir ELOOP hatası
maksimum değer aşıldığında döndürülür ("Çok fazla sembolik bağlantı düzeyi").
open(pathname = "/tmp/dangling", flags = O_RDONLY) başarısız oldu, Çok fazla seviye
sembolik linkler (40, ELOOP) çünkü sembolik bir link döngüsü ile karşılaşıldı.
yol adı, "/tmp/dangling" ile başlar
Çok fazla sembolik bağlantı varsa, ancak hiçbir şey yoksa bir ELOOP veya EMLINK hatası almak da mümkündür.
döngü tespit edildi.
open(pathname = "/tmp/rabbit-hole", flags = O_RDONLY) başarısız oldu, Çok fazla seviye
sembolik bağlar (40, ELOOP) çünkü çok fazla sembolik bağla karşılaşıldı.
yol adı (8)
Gerçek sınırın nasıl yazdırıldığına da dikkat edin.

adım 3: bulmak the son giriş
Yol adının son bileşeninin aranması, diğer tüm bileşenlerinki gibi gider.
bileşenleri, önceki adımda açıklandığı gibi, iki farkla:

(i) Son bileşenin bir dizin olması gerekmez (en azından yol çözünürlüğü
süreç söz konusudur. Bir dizin veya dizin dışı olması gerekebilir, çünkü
özel sistem çağrısının gereksinimleri).

(Ii)
Nihai bileşenin bulunamaması mutlaka bir hata değildir; belki biz sadece
onu yaratmak. Son girişin işlenmesine ilişkin ayrıntılar,
belirli sistem çağrılarının manuel sayfaları.

(Iii)
Sembolik bir bağlantı ise, son bileşenle ilgili bir sorun olması da mümkündür.
ve takip edilmemelidir. Örneğin, açık(2) O_NOFOLLOW işareti:
open(pathname = "a-symlink", flags = O_RDONLY | O_NOFOLLOW) başarısız oldu, Çok fazla seviye
sembolik bağlantılar (ELOOP) çünkü O_NOFOLLOW belirtildi ancak yol adı bir
sembolik bağlantı

(Iv)
Kullanıcıların yol adlarını yazarken hata yapması yaygındır. libexplain kitaplığı
ENOENT döndürüldüğünde önerilerde bulunmaya çalışır, örneğin:
open(pathname = "/usr/include/filecontrl.h", flags = O_RDONLY) başarısız oldu, Böyle bir dosya yok veya
dizin (2, ENOENT) çünkü yol adında "filecontrl.h" normal dosyası yok
"/ usr / include" dizini, bunun yerine "fcntl.h" normal dosyasını mı kastettiniz?

(v) Nihai bileşenin başka bir şey olması da mümkündür.
normal dosya:
readlink(pathname = "sadece-bir dosya", data = 0x7F930A50, data_size = 4097) başarısız oldu,
Yol adı sembolik bir bağlantı değil, normal bir dosya olduğundan geçersiz argüman (22, EINVAL)

(Vi)
FIXME: "t" bitinin işlenmesi.

Sınırları
Yol adları ve dosya adlarıyla ilgili bir takım sınırlamalar vardır.

Yol adı uzunluk sınırı
Yol adları için bir maksimum uzunluk vardır. Yol adı (veya bazı ara
sembolik bağları çözerken elde edilen yol adı) çok uzun, bir ENAMETOOLONG
hata döndürülür ("Dosya adı çok uzun"). Sistem sınırının nasıl dahil edildiğine dikkat edin
hata mesajında.
open(yol adı = "çok uzun", flags = O_RDONLY) başarısız oldu, Dosya adı çok uzun (36,
ENAMETOOLONG) çünkü yol adı sistem maksimum yol uzunluğunu aşıyor (4096)

Dosya adı uzunluk sınırı
Bazı Unix türevleri, her yol bileşenindeki bayt sayısında bir sınıra sahiptir.
Bazıları bununla sessizce ilgilenir, bazıları ise ENAMETOOLONG verir; libexplain
kütüphane kullanımları yol bilgisi(3) hangisini söylemek için _PC_NO_TRUNC. Bu hata oluşursa,
libexplain kütüphanesi hata mesajında ​​limiti belirtecektir, limit
şuradan alınmıştır yol bilgisi(3) _PC_NAME_MAX. Sistem sınırının nasıl dahil edildiğine dikkat edin
hata mesajında.
open(yol adı = "system7/only-14-karakter", bayraklar = O_RDONLY) başarısız oldu, Dosya
ad çok uzun (36, ENAMETOOLONG) çünkü "yalnızca 14 karaktere sahipti" bileşeni
sistem sınırından daha uzun (14)

Boş yol adı
Orijinal Unix'te, boş yol adı geçerli dizine atıfta bulunur.
Günümüzde POSIX, boş bir yol adının başarıyla çözülmemesi gerektiğine karar veriyor.
open(pathname = "", flags = O_RDONLY) başarısız oldu, Böyle bir dosya veya dizin yok (2,
ENOENT) çünkü POSIX, boş bir yol adının çözülmemesi gerektiğine karar verir.
başarılı olarak

İzinler
Bir dosyanın izin bitleri, üç bitlik üç gruptan oluşur. ilk grup
üç, arama işleminin etkin kullanıcı kimliği, arama işleminin sahip kimliğine eşit olduğunda kullanılır.
dosya. Üçlü ikinci grup, dosyanın grup kimliği aşağıdakilerden birine eşit olduğunda kullanılır.
çağrı sürecinin etkin grup kimliği veya çağrı sürecinin tamamlayıcı grup kimliklerinden biridir.
arama süreci. İkisi de geçerli olmadığında üçüncü grup kullanılır.
open(yol adı = "/ Etc / passwd", flags = O_WRONLY) başarısız oldu, İzin reddedildi (13,
EACCES) çünkü işlemin "passwd" normaline yazma izni yoktur.
yol adındaki dosya "/ Etc" dizini, işlem etkin UID 1000 "pmiller"
normal dosya sahibi 0 "root" ile eşleşmiyor, bu nedenle sahip izin modu "rw-"
yoksayılır, diğerleri izin modu "r--"dir ve işlem ayrıcalıklı değildir
(DAC_OVERRIDE özelliğine sahip değil)
Çoğu kullanıcı bunu bilmediğinden, bu açıklamaya önemli ölçüde yer verilmiştir.
izin sisteminin nasıl çalıştığıdır. Özellikle: sahip, grup ve diğer
izinler özeldir, birlikte “VEYA” değildirler.

GARİP VE İLGİNÇ SİSTEM ARAMALAR


Her sistem çağrısı için belirli bir hata işleyici yazma işlemi genellikle
ilginç tuhaflıklar ve sınır koşulları veya belirsiz hata(3) değerleri.

ENOMEDYUM, Yok hayır orta bulundu
Bu makalenin başlığının kaynağı bir CD kopyalama eylemiydi.
$ dd if=/dev/cdrom of=fubar.iso
dd: “/dev/cdrom” açılıyor: Ortam bulunamadı
$
Yazar, bilgisayarının kendisine neden medyum diye bir şey olmadığını söylediğini merak etti.
orta. Anadili İngilizce olan çok sayıda kişinin
"medium" un tekil olduğunu, "medya"nın çoğul olduğunun farkında bile, dize
tarafından iade edildi korku(3) ENOMEDIUM için neredeyse tamamen arınmış olacak kadar kısa ve öz
içeriği.

Ne zaman açık(2) ENOMEDIUM'u döndürür, libexplain kitaplığının bir
Bu, sürücünün türüne bağlı olarak çok az. Örneğin:
...çünkü disket sürücüsünde disk yok
...çünkü CD-ROM sürücüsünde disk yok
...çünkü teyp sürücüsünde teyp yok
... çünkü kart okuyucuda hafıza çubuğu yok

Ve böylece oldu...
open(pathname = "/dev/cdrom", flags = O_RDONLY) başarısız oldu, Ortam bulunamadı (123,
ENOMEDIUM) çünkü CD-ROM sürücüsünde bir disk görünmüyor
Yazarın daha önce bilmediği hile, cihazı kullanarak cihazı açmaktı.
O_NONBLOCK bayrağı, içinde ortam olmayan bir sürücüyü açmanıza izin verir. sen o zaman
cihaza özel sorun ioctl(2) ne halt olduğunu anlayana kadar istekler. (Değil
bunun POSIX olup olmadığından emin olun, ancak BSD ve Solaris'te de bu şekilde çalışıyor gibi görünüyor.
the Wodim(1) kaynaklar.)

Ayrıca bağlam içinde "disk" ve "disk"in farklı kullanımlarına da dikkat edin. CD standardı kökenli
Fransa'da, ama diğer her şeyin bir "k"si var.

EFSANE, Kötü adres
İşaretçi argümanı alan herhangi bir sistem çağrısı EFAULT döndürebilir. libexplain kitaplığı
Hangi argümanın hatalı olduğunu anlayabilir ve bunu süreci bozmadan yapar.
(veya iş parçacığı) sinyal işleme.

Kullanılabilir olduğunda, minör(2) sistem çağrısı, bellek bölgesinin geçerli olup olmadığını sormak için kullanılır.
Üç sonuç döndürebilir: eşlenmiş ancak fiziksel bellekte değil, eşlenmiş ve fiziksel olarak
bellek ve eşlenmemiş. Bir işaretçinin geçerliliğini test ederken, ilk ikisi “evet”tir.
ve sonuncusu “hayır”.

C dizelerini kontrol etmek daha zordur, çünkü bir işaretçi ve bir boyut yerine sadece
bir işaretçi var. Boyutu belirlemek için NUL'u bulmamız gerekecek ve bu
segfault, yakalama-22.

Bu soruna geçici bir çözüm bulmak için libexplain kitaplığı şunları kullanır: lstat(2) sistem çağrısı (bilinen bir
iyi ikinci argüman) geçerlilik için C dizelerini test etmek için. Bir başarısızlık dönüşü && errno == EFAULT
"hayır"dır ve başka her şey "evet"tir. Bu, elbette dizeleri PATH_MAX ile sınırlar
karakterler, ancak bu genellikle libexplain kitaplığı için bir sorun değildir, çünkü bu
neredeyse her zaman umursadığı en uzun dizeler.

EMDOSYA, Çok çok açık Dosyaları
Bu hata, bir işlem zaten maksimum sayıda açık dosya tanımlayıcıya sahip olduğunda oluşur.
Gerçek sınır yazdırılacaksa ve libexplain kitaplığı bunu denerse, açamazsınız.
içinde bir dosya / proc ne olduğunu okumak için.
open_max = sysconf(_SC_OPEN_MAX);
Bu çok zor değil, bir sysconf(3) limiti elde etme yolu.

DOSYA, Çok çok açık Dosyaları in sistem
Bu hata, toplam açık dosya sayısındaki sistem sınırı aşıldığında oluşur.
ulaşmış. Bu durumda kullanışlı değil sysconf(3) limiti elde etmenin yolu.

Daha derine inildiğinde, kişi Linux'ta bir / proc okuyabileceğimiz giriş
bu değeri elde edin. Yakalama‐22: dosya tanımlayıcılarımız tükendi, bu nedenle bir dosyayı açamıyoruz.
limiti okuyun.

Linux'ta onu elde etmek için bir sistem çağrısı vardır, ancak [e]glibc sarmalayıcı işlevi yoktur, bu nedenle
hepsini çok dikkatli yapmalısın:
ve kazandırdı
açıklamak_maxfile(void)
{
#ifdef__linux__
struct __sysctl_args argümanları;
int32_t maksimum dosya;
size_t maksimum dosya_boyutu = sizeof(maksimum dosya);
int isim[] = { CTL_FS, FS_MAXFILE };
memset(&args, 0, sizeof(struct __sysctl_args));
args.name = isim;
args.nlen = 2;
args.oldval = &maxfile;
args.oldlenp = &maxfile_size;
if (syscall(SYS__sysctl, &args) >= 0)
maxfile döndür;
#endif
dönüş -1;
}
Bu, mümkün olduğunda sınırın hata mesajına dahil edilmesine izin verir.

EİNVAL "Geçersiz argüman" vs ENOSİSLER "İşlev değil uygulandı”
Desteklenmeyen eylemler (ör. Sembolik bağ(2) bir FAT dosya sisteminde) rapor edilmez
sürekli olarak bir sistem çağrısından diğerine. EINVAL veya
ENOSYS geri döndü.

Sonuç olarak, bu hata durumlarının doğru olması için özellikle dikkat edilmesi gerekir.
EINVAL, bir veya daha fazla sistem çağrısı argümanıyla ilgili sorunlara da atıfta bulunabileceğinden.

not o hata(3) is değil her zaman set
Nasıl ve ne şekilde yapılacağını belirlemek için [e]glibc kaynaklarını okumanın gerekli olduğu zamanlar vardır.
bazı sistem çağrıları için hatalar döndürüldüğünde.

feof(3) dosya yok(3)
Genellikle bu işlevlerin bir hata döndüremeyeceği varsayılır. Bu sadece eğer doğruysa
the dere argüman geçerlidir, ancak geçersiz bir argüman tespit edebilirler.
Işaretçi.

fpathconf(3) yol bilgisi(3)
Dönüş değeri fpathconf(2) ve yol bilgisi(2) yasal olarak -1 olabilir, yani
görmek için gerekli hata(3) açıkça ayarlanmıştır.

ioctl(2)
Dönüş değeri ioctl(2) yasal olarak -1 olabilir, bu nedenle
hata(3) açıkça ayarlanmıştır.

okumak(3)
Dönüş değeri okumak(3) hem hatalar hem de dosya sonu için NULL'dur. Bu
görmek için gerekli hata(3) açıkça ayarlanmıştır.

setbuf(3) ayar tamponu(3) setlinebuf(3) setvbuf(3)
Bu işlevlerin sonuncusu hariç tümü void döndürür. Ve setvbuf(3) yalnızca şu şekilde belgelenmiştir:
hata durumunda "sıfır olmayan" döndürme. olup olmadığını görmek gereklidir hata(3) açıkça
ayarlayın.

strtod(3) strtol(3) strold(3) strtoll(3) strtoul(3) strtoull(3)
Bu işlevler hata durumunda 0 döndürür, ancak bu aynı zamanda geçerli bir dönüş değeridir. Bu
görmek için gerekli hata(3) açıkça ayarlanmıştır.

ungget(3)
ANSI C standardı tarafından yalnızca tek bir yedekleme karakteri zorunlu kılınırken,
[e]glibc daha fazlasına izin veriyor... ama bu ENOMEM ile başarısız olabileceği anlamına geliyor. Yapabilir
ayrıca EBADF ile başarısız olursa fp sahte. En zoru, eğer EOF'u bir hatadan geçerseniz
dönüş gerçekleşir, ancak errno ayarlanmaz.

libexplain kitaplığı tüm bu hataları doğru bir şekilde algılar.
hata değerleri, eğer varsa, yetersiz belgelenmiştir.

ENOSPC, Yok hayır uzay sol on cihaz
Bu hata bir dosya sistemindeki bir dosyaya atıfta bulunduğunda, libexplain kitaplığı bağlamayı yazdırır.
sorunlu dosya sisteminin noktası. Bu, hatanın kaynağını çok fazla yapabilir
daha net.
write(fildes = 1 "example", data = 0xbfff2340, data_size = 5) başarısız oldu, Boş alan kalmadı
aygıtta (28, ENOSPC) çünkü dosya sistemi ("/ Ana Sayfa") yok
veri için daha fazla alan
Daha özel cihaz desteği eklendikçe, hata mesajlarının cihazı içermesi bekleniyor.
cihazın adı ve gerçek boyutu.

EROFS, Sadece oku dosya sistem
Bu hata bir dosya sistemindeki bir dosyaya atıfta bulunduğunda, libexplain kitaplığı bağlamayı yazdırır.
sorunlu dosya sisteminin noktası. Bu, hatanın kaynağını çok fazla yapabilir
daha net.

Daha özel cihaz desteği eklendikçe, hata mesajlarının cihazı içermesi bekleniyor.
isim ve tip.
open(pathname = "/dev/fd0", O_RDWR, 0666) başarısız oldu, Salt okunur dosya sistemi (30, EROFS)
diskette yazmaya karşı koruma sekmesi bulunduğundan

...çünkü bir CD-ROM yazılabilir değil
...çünkü hafıza kartında yazmaya karşı koruma sekmesi seti var
...çünkü ½ inçlik manyetik bantta yazma halkası yoktur

adını değiştirmek
The adını değiştirmek(2) sistem çağrısı, bir dosyanın yerini veya adını değiştirmek, onu taşımak için kullanılır.
Gerekirse dizinler arasında. Hedef yol adı zaten mevcutsa,
atomik olarak değiştirilir, böylece başka bir işlemin yapmaya çalıştığı hiçbir nokta yoktur.
erişin, onu eksik bulacak.

Ancak sınırlamalar vardır: bir dizini yalnızca diğerinin üzerine yeniden adlandırabilirsiniz.
hedef dizin boş değilse dizin.
rename(oldpath = "foo", newpath = "bar") başarısız oldu, Dizin boş değil (39,
ENOTEMPTY) çünkü newpath boş bir dizin değildir; yani, girişleri içerir
ondan başka "." ve ".."
Dizin olmayan bir dizinin üstündeki bir dizini de yeniden adlandıramazsınız.
rename(oldpath = "foo", newpath = "bar") başarısız oldu, Bir dizin değil (20, ENOTDIR)
çünkü oldpath bir dizindir, ancak newpath bir dizin değil normal bir dosyadır
Tersine de izin verilmez
rename(oldpath = "foo", newpath = "bar") başarısız oldu, Bir dizin mi (21, EISDIR)
çünkü newpath bir dizindir, ancak oldpath bir dizin değil normal bir dosyadır

Bu, elbette, libexplain kitaplığının işini daha karmaşık hale getirir, çünkü
bağlantısını kaldırmak(2) veya rmdir(2) sistem çağrısı dolaylı olarak şu şekilde çağrılır: adını değiştirmek(2) ve böylece tüm
bağlantısını kaldırmak(2) veya rmdir(2) hatalar da tespit edilmeli ve ele alınmalıdır.

dup2
The dup2(2) sistem çağrısı, dosyaya başvuran ikinci bir dosya tanımlayıcısı oluşturmak için kullanılır.
ilk dosya tanımlayıcı ile aynı nesne. Tipik olarak bu, kabuk girdisini uygulamak için kullanılır
ve çıktı yönlendirme.

İşin eğlenceli yanı, tıpkı adını değiştirmek(2) bir dosyanın üstündeki bir dosyayı atomik olarak yeniden adlandırabilir
mevcut dosyayı ve eski dosyayı kaldırın, dup2(2) bunu zaten açık bir dosyada yapabilir
tanımlayıcı.

Bir kez daha, bu, libexplain kitaplığının işini daha karmaşık hale getirir, çünkü kapat(2)
sistem çağrısı dolaylı olarak çağrılır dup2(2) ve böylece hepsi kapat(2)'nin hataları olmalıdır
tespit edilip işlendi.

MACERALAR IN IOCTL DESTEK


The ioctl(2) sistem çağrısı, aygıt sürücüsü yazarlarına aşağıdakilerle iletişim kurmanın bir yolunu sağlar:
mevcut çekirdek API'sine uymayan kullanıcı alanı. Görmek ioctl_list(2).

şifre çözme Talep et Rakamlarla
Yüzeysel bir bakışla ioctl(2) arayüz, büyük ama sınırlı gibi görünüyor
olası sayısı ioctl(2) istekler. Her biri farklı ioctl(2) istek etkindir
başka bir sistem çağrısı, ancak herhangi bir tür güvenliği olmadan - derleyici bir
programcı bunları doğru anlıyor. Bu muhtemelen arkasındaki motivasyondu tcflush(3) ve
arkadaşlar.

İlk izlenim, şifreyi çözebileceğinizdir. ioctl(2) büyük bir anahtar kullanan istekler
Beyan. Bunun mümkün olmadığı ortaya çıkıyor çünkü kişi bunun mümkün olmadığını çok hızlı bir şekilde keşfediyor.
çeşitli tanımlamaları tanımlayan gerekli tüm sistem başlıklarını dahil etmek imkansızdır. ioctl(2)
çünkü birbirleriyle iyi geçinmekte zorlanırlar.

Daha derin bir bakış, bir dizi "özel" istek numarası ve cihaz olduğunu ortaya çıkarır.
sürücü yazarlarının bunları kullanmaları teşvik edilir. Bu, çok daha büyük bir olasılık olduğu anlamına gelir.
belirsiz istek numaralarına sahip istekler kümesi, hemen belirgindir. Ayrıca,
bazı tarihsel belirsizlikler de var.

Anahtarın pratik olmadığını zaten biliyorduk, ancak şimdi
uygun istek adı ve açıklaması, yalnızca istek numarasını değil, aynı zamanda
ayrıca dosya tanımlayıcısı.

Uygulanması ioctl(2) libexplain kitaplığı içindeki destek, bir tabloya sahip olmaktır.
işaretçiler ioctl(2) talep tanımlayıcıları. Bu tanımlayıcıların her biri isteğe bağlı bir
bir anlam ayrımı işlevine işaretçi.

Her istek aslında ayrı bir kaynak dosyada uygulanır, böylece gerekli
include dosyaları başkalarıyla iyi oynama zorunluluğundan kurtulur.

Temsil
libexplain kitaplığının arkasındaki felsefe, olabildiğince fazla bilgi sağlamaktır.
sistem çağrısının doğru bir temsili de dahil olmak üzere mümkündür. Bu durumuda
ioctl(2) bu, doğru istek numarasının (ada göre) ve ayrıca doğru (veya
en azından yararlı) üçüncü argümanın temsili.

The ioctl(2) prototip şöyle görünür:
int ioctl(int dosyalar, int istek, ...);
hangi tip güvenlik alarmlarınızın çalması gerekir. [e]glibc için dahili, bu döndürülür
çeşitli biçimlerde:
int __ioctl(int dosyalar, int istek, uzun argüman);
int __ioctl(int dosyalar, int istek, geçersiz *arg);
ve Linux çekirdek sistem çağrısı arayüzünün beklediği
asmlinkage uzun sys_ioctl(işaretsiz int dosyaları, işaretsiz int isteği, işaretsiz uzun
argüman);
Üçüncü argümanın aşırı değişkenliği, libexplain kitaplığı
bu üçüncü argümanın bir temsilini yazdırmaya çalışır. Ancak, istek numarası bir kez
libexplain kitaplığının ioctl tablosundaki her girişin bir
özel print_data işlevi (OO manuel olarak yapılır).

açıklamalar
Kullanılacak açıklamayı belirlemede daha az sorun vardır. Bir kez istek numarası
belirginleştirildi, libexplain kitaplığının ioctl tablosundaki her girişin özel bir
print_explanation işlevi (yine, OO manuel olarak yapılır).

2. ve 3. bölüm sistem çağrılarının aksine, çoğu ioctl(2) isteklerde hata yok
belgelendi. Bu, iyi hata açıklamaları vermek için kernel okumak gerektiği anlamına gelir.
keşfedilecek kaynaklar

· ne hata(3) değerler döndürülebilir ve

· her hatanın nedeni.

Çekirdekle birlikte gönderilen işlev çağrısının OO doğası nedeniyle, okumanız gerekir
herşey bunu uygulayan kaynaklar ioctl(2) istek, yalnızca genel uygulama değil. o
farklı çekirdeklerin farklı hata numaralarına sahip olması ve ustaca
farklı hata nedenleri.

EİNVAL vs ENOTİ
durum daha da vahim ioctl(2) EINVAL ile sistem çağrılarından daha fazla istek ve
ENOTY her ikisi de bir ioctl(2) istek şu durumda uygun değil
bağlamda ve bazen ENOSYS, ENOTSUP ve EOPNOTSUPP (soketler için kullanılması amaçlanmıştır) olarak
kuyu. Linux çekirdek kaynaklarında ilerici bir gelişmeye işaret eden yorumlar var.
temizlik yapılıyor. Ekstra kaos için BSD, karışıklığa ENOIOCTL ekler.

Sonuç olarak, bu hata durumlarının doğru olması için özellikle dikkat edilmesi gerekir.
EINVAL, bir veya daha fazla sistem çağrısı argümanıyla ilgili sorunlara da atıfta bulunabileceğinden.

intptr_t
C99 standardı, herhangi bir işaretçiyi tutabilmesi garanti edilen bir tamsayı türü tanımlar.
temsil kaybı olmadan.

Yukarıdaki fonksiyon sistem çağrısı prototipi daha iyi yazılır
long sys_ioctl(imzasız int dosyaları, imzasız int isteği, intptr_t arg);
Sorun, aygıta özgü veya dosya sistemine özgü tarafından indüklenen bilişsel uyumsuzluktur.
ioctl(2) aşağıdakiler gibi uygulamalar:
uzun vfs_ioctl(yapı dosyası *filp, imzasız int cmd, imzasız uzun argüman);
Çoğunluğu ioctl(2) isteklerin aslında bir int *arg üçüncü argümanı vardır. Ama sahip olmak
beyan edilen uzun yol, kodun bunu uzun *arg olarak ele almasına neden olur. Bu 32 bitte zararsızdır
(sizeof(long) == sizeof(int)) ama 64 bit üzerinde kötü (sizeof(long) != sizeof(int))).
Endianlığa bağlı olarak, beklediğiniz değeri alırsınız veya almazsınız, ancak her zaman almak
bir hafıza karalaması veya yığın karalaması da.

Bütün bunları şöyle yazmak
int ioctl(int dosyalar, int istek, ...);
int __ioctl(int dosyalar, int istek, intptr_t argüman);
long sys_ioctl(imzasız int dosyaları, imzasız int isteği, intptr_t arg);
uzun vfs_ioctl(yapı dosyası *filp, imzasız int cmd, intptr_t arg);
tamsayının yalnızca neredeyse olan bir miktarı temsil eden bir tam sayı olduğunu vurgular.
her zaman ilgisiz bir işaretçi türü.

SONUÇ


libexplain kullanın, kullanıcılarınız beğenecektir.

TELİF HAKKI


libexplain sürüm 1.4
Telif Hakkı (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Peter Miller

onworks.net hizmetlerini kullanarak açıklayıcı_lca2010'u çevrimiçi kullanın


Ücretsiz Sunucular ve İş İstasyonları

Windows ve Linux uygulamalarını indirin

  • 1
    yudum
    yudum
    SWIG bir yazılım geliştirme aracıdır
    C ile yazılmış programları birbirine bağlayan ve
    Çeşitli yüksek seviyeli C++
    Programlama dilleri. SWIG ile birlikte kullanılır
    farklı...
    SWIG'i indirin
  • 2
    WooCommerce Nextjs Tepki Tepkisi
    WooCommerce Nextjs Tepki Tepkisi
    İle oluşturulmuş React WooCommerce teması
    Sonraki JS, Webpack, Babel, Node ve
    GraphQL ve Apollo kullanarak Express
    Müşteri. React'te WooCommerce Mağazası(
    içerir: Ürünler...
    WooCommerce Nextjs React Temasını İndirin
  • 3
    arşiv_repo
    arşiv_repo
    ArchLabs için paket deposu Bu bir
    ayrıca alınabilen uygulama
    itibaren
    https://sourceforge.net/projects/archlabs-repo/.
    OnWorks'te barındırılan...
    archlabs_repo'yu indirin
  • 4
    Zephyr Projesi
    Zephyr Projesi
    Zephyr Projesi yeni nesildir
    gerçek zamanlı işletim sistemi (RTOS)
    birden fazla donanımı destekler
    mimariler. Bir
    az yer kaplayan çekirdek...
    Zephyr Projesini İndirin
  • 5
    SCon'lar
    SCon'lar
    SCons bir yazılım oluşturma aracıdır
    bu daha üstün bir alternatif
    klasik "Yap" oluşturma aracı
    hepimiz biliyoruz ve seviyoruz. SCons (şimdiki değeri)
    uygulanmış...
    SCons'u İndirin
  • 6
    PSeInt
    PSeInt
    PSeInt, aşağıdakiler için bir sözde kod yorumlayıcısıdır.
    ispanyolca konuşan programlama öğrencileri.
    Temel amacı, bir araç olmaktır.
    temel bilgileri öğrenmek ve anlamak
    konsept...
    PSeInt'i indirin
  • Daha fazla »

Linux komutları

Ad