InglesPransesEspanyol

Ad


OnWorks favicon

explain_lca2010 - Online sa Cloud

Patakbuhin ang explain_lca2010 sa OnWorks na libreng hosting provider sa Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator

Ito ang command na explain_lca2010 na maaaring patakbuhin sa OnWorks na libreng hosting provider gamit ang isa sa aming maramihang libreng online na workstation gaya ng Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator

PROGRAMA:

NAME


explain_lca2010 - Walang nakitang medium: kapag oras na para ihinto ang pagsubok na magbasa strerror(3)'s
isip.

pagganyak


Ang ideya para sa libexplain ay nangyari sa akin noong unang bahagi ng 1980s. Sa tuwing may system call
nagbabalik ng isang error, alam ng kernel kung ano ang nangyaring mali... at i-compress ito sa
mas mababa sa 8 bits ng mali. Ang espasyo ng user ay may access sa parehong data gaya ng kernel, ito
ay dapat na posible para sa espasyo ng gumagamit upang malaman kung ano mismo ang nangyari upang pukawin ang error
bumalik, at gamitin ito upang magsulat ng magagandang mensahe ng error.

Ganoon ba kasimple?

pagkakamali mensahe as pagkapino
Ang mga magagandang mensahe ng error ay kadalasan ang mga "isang porsyento" na gawain na nababawasan kapag nakaiskedyul
pinipiga ng presyon ang iyong proyekto. Gayunpaman, ang isang magandang mensahe ng error ay maaaring gumawa ng malaking,
hindi katimbang na pagpapabuti sa karanasan ng gumagamit, kapag ang gumagamit ay gumagala sa nakakatakot
hindi kilalang teritoryo na hindi karaniwang nakatagpo. Ito ay hindi madaling gawain.

Bilang isang larval programmer, hindi nakita ng may-akda ang problema sa (ganap na tumpak) error
mga mensahe tulad nito:
lumulutang na exception (core dumped)
hanggang sa maituro ang alternatibong interpretasyong hindi programmer. Ngunit hindi iyon ang
ang mali lang sa mga mensahe ng error sa Unix. Gaano kadalas ka nakakakita ng mga mensahe ng error tulad ng:
$ ./bobo
hindi mabuksan ang file
$
Mayroong dalawang opsyon para sa isang developer sa puntong ito:

1.
maaari kang magpatakbo ng isang debugger, tulad ng gdb(1), o

2.
pwede mong gamitin bakas(1) o salo(1) tumingin sa loob.

· Tandaan na ang iyong mga user ay maaaring walang access sa mga tool na ito, lalo pa ang kakayahan
upang gamitin ang mga ito. (Ito ay napakatagal na panahon mula noon Unix baguhan ang ibig sabihin ay “isinulat lamang isa
driver ng device”.)

Sa halimbawang ito, gayunpaman, gamit bakas(1) naghahayag
$ bakas -e bakas=bukas ./bobo
open("some/file", O_RDONLY) = -1 ENOENT (Walang ganoong file o direktoryo)
hindi mabuksan ang file
$
Ito ay mas maraming impormasyon kaysa sa ibinibigay ng mensahe ng error. Karaniwan, ang
ganito ang hitsura ng hangal na source code
int fd = bukas("ilang/bagay", O_RDONLY);
kung (fd < 0)
{
fprintf(stderr, "hindi mabuksan ang file\n");
lumabas(1);
}
Ang gumagamit ay hindi sinabihan alin file, at nabigo ring sabihin sa gumagamit alin pagkakamali. Ay ang file
kahit doon? Nagkaroon ba ng problema sa mga pahintulot? Sinasabi nito sa iyo na sinusubukan nitong buksan ang a
file, ngunit malamang na iyon ay hindi sinasadya.

Kunin ang iyong clue stick at talunin ang larval programmer dito. Sabihin sa kanya ang tungkol sa kaguluhanNa (3).
Sa susunod na gamitin mo ang program makakakita ka ng ibang mensahe ng error:
$ ./bobo
bukas: Walang ganoong file o direktoryo
$
Pag-unlad, ngunit hindi ang inaasahan namin. Paano maaayos ng gumagamit ang problema kung ang mensahe ng error
hindi niya sinasabi kung ano ang problema? Pagtingin sa pinanggalingan, nakita natin
int fd = bukas("ilang/bagay", O_RDONLY);
kung (fd < 0)
{
perror("bukas");
lumabas(1);
}
Oras na para sa isa pang pagtakbo gamit ang clue stick. Sa pagkakataong ito, ang mensahe ng error ay tumatagal ng isang hakbang
pasulong at isang hakbang pabalik:
$ ./bobo
ilang/bagay: Walang ganoong file o direktoryo
$
Ngayon alam na namin ang file na sinusubukan nitong buksan, ngunit hindi na alam na ito nga buksan(2)
nabigo iyon. Sa kasong ito, malamang na hindi ito makabuluhan, ngunit maaari itong maging makabuluhan para sa
iba pang mga tawag sa system. Maaaring ito ay tagalikha(2) sa halip, isang operasyon na nagpapahiwatig na
iba't ibang mga pahintulot ang kailangan.
const char *filename = "ilang/bagay";
int fd = open(filename, O_RDONLY);
kung (fd < 0)
{
perror(filename);
lumabas(1);
}
Sa kasamaang-palad, ang halimbawang code sa itaas ay tipikal din ng mga non-larval programmer. Oras
upang sabihin sa aming padawan na nag-aaral tungkol sa strerror(3) tawag sa sistema.
$ ./bobo
buksan ilang/bagay: Walang ganoong file o direktoryo
$
Pina-maximize nito ang impormasyong maaaring iharap sa user. Mukhang ang code
ito:
const char *filename = "ilang/bagay";
int fd = open(filename, O_RDONLY);
kung (fd < 0)
{
fprintf(stderr, "bukas %s: %s\n", filename, strerror(errno));
lumabas(1);
}
Ngayon ay mayroon na tayong system call, ang filename, at ang error string. Ito ay naglalaman ng lahat ng
impormasyon na bakas(1) nakalimbag. Iyan ay kasing ganda nito.

O kaya?

Mga hangganan of kaguluhan at strerror
Ang problemang nakita ng may-akda, noong 1980s, ay ang mensahe ng error ay hindi kumpleto.
Ang "walang ganoong file o direktoryo" ba ay tumutukoy sa "ilan” direktoryo, o sa “bagay” file in
ang "ilan” direktoryo?

Isang mabilis na pagtingin sa pahina ng tao para sa strerror(3) ay nagsasabi:
strerror - ibalik ang string na naglalarawan ng error number
Tandaang mabuti: inilalarawan nito ang error numero, hindi ang error.

Sa kabilang banda, ang kernel alam mo kung ano ang pagkakamali. Nagkaroon ng tiyak na punto sa
kernel code, sanhi ng isang partikular na kundisyon, kung saan nagsanga ang kernel code at sinabing "hindi".
Maaari bang malaman ng isang user-space program ang partikular na kundisyon at magsulat ng isang mas mahusay na error
mensahe?

Gayunpaman, lumalalim ang problema. Paano kung mangyari ang problema sa panahon ng basahin(2) sistema
tawag, sa halip na ang buksan(2) tawag? Ito ay simple para sa mensahe ng error na nauugnay sa
buksan(2) upang isama ang pangalan ng file, naroroon mismo. Ngunit upang maisama ang isang pangalan ng file
sa error na nauugnay sa basahin(2) system call, kailangan mong ipasa ang lahat ng pangalan ng file
ang paraan pababa sa call stack, pati na rin ang file descriptor.

At narito ang kaunti na nakakaalam: alam na ng kernel kung anong pangalan ng file ang file
ang deskriptor ay nauugnay sa. Bakit kailangang ipasa ng isang programmer ang lahat ng redundant data
ang paraan pababa sa stack ng tawag para lang mapabuti ang isang mensahe ng error na maaaring hindi kailanman maibigay? Sa
katotohanan, maraming mga programmer ay hindi nag-abala, at ang mga nagresultang mensahe ng error ay mas masahol pa para sa
ito.

Ngunit iyon ay noong 1980s, sa isang PDP11, na may limitadong mga mapagkukunan at walang nakabahaging mga aklatan. Bumalik
pagkatapos, walang lasa ng Unix kasama / proc kahit sa panimulang anyo, at ang lsof(1) programa
ay mahigit isang dekada ang layo. Kaya ang ideya ay nai-shelved bilang hindi praktikal.

Antas Kawalang-hanggan Suporta
Isipin mo na level infinity support ka. Ang iyong paglalarawan ng trabaho ay nagsasabi na hindi mo kailanman
kailanman kailangang makipag-usap sa mga gumagamit. Kung gayon, bakit patuloy pa rin ang daloy ng mga taong nagnanais
ikaw, ang lokal na Unix guru, upang maunawaan ang isa pang mensahe ng error?

Kakaiba, pagkalipas ng 25 taon, sa kabila ng isang simpleng sistema ng mga pahintulot, ipinatupad nang kumpleto
pagkakapare-pareho, karamihan sa mga gumagamit ng Unix ay wala pa ring ideya kung paano i-decode ang "Walang ganoong file o direktoryo",
o alinman sa iba pang misteryosong mensahe ng error na nakikita nila araw-araw. O, hindi bababa sa, misteryoso sa
Kanila.

Hindi ba magiging maganda kung ang unang antas ng tech na suporta ay hindi nangangailangan ng mga mensahe ng error na na-decipher?
Hindi ba maganda na magkaroon ng mga mensahe ng error na mauunawaan ng mga gumagamit nang hindi tumatawag
tech support?

Sa mga araw na ito / proc sa Linux ay higit pa sa kayang magbigay ng impormasyong kinakailangan para mag-decode
ang karamihan sa mga mensahe ng error, at ituro ang user sa malapit na dahilan ng kanilang
problema. Sa mga system na may limitadong / proc pagpapatupad, ang lsof(1) maaaring punan ng utos
marami sa mga puwang.

Noong 2008, masyadong madalas ang daloy ng mga kahilingan sa pagsasalin sa may-akda. Ito ay
oras na upang muling suriin ang 25 taong gulang na ideya, at libexplain ang resulta.

GAMIT ANG LIBRARY


Ang interface sa library ay sumusubok na maging pare-pareho, kung posible. Magsimula tayo sa isang
halimbawa gamit strerror(3):
if (rename(old_path, new_path) < 0)
{
fprintf(stderr, "palitan ang pangalan ng %s %s: %s\n", old_path, new_path,
strerror(errno));
lumabas(1);
}
Ang ideya sa likod ng libexplain ay magbigay ng a strerror(3) katumbas ng bawat tawag sa sistema,
partikular na iniayon sa system call na iyon, para makapagbigay ito ng mas detalyadong error
mensahe, na naglalaman ng karamihan ng impormasyong nakikita mo sa ilalim ng "ERRORS" heading ng seksyon
2 3 at lalaki mga pahina, na dinagdagan ng impormasyon tungkol sa aktwal na mga kondisyon, aktwal na argumento
mga halaga, at mga limitasyon ng system.

Ang Simple kaso
Ang strerror(3) kapalit:
if (rename(old_path, new_path) < 0)
{
fprintf(stderr, "%s\n", explain_rename(old_path, new_path));
lumabas(1);
}

Ang Errno kaso
Posible ring magpasa ng tahasan mali(3) halaga, kung kailangan mo munang gawin ang ilan
pagproseso na makakaistorbo mali, tulad ng pagbawi ng error:
if (rename(old_path, new_path < 0))
{
int old_errno = errno;
...code na nakakagambala mali...
fprintf(stderr, "%s\n", explain_errno_rename(old_errno,
old_path, new_path));
lumabas(1);
}

Ang Multi-thread Cases
Ang ilang mga application ay multi-threaded, at sa gayon ay hindi maibabahagi ang panloob ng libexplain
buffer. Maaari kang magbigay ng iyong sariling buffer gamit
kung (i-unlink(pathname))
{
char message[3000];
explain_message_unlink(mensahe, sukat ng(mensahe), pangalan ng landas);
error_dialog(mensahe);
bumalik -1;
}
At para sa pagiging kumpleto, pareho mali(3) at ligtas sa thread:
ssize_t nbytes = read(fd, data, sizeof(data));
kung (nbytes < 0)
{
char message[3000];
int old_errno = errno;
...mali pagbawi...
explain_message_errno_read(mensahe, sukat ng(mensahe),
old_errno, fd, data, sizeof(data));
error_dialog(mensahe);
bumalik -1;
}

Ito ay mga kapalit para sa strerror_r(3), sa mga sistemang mayroon nito.

interface Asukal
Isang set ng mga function na idinagdag bilang convenience function, upang manligaw sa mga programmer na gamitin ang
libexplain library, lumabas na ang pinakakaraniwang ginagamit na function ng libexplain ng may-akda sa
mga programa ng command line:
int fd = explain_creat_or_die(filename, 0666);
Sinusubukan ng function na ito na lumikha ng isang bagong file. Kung hindi nito magawa, nagpi-print ito ng mensahe ng error at
paglabas na may EXIT_FAILURE. Kung walang error, ibinabalik nito ang bagong descriptor ng file.

Isang nauugnay na function:
int fd = explain_creat_on_error(filename, 0666);
ay magpi-print ng mensahe ng error sa pagkabigo, ngunit ibabalik din ang orihinal na resulta ng error, at
mali(3) ay hindi nababagabag, pati na rin.

lahat ang iba sistema tawag
Sa pangkalahatan, ang bawat tawag sa system ay may sariling file na kasama
#isamapangalan.h>
na tumutukoy sa mga prototype ng function para sa anim na function:

· ipaliwanag_pangalan,

· explain_errno_pangalan,

· ipaliwanag_mensahe_pangalan,

· explain_message_errno_pangalan,

· ipaliwanag_pangalan_o_mamatay at

· ipaliwanag_pangalan_on_error.

Ang bawat prototype ng function ay mayroong dokumentasyon ng Doxygen, at ang dokumentasyong ito is hindi hinubad
kapag naka-install ang mga kasamang file.

Ang maghintay(2) system call (at mga kaibigan) ay may ilang dagdag na variant na nagbibigay-kahulugan din sa pagkabigo
upang maging exit status na hindi EXIT_SUCCESS. Nalalapat ito sa sistema(3) at pclose(3) bilang
mabuti.

Kasama sa saklaw ang 221 system call at 547 ioctl na kahilingan. Marami pang sistema
mga panawagan para ipatupad pa. Mga tawag sa system na hindi na bumalik, tulad ng lumabas(2), ay wala
sa silid-aklatan, at hindi kailanman magiging. Ang exec pamilya ng mga system call ay suportado, dahil
bumabalik sila kapag may mali.

Pusa
Ito ang maaaring maging hitsura ng isang hypothetical na "pusa" na programa, na may ganap na pag-uulat ng error,
gamit ang libexplain.
#isama
# isama
#isama
May kasama para sa libexplain, kasama ang mga karaniwang suspek. (Kung nais mong bawasan ang
preprocessor load, maaari mong gamitin ang tiyakpangalan.h> kasama.)
static na walang bisa
proseso(FILE *fp)
{
para sa (;;)
{
char buffer[4096];
size_t n = explain_fread_or_die(buffer, 1, sizeof(buffer), fp);
kung (!n)
masira;
explain_fwrite_or_die(buffer, 1, n, stdout);
}
}
Ang paraan Kinokopya ng function ang isang file stream sa karaniwang output. Kung may nangyaring error
para sa alinman sa pagbabasa o pagsusulat, ito ay iniuulat (at ang pathname ay isasama sa
error) at lalabas ang command na may EXIT_FAILURE. Hindi rin kami nag-aalala tungkol sa pagsubaybay sa
pathname, o pagpasa sa kanila sa call stack.
int
main(int argc, char **argv)
{
para sa (;;)
{
int c = getopt(argc, argv, "o:");
kung (c == EOF)
masira;
lumipat (c)
{
kaso 'o':
explain_freopen_or_die(optarg, "w", stdout);
masira;
Ang nakakatuwang bahagi ng code na ito ay ang libexplain ay maaaring mag-ulat ng mga error kabilang ang pangalan ng landas kahit na
kung huwag tahasang muling buksan ang stdout gaya ng ginagawa dito. Hindi man lang kami nag-aalala
pagsubaybay sa pangalan ng file.
default:
fprintf(stderr, "Paggamit: %ss [ -o ] ...\n",
argv[0]);
ibalik ang EXIT_FAILURE;
}
}
kung (optind == argc)
proseso(stdin);
iba
{
habang (optind < argc)
{
FILE *fp = explain_fopen_or_die(argv[optind]++, "r");
proseso(fp);
explain_fclose_or_die(fp);
}
}
Ang karaniwang output ay isasara nang tahasan, ngunit huli na para maging isang ulat ng error
inisyu, kaya ginagawa namin iyon dito, kung sakaling ang buffered na I/O ay wala pang nakasulat, at
mayroong isang ENOSPC error o isang bagay.
explain_fflush_or_die(stdout);
ibalik ang EXIT_SUCCESS;
}
Iyon lang. Buong pag-uulat ng error, malinaw na code.

kay Rusty iskala of interface Kabutihan
Para sa mga hindi pamilyar dito, ang "How Do I Make This Hard to Misuse?" ni Rusty Russel.
page ay isang dapat-basahin para sa mga taga-disenyo ng API.
http://ozlabs.org/~rusty/index.cgi/tech/2008‐03–30.html

10. Ito ay imposible sa makuha mali.

Ang mga layunin ay kailangang itakda nang mataas, lubos na mataas, baka matupad mo ang mga ito at isipin na ikaw ay
tapos kapag wala ka.

Nakikita ng libexplain library ang mga huwad na payo at marami pang ibang parameter ng tawag sa system na huwad,
at sa pangkalahatan ay sinusubukang iwasan ang mga segfault sa kahit na ang pinaka-masubok na mga pangyayari.

Ang library ng libexplain ay idinisenyo upang maging ligtas sa thread. Malamang na mas maraming real-world na paggamit
ibunyag ang mga lugar na maaari itong mapabuti.

Ang pinakamalaking problema ay sa aktwal na mga pangalan ng function mismo. Dahil wala si C
name‐spaces, ang libexplain library ay palaging gumagamit ng explain_ name prefix. Ito ang
tradisyonal na paraan ng paglikha ng pseudo‐name‐space upang maiwasan ang mga salungatan ng simbolo.
Gayunpaman, nagreresulta ito sa ilang hindi natural na tunog na mga pangalan.

9. Ang tagatala or Link ay hindi mag pabayaan ikaw makuha it mali.

Ang isang karaniwang pagkakamali ay ang paggamit ng explain_open kung saan nilayon ang explain_open_or_die.
Sa kabutihang palad, ang compiler ay madalas na maglalabas ng isang uri ng error sa puntong ito (hal hindi makapagtalaga
const char * rvalue sa isang int lvalue).

8. Ang tagatala habilin balaan if ikaw makuha it mali.

Kung ginamit ang explain_rename kapag sinadya ang explain_rename_or_die, maaari itong magdulot ng iba
mga problema. Ang GCC ay may kapaki-pakinabang na katangian ng function na warn_unused_result, at ang libexplain
ikinakabit ito ng library sa lahat ng explain_pangalan function na tawag upang makagawa ng babala kapag ikaw
gawin itong pagkakamali. Pagsamahin ito sa gcc -Werror upang isulong ito sa antas 9 na kabutihan.

7. Ang Halata gamitin is (malamang) ang itama isa.

Ang mga pangalan ng function ay pinili upang ihatid ang kanilang kahulugan, ngunit ito ay hindi palaging
matagumpay. Habang nagpapaliwanag_pangalan_o_mamatay at ipaliwanag_pangalan_on_error ay medyo naglalarawan,
mas mahirap i-decode ang mga hindi gaanong ginagamit na thread safe na variant. Ang mga prototype ng function ay tumutulong sa
compiler tungo sa pag-unawa, at ang mga komento ng Doxygen sa mga file ng header ay nakakatulong sa user
tungo sa pagkakaunawaan.

6. Ang pangalan nagsasabi ikaw paano sa gamitin ito.

Ito ay partikular na mahalaga na basahin ang explain_pangalan_or_die bilang “ipaliwanag (pangalan o mamatay)".
Ang paggamit ng isang pare-parehong explain_ name-space prefix ay may ilang kapus-palad na side-effects sa
obviousness department, pati na rin.

Ang pagkakasunud-sunod ng mga salita sa mga pangalan ay nagpapahiwatig din ng pagkakasunud-sunod ng mga argumento. Ang argumento
mga listahan palagi dulo na may parehong mga argumento na ipinasa sa system call; lahat of sila. Kung
Lumilitaw ang _errno_ sa pangalan, ang argumento nito ay palaging nauuna sa mga argumento ng system call. Kung
Lumilitaw ang _message_ sa pangalan, ang dalawang argumento nito ay laging nauuna.

5. Do it karapatan or it habilin masira at runtime.

Nakikita ng libexplain library ang mga huwad na payo at marami pang ibang parameter ng tawag sa system na huwad,
at sa pangkalahatan ay sinusubukang iwasan ang mga segfault sa kahit na ang pinaka-masubok na mga pangyayari. Dapat
hindi kailanman masira sa runtime, ngunit mas maraming real-world na paggamit ay walang dudang mapapabuti ito.

Ang ilang mga mensahe ng error ay naglalayong sa mga developer at maintainer sa halip na mga end user, dahil dito
maaaring tumulong sa paglutas ng bug. Hindi gaanong "break sa runtime" bilang "maging nagbibigay-kaalaman sa
runtime” (pagkatapos ng system call barfs).

4. sundin pangkaraniwan kapulungan at gagawin mo makuha it tama.

Dahil ang C ay walang name‐spaces, ang libexplain library ay palaging gumagamit ng explain_ name
unlapi. Ito ang tradisyunal na paraan ng paglikha ng pseudo-name-space upang maiwasan
mga salungatan ng simbolo.

Ang mga sumusunod na argumento ng lahat ng libexplain na tawag ay magkapareho sa system call nila
ay naglalarawan. Nilalayon nitong magbigay ng pare-parehong kumbensyon na karaniwan sa
tinatawag ng system ang kanilang sarili.

3. Basahin ang dokumentasyon at gagawin mo makuha it tama.

Nilalayon ng libexplain library na magkaroon ng kumpletong dokumentasyon ng Doxygen para sa bawat isa
pampublikong API na tawag (at sa loob din).

MESSAGE NILALAMAN


Ang paggawa sa libexplain ay parang pagtingin sa ilalim ng iyong sasakyan kapag naka-on ito
ang hoist sa mekaniko. Mayroong ilang mga pangit na bagay sa ilalim doon, kasama ang putik at crud, at
bihira itong makita ng mga gumagamit. Ang isang magandang mensahe ng error ay kailangang maging nagbibigay-kaalaman, kahit na para sa isang user na
ay naging masuwerte na hindi na kailangang tumingin sa ilalim ng napakadalas, at gayundin
nagbibigay-kaalaman para sa mekaniko na nakikinig sa paglalarawan ng user sa telepono. Ito ay
walang madaling gawain.

Sa muling pagbisita sa aming unang halimbawa, gusto ito ng code kung gumagamit ito ng libexplain:
int fd = explain_open_or_die("some/thing", O_RDONLY, 0);
ay mabibigo sa isang mensahe ng error na tulad nito
open(pathname = "some/file", flags = O_RDONLY) failed, Walang ganoong file o directory
(2, ENOENT) dahil walang "ilang" na direktoryo sa kasalukuyang direktoryo
Ito ay nahahati sa tatlong piraso
sistema-tawag nabigo, system-error dahil sa
paliwanag

Bago dahil sa
Posibleng makita ang bahagi ng mensahe bago ang "dahil" bilang sobrang teknikal sa hindi
teknikal na mga user, kadalasan bilang resulta ng tumpak na pag-print ng system call mismo sa
simula ng mensahe ng error. At parang bakas(1) output, para sa bonus geek
puntos.
open(pathname = "some/file", flags = O_RDONLY) failed, Walang ganoong file o directory
(2, ENOENT)
Ang bahaging ito ng mensahe ng error ay mahalaga sa developer kapag isinusulat niya ang code,
at parehong mahalaga sa maintainer na kailangang magbasa ng mga ulat ng bug at ayusin ang mga bug sa
code. Sinasabi nito kung ano ang nabigo.

Kung ang tekstong ito ay hindi ipinakita sa gumagamit kung gayon ang gumagamit ay hindi maaaring kopyahin-at-i-paste ito sa a
ulat ng bug, at kung wala ito sa ulat ng bug, hindi malalaman ng tagapangasiwa kung ano talaga ang nangyari
mali.

Madalas gagamit ng mga tech staff bakas(1) o salo(1) upang makuha ang eksaktong impormasyong ito, ngunit
hindi bukas ang avenue na ito kapag nagbabasa ng mga ulat ng bug. Malayo ang sistema ng reporter ng bug
malayo, at, sa ngayon, nasa ibang estado. Kaya, ang impormasyong ito ay kailangang nasa
ulat ng bug, na nangangahulugang nasa mensahe ng error ito.

Ang representasyon ng system call ay nagbibigay din ng konteksto sa natitirang bahagi ng mensahe. Kapag kailangan
lumitaw, ang nakakasakit na argumento ng system call ay maaaring i-refer sa pamamagitan ng pangalan sa paliwanag
pagkatapos ng "dahil". Bilang karagdagan, ang lahat ng mga string ay ganap na sinipi at nakatakas sa mga C string, kaya
ang mga naka-embed na bagong linya at hindi nagpi-print na mga character ay hindi magiging sanhi ng pag-alis ng terminal ng user
haywire.

Ang system-error ay kung ano ang lumalabas sa strerror(2), kasama ang simbolo ng error. naiinip at
Ang mga dalubhasang sysadmin ay maaaring huminto sa pagbabasa sa puntong ito, ngunit ang karanasan ng may-akda hanggang ngayon ay
na ang pagbabasa ng karagdagang ay kapakipakinabang. (Kung hindi ito kapaki-pakinabang, malamang na ito ay isang lugar ng
libexplain na maaaring mapabuti. Tinatanggap ang mga kontribusyon sa code, siyempre.)

pagkatapos dahil sa
Ito ang bahagi ng mensahe ng error na naglalayong hindi teknikal na mga gumagamit. Tumingin ito sa kabila
ang mga simpleng argumento ng system call, at naghahanap ng mas tiyak.
walang "ilang" na direktoryo sa kasalukuyang direktoryo
Sinusubukan ng bahaging ito na ipaliwanag ang proximal na sanhi ng error sa simpleng wika, at ito
narito na ang internasyonalisasyon ay mahalaga.

Sa pangkalahatan, ang patakaran ay magsama ng maraming impormasyon hangga't maaari, upang ang user
ay hindi kailangang hanapin ito (at hindi ito iniiwan sa ulat ng bug).

internationalization
Karamihan sa mga mensahe ng error sa libexplain library ay nai-internationalized. doon
ay wala pang lokalisasyon, kaya kung gusto mo ang mga paliwanag sa iyong sariling wika,
mangyaring mag-ambag.

Ang "karamihan ng" qualifier, sa itaas, ay nauugnay sa katotohanan na ang patunay-ng-konsepto
hindi kasama sa pagpapatupad ang suporta sa internasyonalisasyon. Ang code base ay pagiging
progresibong binago, kadalasan bilang resulta ng refactoring na mga mensahe upang ang bawat error
lilitaw ang string ng mensahe sa code nang eksaktong isang beses.

Ang probisyon ay ginawa para sa mga wika na kailangang tipunin ang mga bahagi ng
sistema-tawag nabigo, system-error dahil sa paliwanag
sa iba't ibang mga order para sa tamang grammar sa mga naisalokal na mensahe ng error.

I-post ang mortem
May mga pagkakataon na ang isang programa ay hindi pa gumagamit ng libexplain, at hindi mo magagamit bakas(1)
alinman. May isang ipaliwanag(1) utos na kasama sa libexplain na maaaring magamit sa
decipher ang mga mensahe ng error, kung ang estado ng pinagbabatayan na sistema ay hindi masyadong nagbago.
$ ipaliwanag palitan ang pangalan foo /tmp/bar/baz -e ENOENT
rename(oldpath = "foo", newpath = "/tmp/bar/baz") ay nabigo, Walang ganoong file o direktoryo
(2, ENOENT) dahil walang "bar" na direktoryo sa newpath "/ Tmp"direktoryo
$
Tandaan kung paano nireresolba ang kalabuan ng landas sa pamamagitan ng paggamit ng pangalan ng argumento ng system call. Ng
Siyempre, kailangan mong malaman ang error at ang tawag sa system ipaliwanag(1) upang maging kapaki-pakinabang. Bilang isang
bukod pa, isa ito sa mga paraan na ginagamit ng libexplain automatic test suite para ma-verify iyon
gumagana ang libexplain.

Pilosopya
"Sabihin sa akin ang lahat, kasama ang mga bagay na hindi ko alam na hahanapin."

Ang library ay ipinatupad sa paraang kapag statically linked, tanging ang code mo
aktwal na paggamit ay mai-link. Ito ay nakakamit sa pamamagitan ng pagkakaroon ng isang function sa bawat source file,
sa tuwing magagawa.

Kapag posible na magbigay ng higit pang impormasyon, gagawin ito ng libexplain. Mas kaunti ang gumagamit
kailangang subaybayan para sa kanilang sarili, mas mabuti. Nangangahulugan ito na ang mga UID ay sinamahan ng
user name, ang mga GID ay sinamahan ng pangalan ng grupo, ang mga PID ay sinamahan ng proseso
pangalan, file descriptor at stream ay sinamahan ng pathname, at iba pa.

Kapag nire-resolve ang mga path, kung walang component ng path, maghahanap ng katulad ang libexplain
mga pangalan, upang magmungkahi ng mga alternatibo para sa mga typographical error.

Sinusubukan ng libexplain library na gumamit ng kaunting tambak hangga't maaari, at karaniwan ay wala. Ito ay
upang maiwasang magulo ang estado ng proseso, hangga't maaari, bagama't kung minsan ito ay
hindi maiiwasan

Ang libexplain library ay sumusubok na maging thread safe, sa pamamagitan ng pag-iwas sa mga global variable, pagpapanatili
estado sa stack hangga't maaari. Mayroong isang karaniwang buffer ng mensahe, at ang
ang mga function na gumagamit nito ay nakadokumento bilang hindi ligtas sa thread.

Ang library ng libexplain ay hindi nakakagambala sa mga humahawak ng signal ng isang proseso. Ginagawa nitong
pagtukoy kung ang isang pointer ay magse-segfault ng isang hamon, ngunit hindi imposible.

Kapag ang impormasyon ay makukuha sa pamamagitan ng isang system call gayundin sa pamamagitan ng a / proc
entry, mas gusto ang system call. Ito ay upang maiwasang maabala ang estado ng proseso.
May mga pagkakataon ding walang available na file descriptor.

Ang library ng libexplain ay pinagsama-sama na may malaking suporta sa file. Walang malaki/maliit
schizophrenia. Kung saan nakakaapekto ito sa mga uri ng argumento sa API, at ibibigay ang error
kung wala ang kinakailangang malaking file define.

FIXME: Kailangan ang trabaho upang matiyak na ang mga quota ng file system ay pinangangasiwaan sa code. Ito
naaangkop sa ilan getrlimit(2) mga hangganan, pati na rin.

May mga kaso kapag ang mga landas ng mga kamag-anak ay hindi nakakaalam. Halimbawa: mga daemon ng system,
mga server at mga proseso sa background. Sa mga kasong ito, ginagamit ang mga absolute path sa error
Mga paliwanag.

PATH RESOLUSYON


Maikling bersyon: tingnan path_resolutionNa (7).

Mahabang bersyon: Karamihan sa mga user ay hindi pa nakarinig ng tungkol path_resolution(7), at maraming mga advanced na user
hindi pa nababasa. Narito ang isang annotated na bersyon:

Hakbang 1: simula of ang paglutas paraan
Kung ang pathname ay nagsisimula sa slash (“/”) na character, ang panimulang lookup na direktoryo ay
ang root directory ng proseso ng pagtawag.

Kung ang pathname ay hindi magsisimula sa slash(“/”) na character, ang panimulang paghahanap
direktoryo ng proseso ng paglutas ay ang kasalukuyang gumaganang direktoryo ng proseso.

Hakbang 2: Maglakad kasama ang landas
Itakda ang kasalukuyang lookup directory sa panimulang lookup directory. Ngayon, para sa bawat hindi
panghuling bahagi ng pathname, kung saan ang isang bahagi ay isang substring na nililimitahan ng slash (“/”)
character, ang bahaging ito ay hinahanap sa kasalukuyang direktoryo ng paghahanap.

Kung ang proseso ay walang pahintulot sa paghahanap sa kasalukuyang direktoryo ng paghahanap, isang EACCES
ibinalik ang error ("Tinanggihan ang pahintulot").
open(pathname = "/home/archives/.ssh/private_key", mga flag = O_RDONLY) ay nabigo,
Tinanggihan ang pahintulot (13, EACCES) dahil walang pahintulot sa paghahanap ang proseso
sa pathname na "/home/archives/.ssh" na direktoryo, ang proseso ay epektibong GID 1000
Ang "pmiller" ay hindi tumutugma sa may-ari ng direktoryo 1001 "mga archive" kaya ang may-ari
Ang permission mode na "rwx" ay hindi pinansin, ang iba pang permission mode ay "---", at ang
hindi pribilehiyo ang proseso (walang kakayahan sa DAC_READ_SEARCH)

Kung hindi nahanap ang bahagi, isang ENOENT error ang ibabalik ("Walang ganoong file o direktoryo").
hindi na-unlink(pathname = "/home/microsoft/rubbish") ang nabigo, Walang ganoong file o direktoryo (2,
ENOENT) dahil walang "microsoft" na direktoryo sa pathname na "/ home"direktoryo

Mayroon ding ilang suporta para sa mga user kapag nagkamali sila ng uri ng mga pathname, na nagmumungkahi kung kailan
Ibinalik ang ENOENT:
open(pathname = "/user/include/fcntl.h", flags = O_RDONLY) nabigo, Walang ganoong file o
direktoryo (2, ENOENT) dahil walang direktoryo ng "user" sa pathname na "/"
direktoryo, ang ibig mo bang sabihin ay ang direktoryo na "usr" sa halip?

Kung ang bahagi ay natagpuan, ngunit hindi isang direktoryo o isang simbolikong link, isang ENOTDIR
ibinalik ang error ("Hindi isang direktoryo").
bukas(pathname = "/home/pmiller/.netrc/lca", mga flag = O_RDONLY) ay nabigo, Hindi isang
directory (20, ENOTDIR) dahil ang ".netrc" na regular na file sa pathname
Ang "/home/pmiller" na direktoryo ay ginagamit bilang isang direktoryo kapag hindi

Kung ang bahagi ay natagpuan at ito ay isang direktoryo, itinakda namin ang kasalukuyang direktoryo ng paghahanap doon
direktoryo, at pumunta sa susunod na bahagi.

Kung ang bahagi ay natagpuan at ito ay isang simbolikong link (symlink), una naming lutasin ang simbolikong ito
link (na may kasalukuyang lookup directory bilang panimulang lookup directory). Sa pagkakamali, iyon
ibinalik ang error. Kung ang resulta ay hindi isang direktoryo, isang ENOTDIR error ang ibinalik.
hindi na-unlink(pathname = "/tmp/dangling/rubbish") ang nabigo, Walang ganoong file o direktoryo (2,
ENOENT) dahil ang "nakakalawit" na simbolikong link sa pathname na "/ Tmp"direktoryo
tumutukoy sa "wala kahit saan" na wala
Kung ang resolution ng symlink ay matagumpay at nagbabalik ng isang direktoryo, itinakda namin ang kasalukuyang
maghanap ng direktoryo sa direktoryo na iyon, at pumunta sa susunod na bahagi. Tandaan na ang
Ang proseso ng paglutas dito ay nagsasangkot ng recursion. Upang maprotektahan ang kernel laban sa stack
overflow, at upang maprotektahan laban sa pagtanggi sa serbisyo, may mga limitasyon sa maximum
recursion depth, at sa maximum na bilang ng mga simbolikong link na sinundan. Ang isang error sa ELOOP ay
ibinalik kapag nalampasan ang maximum ("Masyadong maraming antas ng simbolikong mga link").
open(pathname = "/tmp/dangling", flags = O_RDONLY) nabigo, Masyadong maraming antas ng
symbolic links (40, ELOOP) dahil may na-encounter na symbolic link loop sa
pathname, simula sa "/tmp/dangling"
Posible ring makakuha ng ELOOP o EMLINK error kung napakaraming symlink, ngunit walang
natukoy ang loop.
open(pathname = "/tmp/rabbit‐hole", flags = O_RDONLY) ang nabigo, Masyadong maraming antas ng
simbolikong link (40, ELOOP) dahil napakaraming simbolikong link ang nakatagpo sa
pathname (8)
Pansinin kung paano naka-print din ang aktwal na limitasyon.

Hakbang 3: Mahanap ang pangwakas pagpasok
Ang paghahanap ng panghuling bahagi ng pathname ay napupunta tulad ng sa lahat ng iba pa
mga bahagi, tulad ng inilarawan sa nakaraang hakbang, na may dalawang pagkakaiba:

(i) Ang panghuling bahagi ay hindi kailangang isang direktoryo (kahit man lamang sa paglutas ng landas
nababahala ang proseso. Maaaring ito ay isang direktoryo, o isang hindi-direktoryo, dahil sa
ang mga kinakailangan ng partikular na tawag sa system).

(II)
Ito ay hindi kinakailangang isang error kung ang panghuling bahagi ay hindi natagpuan; baka kami lang
paglikha nito. Ang mga detalye sa paggamot ng huling entry ay inilarawan sa
mga manu-manong pahina ng mga partikular na tawag sa system.

(iii)
Posible rin na magkaroon ng problema sa huling bahagi kung ito ay isang simbolikong link
at hindi ito dapat sundin. Halimbawa, gamit ang buksan(2) O_NOFOLLOW flag:
open(pathname = "a‐symlink", mga flag = O_RDONLY | O_NOFOLLOW) ang nabigo, Masyadong maraming antas ng
symbolic links (ELOOP) dahil ang O_NOFOLLOW ay tinukoy ngunit ang pathname ay tumutukoy sa a
simbolong link

(iv)
Karaniwang nagkakamali ang mga user kapag nagta-type ng mga pathname. Ang libexplain library
sumusubok na gumawa ng mga mungkahi kapag ibinalik ang ENOENT, halimbawa:
open(pathname = "/usr/include/filecontrl.h", flags = O_RDONLY) nabigo, Walang ganoong file o
directory (2, ENOENT) dahil walang regular na file na "filecontrl.h" sa pathname
"/ usr / isama" directory, ang ibig mo bang sabihin ay ang "fcntl.h" na regular na file sa halip?

(v) Posible rin na ang panghuling bahagi ay kinakailangan na maging isang bagay maliban sa a
regular na file:
readlink(pathname = "just‐a‐file", data = 0x7F930A50, data_size = 4097) ay nabigo,
Di-wastong argumento (22, EINVAL) dahil ang pathname ay isang regular na file, hindi isang simbolikong link

(vi)
FIXME: paghawak ng "t" bit.

Mga Limitasyon
Mayroong ilang mga limitasyon patungkol sa mga pathname at filename.

Limitasyon sa haba ng pathname
Mayroong maximum na haba para sa mga pathname. Kung ang pathname (o ilang intermediate
pathname na nakuha habang nireresolba ang mga simbolikong link) ay masyadong mahaba, isang ENAMETOOLONG
ibinalik ang error ("Napakahaba ng pangalan ng file"). Pansinin kung paano kasama ang limitasyon ng system
sa mensahe ng error.
bukas(pathname = "napakatagal", mga flag = O_RDONLY) ay nabigo, Masyadong mahaba ang pangalan ng file (36,
ENAMETOOLONG) dahil lumampas ang pathname sa maximum na haba ng path ng system (4096)

Limitasyon sa haba ng filename
Ang ilang mga variant ng Unix ay may limitasyon sa bilang ng mga byte sa bawat bahagi ng path.
Ang ilan sa kanila ay nakikitungo dito nang tahimik, at ang ilan ay nagbibigay ng ENAMETOOLONG; ang libexplain
gamit ng aklatan pathconf(3) _PC_NO_TRUNC para sabihin kung alin. Kung mangyari ang error na ito, ang
Sasabihin ng libexplain library ang limitasyon sa mensahe ng error, ang limitasyon ay
nakuha mula sa pathconf(3) _PC_NAME_MAX. Pansinin kung paano kasama ang limitasyon ng system
sa mensahe ng error.
bukas(pathname = "system7/only-had-14-character", mga flag = O_RDONLY) ay nabigo, File
masyadong mahaba ang pangalan (36, ENAMETOOLONG) dahil ang "only-had-14-character" na bahagi ay
mas mahaba kaysa sa limitasyon ng system (14)

Walang laman ang pathname
Sa orihinal na Unix, ang walang laman na pathname ay tumutukoy sa kasalukuyang direktoryo.
Sa ngayon, ang POSIX ay nag-utos na ang isang walang laman na pathname ay hindi dapat matagumpay na lutasin.
open(pathname = "", flags = O_RDONLY) nabigo, Walang ganoong file o direktoryo (2,
ENOENT) dahil ang POSIX ay nag-utos na ang isang walang laman na pathname ay hindi dapat lutasin
matagumpay

Pahintulot
Ang mga bit ng pahintulot ng isang file ay binubuo ng tatlong grupo ng tatlong bit. Ang unang pangkat ng
tatlo ang ginagamit kapag ang epektibong user ID ng proseso ng pagtawag ay katumbas ng owner ID ng
file. Ang pangalawang pangkat ng tatlo ay ginagamit kapag ang group ID ng file ay alinman sa katumbas ng
epektibong group ID ng proseso ng pagtawag, o isa sa mga pandagdag na ID ng grupo ng
proseso ng pagtawag. Kapag walang hawak, ang ikatlong pangkat ang ginagamit.
bukas(pathname = "/ etc / passwd", mga flag = O_WRONLY) nabigo, Tinanggihan ang pahintulot (13,
EACCES) dahil ang proseso ay walang pahintulot sa pagsulat sa regular na "passwd".
file sa pathname na "/ atbp" direktoryo, ang proseso ay epektibong UID 1000 "pmiller"
ay hindi tumutugma sa regular na may-ari ng file 0 "root" kaya ang mode ng pahintulot ng may-ari na "rw-"
ay binabalewala, ang iba pang permission mode ay "r--", at ang proseso ay hindi pribilehiyo
(walang kakayahan sa DAC_OVERRIDE)
Ang ilang malaking espasyo ay ibinibigay sa paliwanag na ito, dahil ang karamihan sa mga gumagamit ay hindi alam na ito
ay kung paano gumagana ang sistema ng mga pahintulot. Sa partikular: ang may-ari, grupo at iba pa
eksklusibo ang mga pahintulot, hindi sila "O" magkasama.

KAHIRAPAN AT PAGPAPAKITA SYSTEM TUMAWAG


Ang proseso ng pagsulat ng isang partikular na tagapangasiwa ng error para sa bawat tawag sa system ay madalas na nagpapakita
kawili-wiling mga quirks at hangganan kondisyon, o nakakubli mali(3) mga halaga.

ENOMEDIUM, Hindi medium natagpuan
Ang pagkilos ng pagkopya ng CD ang pinagmulan ng pamagat para sa papel na ito.
$ dd kung=/dev/cdrom ng=fubar.iso
dd: pagbubukas ng "/dev/cdrom": Walang nakitang medium
$
Nagtaka ang may-akda kung bakit sinasabi sa kanya ng kanyang computer na walang ganoong bagay bilang isang saykiko
daluyan. Medyo bukod sa ang katunayan na ang malaking bilang ng mga katutubong nagsasalita ng Ingles ay hindi
kahit na alam na ang "media" ay isang maramihan, pabayaan na ang "medium" ay ang kanyang isahan, ang string
ibinalik ni strerror(3) para sa ENOMEDIUM ay napakaikli na halos ganap na malaya
nilalaman.

Kailan buksan(2) nagbabalik ng ENOMEDIUM mas maganda kung ang libexplain library ay mapapalawak a
maliit dito, batay sa uri ng drive na ito. Halimbawa:
... dahil walang disk sa floppy drive
... dahil walang disc sa CD-ROM drive
... dahil walang tape sa tape drive
... dahil walang memory stick sa card reader

At nangyari nga...
open(pathname = "/dev/cdrom", flags = O_RDONLY) nabigo, Walang nakitang medium (123,
ENOMEDIUM) dahil mukhang walang disc sa CD-ROM drive
Ang trick, na dati nang hindi alam ng may-akda, ay buksan ang device gamit ang
O_NONBLOCK flag, na magbibigay-daan sa iyong magbukas ng drive na walang medium sa loob nito. Ikaw noon
partikular na isyu sa device ioctls(2) humihiling hanggang sa malaman mo kung ano ito. (Hindi
sigurado kung ito ay POSIX, ngunit tila gumagana din ito sa BSD at Solaris, ayon sa
ang wodim(1) mga mapagkukunan.)

Pansinin din ang magkakaibang paggamit ng "disk" at "disc" sa konteksto. Nagmula ang pamantayan ng CD
sa France, ngunit lahat ng iba ay may "k".

EFAULT, Masama tirahan
Ang anumang tawag sa system na kumukuha ng argumento ng pointer ay maaaring magbalik ng EFAULT. Ang libexplain library
maaaring malaman kung aling argumento ang may kasalanan, at ginagawa nito ito nang hindi nakakagambala sa proseso
(o thread) paghawak ng signal.

Kapag available, ang mincore(2) sistema ng tawag ay ginagamit, upang tanungin kung ang memory rehiyon ay wasto.
Maaari itong magbalik ng tatlong resulta: nakamapa ngunit hindi sa pisikal na memorya, nakamapa at sa pisikal
memorya, at hindi nakamapa. Kapag sinusuri ang bisa ng isang pointer, ang unang dalawa ay "oo"
at ang huli ay "hindi".

Ang pagsuri sa mga string ng C ay mas mahirap, dahil sa halip na isang pointer at isang sukat, kami lamang
may pointer. Upang matukoy ang laki na kailangan nating hanapin ang NUL, at magagawa iyon
segfault, catch-22.

Upang ayusin ito, ginagamit ng libexplain library ang lstat(2) sysem call (na may kilala
magandang pangalawang argumento) upang subukan ang mga string ng C para sa bisa. A failure return && errno == EFAULT
ay isang "hindi", at anumang iba pa ay isang "oo". Siyempre, nililimitahan nito ang mga string sa PATH_MAX
mga character, ngunit kadalasan ay hindi problema para sa libexplain library, dahil iyon nga
halos palaging ang pinakamahabang string na pinapahalagahan nito.

EMFILE, Masyado marami buksan file
Ang error na ito ay nangyayari kapag ang isang proseso ay mayroon nang maximum na bilang ng mga file descriptor na nakabukas.
Kung ang aktwal na limitasyon ay ipi-print, at sinubukan ng libexplain library, hindi mo mabubuksan
isang file sa / proc para basahin kung ano ito.
open_max = sysconf(_SC_OPEN_MAX);
Ang isang ito ay hindi napakahirap, mayroong isang sysconf(3) paraan ng pagkuha ng limitasyon.

ENFILE, Masyado marami buksan file in sistema
Ang error na ito ay nangyayari kapag ang limitasyon ng system sa kabuuang bilang ng mga bukas na file ay naging
naabot. Sa kasong ito walang madaling gamitin sysconf(3) paraan ng pagkuha ng limitasyon.

Sa paghuhukay ng mas malalim, maaaring matuklasan ng isa na sa Linux mayroong isang / proc entry na mababasa natin
makuha ang halagang ito. Catch‐22: wala na kami sa mga file descriptor, kaya hindi kami makapagbukas ng file sa
basahin ang limitasyon.

Sa Linux mayroong system call para makuha ito, ngunit wala itong [e]glibc wrapper function, kaya
kailangan mong gawin ang lahat ng ito nang maingat:
mahaba
explain_maxfile(walang bisa)
{
#ifdef __linux__
struct __sysctl_args args;
int32_t maxfile;
size_t maxfile_size = sukat ng(maxfile);
int name[] = { CTL_FS, FS_MAXFILE };
memset(&args, 0, sizeof(struct __sysctl_args));
args.name = pangalan;
args.nlen = 2;
args.oldval = &maxfile;
args.oldlenp = &maxfile_size;
if (syscall(SYS__sysctl, &args) >= 0)
ibalik ang maxfile;
#endif
bumalik -1;
}
Pinapahintulutan nito ang limitasyon na maisama sa mensahe ng error, kapag available.

EINVAL “Invalid argumento” vs ENOSYS “Pag-andar hindi ipinatupad”
Mga hindi sinusuportahang aksyon (tulad ng symlink(2) sa isang FAT file system) ay hindi naiulat
tuloy-tuloy mula sa isang system call hanggang sa susunod. Posibleng magkaroon ng EINVAL o
Bumalik si ENOSYS.

Bilang resulta, dapat bigyang pansin ang mga kaso ng error na ito upang maitama ang mga ito, lalo na
dahil ang EINVAL ay maaari ding tumutukoy sa mga problema sa isa o higit pang mga argumento ng system call.

nota na mali(3) is hindi palagi itakda
May mga pagkakataong kailangang basahin ang [e]glibc sources upang matukoy kung paano at
kapag ang mga error ay ibinalik para sa ilang mga tawag sa system.

feofNa (3), fileno(3)
Madalas na ipinapalagay na ang mga function na ito ay hindi maaaring magbalik ng isang error. Ito ay totoo lamang kung
ang daloy Ang argumento ay wasto, gayunpaman sila ay may kakayahang makakita ng isang hindi wasto
pointer

fpathconfNa (3), pathconf(3)
Ang return value ng fpathconf(2) at pathconf(2) ay maaaring lehitimong maging -1, kaya nga
kinakailangan upang makita kung mali(3) ay tahasang itinakda.

ioctls(2)
Ang return value ng ioctlsAng (2) ay maaaring lehitimong maging -1, kaya kinakailangan upang makita kung
mali(3) ay tahasang itinakda.

readdir(3)
Ang return value ng readdir(3) ay NULL para sa parehong mga error at end-of-file. Ito ay
kinakailangan upang makita kung mali(3) ay tahasang itinakda.

setbufNa (3), setbufferNa (3), setlinebufNa (3), setvbuf(3)
Lahat maliban sa huli sa mga function na ito ay bumalik na walang bisa. At setvbuf(3) ay dokumentado lamang bilang
nagbabalik ng "non-zero" kapag nagkamali. Ito ay kinakailangan upang makita kung mali(3) ay tahasang
itakda.

strtodNa (3), strtolNa (3), strtoldNa (3), strotollNa (3), strtoulNa (3), strtoull(3)
Ang mga function na ito ay nagbabalik ng 0 kapag nagkamali, ngunit iyon ay isa ring lehitimong halaga ng pagbabalik. Ito ay
kinakailangan upang makita kung mali(3) ay tahasang itinakda.

ungetc(3)
Bagama't iisang character lang ng backup ang ipinag-uutos ng pamantayan ng ANSI C, lumiliko ito
na pinahihintulutan ng [e]glibc ang higit pa... ngunit nangangahulugan iyon na maaari itong mabigo sa ENOMEM. Maaari itong
bagsak din sa EBADF kung fp ay huwad. Pinakamahirap sa lahat, kung pumasa ka sa EOF ng isang error
nangyayari ang pagbabalik, ngunit hindi nakatakda ang errno.

Nakikita ng libexplain library nang tama ang lahat ng mga error na ito, kahit na sa mga kaso kung saan ang
ang mga halaga ng error ay hindi gaanong naidokumento, kung mayroon man.

ENOSPC, Hindi puwang kaliwa on aparato
Kapag ang error na ito ay tumutukoy sa isang file sa isang file system, ini-print ng libexplain library ang mount
punto ng file system na may problema. Maaari nitong gawin ang pinagmulan ng error
mas malinaw
write(fildes = 1 "halimbawa", data = 0xbfff2340, data_size = 5) nabigo, Walang natitira sa espasyo
sa device (28, ENOSPC) dahil ang file system na naglalaman ng mga fildes ("/ home") ay wala
mas maraming espasyo para sa data
Habang nagdaragdag ng higit pang espesyal na suporta sa device, inaasahang kasama sa mga mensahe ng error ang device
pangalan at aktwal na laki ng device.

EROFS, Basahin lamang file sistema
Kapag ang error na ito ay tumutukoy sa isang file sa isang file system, ini-print ng libexplain library ang mount
punto ng file system na may problema. Maaari nitong gawin ang pinagmulan ng error
mas malinaw

Habang nagdaragdag ng higit pang espesyal na suporta sa device, inaasahang kasama sa mga mensahe ng error ang device
pangalan at uri.
open(pathname = "/dev/fd0", O_RDWR, 0666) failed, Read-only file system (30, EROFS)
dahil ang floppy disk ay may write protect tab set

...dahil ang CD-ROM ay hindi nasusulat
...dahil ang memory card ay may write protect tab set
...dahil ang ½ pulgadang magnetic tape ay walang write ring

palitan ang pangalan
Ang palitan ang pangalan(2) system call ay ginagamit upang baguhin ang lokasyon o pangalan ng isang file, ilipat ito
sa pagitan ng mga direktoryo kung kinakailangan. Kung ang patutunguhang pathname ay umiiral na ito ay magiging
atomically pinalitan, kaya na walang punto sa kung saan ang isa pang proseso na sinusubukang gawin
ma-access ito ay makikita itong nawawala.

May mga limitasyon, gayunpaman: maaari mo lamang palitan ang pangalan ng isang direktoryo sa ibabaw ng isa pa
direktoryo kung ang direktoryo ng patutunguhan ay walang laman.
rename(oldpath = "foo", newpath = "bar") bigo, Directory not empty (39,
ENOTEMPTY) dahil ang newpath ay hindi isang walang laman na direktoryo; ibig sabihin, naglalaman ito ng mga entry
maliban sa "." at ".."
Hindi mo rin mapapalitan ang pangalan ng isang direktoryo sa itaas ng isang hindi direktoryo.
rename(oldpath = "foo", newpath = "bar") ay nabigo, Hindi isang direktoryo (20, ENOTDIR)
dahil ang oldpath ay isang direktoryo, ngunit ang newpath ay isang regular na file, hindi isang direktoryo
Hindi rin pinapayagan ang kabaligtaran
rename(oldpath = "foo", newpath = "bar") ay nabigo, Ay isang direktoryo (21, EISDIR)
dahil ang newpath ay isang direktoryo, ngunit ang oldpath ay isang regular na file, hindi isang direktoryo

Ito, siyempre, ay ginagawang mas kumplikado ang trabaho ng libexplain library, dahil ang
unlink(2) o ay rm(2) tawag sa sistema ay tinatawag na tahasan ng palitan ang pangalan(2), at kaya lahat ng
unlink(2) o ay rm(2) ang mga error ay dapat makita at mahawakan din.

dup2
Ang dup2(2) system call ay ginagamit upang lumikha ng pangalawang file descriptor na tumutukoy sa
parehong bagay bilang ang unang file descriptor. Kadalasan ito ay ginagamit upang ipatupad ang shell input
at pag-redirect ng output.

Ang nakakatuwang bagay ay iyon, tulad ng palitan ang pangalan(2) maaaring atomically palitan ang pangalan ng isang file sa itaas ng isang
umiiral na file at alisin ang lumang file, dup2(2) ay maaaring gawin ito sa isang naka-bukas na file
deskriptor.

Muli, ginagawa nitong mas kumplikado ang trabaho ng libexplain library, dahil ang malapit(2)
tawag sa system ay implicitly na tinatawag ng dup2(2), at lahat ng malapitAng mga pagkakamali ni (2) ay dapat
nakita at nahawakan, pati na rin.

Pakikipagsapalaran IN IOCTL SUPORTA


Ang ioctls(2) ang system call ay nagbibigay sa mga may-akda ng driver ng device ng isang paraan upang makipag-usap
user-space na hindi akma sa loob ng umiiral na kernel API. Tingnan mo ioctl_listNa (2).

Pagkabasa Hiling Numero
Mula sa isang mabilis na pagtingin sa ioctls(2) interface, magkakaroon ng isang malaki ngunit may hangganan
bilang ng posible ioctls(2) mga kahilingan. Magkaiba ang bawat isa ioctls(2) ang kahilingan ay epektibo
isa pang tawag sa system, ngunit walang anumang uri-kaligtasan - hindi makakatulong ang compiler a
tama ang mga programmer. Ito marahil ang motibasyon sa likod tcflush(3) at
mga kaibigan.

Ang unang impression ay maaari kang mag-decode ioctls(2) mga kahilingan gamit ang isang malaking switch
pahayag. Ito ay lumalabas na hindi magagawa dahil ang isa ay napakabilis na natuklasan na ito ay
imposibleng isama ang lahat ng kinakailangang mga header ng system na tumutukoy sa iba't-ibang ioctls(2)
mga kahilingan, dahil nahihirapan silang makipaglaro ng mabuti sa isa't isa.

Ang mas malalim na pagtingin ay nagpapakita na mayroong isang hanay ng mga "pribado" na numero ng kahilingan, at device
hinihikayat ang mga may-akda ng driver na gamitin ang mga ito. Nangangahulugan ito na mayroong isang mas malaking posible
hanay ng mga kahilingan, na may hindi tiyak na mga numero ng kahilingan, kaysa sa kaagad na nakikita. Gayundin,
may ilang mga makasaysayang kalabuan din.

Alam na namin na ang switch ay hindi praktikal, ngunit ngayon alam namin na upang piliin ang
angkop na pangalan ng kahilingan at paliwanag dapat nating isaalang-alang hindi lamang ang numero ng kahilingan kundi
din ang file descriptor.

Ang pagpapatupad ng ioctls(2) ang suporta sa loob ng libexplain library ay ang pagkakaroon ng table ng
mga payo sa ioctls(2) humiling ng mga deskriptor. Ang bawat isa sa mga deskriptor na ito ay may kasamang opsyonal
pointer sa isang function ng disambiguation.

Ang bawat kahilingan ay aktwal na ipinatupad sa isang hiwalay na source file, upang ang kinakailangan
isama ang mga file ay hinalinhan ng obligasyon na makipaglaro ng mabuti sa iba.

Pagkatawan
Ang pilosopiya sa likod ng libexplain library ay ang magbigay ng mas maraming impormasyon gaya ng
posible, kabilang ang isang tumpak na representasyon ng system call. Sa kaso ng
ioctls(2) nangangahulugan ito ng pag-print ng tamang numero ng kahilingan (sa pangalan) at isang tama (o
hindi bababa sa kapaki-pakinabang) representasyon ng ikatlong argumento.

Ang ioctls(2) ganito ang hitsura ng prototype:
int ioctl(int fildes, int kahilingan, ...);
na dapat ay tumunog ang iyong mga uri-safety alarm. Sa loob ng [e]glibc, ito ay nakabukas
sa iba't ibang anyo:
int __ioctl(int fildes, int request, long arg);
int __ioctl(int fildes, int request, void *arg);
at inaasahan ng Linux kernel syscall interface
asmlinkage long sys_ioctl(unsigned int fildes, unsigned int request, unsigned long
arg);
Ang matinding pagkakaiba-iba ng ikatlong argumento ay isang hamon, kapag ang libexplain library
sumusubok na mag-print ng representasyon ng ikatlong argumentong iyon. Gayunpaman, sa sandaling ang numero ng kahilingan
ay na-disambiguated, ang bawat entry sa ioctl table ng libexplain library ay may a
custom print_data function (OO tapos na mano-mano).

Mga Paliwanag
Mas kaunti ang mga problema sa pagtukoy sa paliwanag na gagamitin. Kapag ang request number
ay na-disambiguated, ang bawat entry sa ioctl table ng libexplain library ay may custom
print_explanation function (muli, OO tapos manually).

Hindi tulad ng section 2 at section 3 system calls, karamihan ioctls(2) ang mga kahilingan ay walang mga pagkakamali
dokumentado. Nangangahulugan ito, upang magbigay ng magandang paglalarawan ng error, kinakailangan na basahin ang kernel
mga mapagkukunan upang matuklasan

· Ano mali(3) ang mga halaga ay maaaring ibalik, at

· ang sanhi ng bawat pagkakamali.

Dahil sa likas na OO ng function na pagpapadala ng tawag sa kernel, kailangan mong basahin
lahat mga mapagkukunan na nagpapatupad nito ioctls(2) kahilingan, hindi lamang ang pangkalahatang pagpapatupad. Ito
ay inaasahan na ang iba't ibang mga kernel ay magkakaroon ng iba't ibang mga numero ng error at banayad
iba't ibang sanhi ng pagkakamali.

EINVAL vs ENOTTY
Ang sitwasyon ay mas masahol pa para sa ioctls(2) mga kahilingan kaysa sa mga system call, kasama ang EINVAL at
ENOTTY parehong ginagamit upang ipahiwatig na ang isang ioctls(2) ang kahilingan ay hindi nararapat doon
konteksto, at paminsan-minsan ang ENOSYS, ENOTSUP at EOPNOTSUPP (ginamit para sa mga socket) bilang
mabuti. May mga komento sa Linux kernel source na tila nagpapahiwatig ng isang progresibo
isinasagawa ang paglilinis. Para sa dagdag na kaguluhan, idinaragdag ng BSD ang ENOIOCTL sa kalituhan.

Bilang resulta, dapat bigyang pansin ang mga kaso ng error na ito upang maitama ang mga ito, lalo na
dahil ang EINVAL ay maaari ding tumutukoy sa mga problema sa isa o higit pang mga argumento ng system call.

inpttr_t
Tinutukoy ng pamantayan ng C99 ang isang uri ng integer na garantisadong makakahawak ng anumang pointer
nang walang pagkawala ng representasyon.

Ang function sa itaas na syscall prototype ay mas mahusay na isulat
long sys_ioctl(unsigned int fildes, unsigned int request, intptr_t arg);
Ang problema ay ang cognitive dissonance na dulot ng partikular sa device o file-system-specific.
ioctls(2) mga pagpapatupad, tulad ng:
long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
Ang karamihan ng ioctls(2) ang mga kahilingan ay talagang mayroong isang int *arg ikatlong argumento. Ngunit pagkakaroon nito
ipinahayag na mahaba ay humahantong sa code na tinatrato ito hangga't *arg. Ito ay hindi nakakapinsala sa 32-bits
(sizeof(long) == sizeof(int)) ngunit pangit sa 64‐bits (sizeof(long) != sizeof(int)).
Depende sa endian‐ness, nakukuha mo o hindi mo makuha ang halaga na iyong inaasahan, ngunit ikaw palagi makuha
isang memory scribble o stack scribble din.

Isinulat ang lahat ng ito bilang
int ioctl(int fildes, int kahilingan, ...);
int __ioctl(int fildes, int kahilingan, intptr_t arg);
long sys_ioctl(unsigned int fildes, unsigned int request, intptr_t arg);
mahabang vfs_ioctl(struct file *filp, unsigned int cmd, intptr_t arg);
binibigyang-diin na ang integer ay isang integer lamang upang kumatawan sa isang dami na halos
palaging isang hindi nauugnay na uri ng pointer.

Konklusyon


Gumamit ng libexplain, magugustuhan ito ng iyong mga user.

COPYRIGHT


libexplain bersyon 1.4
Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Peter Miller

Gamitin ang explain_lca2010 online gamit ang mga serbisyo ng onworks.net


Mga Libreng Server at Workstation

Mag-download ng Windows at Linux apps

  • 1
    SWIG
    SWIG
    Ang SWIG ay isang software development tool
    na nag-uugnay sa mga programang nakasulat sa C at
    C++ na may iba't ibang mataas na antas
    mga programming language. Ang SWIG ay ginagamit kasama ng
    iba...
    I-download ang SWIG
  • 2
    WooCommerce Nextjs React Theme
    WooCommerce Nextjs React Theme
    React WooCommerce theme, built with
    Susunod na JS, Webpack, Babel, Node, at
    Express, gamit ang GraphQL at Apollo
    Kliyente. Tindahan ng WooCommerce sa React(
    naglalaman ng: Mga produkto...
    I-download ang WooCommerce Nextjs React Theme
  • 3
    archlabs_repo
    archlabs_repo
    Package repo para sa ArchLabs Ito ay isang
    application na maaari ding makuha
    mula
    https://sourceforge.net/projects/archlabs-repo/.
    Ito ay na-host sa OnWorks sa...
    I-download ang archlabs_repo
  • 4
    Zephyr Project
    Zephyr Project
    Ang Zephyr Project ay isang bagong henerasyon
    real-time na operating system (RTOS) na
    sumusuporta sa maramihang hardware
    mga arkitektura. Ito ay batay sa a
    maliit na footprint kernel...
    I-download ang Zephyr Project
  • 5
    SCons
    SCons
    Ang SCons ay isang tool sa pagbuo ng software
    iyon ay isang superior alternatibo sa
    classic na "Make" build tool na
    alam at mahal nating lahat. Ang SCons ay
    nagpatupad ng...
    I-download ang SCons
  • 6
    PSeInt
    PSeInt
    Ang PSeInt ay isang pseudo-code interpreter para sa
    mga mag-aaral sa programming na nagsasalita ng Espanyol.
    Ang pangunahing layunin nito ay maging kasangkapan para sa
    pag-aaral at pag-unawa sa basic
    konsepto...
    I-download ang PSeInt
  • Marami pa »

Linux command

Ad