ພາສາອັງກິດພາສາຝຣັ່ງແອສປາໂຍນ

Ad


OnWorks favicon

explain_lca2010 - ອອນລາຍໃນຄລາວ

ດໍາເນີນການອະທິບາຍ_lca2010 ໃນ OnWorks ຜູ້ໃຫ້ບໍລິການໂຮດຕິ້ງຟຣີຜ່ານ Ubuntu Online, Fedora Online, Windows online emulator ຫຼື MAC OS online emulator

ນີ້ແມ່ນຄໍາສັ່ງອະທິບາຍ_lca2010 ທີ່ສາມາດດໍາເນີນການໄດ້ໃນ OnWorks ຜູ້ໃຫ້ບໍລິການໂຮດຕິ້ງຟຣີໂດຍໃຊ້ຫນຶ່ງໃນຫຼາຍໆບ່ອນເຮັດວຽກອອນໄລນ໌ຂອງພວກເຮົາເຊັ່ນ Ubuntu Online, Fedora Online, Windows online emulator ຫຼື MAC OS online emulator

ໂຄງການ:

NAME


explain_lca2010 - ບໍ່ພົບສື່ກາງ: ເມື່ອເຖິງເວລາຢຸດພະຍາຍາມອ່ານ ຄວາມຜິດພາດ(3) ຂອງ
ຈິດໃຈ.

ແຮງຈູງໃຈ


ແນວຄວາມຄິດສໍາລັບ libexplain ເກີດຂຶ້ນກັບຂ້ອຍໃນຕົ້ນຊຸມປີ 1980. ທຸກຄັ້ງທີ່ລະບົບໂທ
ສົ່ງຄືນຂໍ້ຜິດພາດ, kernel ຮູ້ສິ່ງທີ່ຜິດພາດ ... ແລະບີບອັດມັນເຂົ້າໄປໃນ
ຫນ້ອຍກວ່າ 8 bits ຂອງ ຜິດພາດ. ພື້ນທີ່ຜູ້ໃຊ້ມີການເຂົ້າເຖິງຂໍ້ມູນດຽວກັນກັບ kernel, ມັນ
ຄວນຈະເປັນໄປໄດ້ສໍາລັບພື້ນທີ່ຜູ້ໃຊ້ທີ່ຈະຄິດອອກຢ່າງແທ້ຈິງສິ່ງທີ່ເກີດຂຶ້ນເພື່ອ provoke ຄວາມຜິດພາດ
ກັບຄືນ, ແລະໃຊ້ນີ້ເພື່ອຂຽນຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ດີ.

ມັນອາດຈະເປັນແບບງ່າຍໆບໍ?

Error ຂໍ້ຄວາມ as ຄວາມງາມ
ຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ດີມັກຈະເປັນ "ຫນຶ່ງເປີເຊັນ" ວຽກງານທີ່ຫຼຸດລົງໃນເວລາທີ່ກໍານົດເວລາ
ຄວາມກົດດັນບີບບັງຄັບໂຄງການຂອງທ່ານ. ຢ່າງໃດກໍຕາມ, ຂໍ້ຄວາມຜິດພາດທີ່ດີສາມາດເຮັດໃຫ້ຂະຫນາດໃຫຍ່,
ການປັບປຸງທີ່ບໍ່ສົມດຸນກັບປະສົບການຂອງຜູ້ໃຊ້, ເມື່ອຜູ້ໃຊ້ເຂົ້າໄປໃນຄວາມຢ້ານ
ອານາເຂດທີ່ບໍ່ຮູ້ຈັກມັກຈະບໍ່ພົບ. ນີ້ບໍ່ແມ່ນວຽກງ່າຍ.

ໃນຖານະເປັນນັກຂຽນໂປລແກລມຕົວອ່ອນ, ຜູ້ຂຽນບໍ່ໄດ້ເຫັນບັນຫາທີ່ມີຄວາມຜິດພາດ (ຖືກຕ້ອງຢ່າງສົມບູນ)
ຂໍ້ຄວາມຄືອັນນີ້:
ຂໍ້ຍົກເວັ້ນແບບເລື່ອນ (ຫຼັກຖືກຖິ້ມ)
ຈົນ​ກ​່​ວາ​ການ​ຕີ​ລາ​ຄາ​ທີ່​ບໍ່​ແມ່ນ​ໂຄງ​ການ​ທາງ​ເລືອກ​ໄດ້​ຖືກ​ຊີ້​ອອກ​. ແຕ່ນັ້ນບໍ່ແມ່ນ
ສິ່ງດຽວທີ່ຜິດພາດກັບຂໍ້ຄວາມຜິດພາດ Unix. ເຈົ້າເຫັນຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດເລື້ອຍໆສໍ່າໃດເຊັ່ນ:
$ ./ໂງ່
ບໍ່ສາມາດເປີດໄຟລ໌ໄດ້
$
ມີສອງທາງເລືອກສໍາລັບນັກພັດທະນາໃນຈຸດນີ້:

1.
ທ່ານສາມາດດໍາເນີນການ debugger ໄດ້, ເຊັ່ນ: gdb(1), ຫຼື

2.
ທ່ານສາມາດໃຊ້ ສາຍແຮ່(1) ຫຼື ມັດ(1) ເພື່ອເບິ່ງພາຍໃນ.

· ຈື່ໄວ້ວ່າຜູ້ໃຊ້ຂອງທ່ານອາດຈະບໍ່ມີການເຂົ້າເຖິງເຄື່ອງມືເຫຼົ່ານີ້, ປ່ອຍໃຫ້ຄວາມສາມາດ
ເພື່ອໃຊ້ພວກມັນ. (ມັນ​ເປັນ​ເວ​ລາ​ດົນ​ນານ​ຫຼາຍ​ນັບ​ຕັ້ງ​ແຕ່​ Unix ຜູ້ເລີ່ມຕົ້ນ ຫມາຍຄວາມວ່າ "ໄດ້ຂຽນພຽງແຕ່ ຫນຶ່ງ
ໄດເວີອຸປະກອນ”.)

ໃນຕົວຢ່າງນີ້, ຢ່າງໃດກໍຕາມ, ການນໍາໃຊ້ ສາຍແຮ່(1) ເປີດເຜີຍ
$ ສາຍແຮ່ -e trace=ເປີດ ./ໂງ່
open("some/file", O_RDONLY) = -1 ENOENT (ບໍ່ມີໄຟລ໌ ຫຼືໄດເລກະທໍລີດັ່ງກ່າວ)
ບໍ່ສາມາດເປີດໄຟລ໌ໄດ້
$
ນີ້ແມ່ນຂໍ້ມູນຫຼາຍຫຼາຍກ່ວາຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດ. ໂດຍປົກກະຕິ, ໄດ້
ລະຫັດແຫຼ່ງ stupid ເບິ່ງຄືວ່ານີ້
int fd = ເປີດ("ບາງ​ສິ່ງ​ບາງ​ຢ່າງ​", O_RDONLY);
ຖ້າ (fd < 0)
{
fprintf(stderr, "ບໍ່ສາມາດເປີດໄຟລ໌ໄດ້\n");
ການທ່ອງທ່ຽວ(1)
}
ຜູ້ໃຊ້ບໍ່ໄດ້ບອກ ທີ່ ໄຟລ໌, ແລະຍັງບໍ່ສາມາດບອກຜູ້ໃຊ້ໄດ້ ທີ່ ຄວາມຜິດພາດ. ແມ່ນໄຟລ໌
ແມ້ແຕ່ມີ? ມີບັນຫາການອະນຸຍາດບໍ? ມັນບອກເຈົ້າວ່າມັນກໍາລັງພະຍາຍາມເປີດ a
ໄຟລ໌, ແຕ່ວ່າອາດຈະເປັນໂດຍບັງເອີນ.

ຈັບໄມ້ຄ້ອນເທົ້າຂອງເຈົ້າແລ້ວໄປຕີໂປຣແກມເມີເຕີຕົວອ່ອນກັບມັນ. ບອກລາວກ່ຽວກັບ ຄວາມຜິດພາດ(3).
ໃນຄັ້ງຕໍ່ໄປທີ່ທ່ານໃຊ້ໂປຣແກຣມ ທ່ານຈະເຫັນຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ແຕກຕ່າງກັນ:
$ ./ໂງ່
ເປີດ: ບໍ່ມີໄຟລ໌ຫຼືໄດເລກະທໍລີດັ່ງກ່າວ
$
ຄວາມກ້າວຫນ້າ, ແຕ່ບໍ່ແມ່ນສິ່ງທີ່ພວກເຮົາຄາດຫວັງ. ຜູ້ໃຊ້ສາມາດແກ້ໄຂບັນຫາໄດ້ແນວໃດຖ້າຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດ
ບໍ່ບອກລາວວ່າບັນຫາແມ່ນຫຍັງ? ຊອກຫາຢູ່ໃນແຫຼ່ງ, ພວກເຮົາເຫັນ
int fd = ເປີດ("ບາງ​ສິ່ງ​ບາງ​ຢ່າງ​", O_RDONLY);
ຖ້າ (fd < 0)
{
perror("ເປີດ");
ການທ່ອງທ່ຽວ(1)
}
ເວລາສໍາລັບການແລ່ນອີກຄັ້ງດ້ວຍໄມ້ຄ້ອນເທົ້າ. ເວລານີ້, ຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດໃຊ້ເວລາຫນຶ່ງຂັ້ນຕອນ
ໄປ​ຂ້າງ​ຫນ້າ​ແລະ​ຫນຶ່ງ​ບາດ​ກ້າວ​ກັບ​ຄືນ​ໄປ​ບ່ອນ​:
$ ./ໂງ່
ບາງ​ສິ່ງ​ບາງ​ຢ່າງ​: ບໍ່ມີເອກະສານຫລືໄດເລກະທໍລີດັ່ງກ່າວ
$
ດຽວນີ້ພວກເຮົາຮູ້ວ່າໄຟລ໌ທີ່ມັນພະຍາຍາມເປີດ, ແຕ່ບໍ່ໄດ້ແຈ້ງວ່າມັນແມ່ນ ເປີດ(2​)
ລົ້ມເຫລວ. ໃນ​ກໍ​ລະ​ນີ​ນີ້​ມັນ​ອາດ​ຈະ​ບໍ່​ມີ​ຄວາມ​ສໍາ​ຄັນ​, ແຕ່​ວ່າ​ມັນ​ສາ​ມາດ​ສໍາ​ຄັນ​ສໍາ​ລັບ​ການ​
ໂທລະບົບອື່ນໆ. ມັນອາດຈະເປັນ ສ້າງສັນ(2​) ແທນ​ທີ່​ຈະ​ເປັນ​, ການ​ດໍາ​ເນີນ​ງານ​ຫມາຍ​ຄວາມ​ວ່າ​
ການອະນຸຍາດທີ່ແຕກຕ່າງກັນແມ່ນມີຄວາມຈໍາເປັນ.
const char *filename = "ບາງ​ສິ່ງ​ບາງ​ຢ່າງ​";
int fd = ເປີດ(ຊື່ໄຟລ໌, O_RDONLY);
ຖ້າ (fd < 0)
{
ຜິດ​ພາດ (ຊື່​ໄຟລ​໌​)​;
ການທ່ອງທ່ຽວ(1)
}
ລະຫັດຕົວຢ່າງຂ້າງເທິງແມ່ນຫນ້າເສຍດາຍປົກກະຕິຂອງນັກຂຽນໂປລແກລມທີ່ບໍ່ແມ່ນຕົວອ່ອນເຊັ່ນກັນ. ເວລາ
ເພື່ອບອກຜູ້ຮຽນ padawan ຂອງພວກເຮົາກ່ຽວກັບ ຄວາມຜິດພາດ(3) ລະບົບການໂທ.
$ ./ໂງ່
ເປີດ ບາງ​ສິ່ງ​ບາງ​ຢ່າງ​: ບໍ່ມີເອກະສານຫລືໄດເລກະທໍລີດັ່ງກ່າວ
$
ນີ້ເຮັດໃຫ້ຂໍ້ມູນສູງສຸດທີ່ສາມາດນໍາສະເຫນີໃຫ້ຜູ້ໃຊ້ໄດ້. ລະຫັດເບິ່ງຄືວ່າ
ນີ້:
const char *filename = "ບາງ​ສິ່ງ​ບາງ​ຢ່າງ​";
int fd = ເປີດ(ຊື່ໄຟລ໌, O_RDONLY);
ຖ້າ (fd < 0)
{
fprintf(stderr, "open %s: %s\n", ຊື່ໄຟລ໌, strerror(errno));
ການທ່ອງທ່ຽວ(1)
}
ໃນປັດຈຸບັນພວກເຮົາມີການໂທລະບົບ, ຊື່ໄຟລ໌, ແລະສາຍຄວາມຜິດພາດ. ນີ້ປະກອບດ້ວຍທັງຫມົດ
ຂໍ້​ມູນ​ທີ່​ ສາຍແຮ່(1) ພິມ. ນັ້ນແມ່ນດີເທົ່າທີ່ມັນໄດ້ຮັບ.

ຫລືມັນແມ່ນບໍ?

ຂໍ້ຈໍາກັດ of ຄວາມຜິດພາດ ແລະ ຄວາມຜິດພາດ
ບັນຫາທີ່ຜູ້ຂຽນເຫັນ, ໃນຊຸມປີ 1980, ແມ່ນວ່າຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດບໍ່ຄົບຖ້ວນ.
"ບໍ່ມີເອກະສານຫຼືໄດເລກະທໍລີດັ່ງກ່າວ" ຫມາຍເຖິງ "ບາງ"ໄດເລກະທໍລີ" ຫຼື "ສິ່ງທີ່” ໄຟລ໌ໃນ
ໄດ້“ບາງ” ໄດເລກະທໍລີ?

ເບິ່ງໄວຢູ່ໃນຫນ້າຜູ້ຊາຍສໍາລັບ ຄວາມຜິດພາດ(3) ກໍາລັງບອກ:
strerror - ກັບຄືນສະຕຣິງທີ່ອະທິບາຍຈໍານວນຂໍ້ຜິດພາດ
ຫມາຍເຫດດີ: ມັນແມ່ນການອະທິບາຍຄວາມຜິດພາດ ຈໍານວນ, ບໍ່ແມ່ນຄວາມຜິດພາດ.

ໃນທາງກົງກັນຂ້າມ, ແກ່ນ ຮູ້ຈັກ ຄວາມຜິດພາດແມ່ນຫຍັງ. ມີຈຸດສະເພາະຢູ່ໃນ
ລະຫັດ kernel, ທີ່ເກີດຈາກເງື່ອນໄຂສະເພາະໃດຫນຶ່ງ, ບ່ອນທີ່ລະຫັດ kernel ແຍກແລະເວົ້າວ່າ "ບໍ່".
ໂຄງການພື້ນທີ່ຜູ້ໃຊ້ສາມາດຊອກຫາເງື່ອນໄຂສະເພາະແລະຂຽນຂໍ້ຜິດພາດທີ່ດີກວ່າ
ຂໍ້ຄວາມ?

ຢ່າງໃດກໍຕາມ, ບັນຫາແມ່ນເລິກລົງ. ຈະເປັນແນວໃດຖ້າຫາກວ່າບັນຫາເກີດຂຶ້ນໃນລະຫວ່າງການ ອ່ານ(2) ລະບົບ
ໂທ, ແທນທີ່ຈະກ່ວາ ເປີດ(2) ໂທ? ມັນງ່າຍດາຍສໍາລັບຂໍ້ຄວາມຄວາມຜິດພາດທີ່ກ່ຽວຂ້ອງກັບ
ເປີດ(2​) ເພື່ອ​ປະ​ກອບ​ມີ​ຊື່​ໄຟລ​໌​, ມັນ​ຢູ່​ທີ່​ນັ້ນ​. ແຕ່ເພື່ອໃຫ້ສາມາດປະກອບມີຊື່ໄຟລ໌
ໃນ​ຄວາມ​ຜິດ​ພາດ​ທີ່​ກ່ຽວ​ຂ້ອງ​ກັບ​ ອ່ານ(2) ການໂທລະບົບ, ທ່ານຕ້ອງຜ່ານຊື່ໄຟລ໌ທັງຫມົດ
ວິທີການລົງ stack ການໂທ, ເຊັ່ນດຽວກັນກັບຕົວອະທິບາຍໄຟລ໌.

ແລະນີ້ແມ່ນເລັກນ້ອຍທີ່ grate: kernel ຮູ້ແລ້ວວ່າໄຟລ໌ຊື່ໄຟລ໌ໃດ
ຕົວອະທິບາຍແມ່ນກ່ຽວຂ້ອງກັບ. ເປັນຫຍັງນັກຂຽນໂປລແກລມຕ້ອງຜ່ານຂໍ້ມູນທີ່ຊ້ໍາກັນທັງຫມົດ
ວິທີການລົງ stack ການໂທພຽງແຕ່ເພື່ອປັບປຸງຂໍ້ຄວາມຄວາມຜິດພາດທີ່ອາດຈະບໍ່ໄດ້ຮັບການອອກ? ໃນ
ຄວາມເປັນຈິງ, ນັກຂຽນໂປລແກລມຫຼາຍຄົນບໍ່ເບື່ອຫນ່າຍ, ແລະຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ເກີດຂື້ນແມ່ນຮ້າຍແຮງກວ່າເກົ່າ
ມັນ.

ແຕ່ນັ້ນແມ່ນຊຸມປີ 1980, ໃນ PDP11, ມີຊັບພະຍາກອນທີ່ຈໍາກັດແລະບໍ່ມີຫ້ອງສະຫມຸດຮ່ວມກັນ. ກັບຄືນໄປບ່ອນ
ຫຼັງຈາກນັ້ນ, ບໍ່ມີລົດຊາດຂອງ Unix ລວມ / proc ເຖິງແມ່ນວ່າໃນຮູບແບບພື້ນຖານ, ແລະ lsof(1) ໂຄງການ
ຫ່າງ​ໄກ​ຫຼາຍ​ກວ່າ​ທົດ​ສະ​ວັດ. ສະນັ້ນ ຄວາມຄິດດັ່ງກ່າວຈຶ່ງຖືກຫຼົງເຫຼືອໄວ້ເປັນສິ່ງທີ່ບໍ່ມີປະໂຫຍດ.

ລະດັບ Infinity ສະຫນັບສະຫນູນ
ຈິນຕະນາການວ່າທ່ານເປັນຜູ້ສະຫນັບສະຫນູນລະດັບ infinity. ລາຍລະອຽດວຽກຂອງເຈົ້າບອກວ່າເຈົ້າບໍ່ເຄີຍ
ເຄີຍ ຕ້ອງເວົ້າກັບຜູ້ໃຊ້. ດັ່ງນັ້ນ, ເປັນຫຍັງ, ຍັງມີກະແສຂອງປະຊາຊົນຕ້ອງການຢ່າງຕໍ່ເນື່ອງ
ທ່ານ, guru Unix ທ້ອງຖິ່ນ, ເພື່ອຖອດລະຫັດຂໍ້ຄວາມຂໍ້ຜິດພາດອື່ນບໍ?

ແປກ, 25 ປີຕໍ່ມາ, ເຖິງວ່າຈະມີລະບົບການອະນຸຍາດທີ່ງ່າຍດາຍ, ປະຕິບັດຢ່າງສົມບູນ
ຄວາມສອດຄ່ອງ, ຜູ້ໃຊ້ Unix ສ່ວນໃຫຍ່ຍັງບໍ່ມີຄວາມຄິດທີ່ຈະຖອດລະຫັດ "ບໍ່ມີໄຟລ໌ຫຼືໄດເລກະທໍລີດັ່ງກ່າວ",
ຫຼືຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ເປັນລະຫັດລັບອື່ນໆທີ່ພວກເຂົາເຫັນທຸກໆມື້. ຫຼື, ຢ່າງຫນ້ອຍ, cryptic ກັບ
ໃຫ້ເຂົາເຈົ້າ.

ມັນຈະບໍ່ດີບໍຖ້າການສະຫນັບສະຫນູນເຕັກໂນໂລຢີລະດັບທໍາອິດບໍ່ຈໍາເປັນຕ້ອງມີຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ຖືກຖອດລະຫັດ?
ມັນບໍ່ດີບໍທີ່ຈະມີຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ຜູ້ໃຊ້ສາມາດເຂົ້າໃຈໄດ້ໂດຍບໍ່ຕ້ອງໂທຫາ
ສະ​ຫນັບ​ສະ​ຫນູນ​ເຕັກ​ໂນ​ໂລ​ຊີ​?

ມື້ນີ້ / proc ໃນ Linux ແມ່ນຫຼາຍກ່ວາສາມາດສະຫນອງຂໍ້ມູນທີ່ຈໍາເປັນເພື່ອຖອດລະຫັດ
ສ່ວນໃຫຍ່ຂອງຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດ, ແລະຊີ້ຜູ້ໃຊ້ໄປຫາສາເຫດໃກ້ຄຽງຂອງພວກມັນ
ບັນຫາ. ໃນ​ລະ​ບົບ​ທີ່​ມີ​ຈໍາ​ກັດ​ / proc ການ​ປະ​ຕິ​ບັດ​, ໄດ້​ lsof(1) ຄໍາສັ່ງສາມາດຕື່ມຂໍ້ມູນໃສ່ໃນ
ຊ່ອງຫວ່າງຫຼາຍ.

ໃນປີ 2008, ກະແສການຮ້ອງຂໍການແປພາສາເກີດຂຶ້ນກັບຜູ້ຂຽນເລື້ອຍໆເກີນໄປ. ມັນແມ່ນ
ເວລາທີ່ຈະທົບທວນຄືນຄວາມຄິດທີ່ມີອາຍຸ 25 ປີ, ແລະ libexplain ແມ່ນຜົນໄດ້ຮັບ.

ການ ນຳ ໃຊ້ ການ ຫໍສະຫມຸດ


ການໂຕ້ຕອບກັບຫ້ອງສະຫມຸດພະຍາຍາມທີ່ຈະສອດຄ່ອງ, ບ່ອນທີ່ເປັນໄປໄດ້. ໃຫ້ເລີ່ມຕົ້ນດ້ວຍ
ຕົວຢ່າງການນໍາໃຊ້ ຄວາມຜິດພາດ(3):
ຖ້າ (ປ່ຽນຊື່(old_path, new_path) < 0)
{
fprintf(stderr, "ປ່ຽນຊື່ %s %s: %s\n", old_path, new_path,
strerror(errno));
ການທ່ອງທ່ຽວ(1)
}
ແນວຄວາມຄິດທີ່ຢູ່ເບື້ອງຫລັງ libexplain ແມ່ນເພື່ອສະຫນອງ a ຄວາມຜິດພາດ(3) ທຽບເທົ່າສໍາລັບ ແຕ່ລະຄົນ ໂທ​ລະ​ບົບ​,
ປັບແຕ່ງສະເພາະກັບການໂທລະບົບນັ້ນ, ເພື່ອໃຫ້ມັນສາມາດສະຫນອງຄວາມຜິດພາດທີ່ລະອຽດກວ່າ
ຂໍ້ຄວາມ, ປະກອບດ້ວຍຂໍ້ມູນຫຼາຍຢ່າງທີ່ເຈົ້າເຫັນພາຍໃຕ້ຫົວຂໍ້ “Error” ຂອງພາກສ່ວນ
2 ແລະ 3 ຜູ້ຊາຍ ຫນ້າ, ເສີມດ້ວຍຂໍ້ມູນກ່ຽວກັບເງື່ອນໄຂຕົວຈິງ, ການໂຕ້ຖຽງຕົວຈິງ
ຄ່າ, ແລະຂໍ້ຈໍາກັດຂອງລະບົບ.

ໄດ້ ງ່າຍດາຍ ກໍລະນີ
ໄດ້ ຄວາມຜິດພາດ(3​) ການ​ທົດ​ແທນ​:
ຖ້າ (ປ່ຽນຊື່(old_path, new_path) < 0)
{
fprintf(stderr, "%s\n", explain_rename(old_path, new_path));
ການທ່ອງທ່ຽວ(1)
}

ໄດ້ ເອີໂຣ ກໍລະນີ
ມັນເປັນໄປໄດ້ທີ່ຈະຜ່ານຢ່າງຈະແຈ້ງ ຜິດພາດ(3) ມູນຄ່າ, ຖ້າຫາກວ່າທ່ານທໍາອິດຕ້ອງເຮັດບາງ
ການປະມວນຜົນທີ່ຈະລົບກວນ ຜິດພາດ, ເຊັ່ນ​ວ່າ​ການ​ຟື້ນ​ຕົວ​ຄວາມ​ຜິດ​ພາດ​:
ຖ້າ (ປ່ຽນຊື່(old_path, new_path < 0))
{
int old_errno = errno;
...ລະຫັດ ທີ່ ລົບກວນ ຜິດພາດ...
fprintf(stderr, "%s\n", ອະທິບາຍ_errno_rename(old_errno,
old_path, new_path));
ການທ່ອງທ່ຽວ(1)
}

ໄດ້ ຫຼາຍກະທູ້ ກໍລະນີ
ບາງແອັບພລິເຄຊັນແມ່ນມີຫຼາຍກະທູ້, ແລະດັ່ງນັ້ນຈຶ່ງບໍ່ສາມາດແບ່ງປັນ libexplain ພາຍໃນໄດ້
ບັຟເຟີ. ທ່ານສາມາດສະຫນອງ buffer ຂອງທ່ານເອງໂດຍໃຊ້
ຖ້າ (ຖອນການເຊື່ອມຕໍ່(ຊື່ເສັ້ນທາງ))
{
char message[3000];
explain_message_unlink(ຂໍ້ຄວາມ, ຂະຫນາດຂອງ(ຂໍ້ຄວາມ), ຊື່ເສັ້ນທາງ);
error_dialog(ຂໍ້ຄວາມ);
ກັບຄືນ -1;
}
ແລະສໍາລັບຄວາມສົມບູນ, ທັງສອງ ຜິດພາດ(3​) ແລະ​ປອດ​ໄພ​ກະ​ທູ້​:
ssize_t nbytes = read(fd, data, sizeof(data));
ຖ້າ (nbytes < 0)
{
char message[3000];
int old_errno = errno;
...ຄວາມຜິດພາດ ການຟື້ນຟູ...
explain_message_errno_read(ຂໍ້ຄວາມ, ຂະຫນາດຂອງ(ຂໍ້ຄວາມ),
old_errno, fd, data, sizeof(data));
error_dialog(ຂໍ້ຄວາມ);
ກັບຄືນ -1;
}

ເຫຼົ່ານີ້ແມ່ນການທົດແທນສໍາລັບການ strerror_r(3), ກ່ຽວກັບລະບົບທີ່ມີມັນ.

ການໂຕ້ຕອບ ້ໍາຕານ
ຊຸດຂອງຫນ້າທີ່ເພີ່ມເປັນຫນ້າທີ່ສະດວກ, ເພື່ອ woo programmer ທີ່ຈະນໍາໃຊ້
libexplain ຫໍສະຫມຸດ, ກາຍເປັນຫນ້າທີ່ libexplain ທີ່ໃຊ້ທົ່ວໄປທີ່ສຸດຂອງຜູ້ຂຽນໃນ
ໂຄງ​ການ​ເສັ້ນ​ຄໍາ​ສັ່ງ​:
int fd = ອະທິບາຍ_creat_or_die(ຊື່ໄຟລ໌, 0666);
ຟັງຊັນນີ້ພະຍາຍາມສ້າງໄຟລ໌ໃຫມ່. ຖ້າ​ຫາກ​ວ່າ​ມັນ​ບໍ່​ສາ​ມາດ​, ມັນ​ພິມ​ຂໍ້​ຄວາມ​ຜິດ​ພາດ​ແລະ​
ອອກໄປດ້ວຍ EXIT_FAILURE. ຖ້າບໍ່ມີຂໍ້ຜິດພາດ, ມັນຈະສົ່ງຄືນຕົວອະທິບາຍໄຟລ໌ໃຫມ່.

ຫນ້າ​ທີ່​ທີ່​ກ່ຽວ​ຂ້ອງ​:
int fd = ອະທິບາຍ_creat_on_error(ຊື່ໄຟລ໌, 0666);
ຈະພິມຂໍ້ຄວາມຄວາມຜິດພາດກ່ຽວກັບຄວາມລົ້ມເຫຼວ, ແຕ່ຍັງສົ່ງຄືນຜົນໄດ້ຮັບຄວາມຜິດພາດຕົ້ນສະບັບ, ແລະ
ຜິດພາດ(3) ແມ່ນ unmolested, ເຊັ່ນດຽວກັນ.

ທັງຫມົດ ໄດ້ ອື່ນໆ ລະບົບ ໂທ
ໂດຍທົ່ວໄປ, ທຸກໆການໂທລະບົບມີໄຟລ໌ຂອງຕົນເອງ
#ລວມທັງຊື່.h>
ທີ່ກໍານົດ prototypes ຫນ້າທີ່ສໍາລັບຫົກຫນ້າທີ່:

·ອະທິບາຍ_ຊື່,

·ອະທິບາຍ_errno_ຊື່,

·ອະທິບາຍ_ຂໍ້ຄວາມ_ຊື່,

·ອະທິບາຍ_ຂໍ້ຄວາມ_errno_ຊື່,

·ອະທິບາຍ_ຊື່_or_die ແລະ

·ອະທິບາຍ_ຊື່_on_error.

ທຸກໆຕົ້ນແບບຟັງຊັນມີເອກະສານ Doxygen, ແລະເອກະສານນີ້ is ບໍ່ ປິດ
ເມື່ອໄຟລ໌ລວມຖືກຕິດຕັ້ງ.

ໄດ້ ລໍຖ້າ(2) ການໂທຫາລະບົບ (ແລະຫມູ່ເພື່ອນ) ມີບາງຕົວແປເພີ່ມເຕີມທີ່ຕີຄວາມລົ້ມເຫຼວ
ເພື່ອເປັນສະຖານະທາງອອກທີ່ບໍ່ແມ່ນ EXIT_SUCCESS. ນີ້ໃຊ້ກັບ ລະບົບ(3) ແລະ ປິດ(3) ເປັນ
ດີ.

ການຄຸ້ມຄອງປະກອບມີ 221 ການໂທຫາລະບົບແລະການຮ້ອງຂໍ 547 ioctl. ມີຫຼາຍລະບົບຫຼາຍ
ການຮຽກຮ້ອງຍັງບໍ່ທັນປະຕິບັດ. ລະບົບການໂທທີ່ບໍ່ເຄີຍກັບຄືນມາ, ເຊັ່ນ: ການທ່ອງທ່ຽວ(2), ບໍ່ມີ
ໃນຫ້ອງສະຫມຸດ, ແລະຈະບໍ່ເປັນ. ໄດ້ exec ຄອບຄົວຂອງການໂທລະບົບ ມີ ສະຫນັບສະຫນູນ, ເນື່ອງຈາກວ່າ
ພວກເຂົາເຈົ້າກັບຄືນເມື່ອມີຄວາມຜິດພາດ.

ແມວ
ນີ້ແມ່ນສິ່ງທີ່ໂຄງການ "cat" ສົມມຸດຕິຖານສາມາດເບິ່ງຄືວ່າ, ດ້ວຍການລາຍງານຄວາມຜິດພາດຢ່າງເຕັມທີ່,
ໃຊ້ libexplain.
#ລວມທັງ
# ປະກອບ
#ລວມທັງ
ມີຫນຶ່ງປະກອບມີສໍາລັບ libexplain, ບວກກັບຜູ້ຕ້ອງສົງໄສປົກກະຕິ. (ຖ້າຫາກວ່າທ່ານຕ້ອງການທີ່ຈະຫຼຸດຜ່ອນການ
ການໂຫຼດ preprocessor, ທ່ານສາມາດນໍາໃຊ້ສະເພາະຊື່.h> ປະກອບມີ.)
void static
ຂະ​ບວນ​ການ (FILE *fp​)
{
ສໍາລັບ (;;)
{
char buffer[4096];
size_t n = ອະທິບາຍ_fread_or_die(buffer, 1, sizeof(buffer), fp);
ຖ້າ (!n)
ທໍາລາຍ;
explain_fwrite_or_die(buffer, 1, n, stdout);
}
}
ໄດ້ ຂະບວນການ ຟັງຊັນຄັດລອກກະແສໄຟລ໌ໄປຫາຜົນຜະລິດມາດຕະຖານ. ຄວນມີຂໍ້ຜິດພາດເກີດຂຶ້ນ
ສໍາລັບການອ່ານຫຼືຂຽນ, ມັນຖືກລາຍງານ (ແລະຊື່ເສັ້ນທາງຈະຖືກລວມຢູ່ໃນ
error) ແລະຄໍາສັ່ງອອກດ້ວຍ EXIT_FAILURE. ພວກເຮົາບໍ່ກັງວົນກ່ຽວກັບການຕິດຕາມ
pathnames, ຫຼືຖ່າຍທອດໃຫ້ເຂົາເຈົ້າລົງ stack ການໂທ.
int
main(int argc, char **argv)
{
ສໍາລັບ (;;)
{
int c = getopt(argc, argv, "o:");
ຖ້າ (c == EOF)
ທໍາລາຍ;
ສະຫຼັບ (c)
{
ກໍລະນີ 'o':
ອະທິບາຍ_freopen_or_die(optarg, "w", stdout);
ທໍາລາຍ;
ພາກສ່ວນທີ່ມ່ວນຂອງລະຫັດນີ້ແມ່ນວ່າ libexplain ສາມາດລາຍງານຂໍ້ຜິດພາດ ລວມທັງ ໄດ້ ຊື່ເສັ້ນທາງ ເຖິງແມ່ນວ່າ
ຖ້າ​ເຈົ້າ ບໍ່ໄດ້ ເປີດ stdout ຄືນໃໝ່ຢ່າງຈະແຈ້ງຕາມທີ່ເຮັດຢູ່ນີ້. ພວກເຮົາບໍ່ເປັນຫ່ວງກ່ຽວກັບ
ຕິດ​ຕາມ​ຊື່​ໄຟລ​໌​.
default:
fprintf(stderr, "ການນຳໃຊ້: %ss [ -o ] ...\n",
argv[0]);
ກັບຄືນ EXIT_FAILURE;
}
}
ຖ້າ (optind == argc)
ຂະບວນການ(stdin);
ອື່ນ
{
ໃນຂະນະທີ່ (ເລືອກ < argc)
{
FILE *fp = explain_fopen_or_die(argv[optind]++, "r");
ຂະບວນການ(fp);
ອະທິບາຍ_fclose_or_die(fp);
}
}
ຜົນຜະລິດມາດຕະຖານຈະຖືກປິດຢ່າງບໍ່ຊັດເຈນ, ແຕ່ຊ້າເກີນໄປສໍາລັບການລາຍງານຄວາມຜິດພາດ
ອອກມາ, ດັ່ງນັ້ນພວກເຮົາເຮັດມັນຢູ່ທີ່ນີ້, ພຽງແຕ່ໃນກໍລະນີທີ່ I/O buffed ຍັງບໍ່ໄດ້ຂຽນຫຍັງເທື່ອ, ແລະ
ມີຄວາມຜິດພາດ ENOSPC ຫຼືບາງສິ່ງບາງຢ່າງ.
ອະທິບາຍ_fflush_or_die(stdout);
ກັບຄືນ EXIT_SUCCESS;
}
ຫມົດ​ເທົ່າ​ນີ້. ລາຍງານຂໍ້ຜິດພາດເຕັມ, ລະຫັດຊັດເຈນ.

ຂອງ Rusty ຂະຫນາດ of ການໂຕ້ຕອບ ຄວາມດີ
ສໍາລັບຜູ້ທີ່ບໍ່ຄຸ້ນເຄີຍກັບມັນ, Rusty Russel ຂອງ "ຂ້ອຍຈະເຮັດໃຫ້ມັນຍາກທີ່ຈະໃຊ້ໃນທາງທີ່ຜິດ?"
ຫນ້າແມ່ນຕ້ອງອ່ານສໍາລັບຜູ້ອອກແບບ API.
http://ozlabs.org/~rusty/index.cgi/tech/2008-03-30.html

10​. ມັນເປັນ ເປັນໄປບໍ່ໄດ້ to ໄດ້ຮັບ ຜິດ

ເປົ້າໝາຍຕ້ອງຕັ້ງໃຫ້ສູງ, ມີຄວາມທະເຍີທະຍານສູງ, ຢ້ານວ່າເຈົ້າຈະເຮັດສຳເລັດ ແລະຄິດວ່າເຈົ້າເປັນເຈົ້າ
ສໍາເລັດໃນເວລາທີ່ທ່ານບໍ່ໄດ້.

ຫ້ອງສະຫມຸດ libexplain ກວດພົບຕົວຊີ້ປອມແລະຕົວກໍານົດການໂທຫາລະບົບປອມຈໍານວນຫຼາຍ,
ແລະໂດຍທົ່ວໄປແລ້ວພະຍາຍາມຫຼີກລ້ຽງຄວາມຜິດໃນກໍລະນີທີ່ພະຍາຍາມທີ່ສຸດ.

ຫ້ອງສະໝຸດ libexplain ຖືກອອກແບບມາໃຫ້ມີຄວາມປອດໄພຂອງກະທູ້. ມີແນວໂນ້ມທີ່ຈະໃຊ້ໃນໂລກຕົວຈິງຫຼາຍຂຶ້ນ
ເປີດເຜີຍສະຖານທີ່ນີ້ສາມາດປັບປຸງໄດ້.

ບັນຫາໃຫຍ່ທີ່ສຸດແມ່ນກັບຊື່ຫນ້າທີ່ຕົວຈິງຂອງຕົນເອງ. ເນື່ອງຈາກວ່າ C ບໍ່ມີ
name-spaces, ຫ້ອງສະຫມຸດ libexplain ໃຊ້ຄໍານໍາຫນ້າຊື່ອະທິບາຍ. ນີ້​ແມ່ນ
ວິທີການແບບດັ້ງເດີມຂອງການສ້າງ pseudo-name-space ເພື່ອຫຼີກເວັ້ນການຂັດແຍ້ງຂອງສັນຍາລັກ.
ຢ່າງໃດກໍຕາມ, ມັນສົ່ງຜົນໃຫ້ບາງຊື່ສຽງທີ່ຜິດທໍາມະຊາດ.

9. ໄດ້ ນັກຂຽນ or linker ຈະ​ບໍ່ ໃຫ້ ທ່ານ ໄດ້ຮັບ it ຜິດ

ຄວາມຜິດພາດທົ່ວໄປແມ່ນການໃຊ້ description_open ບ່ອນທີ່ອະທິບາຍ_open_or_die ມີຈຸດປະສົງ.
ໂຊກດີ, compiler ມັກຈະອອກຂໍ້ຜິດພາດປະເພດຢູ່ໃນຈຸດນີ້ (ຕົວຢ່າງ: ບໍ່ສາມາດມອບໝາຍໄດ້
const char * rvalue ເປັນ int lvalue).

8. ໄດ້ ນັກຂຽນ ຈະ ເຕືອນ if ທ່ານ ໄດ້ຮັບ it ຜິດ

ຖ້າexplan_rename ຖືກໃຊ້ເມື່ອexplain_rename_or_die ມີຈຸດປະສົງ, ອັນນີ້ອາດເຮັດໃຫ້ເກີດອັນອື່ນ
ບັນຫາ. GCC ມີຄຸນສົມບັດຫນ້າທີ່ warn_unused_result ທີ່ເປັນປະໂຫຍດ, ແລະ libexplain
ຫ້ອງສະຫມຸດຄັດຕິດມັນກັບຄໍາອະທິບາຍທັງຫມົດຊື່ ຟັງຊັນໂທເພື່ອຜະລິດຄໍາເຕືອນໃນເວລາທີ່ທ່ານ
ເຮັດ​ຜິດ​ພາດ​ນີ້​. ສົມທົບການນີ້ກັບ gcc - ຄວາມ​ຜິດ​ພາດ​ ເພື່ອ​ສົ່ງ​ເສີມ​ອັນ​ນີ້​ເຖິງ​ລະ​ດັບ 9 ຄວາມ​ດີ​.

7. ໄດ້ ເຫັນໄດ້ຊັດເຈນ ການນໍາໃຊ້ is (ອາດຈະເປັນ) ໄດ້ ທີ່ຖືກຕ້ອງ ຫນຶ່ງ.

ຊື່ຟັງຊັນໄດ້ຖືກເລືອກເພື່ອສະແດງຄວາມຫມາຍຂອງມັນ, ແຕ່ນີ້ບໍ່ແມ່ນສະເຫມີໄປ
ສໍາເລັດ. ໃນຂະນະທີ່ອະທິບາຍ_ຊື່_or_die ແລະອະທິບາຍ_ຊື່_on_error ມີ​ການ​ອະ​ທິ​ບາຍ​ພໍ​ສົມ​ຄວນ​,
ຕົວແປທີ່ປອດໄພຂອງກະທູ້ທີ່ໃຊ້ໜ້ອຍແມ່ນຍາກທີ່ຈະຖອດລະຫັດໄດ້. prototypes ຫນ້າ​ທີ່​ຊ່ວຍ​ໃຫ້​
compiler ໄປສູ່ຄວາມເຂົ້າໃຈ, ແລະຄໍາເຫັນ Doxygen ໃນໄຟລ໌ header ຊ່ວຍໃຫ້ຜູ້ໃຊ້
ໄປສູ່ຄວາມເຂົ້າໃຈ.

6. ໄດ້ ຊື່ ບອກວ່າ ທ່ານ ວິທີການ to ການນໍາໃຊ້ ມັນ.

ມັນເປັນສິ່ງສໍາຄັນທີ່ຈະອ່ານອະທິບາຍ_ຊື່_or_die ເປັນ “ອະທິບາຍ (ຊື່ ຫຼືຕາຍ)”.
ການ​ນໍາ​ໃຊ້​ຄໍາ​ນໍາ​ຫນ້າ​ຊື່​ອະ​ທິ​ບາຍ​ທີ່​ສອດ​ຄ້ອງ​ກັນ​ມີ​ບາງ​ຜົນ​ກະ​ທົບ​ຂ້າງ​ຄຽງ​ທີ່​ໂຊກ​ດີ​ໃນ​
ພະແນກຄວາມຊັດເຈນ, ເຊັ່ນດຽວກັນ.

ຄໍາສັ່ງຂອງຄໍາສັບຕ່າງໆໃນຊື່ຍັງຊີ້ໃຫ້ເຫັນຄໍາສັ່ງຂອງການໂຕ້ຖຽງ. ການໂຕ້ຖຽງ
ລາຍຊື່ສະເຫມີ ໃນຕອນທ້າຍ ມີການໂຕ້ຖຽງດຽວກັນກັບການໂທຜ່ານລະບົບ; ທັງຫມົດ of ໃຫ້ເຂົາເຈົ້າທີ່ຢູ່ ຖ້າຫາກວ່າ
_errno_ ປາກົດຢູ່ໃນຊື່, ການໂຕ້ຖຽງຂອງມັນຢູ່ກ່ອນການໂຕ້ຖຽງການໂທລະບົບ. ຖ້າ
_message_ ປາກົດຢູ່ໃນຊື່, ສອງຂໍ້ໂຕ້ແຍ້ງຂອງມັນມາກ່ອນ.

5. Do it ສິດ or it ຈະ ພັກຜ່ອນ at ເວລາແລ່ນ.

ຫ້ອງສະຫມຸດ libexplain ກວດພົບຕົວຊີ້ປອມແລະຕົວກໍານົດການໂທຫາລະບົບປອມຈໍານວນຫຼາຍ,
ແລະໂດຍທົ່ວໄປແລ້ວພະຍາຍາມຫຼີກລ້ຽງຄວາມຜິດໃນກໍລະນີທີ່ພະຍາຍາມທີ່ສຸດ. ມັນ​ຄວນ
ບໍ່ເຄີຍແຕກຫັກໃນເວລາແລ່ນ, ແຕ່ການນໍາໃຊ້ໃນໂລກທີ່ແທ້ຈິງຫຼາຍຈະປັບປຸງສິ່ງນີ້ຢ່າງແນ່ນອນ.

ຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດບາງຢ່າງແມ່ນແນໃສ່ນັກພັດທະນາແລະຜູ້ຮັກສາຫຼາຍກວ່າຜູ້ໃຊ້ສຸດທ້າຍ, ຍ້ອນວ່ານີ້
ສາມາດຊ່ວຍແກ້ໄຂຂໍ້ຜິດພາດໄດ້. ບໍ່ຫຼາຍປານໃດ "ພັກຜ່ອນໃນເວລາແລ່ນ" ເປັນ "ໃຫ້ຂໍ້ມູນຢູ່
runtime” (ຫຼັງຈາກລະບົບການໂທ barfs).

4. ປະຕິບັດຕາມ ທົ່ວໄປ ສົນທິສັນຍາ ແລະ ເຈົ້າຈະ ໄດ້ຮັບ it right

ເນື່ອງຈາກວ່າ C ບໍ່ມີຊ່ອງຫວ່າງຊື່, ຫ້ອງສະຫມຸດ libexplain ໃຊ້ຊື່ອະທິບາຍສະເຫມີ
ຄຳນຳໜ້າ. ນີ້ແມ່ນວິທີການພື້ນເມືອງຂອງການສ້າງ pseudo-name-space ເພື່ອຫຼີກເວັ້ນການ
ສັນຍາລັກຂັດກັນ.

ການໂຕ້ຖຽງຕໍ່ທ້າຍຂອງການໂທ libexplain ທັງຫມົດແມ່ນຄືກັນກັບລະບົບໂທຫາພວກເຂົາ
ກໍາລັງອະທິບາຍ. ນີ້ແມ່ນຈຸດປະສົງເພື່ອສະຫນອງສົນທິສັນຍາທີ່ສອດຄ່ອງກັນກັບ
ລະບົບເອີ້ນຕົວເອງ.

3. ອ່ານ ໄດ້ ເອກະສານ ແລະ ເຈົ້າຈະ ໄດ້ຮັບ it right

ຫ້ອງສະຫມຸດ libexplain ມີຈຸດປະສົງເພື່ອໃຫ້ມີເອກະສານ Doxygen ຄົບຖ້ວນສໍາລັບແຕ່ລະຄົນ
ການໂທ API ສາທາລະນະ (ແລະພາຍໃນເຊັ່ນດຽວກັນ).

ຂໍ້ຄວາມ ເນື້ອໃນ


ການເຮັດວຽກກ່ຽວກັບ libexplain ແມ່ນຄ້າຍຄືກັບເບິ່ງດ້ານລຸ່ມຂອງລົດຂອງເຈົ້າເມື່ອມັນຂຶ້ນ
hoist ຢູ່ກົນຈັກ. ມີ​ສິ່ງ​ທີ່​ໜ້າ​ກຽດ​ບາງ​ຢ່າງ​ຢູ່​ໃຕ້​ບ່ອນ​ນັ້ນ, ບວກ​ກັບ​ຂີ້​ຕົມ ແລະ​ຂີ້​ຕົມ, ແລະ
ຜູ້ໃຊ້ບໍ່ຄ່ອຍເຫັນມັນ. ຂໍ້​ຄວາມ​ຜິດ​ພາດ​ທີ່​ດີ​ຈໍາ​ເປັນ​ຕ້ອງ​ໃຫ້​ຂໍ້​ມູນ​, ເຖິງ​ແມ່ນ​ວ່າ​ສໍາ​ລັບ​ຜູ້​ໃຊ້​ທີ່​
ໂຊກດີພໍທີ່ຈະບໍ່ຕ້ອງເບິ່ງຂ້າງລຸ່ມເລື້ອຍໆ, ແລະເຊັ່ນກັນ
ຂໍ້ມູນສໍາລັບກົນໄກການຟັງຄໍາອະທິບາຍຂອງຜູ້ໃຊ້ຜ່ານໂທລະສັບ. ນີ້​ແມ່ນ
ບໍ່​ມີ​ວຽກ​ງານ​ງ່າຍ​ດາຍ​.

ກວດເບິ່ງຕົວຢ່າງທໍາອິດຂອງພວກເຮົາ, ລະຫັດຕ້ອງການນີ້ຖ້າມັນໃຊ້ libexplain:
int fd = explain_open_or_die("ບາງອັນ", O_RDONLY, 0);
ຈະລົ້ມເຫລວກັບຂໍ້ຄວາມຜິດພາດເຊັ່ນນີ້
open(pathname = "some/file", flags = O_RDONLY) ລົ້ມເຫລວ, ບໍ່ມີໄຟລ໌ ຫຼື directory
(2, ENOENT) ເພາະວ່າບໍ່ມີລາຍການ "ບາງ" ໃນໄດເລກະທໍລີປະຈຸບັນ
ນີ້ແບ່ງອອກເປັນສາມຕ່ອນ
ໂທ​ລະ​ບົບ​ ລົ້ມເຫລວ, ຄວາມ​ຜິດ​ພາດ​ລະ​ບົບ​ ເນື່ອງຈາກວ່າ
ຄໍາອະທິບາຍ

ກ່ອນທີ່ຈະ ເນື່ອງຈາກວ່າ
ມັນເປັນໄປໄດ້ທີ່ຈະເຫັນສ່ວນຂອງຂໍ້ຄວາມກ່ອນ "ເພາະວ່າ" ເປັນເຕັກນິກຫຼາຍເກີນໄປທີ່ຈະບໍ່ແມ່ນ.
ຜູ້​ໃຊ້​ດ້ານ​ວິ​ຊາ​ການ​, ສ່ວນ​ໃຫຍ່​ແມ່ນ​ເປັນ​ຜົນ​ມາ​ຈາກ​ການ​ພິມ​ຢ່າງ​ຖືກ​ຕ້ອງ​ລະ​ບົບ​ໂທ​ຫາ​ຕົວ​ມັນ​ເອງ​ຢູ່​ທີ່​
ການ​ເລີ່ມ​ຕົ້ນ​ຂອງ​ຂໍ້​ຄວາມ​ຜິດ​ພາດ​. ແລະເບິ່ງຄືວ່າ ສາຍແຮ່(1) ຜົນຜະລິດ, ສໍາລັບ geek ໂບນັດ
ຈຸດ.
open(pathname = "some/file", flags = O_RDONLY) ລົ້ມເຫລວ, ບໍ່ມີໄຟລ໌ ຫຼື directory
(2, ENOENT)
ສ່ວນຫນຶ່ງຂອງຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດນີ້ເປັນສິ່ງຈໍາເປັນສໍາລັບນັກພັດທະນາໃນເວລາທີ່ລາວກໍາລັງຂຽນລະຫັດ,
ແລະມີຄວາມສໍາຄັນເທົ່າທຽມກັນກັບຜູ້ຮັກສາທີ່ຕ້ອງອ່ານບົດລາຍງານ bug ແລະແກ້ໄຂຂໍ້ບົກພ່ອງໃນ
ລະຫັດ. ມັນບອກວ່າສິ່ງທີ່ລົ້ມເຫລວ.

ຖ້າຂໍ້ຄວາມນີ້ບໍ່ໄດ້ຖືກນໍາສະເຫນີຕໍ່ຜູ້ໃຊ້, ຜູ້ໃຊ້ບໍ່ສາມາດຄັດລອກແລະວາງມັນເຂົ້າໄປໃນ a
ລາຍງານ bug, ແລະຖ້າຫາກວ່າມັນບໍ່ໄດ້ຢູ່ໃນບົດລາຍງານ bug ຜູ້ຮັກສາບໍ່ສາມາດຮູ້ວ່າສິ່ງທີ່ເປັນໄປ.
ຜິດ

ເລື້ອຍໆພະນັກງານເຕັກໂນໂລຢີຈະໃຊ້ ສາຍແຮ່(1) ຫຼື ມັດ(1) ເພື່ອໃຫ້ໄດ້ຮັບຂໍ້ມູນທີ່ແນ່ນອນນີ້, ແຕ່
ເສັ້ນທາງນີ້ບໍ່ເປີດໃນເວລາອ່ານລາຍງານຂໍ້ຜິດພາດ. ລະບົບນັກຂ່າວ bug ແມ່ນຢູ່ໄກ
ໄປ, ແລະ, ໃນປັດຈຸບັນ, ຢູ່ໃນສະພາບທີ່ແຕກຕ່າງກັນໄກ. ດັ່ງນັ້ນ, ຂໍ້ມູນນີ້ຈໍາເປັນຕ້ອງຢູ່ໃນ
ລາຍງານຂໍ້ຜິດພາດ, ຊຶ່ງຫມາຍຄວາມວ່າມັນຕ້ອງຢູ່ໃນຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດ.

ການເປັນຕົວແທນການໂທລະບົບຍັງໃຫ້ບໍລິບົດກັບສ່ວນທີ່ເຫຼືອຂອງຂໍ້ຄວາມ. ຖ້າຕ້ອງການ
ເກີດຂຶ້ນ, ການໂຕ້ຖຽງການໂທລະບົບ offending ອາດຈະຖືກກ່າວເຖິງໂດຍຊື່ໃນຄໍາອະທິບາຍ
ຫຼັງຈາກ "ເພາະວ່າ". ນອກຈາກນັ້ນ, strings ທັງຫມົດໄດ້ຖືກອ້າງອີງຢ່າງເຕັມສ່ວນແລະຫນີ C strings, ດັ່ງນັ້ນ
ແຖວໃໝ່ທີ່ຝັງໄວ້ ແລະຕົວອັກສອນທີ່ບໍ່ໄດ້ພິມຈະບໍ່ເຮັດໃຫ້ເຄື່ອງຂອງຜູ້ໃຊ້ໄປ
ເສັ້ນໄຍ.

ໄດ້ ຄວາມ​ຜິດ​ພາດ​ລະ​ບົບ​ ແມ່ນສິ່ງທີ່ອອກມາຈາກ ຄວາມຜິດພາດ(2), ບວກກັບສັນຍາລັກຄວາມຜິດພາດ. ອົດທົນ ແລະ
sysadmins ຜູ້ຊ່ຽວຊານສາມາດຢຸດການອ່ານຢູ່ໃນຈຸດນີ້, ແຕ່ປະສົບການຂອງຜູ້ຂຽນຈົນເຖິງປະຈຸບັນແມ່ນ
ການອ່ານຕໍ່ໄປແມ່ນໃຫ້ລາງວັນ. (ຖ້າມັນບໍ່ແມ່ນລາງວັນ, ມັນອາດຈະເປັນພື້ນທີ່ຂອງ
libexplain ທີ່ສາມາດປັບປຸງໄດ້. ການປະກອບສ່ວນລະຫັດແມ່ນຍິນດີຕ້ອນຮັບ, ແນ່ນອນ.)

ຫຼັງຈາກ ເນື່ອງຈາກວ່າ
ນີ້ແມ່ນສ່ວນຂອງຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ແນໃສ່ຜູ້ໃຊ້ທີ່ບໍ່ແມ່ນວິຊາການ. ມັນເບິ່ງເກີນກວ່າ
ການໂຕ້ຖຽງການໂທລະບົບທີ່ງ່າຍດາຍ, ແລະຊອກຫາສິ່ງທີ່ສະເພາະຫຼາຍ.
ບໍ່ມີໄດເລກະທໍລີ "ບາງ" ໃນໄດເລກະທໍລີປະຈຸບັນ
ສ່ວນນີ້ພະຍາຍາມອະທິບາຍສາເຫດໃກ້ຄຽງຂອງຄວາມຜິດພາດໃນພາສາທໍາມະດາ, ແລະມັນ
ຢູ່ທີ່ນີ້, ຄວາມເປັນສາກົນແມ່ນມີຄວາມຈຳເປັນ.

ໂດຍທົ່ວໄປ, ນະໂຍບາຍແມ່ນເພື່ອປະກອບມີຂໍ້ມູນຫຼາຍເທົ່າທີ່ເປັນໄປໄດ້, ເພື່ອໃຫ້ຜູ້ໃຊ້
ບໍ່ຈໍາເປັນຕ້ອງໄປຊອກຫາມັນ (ແລະບໍ່ໄດ້ປ່ອຍໃຫ້ມັນອອກຈາກບົດລາຍງານ bug).

Internationalization
ຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດສ່ວນໃຫຍ່ໃນຫ້ອງສະຫມຸດ libexplain ໄດ້ຖືກປັບປຸງເປັນສາກົນ. ຢູ່ທີ່ນັ້ນ
ຍັງບໍ່ມີການທ້ອງຖິ່ນເທື່ອ, ສະນັ້ນຖ້າທ່ານຕ້ອງການຄໍາອະທິບາຍເປັນພາສາກໍາເນີດຂອງທ່ານ,
ກະລຸນາປະກອບສ່ວນ.

ຄຸນສົມບັດ "ຫຼາຍທີ່ສຸດ", ຂ້າງເທິງ, ກ່ຽວຂ້ອງກັບຄວາມຈິງທີ່ວ່າຫຼັກຖານສະແດງແນວຄວາມຄິດ
ການຈັດຕັ້ງປະຕິບັດບໍ່ໄດ້ລວມເອົາການສະໜັບສະໜູນສາກົນ. ພື້ນຖານລະຫັດແມ່ນເປັນ
ປັບປຸງແກ້ໄຂເທື່ອລະກ້າວ, ປົກກະຕິແລ້ວເປັນຜົນມາຈາກການ refactoring ຂໍ້ຄວາມເພື່ອໃຫ້ແຕ່ລະຂໍ້ຜິດພາດ
ຂໍ້ຄວາມສະຕຣິງປາກົດຢູ່ໃນລະຫັດແນ່ນອນຫນຶ່ງຄັ້ງ.

ການ​ຈັດ​ສັນ​ໄດ້​ຖືກ​ສ້າງ​ຂຶ້ນ​ສໍາ​ລັບ​ພາ​ສາ​ທີ່​ຈໍາ​ເປັນ​ຕ້ອງ​ໄດ້​ປະ​ກອບ​ສ່ວນ​ຂອງ​
ໂທ​ລະ​ບົບ​ ລົ້ມເຫລວ, ຄວາມ​ຜິດ​ພາດ​ລະ​ບົບ​ ເນື່ອງຈາກວ່າ ຄໍາອະທິບາຍ
ໃນຄໍາສັ່ງທີ່ແຕກຕ່າງກັນສໍາລັບໄວຍະກອນທີ່ຖືກຕ້ອງໃນຂໍ້ຄວາມຄວາມຜິດພາດໃນທ້ອງຖິ່ນ.

ໄປສະນີ mortem
ມີເວລາທີ່ໂຄງການຍັງບໍ່ທັນໃຊ້ libexplain, ແລະທ່ານບໍ່ສາມາດໃຊ້ໄດ້ ສາຍແຮ່(1​)
ບໍ່ວ່າຈະ. ມີ ອະທິບາຍ(1) ຄໍາສັ່ງລວມກັບ libexplain ທີ່ສາມາດຖືກນໍາໃຊ້ເພື່ອ
ຖອດລະຫັດຂໍ້ຄວາມຜິດພາດ, ຖ້າສະຖານະຂອງລະບົບພື້ນຖານບໍ່ໄດ້ປ່ຽນແປງຫຼາຍເກີນໄປ.
$ ອະທິບາຍ ປ່ຽນຊື່ ຟູ /tmp/bar/baz -e ENOENT
rename(oldpath = "foo", newpath = "/tmp/bar/baz") ລົ້ມເຫລວ, ບໍ່ມີໄຟລ໌ຫຼືໄດເລກະທໍລີດັ່ງກ່າວ.
(2, ENOENT) ເນື່ອງຈາກວ່າບໍ່ມີ "bar" directory ໃນ newpath "./ tmp"ໄດເລກະທໍລີ
$
ໃຫ້ສັງເກດວິທີການແກ້ໄຂຄວາມບໍ່ຊັດເຈນຂອງເສັ້ນທາງໂດຍການໃຊ້ຊື່ argument ການເອີ້ນລະບົບ. ຂອງ
ແນ່ນອນ, ທ່ານຕ້ອງຮູ້ຂໍ້ຜິດພາດແລະລະບົບໂທຫາ ອະທິບາຍ(1) ເປັນປະໂຫຍດ. ເປັນ
ຫລີກໄປທາງຫນຶ່ງ, ນີ້ແມ່ນວິທີຫນຶ່ງທີ່ໃຊ້ໂດຍຊຸດທົດສອບອັດຕະໂນມັດ libexplain ເພື່ອກວດສອບວ່າ
libexplain ເຮັດວຽກ.

ປັດຊະຍາ
"ບອກຂ້ອຍທຸກຢ່າງ, ລວມທັງສິ່ງທີ່ຂ້ອຍບໍ່ຮູ້ວ່າຈະຊອກຫາ."

ຫ້ອງສະຫມຸດໄດ້ຖືກປະຕິບັດໃນລັກສະນະທີ່ເມື່ອເຊື່ອມຕໍ່ແບບຄົງທີ່, ພຽງແຕ່ລະຫັດທ່ານ
ການນໍາໃຊ້ຕົວຈິງຈະຖືກເຊື່ອມຕໍ່. ນີ້ແມ່ນບັນລຸໄດ້ໂດຍການມີຫນຶ່ງຟັງຊັນຕໍ່ໄຟລ໌ແຫຼ່ງ,
ທຸກ​ຄັ້ງ​ທີ່​ເປັນ​ໄປ​ໄດ້​.

ເມື່ອມັນເປັນໄປໄດ້ທີ່ຈະສະຫນອງຂໍ້ມູນເພີ່ມເຕີມ, libexplain ຈະເຮັດແນວນັ້ນ. ຜູ້ໃຊ້ຫນ້ອຍລົງ
ມີການຕິດຕາມລົງສໍາລັບຕົນເອງ, ທີ່ດີກວ່າ. ນີ້ຫມາຍຄວາມວ່າ UIDs ແມ່ນມາພ້ອມກັບ
ຊື່ຜູ້ໃຊ້, GIDs ແມ່ນມາພ້ອມກັບຊື່ກຸ່ມ, PIDs ແມ່ນມາພ້ອມກັບຂະບວນການ.
ຊື່, ຕົວອະທິບາຍໄຟລ໌ ແລະກະແສແມ່ນມາພ້ອມກັບຊື່ເສັ້ນທາງ, ແລະອື່ນໆ.

ເມື່ອແກ້ໄຂເສັ້ນທາງ, ຖ້າອົງປະກອບຂອງເສັ້ນທາງບໍ່ມີ, libexplain ຈະຊອກຫາທີ່ຄ້າຍຄືກັນ
ຊື່, ເພື່ອແນະນໍາທາງເລືອກສໍາລັບຄວາມຜິດພາດ typographical.

ຫ້ອງສະໝຸດ libexplain ພະຍາຍາມໃຊ້ heap ໜ້ອຍທີ່ສຸດເທົ່າທີ່ເປັນໄປໄດ້, ແລະປົກກະຕິແລ້ວບໍ່ມີ. ນີ້​ແມ່ນ
ເພື່ອຫຼີກເວັ້ນການລົບກວນສະຖານະຂະບວນການ, ເທົ່າທີ່ເປັນໄປໄດ້, ເຖິງແມ່ນວ່າບາງຄັ້ງມັນກໍ່ເປັນ
ຫຼີກລ່ຽງບໍ່ໄດ້.

ຫ້ອງສະຫມຸດ libexplain ພະຍາຍາມທີ່ຈະປອດໄພ, ໂດຍການຫຼີກເວັ້ນຕົວແປທົ່ວໂລກ, ການຮັກສາ
ລັດໃນ stack ໄດ້ຫຼາຍເທົ່າທີ່ເປັນໄປໄດ້. ມີ buffer ຂໍ້ຄວາມທົ່ວໄປດຽວ, ແລະ
ຟັງຊັນທີ່ໃຊ້ມັນຖືກບັນທຶກໄວ້ວ່າບໍ່ປອດໄພ.

ຫ້ອງສະໝຸດ libexplain ບໍ່ລົບກວນຕົວຈັດການສັນຍານຂອງຂະບວນການ. ນີ້ເຮັດໃຫ້
ການກໍານົດວ່າຕົວຊີ້ຈະກໍານົດຄວາມຜິດຂອງສິ່ງທ້າທາຍ, ແຕ່ບໍ່ແມ່ນເປັນໄປບໍ່ໄດ້.

ເມື່ອຂໍ້ມູນມີໃຫ້ຜ່ານລະບົບການໂທເຊັ່ນດຽວກັນກັບມີຢູ່ຜ່ານ ກ / proc
ເຂົ້າ, ໂທລະບົບແມ່ນມັກ. ນີ້ແມ່ນເພື່ອຫຼີກເວັ້ນການລົບກວນສະຖານະຂອງຂະບວນການ.
ຍັງມີເວລາທີ່ບໍ່ມີຕົວອະທິບາຍໄຟລ໌ທີ່ມີຢູ່.

ຫ້ອງສະຫມຸດ libexplain ໄດ້ຖືກລວບລວມດ້ວຍການສະຫນັບສະຫນູນໄຟລ໌ຂະຫນາດໃຫຍ່. ບໍ່ມີຂະໜາດໃຫຍ່/ນ້ອຍ
ໂຣກຈິດ. ບ່ອນທີ່ນີ້ມີຜົນກະທົບຕໍ່ປະເພດການໂຕ້ຖຽງໃນ API, ແລະຂໍ້ຜິດພາດຈະຖືກອອກ
ຖ້າໄຟລ໌ຂະຫນາດໃຫຍ່ທີ່ຈໍາເປັນກໍານົດແມ່ນບໍ່ມີ.

FIXME: ຈໍາເປັນຕ້ອງເຮັດວຽກເພື່ອໃຫ້ແນ່ໃຈວ່າໂຄຕ້າລະບົບໄຟລ໌ຖືກຈັດການຢູ່ໃນລະຫັດ. ນີ້
ໃຊ້ໄດ້ກັບບາງຄົນ ຈຳກັດ(2) ຂອບເຂດ, ເຊັ່ນດຽວກັນ.

ມີກໍລະນີທີ່ເສັ້ນທາງຍາດພີ່ນ້ອງແມ່ນບໍ່ມີຂໍ້ມູນ. ຕົວຢ່າງ: ລະບົບ daemon,
ເຊີບເວີ ແລະຂະບວນການໃນພື້ນຫຼັງ. ໃນກໍລະນີເຫຼົ່ານີ້, ເສັ້ນທາງຢ່າງແທ້ຈິງຖືກນໍາໃຊ້ໃນຄວາມຜິດພາດ
ຄໍາອະທິບາຍ.

PATH ການແກ້ໄຂ


ສະບັບສັ້ນ: ເບິ່ງ ການແກ້ໄຂເສັ້ນທາງ(7).

ຮຸ່ນຍາວ: ຜູ້ໃຊ້ສ່ວນໃຫຍ່ບໍ່ເຄີຍໄດ້ຍິນ ການແກ້ໄຂເສັ້ນທາງ(7), ແລະຜູ້ໃຊ້ຂັ້ນສູງຈໍານວນຫຼາຍ
ບໍ່ເຄີຍອ່ານມັນ. ນີ້ແມ່ນສະບັບຫຍໍ້:

ຂັ້ນ​ຕອນ 1: ເລີ່ມຕົ້ນ of ໄດ້ ການແກ້ໄຂ ຂະບວນການ
ຖ້າຊື່ເສັ້ນທາງເລີ່ມຕົ້ນດ້ວຍຕົວຫຍໍ້ (“/”), ໄດເລກະທໍລີຄົ້ນຫາເລີ່ມຕົ້ນແມ່ນ
ໄດເລກະທໍລີຮາກຂອງຂະບວນການໂທ.

ຖ້າຊື່ເສັ້ນທາງບໍ່ເລີ່ມຕົ້ນດ້ວຍຕົວຫຍໍ້ (“/”), ການຊອກຫາເລີ່ມຕົ້ນ
ໄດເລກະທໍລີຂອງຂະບວນການແກ້ໄຂແມ່ນໄດເລກະທໍລີທີ່ເຮັດວຽກໃນປະຈຸບັນຂອງຂະບວນການ.

ຂັ້ນ​ຕອນ 2: ຍ່າງ ພ້ອມ ໄດ້ ເສັ້ນທາງ
ກໍານົດໄດເລກະທໍລີການຊອກຫາປະຈຸບັນເປັນໄດເລກະທໍລີການຄົ້ນຫາເລີ່ມຕົ້ນ. ໃນປັດຈຸບັນ, ສໍາລັບແຕ່ລະຄົນທີ່ບໍ່ແມ່ນ
ອົງ​ປະ​ກອບ​ສຸດ​ທ້າຍ​ຂອງ​ຊື່​ເສັ້ນ​ທາງ​, ບ່ອນ​ທີ່​ອົງ​ປະ​ກອບ​ເປັນ substring delimited ໂດຍ slash (“/”)
ຕົວອັກສອນ, ອົງປະກອບນີ້ຖືກຊອກຫາຢູ່ໃນໄດເລກະທໍລີການຊອກຫາໃນປະຈຸບັນ.

ຖ້າຂະບວນການບໍ່ມີການອະນຸຍາດຄົ້ນຫາຢູ່ໃນໄດເລກະທໍລີການຊອກຫາໃນປະຈຸບັນ, EACCES
ຂໍ້ຜິດພາດຖືກສົ່ງຄືນ ("ການອະນຸຍາດຖືກປະຕິເສດ").
open(pathname = "/home/archives/.ssh/private_key", flags = O_RDONLY) ລົ້ມເຫລວ,
ການອະນຸຍາດຖືກປະຕິເສດ (13, EACCES) ເພາະວ່າຂະບວນການດັ່ງກ່າວບໍ່ມີການອະນຸຍາດຄົ້ນຫາ
ໄປຫາຊື່ເສັ້ນທາງ "/home/archives/.ssh", ຂະບວນການທີ່ມີປະສິດທິພາບ GID 1000
"pmiller" ບໍ່ກົງກັບເຈົ້າຂອງໄດເລກະທໍລີ 1001 "archives" ດັ່ງນັ້ນເຈົ້າຂອງ
ຮູບແບບການອະນຸຍາດ "rwx" ແມ່ນຖືກລະເລີຍ, ຮູບແບບການອະນຸຍາດອື່ນໆແມ່ນ "--", ແລະ
ຂະບວນການບໍ່ໄດ້ຮັບສິດທິພິເສດ (ບໍ່ມີຄວາມສາມາດ DAC_READ_SEARCH)

ຖ້າອົງປະກອບບໍ່ພົບ, ຂໍ້ຜິດພາດ ENOENT ຈະຖືກສົ່ງຄືນ ("ບໍ່ມີໄຟລ໌ຫຼືໄດເລກະທໍລີດັ່ງກ່າວ").
unlink(pathname = "/home/microsoft/rubbish") ລົ້ມເຫລວ, ບໍ່ມີໄຟລ໌ ຫຼືໄດເລກະທໍລີດັ່ງກ່າວ (2,
ENOENT) ເນື່ອງຈາກວ່າບໍ່ມີໄດເລກະທໍລີ "microsoft" ໃນຊື່ເສັ້ນທາງ "/ ເຮືອນ"ໄດເລກະທໍລີ

ນອກຈາກນີ້ຍັງມີການສະຫນັບສະຫນູນບາງຢ່າງສໍາລັບຜູ້ໃຊ້ໃນເວລາທີ່ພວກເຂົາພິມຊື່ເສັ້ນທາງຜິດ, ເຮັດໃຫ້ຄໍາແນະນໍາໃນເວລາທີ່
ENOENT ຖືກສົ່ງຄືນ:
open(pathname = "/user/include/fcntl.h", flags = O_RDONLY) ລົ້ມເຫລວ, ບໍ່ມີໄຟລ໌ດັ່ງກ່າວ ຫຼື
ໄດເລກະທໍລີ (2, ENOENT) ເພາະວ່າບໍ່ມີໄດເລກະທໍລີ "ຜູ້ໃຊ້" ໃນຊື່ເສັ້ນທາງ "/"
ໄດເລກະທໍລີ, ເຈົ້າຫມາຍເຖິງໄດເລກະທໍລີ "usr" ແທນບໍ?

ຖ້າອົງປະກອບຖືກພົບເຫັນ, ແຕ່ບໍ່ແມ່ນໄດເລກະທໍລີຫຼືການເຊື່ອມຕໍ່ສັນຍາລັກ, ENOTDIR
ຂໍ້ຜິດພາດຖືກສົ່ງຄືນ ("ບໍ່ແມ່ນໄດເລກະທໍລີ").
open(pathname = "/home/pmiller/.netrc/lca", ທຸງ = O_RDONLY) ລົ້ມເຫລວ, ບໍ່ແມ່ນ
directory (20, ENOTDIR) ເນື່ອງຈາກວ່າໄຟລ໌ປົກກະຕິ ".netrc" ໃນຊື່ເສັ້ນທາງ
ໄດເລກະທໍລີ "/home/pmiller" ຖືກໃຊ້ເປັນໄດເລກະທໍລີໃນເວລາທີ່ມັນບໍ່ແມ່ນ

ຖ້າອົງປະກອບຖືກພົບເຫັນແລະເປັນໄດເລກະທໍລີ, ພວກເຮົາກໍານົດໄດເລກະທໍລີການຊອກຫາໃນປະຈຸບັນເປັນສິ່ງນັ້ນ
ໄດເລກະທໍລີ, ແລະໄປທີ່ອົງປະກອບຕໍ່ໄປ.

ຖ້າອົງປະກອບຖືກພົບເຫັນແລະເປັນການເຊື່ອມໂຍງສັນຍາລັກ (symlink), ພວກເຮົາທໍາອິດແກ້ໄຂສັນຍາລັກນີ້
ເຊື່ອມຕໍ່ (ກັບໄດເລກະທໍລີຄົ້ນຫາປະຈຸບັນເປັນໄດເລກະທໍລີການຄົ້ນຫາເລີ່ມຕົ້ນ). ເມື່ອຜິດພາດ, ວ່າ
ຂໍ້ຜິດພາດຖືກສົ່ງຄືນ. ຖ້າຜົນໄດ້ຮັບບໍ່ແມ່ນໄດເລກະທໍລີ, ຂໍ້ຜິດພາດ ENOTDIR ຈະຖືກສົ່ງຄືນ.
unlink(pathname = "/tmp/dangling/rubbish") ລົ້ມເຫລວ, ບໍ່ມີໄຟລ໌ ຫຼືໄດເລກະທໍລີດັ່ງກ່າວ (2,
ENOENT) ເນື່ອງຈາກວ່າການເຊື່ອມຕໍ່ສັນຍາລັກ "dangling" ໃນຊື່ເສັ້ນທາງ "/ tmp"ໄດເລກະທໍລີ
ຫມາຍເຖິງ "ບໍ່ມີບ່ອນໃດ" ທີ່ບໍ່ມີຢູ່
ຖ້າການແກ້ໄຂຂອງ symlink ປະສົບຜົນສໍາເລັດແລະສົ່ງຄືນໄດເລກະທໍລີ, ພວກເຮົາກໍານົດປະຈຸບັນ
ຊອກຫາລາຍການໄປຫາໄດເລກະທໍລີນັ້ນ, ແລະໄປທີ່ອົງປະກອບຕໍ່ໄປ. ໃຫ້ສັງເກດວ່າ
ຂະບວນການແກ້ໄຂຢູ່ທີ່ນີ້ກ່ຽວຂ້ອງກັບການເອີ້ນຄືນ. ເພື່ອປົກປ້ອງແກ່ນຈາກ stack
overflow, ແລະຍັງເພື່ອປ້ອງກັນການປະຕິເສດການບໍລິການ, ມີຂອບເຂດຈໍາກັດສູງສຸດ
ຄວາມເລິກ recursion, ແລະກ່ຽວກັບຈໍານວນສູງສຸດຂອງການເຊື່ອມຕໍ່ສັນຍາລັກປະຕິບັດຕາມ. ຄວາມຜິດພາດ ELOOP ແມ່ນ
ກັບຄືນມາເມື່ອສູງສຸດແມ່ນເກີນ ("ລະດັບການເຊື່ອມໂຍງສັນຍາລັກຫຼາຍເກີນໄປ").
open(pathname = "/tmp/dangling", ທຸງ = O_RDONLY) ລົ້ມເຫລວ, ມີລະດັບຫຼາຍເກີນໄປ.
ການ​ເຊື່ອມ​ຕໍ່​ສັນ​ຍາ​ລັກ (40​, ELOOP​) ເນື່ອງ​ຈາກ​ວ່າ loop ເຊື່ອມ​ຕໍ່​ສັນ​ຍາ​ລັກ​ໄດ້​ພົບ​ໃນ​
ຊື່ເສັ້ນທາງ, ເລີ່ມຕົ້ນທີ່ "/tmp/dangling"
ມັນເປັນໄປໄດ້ທີ່ຈະໄດ້ຮັບຄວາມຜິດພາດ ELOOP ຫຼື EMLINK ຖ້າມີ symlinks ຫຼາຍເກີນໄປ, ແຕ່ບໍ່ມີ.
ກວດພົບ loop.
open(pathname = "/tmp/rabbit-hole", ທຸງ = O_RDONLY) ລົ້ມເຫລວ, ມີລະດັບຫຼາຍເກີນໄປ.
ການເຊື່ອມໂຍງສັນຍາລັກ (40, ELOOP) ເນື່ອງຈາກວ່າການເຊື່ອມຕໍ່ສັນຍາລັກຫຼາຍເກີນໄປໄດ້ຖືກພົບໃນ
ຊື່​ເສັ້ນ​ທາງ (8​)
ສັງເກດເຫັນວິທີການຈໍາກັດຕົວຈິງແມ່ນພິມອອກ.

ຂັ້ນ​ຕອນ 3: ຄົ້ນຫາ ໄດ້ ສຸດທ້າຍ entry
ການຊອກຫາອົງປະກອບສຸດທ້າຍຂອງຊື່ເສັ້ນທາງໄປຄືກັນກັບສິ່ງອື່ນໆທັງໝົດ
ອົງປະກອບ, ດັ່ງທີ່ໄດ້ອະທິບາຍໄວ້ໃນຂັ້ນຕອນທີ່ຜ່ານມາ, ມີສອງຄວາມແຕກຕ່າງ:

(i) ອົງປະກອບສຸດທ້າຍບໍ່ຈໍາເປັນຕ້ອງເປັນໄດເລກະທໍລີ (ຢ່າງຫນ້ອຍເທົ່າກັບການແກ້ໄຂເສັ້ນທາງ
ຂະ​ບວນ​ການ​ແມ່ນ​ເປັນ​ຫ່ວງ​. ມັນອາດຈະຕ້ອງເປັນໄດເລກະທໍລີ, ຫຼືບໍ່ແມ່ນໄດເລກະທໍລີ, ເພາະວ່າ
ຂໍ້ກໍານົດຂອງການໂທລະບົບສະເພາະ).

(ii)
ມັນບໍ່ຈໍາເປັນຕ້ອງມີຄວາມຜິດພາດຖ້າອົງປະກອບສຸດທ້າຍບໍ່ພົບ; ບາງທີພວກເຮົາພຽງແຕ່
ການສ້າງມັນ. ລາຍລະອຽດກ່ຽວກັບການປິ່ນປົວຂອງການເຂົ້າສຸດທ້າຍແມ່ນໄດ້ອະທິບາຍຢູ່ໃນ
ຫນ້າຄູ່ມືຂອງການໂທລະບົບສະເພາະ.

(iii)
ມັນຍັງເປັນໄປໄດ້ທີ່ຈະມີບັນຫາກັບອົງປະກອບສຸດທ້າຍຖ້າມັນເປັນການເຊື່ອມຕໍ່ສັນຍາລັກ
ແລະມັນບໍ່ຄວນປະຕິບັດຕາມ. ສໍາລັບຕົວຢ່າງ, ການນໍາໃຊ້ ເປີດ(2) ທຸງ O_NOFOLLOW:
open(pathname = "a-symlink", flags = O_RDONLY | O_NOFOLLOW) ລົ້ມເຫລວ, ມີລະດັບຫຼາຍເກີນໄປ.
ການເຊື່ອມຕໍ່ສັນຍາລັກ (ELOOP) ເນື່ອງຈາກວ່າ O_NOFOLLOW ຖືກລະບຸໄວ້ແຕ່ຊື່ເສັ້ນທາງຫມາຍເຖິງ a
ການເຊື່ອມຕໍ່ສັນຍາລັກ

(iv)
ມັນເປັນເລື່ອງທໍາມະດາສໍາລັບຜູ້ໃຊ້ທີ່ຈະເຮັດຜິດພາດໃນເວລາທີ່ພິມຊື່ເສັ້ນທາງ. ຫ້ອງສະຫມຸດ libexplain
ພະຍາຍາມໃຫ້ຄຳແນະນຳເມື່ອ ENOENT ຖືກສົ່ງຄືນ, ຕົວຢ່າງ:
open(pathname = "/usr/include/filecontrl.h", flags = O_RDONLY) ລົ້ມເຫລວ, ບໍ່ມີໄຟລ໌ດັ່ງກ່າວ ຫຼື
directory (2, ENOENT) ເນື່ອງຈາກວ່າບໍ່ມີ "filecontrl.h" ໄຟລ໌ປົກກະຕິໃນຊື່ເສັ້ນທາງ
"/ usr / ປະກອບມີ" directory, ເຈົ້າຫມາຍຄວາມວ່າ "fcntl.h" ໄຟລ໌ປົກກະຕິແທນບໍ?

(v) ມັນເປັນໄປໄດ້ວ່າອົງປະກອບສຸດທ້າຍແມ່ນຕ້ອງການເປັນສິ່ງອື່ນນອກຈາກ a
ໄຟລ໌ປົກກະຕິ:
readlink(pathname = "just-a-file", data = 0x7F930A50, data_size = 4097) ລົ້ມເຫລວ,
ການໂຕ້ຖຽງບໍ່ຖືກຕ້ອງ (22, EINVAL) ເພາະວ່າຊື່ເສັ້ນທາງເປັນໄຟລ໌ປົກກະຕິ, ບໍ່ແມ່ນການເຊື່ອມຕໍ່ສັນຍາລັກ

(vi)
FIXME: ການຈັດການບິດ "t".

ຈໍາກັດ
ມີຈໍານວນຈໍາກັດກ່ຽວກັບຊື່ເສັ້ນທາງແລະຊື່ໄຟລ໌.

ຂີດຈຳກັດຄວາມຍາວຂອງຊື່
ມີຄວາມຍາວສູງສຸດສໍາລັບຊື່ເສັ້ນທາງ. ຖ້າຊື່ເສັ້ນທາງ (ຫຼືບາງລະດັບປານກາງ
ຊື່ເສັ້ນທາງທີ່ໄດ້ຮັບໃນຂະນະທີ່ການແກ້ໄຂການເຊື່ອມຕໍ່ສັນຍາລັກ) ຍາວເກີນໄປ, ເປັນ ENAMETOOLONG
ຂໍ້ຜິດພາດຖືກສົ່ງຄືນ ("ຊື່ໄຟລ໌ຍາວເກີນໄປ"). ສັງເກດເຫັນວິທີການຈໍາກັດລະບົບລວມ
ໃນ​ຂໍ້​ຄວາມ​ຜິດ​ພາດ​.
ເປີດ(ຊື່ເສັ້ນທາງ = "ຫຼາຍ...ຍາວ", flags = O_RDONLY) ລົ້ມເຫລວ, ຊື່ໄຟລ໌ຍາວເກີນໄປ (36,
ENAMETOOLONG) ເພາະວ່າຊື່ເສັ້ນທາງເກີນຄວາມຍາວສູງສຸດຂອງລະບົບ (4096)

ຈຳກັດຄວາມຍາວຂອງຊື່ໄຟລ໌
ບາງຕົວແປຂອງ Unix ມີຂອບເຂດຈໍາກັດກ່ຽວກັບຈໍານວນ bytes ໃນແຕ່ລະອົງປະກອບເສັ້ນທາງ.
ບາງຄົນຈັດການກັບເລື່ອງນີ້ຢ່າງງຽບໆ, ແລະບາງຄົນກໍ່ໃຫ້ ENAMETOOLONG; lib ອະທິບາຍ
ການ​ນໍາ​ໃຊ້​ຫ້ອງ​ສະ​ຫມຸດ​ pathconf(3) _PC_NO_TRUNC ບອກອັນໃດ. ຖ້າ​ຫາກ​ວ່າ​ຄວາມ​ຜິດ​ພາດ​ນີ້​ເກີດ​ຂຶ້ນ​, ໄດ້​
ຫ້ອງສະຫມຸດ libexplain ຈະລະບຸຂອບເຂດຈໍາກັດໃນຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດ, ຂອບເຂດຈໍາກັດແມ່ນ
ໄດ້​ມາ​ຈາກ pathconf(3) _PC_NAME_MAX. ສັງເກດເຫັນວິທີການຈໍາກັດລະບົບລວມ
ໃນ​ຂໍ້​ຄວາມ​ຜິດ​ພາດ​.
ເປີດ(ຊື່ເສັ້ນທາງ = "system7/only-had-14-ຕົວອັກສອນ", flags = O_RDONLY) ລົ້ມເຫລວ, ໄຟລ໌
ຊື່ຍາວເກີນໄປ (36, ENAMETOOLONG) ເນື່ອງຈາກວ່າອົງປະກອບ "ພຽງແຕ່-had-14-ຕົວອັກສອນ" ແມ່ນ
ຍາວ​ເກີນ​ຂອບ​ເຂດ​ຈໍາ​ກັດ (14​)

ຊື່ເສັ້ນທາງຫວ່າງເປົ່າ
ໃນ Unix ຕົ້ນສະບັບ, ຊື່ເສັ້ນທາງເປົ່າຫມາຍເຖິງໄດເລກະທໍລີປະຈຸບັນ.
ໃນປັດຈຸບັນ POSIX ດຳລັດວ່າຊື່ເສັ້ນທາງເປົ່າຕ້ອງບໍ່ໄດ້ຮັບການແກ້ໄຂຢ່າງສໍາເລັດຜົນ.
open(pathname = "", flags = O_RDONLY) ລົ້ມເຫລວ, ບໍ່ມີໄຟລ໌ ຫຼື directory ດັ່ງກ່າວ (2,
ENOENT) ເພາະວ່າ POSIX ດຳລັດວ່າຊື່ເສັ້ນທາງເປົ່າຕ້ອງບໍ່ໄດ້ຮັບການແກ້ໄຂ
ສົບຜົນສໍາເລັດ

Permissions
bits ການອະນຸຍາດຂອງໄຟລ໌ປະກອບດ້ວຍສາມກຸ່ມຂອງສາມ bits. ກຸ່ມທໍາອິດຂອງ
ສາມຖືກນໍາໃຊ້ໃນເວລາທີ່ ID ຜູ້ໃຊ້ທີ່ມີປະສິດທິພາບຂອງຂະບວນການໂທຫາເທົ່າກັບ ID ເຈົ້າຂອງ
ໄຟລ໌. ກຸ່ມທີສອງຂອງສາມແມ່ນໃຊ້ເມື່ອ ID ກຸ່ມຂອງໄຟລ໌ທັງສອງເທົ່າກັບ
ID ກຸ່ມທີ່ມີປະສິດທິພາບຂອງຂະບວນການໂທ, ຫຼືເປັນຫນຶ່ງໃນ ID ກຸ່ມເສີມຂອງ
ຂະ​ບວນ​ການ​ໂທ​. ໃນເວລາທີ່ທັງສອງບໍ່ຖື, ກຸ່ມທີສາມຖືກນໍາໃຊ້.
ເປີດ(ຊື່ເສັ້ນທາງ = "/ etc / passwd", flags = O_WRONLY) ລົ້ມເຫລວ, ການອະນຸຍາດຖືກປະຕິເສດ (13,
EACCES) ເນື່ອງຈາກວ່າຂະບວນການບໍ່ມີການອະນຸຍາດໃຫ້ຂຽນ "passwd" ປົກກະຕິ
ໄຟລ໌ໃນຊື່ເສັ້ນທາງ "/ ແລະອື່ນໆ"ໄດເລກະທໍລີ, ຂະບວນການທີ່ມີປະສິດທິພາບ UID 1000 "pmiller"
ບໍ່ກົງກັບເຈົ້າຂອງໄຟລ໌ປົກກະຕິ 0 "ຮາກ" ດັ່ງນັ້ນຮູບແບບການອະນຸຍາດເຈົ້າຂອງ "rw-"
ຖືກລະເລີຍ, ຮູບແບບການອະນຸຍາດອື່ນໆແມ່ນ "r--", ແລະຂະບວນການບໍ່ໄດ້ຮັບສິດທິພິເສດ
(ບໍ່ມີຄວາມສາມາດ DAC_OVERRIDE)
ບາງພື້ນທີ່ຫຼາຍແມ່ນໃຫ້ຄໍາອະທິບາຍນີ້, ຍ້ອນວ່າຜູ້ໃຊ້ສ່ວນໃຫຍ່ບໍ່ຮູ້ວ່ານີ້
ແມ່ນວິທີທີ່ລະບົບການອະນຸຍາດເຮັດວຽກ. ໂດຍສະເພາະ: ເຈົ້າຂອງ, ກຸ່ມແລະອື່ນໆ
ການ​ອະ​ນຸ​ຍາດ​ແມ່ນ​ສະ​ເພາະ​, ພວກ​ເຂົາ​ເຈົ້າ​ບໍ່ "ຫຼື​"ed ຮ່ວມ​ກັນ​.

ແຂງແຮງ ແລະ ການສົນທະນາ SYSTEM ທີ່ເອີ້ນ


ຂະບວນການຂຽນຕົວຈັດການຂໍ້ຜິດພາດສະເພາະສໍາລັບການເອີ້ນລະບົບແຕ່ລະຄັ້ງມັກຈະເປີດເຜີຍ
quirks ທີ່ຫນ້າສົນໃຈແລະເງື່ອນໄຂຂອງເຂດແດນ, ຫຼືບໍ່ເຫັນແຈ້ງ ຜິດພາດ(3) ຄ່າ.

ENOMEDIUM, No ຂະຫນາດກາງ ພົບເຫັນ
ການກະທໍາຂອງການຄັດລອກແຜ່ນຊີດີແມ່ນແຫຼ່ງຂອງຫົວຂໍ້ສໍາລັບເອກະສານນີ້.
$ dd ຖ້າ =/dev/cdrom of=fubar.iso
dd: ເປີດ “/dev/cdrom”: ບໍ່ພົບສື່
$
ຜູ້ຂຽນສົງໄສວ່າເປັນຫຍັງຄອມພິວເຕີຂອງລາວຈຶ່ງບອກລາວວ່າບໍ່ມີສິ່ງດັ່ງກ່າວເປັນ psychic
ກາງ. ນອກ ເໜືອ ຈາກຄວາມຈິງທີ່ວ່າຜູ້ເວົ້າພາສາອັງກິດພື້ນເມືອງ ຈຳ ນວນຫຼວງຫຼາຍບໍ່ແມ່ນ
ເຖິງແມ່ນວ່າຮູ້ວ່າ "ສື່ມວນຊົນ" ແມ່ນຫຼາຍພາສາ, ປ່ອຍໃຫ້ຢູ່ຄົນດຽວວ່າ "ຂະຫນາດກາງ" ແມ່ນຄໍານາມ, ສະຕິງ.
ກັບຄືນໂດຍ ຄວາມຜິດພາດ(3) ສໍາລັບ ENOMEDIUM ແມ່ນ terse ເປັນທີ່ຈະເກືອບຫມົດຂອງ
ເນື້ອໃນ.

ເມື່ອ​ໃດ​ ເປີດ(2) ກັບຄືນ ENOMEDIUM ມັນຈະດີຖ້າຫ້ອງສະຫມຸດ libexplain ສາມາດຂະຫຍາຍ a
ພຽງເລັກນ້ອຍກ່ຽວກັບເລື່ອງນີ້, ອີງຕາມປະເພດຂອງການຂັບມັນແມ່ນ. ຍົກ​ຕົວ​ຢ່າງ:
... ເນື່ອງຈາກວ່າບໍ່ມີແຜ່ນຢູ່ໃນ floppy drive
... ເນື່ອງຈາກວ່າບໍ່ມີແຜ່ນໃນ CD-ROM drive
... ເພາະວ່າບໍ່ມີເທບໃນໄດເທບ
... ເນື່ອງຈາກວ່າບໍ່ມີ memory stick ໃນເຄື່ອງອ່ານກາດ

ແລະ​ສະ​ນັ້ນ​ມັນ​ໄດ້​ບັງ​ເກີດ​ຂຶ້ນ ...
open(pathname = "/dev/cdrom", ທຸງ = O_RDONLY) ລົ້ມເຫລວ, ບໍ່ພົບສື່ກາງ (123,
ENOMEDIUM) ເພາະວ່າບໍ່ປະກົດວ່າມີແຜ່ນຢູ່ໃນແຜ່ນ CD-ROM
ເຄັດລັບ, ທີ່ຜູ້ຂຽນບໍ່ຮູ້ມາກ່ອນ, ແມ່ນການເປີດອຸປະກອນໂດຍໃຊ້
ທຸງ O_NONBLOCK, ເຊິ່ງຈະເຮັດໃຫ້ທ່ານສາມາດເປີດໄດຣຟ໌ທີ່ບໍ່ມີສື່ກາງຢູ່ໃນນັ້ນ. ແລ້ວເຈົ້າ
ອອກອຸປະກອນສະເພາະ ioctls(2) ຮ້ອງ​ຂໍ​ຈົນ​ກວ່າ​ທ່ານ​ຈະ​ຄິດ​ອອກ​ວ່າ heck ມັນ​ແມ່ນ​ຫຍັງ. (ບໍ່
ໃຫ້ແນ່ໃຈວ່ານີ້ແມ່ນ POSIX, ແຕ່ວ່າມັນຍັງເບິ່ງຄືວ່າຈະເຮັດວຽກແບບນັ້ນໃນ BSD ແລະ Solaris, ອີງຕາມ
ໄດ້ ວອມ(1​) ແຫຼ່ງ​ຂໍ້​ມູນ​.

ໃຫ້ສັງເກດວ່າການນໍາໃຊ້ທີ່ແຕກຕ່າງກັນຂອງ "ແຜ່ນ" ແລະ "ແຜ່ນ" ໃນສະພາບການ. ມາດຕະຖານ CD ມາຈາກ
ໃນປະເທດຝຣັ່ງ, ແຕ່ທຸກສິ່ງທຸກຢ່າງມີ "k".

ບໍ່ໄດ້ຜົນ, ບໍ່ດີ ທີ່ຢູ່
ການໂທລະບົບໃດນຶ່ງທີ່ໃຊ້ການໂຕ້ຖຽງຕົວຊີ້ສາມາດສົ່ງຄືນ EFAULT. ຫ້ອງສະຫມຸດ libexplain
ສາ​ມາດ​ຄິດ​ອອກ​ວ່າ​ການ​ໂຕ້​ຖຽງ​ແມ່ນ​ຜິດ​ພາດ​, ແລະ​ມັນ​ເຮັດ​ໄດ້​ໂດຍ​ບໍ່​ມີ​ການ​ລົບ​ກວນ​ຂະ​ບວນ​ການ​
(ຫຼື thread) ການຈັດການສັນຍານ.

ໃນເວລາທີ່ມີ, ໄດ້ ຄະແນນຕ່ຳ(2) ການໂທລະບົບຖືກນໍາໃຊ້, ເພື່ອຖາມວ່າພາກພື້ນຫນ່ວຍຄວາມຈໍາຖືກຕ້ອງ.
ມັນສາມາດສົ່ງຄືນຜົນໄດ້ຮັບສາມຢ່າງ: ແຜນທີ່ແຕ່ບໍ່ແມ່ນຢູ່ໃນຄວາມຊົງຈໍາທາງດ້ານຮ່າງກາຍ, ແຜນທີ່ແລະທາງດ້ານຮ່າງກາຍ
ຄວາມຊົງຈໍາ, ແລະບໍ່ໄດ້ເຮັດແຜນທີ່. ເມື່ອທົດສອບຄວາມຖືກຕ້ອງຂອງຕົວຊີ້, ສອງອັນທໍາອິດແມ່ນ "ແມ່ນ"
ແລະອັນສຸດທ້າຍແມ່ນ "ບໍ່".

ການກວດສອບສາຍ C ແມ່ນຍາກກວ່າ, ເພາະວ່າແທນທີ່ຈະເປັນຕົວຊີ້ແລະຂະຫນາດ, ພວກເຮົາພຽງແຕ່
ມີຕົວຊີ້. ເພື່ອກໍານົດຂະຫນາດທີ່ພວກເຮົາຈະຕ້ອງຊອກຫາ NUL, ແລະມັນສາມາດເຮັດໄດ້
segfault, catch-22.

ເພື່ອເຮັດວຽກນີ້, ຫ້ອງສະຫມຸດ libexplain ໃຊ້ ສະຖິຕິ(2) sysem call (ມີທີ່ຮູ້ຈັກ
ການໂຕ້ຖຽງທີສອງທີ່ດີ) ເພື່ອທົດສອບ C strings ສໍາລັບຄວາມຖືກຕ້ອງ. ກັບຄືນຄວາມລົ້ມເຫຼວ && errno == EFAULT
ແມ່ນ "ບໍ່", ແລະອັນອື່ນແມ່ນ "ແມ່ນ". ອັນນີ້, ແນ່ນອນຈໍາກັດສະຕຣິງໃຫ້ PATH_MAX
ຕົວອັກສອນ, ແຕ່ປົກກະຕິແລ້ວນັ້ນບໍ່ແມ່ນບັນຫາສໍາລັບຫ້ອງສະຫມຸດ libexplain, ເພາະວ່ານັ້ນແມ່ນ
ເກືອບສະເໝີເປັນສາຍທີ່ຍາວທີ່ສຸດທີ່ມັນສົນໃຈ.

ໄຟລ໌ອີເມລ໌, ເກີນໄປ ຈໍານວນຫຼາຍ ເປີດ ໄຟ
ຄວາມຜິດພາດນີ້ເກີດຂຶ້ນເມື່ອຂະບວນການມີຈໍານວນຕົວອະທິບາຍໄຟລ໌ສູງສຸດແລ້ວເປີດ.
ຖ້າຂອບເຂດຈໍາກັດຕົວຈິງຈະຖືກພິມ, ແລະຫ້ອງສະຫມຸດ libexplain ພະຍາຍາມ, ທ່ານບໍ່ສາມາດເປີດໄດ້
ໄຟລ໌ໃນ / proc ເພື່ອອ່ານວ່າມັນແມ່ນຫຍັງ.
open_max = sysconf(_SC_OPEN_MAX);
ອັນນີ້ບໍ່ຍາກຫຼາຍ, ມີ sysconf(3) ວິທີການໄດ້ຮັບຂອບເຂດຈໍາກັດ.

ENFILE, ເກີນໄປ ຈໍານວນຫຼາຍ ເປີດ ໄຟ in ລະບົບ
ຄວາມຜິດພາດນີ້ເກີດຂຶ້ນເມື່ອລະບົບຈໍາກັດຈໍານວນໄຟລ໌ເປີດທັງຫມົດ
ຮອດ. ໃນກໍລະນີດັ່ງກ່າວນີ້, ບໍ່ມີມື sysconf(3) ວິທີການໄດ້ຮັບຂອບເຂດຈໍາກັດ.

ການຂຸດຂຸມເລິກ, ຫນຶ່ງອາດຈະຄົ້ນພົບວ່າຢູ່ໃນ Linux ມີ / proc ເຂົ້າທີ່ພວກເຮົາສາມາດອ່ານໄດ້
ໄດ້​ຮັບ​ຄ່າ​ນີ້​. Catch-22: ພວກເຮົາບໍ່ມີຕົວອະທິບາຍໄຟລ໌, ດັ່ງນັ້ນພວກເຮົາບໍ່ສາມາດເປີດໄຟລ໌ໄປຫາ
ອ່ານຂອບເຂດຈໍາກັດ.

ໃນ Linux ມີການໂທຫາລະບົບເພື່ອໃຫ້ໄດ້ມັນ, ແຕ່ມັນບໍ່ມີ [e] glibc wrapper function, ດັ່ງນັ້ນ.
ທ່ານ​ມີ​ທັງ​ຫມົດ​ມັນ​ລະ​ມັດ​ລະ​ວັງ​ຫຼາຍ​:
ຍາວ
explain_maxfile(void)
{
#ifdef __linux__
struct __sysctl_args args;
int32_t maxfile;
size_t maxfile_size = ຂະຫນາດຂອງ(maxfile);
int name[] = { CTL_FS, FS_MAXFILE };
memset(&args, 0, sizeof(struct __sysctl_args));
args.name = ຊື່;
args.nlen = 2;
args.oldval = &maxfile;
args.oldlenp = &maxfile_size;
ຖ້າ (syscall(SYS__sysctl, &args) >= 0)
ສົ່ງຄືນ maxfile;
#ສຸດທ້າຍ
ກັບຄືນ -1;
}
ນີ້ອະນຸຍາດໃຫ້ຈໍາກັດການລວມຢູ່ໃນຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດ, ເມື່ອມີ.

EINVAL “ບໍ່ຖືກຕ້ອງ ການໂຕ້ຖຽງ” vs ENOSYS “ຟັງຊັນ ບໍ່ ປະຕິບັດ”
ການກະທຳທີ່ບໍ່ຮອງຮັບ (ເຊັ່ນ: symlink(2) ໃນລະບົບໄຟລ໌ FAT) ບໍ່ໄດ້ຖືກລາຍງານ
ຢ່າງຕໍ່ເນື່ອງຈາກການໂທລະບົບຫນຶ່ງໄປຫາຕໍ່ໄປ. ມັນເປັນໄປໄດ້ທີ່ຈະມີທັງ EINVAL ຫຼື
ENOSYS ກັບຄືນມາ.

ດັ່ງນັ້ນ, ຕ້ອງເອົາໃຈໃສ່ກັບກໍລະນີຄວາມຜິດພາດເຫຼົ່ານີ້ເພື່ອໃຫ້ຖືກຕ້ອງ, ໂດຍສະເພາະ
ເນື່ອງຈາກວ່າ EINVAL ຍັງສາມາດອ້າງອີງເຖິງບັນຫາທີ່ມີຫນຶ່ງຫຼືຫຼາຍການໂຕ້ຖຽງການໂທລະບົບ.

ຫມາຍ​ເຫດ​ ທີ່ ຜິດພາດ(3​) is ບໍ່ ສະເຫມີໄປ ທີ່ກໍານົດໄວ້
ມີບາງຄັ້ງທີ່ມັນຈໍາເປັນຕ້ອງອ່ານແຫຼ່ງ [e]glibc ເພື່ອກໍານົດວິທີການແລະ
ເມື່ອຂໍ້ຜິດພາດຖືກສົ່ງຄືນສໍາລັບບາງການໂທລະບົບ.

feof(3) fileno(3​)
ມັນມັກຈະສົມມຸດວ່າຫນ້າທີ່ເຫຼົ່ານີ້ບໍ່ສາມາດສົ່ງຄືນຂໍ້ຜິດພາດໄດ້. ນີ້ແມ່ນພຽງແຕ່ຖ້າຫາກວ່າ
ໄດ້ ນ້ໍາ argument ແມ່ນຖືກຕ້ອງ, ຢ່າງໃດກໍຕາມ, ພວກເຂົາເຈົ້າສາມາດກວດພົບບໍ່ຖືກຕ້ອງ
ຕົວຊີ້.

fpathconf(3) pathconf(3​)
ມູນຄ່າກັບຄືນຂອງ fpathconf(2) ແລະ pathconf(2) ສາມາດເປັນ -1 ຢ່າງຖືກຕ້ອງ, ດັ່ງນັ້ນມັນແມ່ນ
ມີຄວາມຈໍາເປັນເພື່ອເບິ່ງວ່າ ຜິດພາດ(3) ໄດ້ຖືກກໍານົດຢ່າງຈະແຈ້ງ.

ioctls(2​)
ມູນຄ່າກັບຄືນຂອງ ioctls(2) ສາມາດເປັນ -1 ຢ່າງຖືກຕ້ອງ, ສະນັ້ນມັນຈໍາເປັນຕ້ອງເບິ່ງວ່າ
ຜິດພາດ(3) ໄດ້ຖືກກໍານົດຢ່າງຈະແຈ້ງ.

ອ່ານ(3​)
ມູນຄ່າກັບຄືນຂອງ ອ່ານ(3) ແມ່ນ NULL ສໍາລັບທັງສອງຂໍ້ຜິດພາດ ແລະໄຟລ໌ສິ້ນສຸດ. ມັນ​ແມ່ນ
ມີຄວາມຈໍາເປັນເພື່ອເບິ່ງວ່າ ຜິດພາດ(3) ໄດ້ຖືກກໍານົດຢ່າງຈະແຈ້ງ.

setbuf(3) setbuffer(3) setlinebuf(3) setvbuf(3​)
ທັງໝົດແຕ່ສຸດທ້າຍຂອງໜ້າທີ່ເຫຼົ່ານີ້ກັບຄືນມາເປັນໂມຄະ. ແລະ setvbuf(3​) ເປັນ​ເອ​ກະ​ສານ​ພຽງ​ແຕ່​ເປັນ​
ກັບຄືນ "ບໍ່ແມ່ນສູນ" ດ້ວຍຄວາມຜິດພາດ. ມັນເປັນສິ່ງຈໍາເປັນເພື່ອເບິ່ງວ່າ ຜິດພາດ(3) ໄດ້ຢ່າງຈະແຈ້ງ
ຕັ້ງ.

strtod(3) Strtol(3) strtold(3) sttoll(3) strtoul(3) strtoull(3​)
ຟັງຊັນເຫຼົ່ານີ້ສົ່ງຄືນຄ່າ 0 ດ້ວຍຄວາມຜິດພາດ, ແຕ່ນັ້ນກໍ່ແມ່ນຄ່າຕອບແທນທີ່ຖືກຕ້ອງຕາມກົດໝາຍ. ມັນ​ແມ່ນ
ມີຄວາມຈໍາເປັນເພື່ອເບິ່ງວ່າ ຜິດພາດ(3) ໄດ້ຖືກກໍານົດຢ່າງຈະແຈ້ງ.

unget ອື່ນໆ(3​)
ໃນຂະນະທີ່ພຽງແຕ່ລັກສະນະດຽວຂອງການສໍາຮອງຂໍ້ມູນໄດ້ຖືກບັງຄັບໂດຍມາດຕະຖານ ANSI C, ມັນປ່ຽນໄປ
ອອກມາວ່າ [e]glibc ອະນຸຍາດໃຫ້ຫຼາຍກວ່າ ... ແຕ່ນັ້ນຫມາຍຄວາມວ່າມັນສາມາດລົ້ມເຫລວກັບ ENOMEM. ມັນ​ສາ​ມາດ
ຍັງລົ້ມເຫລວກັບ EBADF ຖ້າ fp ແມ່ນປອມ. ຄວາມຫຍຸ້ງຍາກທີ່ສຸດ, ຖ້າທ່ານຜ່ານ EOF ຜິດພາດ
ການກັບຄືນເກີດຂື້ນ, ແຕ່ errno ບໍ່ໄດ້ຖືກກໍານົດ.

ຫ້ອງສະຫມຸດ libexplain ກວດພົບຂໍ້ຜິດພາດເຫຼົ່ານີ້ຢ່າງຖືກຕ້ອງ, ເຖິງແມ່ນວ່າໃນກໍລະນີທີ່ມີ
ຄ່າຄວາມຜິດພາດແມ່ນບັນທຶກບໍ່ດີ, ຖ້າຢູ່ໃນທັງຫມົດ.

ENOSPC, No ຊ່ອງ ໄວ້ on ອຸປະກອນ
ເມື່ອຂໍ້ຜິດພາດນີ້ຫມາຍເຖິງໄຟລ໌ໃນລະບົບໄຟລ໌, ຫ້ອງສະຫມຸດ libexplain ຈະພິມຕົວເຊື່ອມຕໍ່
ຈຸດຂອງລະບົບໄຟລ໌ທີ່ມີບັນຫາ. ນີ້ສາມາດເຮັດໃຫ້ແຫຼ່ງຂອງຄວາມຜິດພາດຫຼາຍ
ຈະແຈ້ງກວ່າ.
write(fildes = 1 "ຕົວຢ່າງ", data = 0xbfff2340, data_size = 5) ລົ້ມເຫລວ, ບໍ່ມີຊ່ອງຫວ່າງ
ຢູ່ໃນອຸປະກອນ (28, ENOSPC) ເພາະວ່າລະບົບໄຟລ໌ທີ່ບັນຈຸໄຟລ໌ ("/ ເຮືອນ") ບໍ່ມີ
ພື້ນທີ່ເພີ່ມເຕີມສໍາລັບຂໍ້ມູນ
ເນື່ອງຈາກການຮອງຮັບອຸປະກອນພິເສດຫຼາຍຂຶ້ນ, ຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດຄາດວ່າຈະລວມເອົາອຸປະກອນ
ຊື່ແລະຂະຫນາດຕົວຈິງຂອງອຸປະກອນ.

EROFS, ອ່ານ​ຢ່າງ​ດຽວ ເອກະສານ ລະບົບ
ເມື່ອຂໍ້ຜິດພາດນີ້ຫມາຍເຖິງໄຟລ໌ໃນລະບົບໄຟລ໌, ຫ້ອງສະຫມຸດ libexplain ຈະພິມຕົວເຊື່ອມຕໍ່
ຈຸດຂອງລະບົບໄຟລ໌ທີ່ມີບັນຫາ. ນີ້ສາມາດເຮັດໃຫ້ແຫຼ່ງຂອງຄວາມຜິດພາດຫຼາຍ
ຈະແຈ້ງກວ່າ.

ເນື່ອງຈາກການຮອງຮັບອຸປະກອນພິເສດຫຼາຍຂຶ້ນ, ຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດຄາດວ່າຈະລວມເອົາອຸປະກອນ
ຊື່​ແລະ​ປະ​ເພດ​.
open(pathname = "/dev/fd0", O_RDWR, 0666) ລົ້ມເຫລວ, ລະບົບໄຟລ໌ອ່ານເທົ່ານັ້ນ (30, EROFS)
ເນື່ອງຈາກວ່າແຜ່ນ floppy disk ມີແຖບປ້ອງກັນການຂຽນ

...ເພາະ CD-ROM ບໍ່ສາມາດຂຽນໄດ້
...ເນື່ອງ​ຈາກ​ວ່າ​ແຜ່ນ​ຄວາມ​ຊົງ​ຈໍາ​ທີ່​ມີ​ແຖບ​ປົກ​ປັກ​ຮັກ​ສາ write ໄດ້​ຕັ້ງ​ໄວ້​
...ເພາະວ່າເທບແມ່ເຫຼັກ ½ ນິ້ວບໍ່ມີແຫວນຂຽນ

ປ່ຽນຊື່
ໄດ້ ປ່ຽນຊື່(2) ການໂທລະບົບຖືກນໍາໃຊ້ເພື່ອປ່ຽນສະຖານທີ່ຫຼືຊື່ຂອງໄຟລ໌, ຍ້າຍມັນ
ລະຫວ່າງໄດເລກະທໍລີຖ້າຕ້ອງການ. ຖ້າຊື່ເສັ້ນທາງປາຍທາງມີຢູ່ແລ້ວ ມັນຈະເປັນ
ທົດແທນດ້ວຍປະລໍາມະນູ, ດັ່ງນັ້ນບໍ່ມີຈຸດໃດທີ່ຂະບວນການອື່ນພະຍາຍາມ
ເຂົ້າເຖິງມັນຈະພົບວ່າມັນຂາດຫາຍໄປ.

ຢ່າງໃດກໍຕາມ, ມີຂໍ້ຈໍາກັດ: ທ່ານພຽງແຕ່ສາມາດປ່ຽນຊື່ໄດເລກະທໍລີຢູ່ເທິງຂອງອື່ນ
ໄດເລກະທໍລີຖ້າໄດເລກະທໍລີປາຍທາງບໍ່ຫວ່າງເປົ່າ.
rename(oldpath = "foo", newpath = "bar") ລົ້ມເຫລວ, Directory ບໍ່ຫວ່າງເປົ່າ (39,
ENOTEMPTY) ເນື່ອງຈາກວ່າ newpath ບໍ່ແມ່ນ directory ຫວ່າງເປົ່າ; ນັ້ນແມ່ນ, ມັນປະກອບດ້ວຍລາຍການ
ນອກ​ຈາກ "." ແລະ ".."
ທ່ານບໍ່ສາມາດປ່ຽນຊື່ໄດເລກະທໍລີຢູ່ເທິງສຸດຂອງລາຍການທີ່ບໍ່ແມ່ນໄດເລກະທໍລີ, ຄືກັນ.
rename(oldpath = "foo", newpath = "bar") ລົ້ມເຫລວ, ບໍ່ແມ່ນ directory (20, ENOTDIR)
ເນື່ອງຈາກວ່າ oldpath ແມ່ນໄດເລກະທໍລີ, ແຕ່ newpath ແມ່ນໄຟລ໌ປົກກະຕິ, ບໍ່ແມ່ນໄດເລກະທໍລີ
ທັງ​ບໍ່​ແມ່ນ​ການ​ປີ້ນ​ກັບ​ກັນ​ໄດ້​ອະ​ນຸ​ຍາດ​ໃຫ້​
rename(oldpath = "foo", newpath = "bar") ລົ້ມເຫລວ, ເປັນໄດເລກະທໍລີ (21, EISDIR)
ເນື່ອງຈາກວ່າ newpath ແມ່ນໄດເລກະທໍລີ, ແຕ່ oldpath ແມ່ນໄຟລ໌ປົກກະຕິ, ບໍ່ແມ່ນໄດເລກະທໍລີ

ນີ້, ແນ່ນອນ, ເຮັດໃຫ້ວຽກຂອງຫ້ອງສະຫມຸດ libexplain ສັບສົນຫຼາຍ, ເພາະວ່າ
ຍົກເລີກການເຊື່ອມຕໍ່(2) ຫຼື ແມ່ນ rm(2) ການໂທລະບົບແມ່ນເອີ້ນວ່າ implicitly ໂດຍ ປ່ຽນຊື່(2), ແລະອື່ນໆທັງຫມົດຂອງ
ຍົກເລີກການເຊື່ອມຕໍ່(2) ຫຼື ແມ່ນ rm(2) ຄວາມຜິດພາດຕ້ອງໄດ້ຮັບການກວດພົບແລະຈັດການ, ເຊັ່ນດຽວກັນ.

dup2
ໄດ້ dup2(2) ການໂທລະບົບແມ່ນໃຊ້ເພື່ອສ້າງຕົວອະທິບາຍໄຟລ໌ທີສອງທີ່ອ້າງອີງເຖິງ
ວັດຖຸດຽວກັນກັບຕົວອະທິບາຍໄຟລ໌ທໍາອິດ. ໂດຍປົກກະຕິແລ້ວ ອັນນີ້ຖືກໃຊ້ເພື່ອປະຕິບັດການປ້ອນຂໍ້ມູນຂອງແກະ
ແລະການປ່ຽນເສັ້ນທາງຜົນຜະລິດ.

ສິ່ງທີ່ມ່ວນແມ່ນວ່າ, ຄືກັນກັບ ປ່ຽນຊື່(2​) ປະ​ລໍາ​ມະ​ນູ​ສາ​ມາດ​ປ່ຽນ​ຊື່​ໄຟລ​໌​ຢູ່​ເທິງ​ຂອງ​ການ​
ໄຟລ໌ທີ່ມີຢູ່ແລ້ວແລະເອົາໄຟລ໌ເກົ່າອອກ, dup2(2​) ສາ​ມາດ​ເຮັດ​ສິ່ງ​ນີ້​ໃສ່​ໄຟລ​໌​ທີ່​ເປີດ​ແລ້ວ​
ຕົວອະທິບາຍ.

ອີກເທື່ອຫນຶ່ງ, ນີ້ເຮັດໃຫ້ວຽກຂອງຫ້ອງສະຫມຸດ libexplain ສັບສົນຫຼາຍ, ເພາະວ່າ ໃກ້(2​)
ການໂທລະບົບແມ່ນເອີ້ນວ່າ implicitly ໂດຍ dup2(2), ແລະອື່ນໆທັງຫມົດຂອງ ໃກ້(2) ຄວາມຜິດພາດຂອງຈະຕ້ອງເປັນ
ກວດ​ພົບ​ແລະ​ຈັດ​ການ​, ເຊັ່ນ​ດຽວ​ກັນ​.

ເລື່ອງຮາວທີ່ແປງ IN IOCTL ສະຫນັບສະຫນູນ


ໄດ້ ioctls(2) ການໂທຫາລະບົບໃຫ້ຜູ້ຂຽນໄດເວີອຸປະກອນທີ່ມີວິທີການຕິດຕໍ່ສື່ສານກັບ
user-space ທີ່ບໍ່ເຫມາະພາຍໃນ kernel API ທີ່ມີຢູ່ແລ້ວ. ເບິ່ງ ioctl_list(2).

ການຖອດລະຫັດ ການຮ້ອງຂໍ ຈໍານວນ
ຈາກ​ການ​ເບິ່ງ cursory ຢູ່​ ioctls(2​) ການ​ໂຕ້​ຕອບ​, ມີ​ຈະ​ປະ​ກົດ​ວ່າ​ມີ​ຂະ​ຫນາດ​ໃຫຍ່​ແຕ່​ຈໍາ​ກັດ​
ຈໍານວນທີ່ເປັນໄປໄດ້ ioctls(2) ຄໍາຮ້ອງຂໍ. ແຕ່ລະຄົນແຕກຕ່າງກັນ ioctls(2) ການຮ້ອງຂໍແມ່ນມີປະສິດຕິຜົນ
ການໂທຫາລະບົບອື່ນ, ແຕ່ບໍ່ມີປະເພດຄວາມປອດໄພໃດໆ - compiler ບໍ່ສາມາດຊ່ວຍໄດ້
programmer ໄດ້ຮັບສິດທິເຫຼົ່ານີ້. ນີ້ອາດຈະເປັນແຮງຈູງໃຈທີ່ຢູ່ເບື້ອງຫຼັງ tcflush(3) ແລະ
ຫມູ່ເພື່ອນ.

ຄວາມປະທັບໃຈເບື້ອງຕົ້ນແມ່ນທ່ານສາມາດຖອດລະຫັດໄດ້ ioctls(2​) ການ​ຮ້ອງ​ຂໍ​ການ​ນໍາ​ໃຊ້​ສະ​ຫຼັບ​ຂະ​ຫນາດ​ໃຫຍ່​
ຖະແຫຼງການ. ອັນນີ້ກາຍເປັນສິ່ງທີ່ເປັນໄປບໍ່ໄດ້ ເພາະວ່າຜູ້ໜຶ່ງຄົ້ນພົບຢ່າງໄວວາວ່າມັນແມ່ນ
ເປັນໄປບໍ່ໄດ້ທີ່ຈະລວມເອົາຫົວຂອງລະບົບທີ່ຈໍາເປັນທັງໝົດເພື່ອກໍານົດສິ່ງຕ່າງໆ ioctls(2​)
ການຮ້ອງຂໍ, ເພາະວ່າພວກເຂົາມີຄວາມຫຍຸ້ງຍາກໃນການຫຼີ້ນທີ່ດີກັບກັນແລະກັນ.

ການເບິ່ງທີ່ເລິກເຊິ່ງສະແດງໃຫ້ເຫັນວ່າມີຈໍານວນການຮ້ອງຂໍ "ສ່ວນຕົວ", ແລະອຸປະກອນ
ຜູ້ຂຽນຄົນຂັບໄດ້ຖືກຊຸກຍູ້ໃຫ້ໃຊ້ພວກມັນ. ນີ້ຫມາຍຄວາມວ່າມີຂະຫນາດໃຫຍ່ກວ່າທີ່ເປັນໄປໄດ້
ຊຸດຂອງຄໍາຮ້ອງຂໍ, ທີ່ມີຕົວເລກການຮ້ອງຂໍທີ່ບໍ່ຊັດເຈນ, ກ່ວາຈະປາກົດຂື້ນໃນທັນທີ. ນອກຈາກນີ້,
ຍັງມີບາງຄວາມບໍ່ແນ່ນອນທາງປະຫວັດສາດເຊັ່ນກັນ.

ພວກ​ເຮົາ​ຮູ້​ແລ້ວ​ວ່າ​ການ​ສະ​ຫຼັບ​ແມ່ນ impractical, ແຕ່​ໃນ​ປັດ​ຈຸ​ບັນ​ພວກ​ເຮົາ​ຮູ້​ວ່າ​ຈະ​ເລືອກ​ເອົາ
ຊື່ຄໍາຮ້ອງຂໍທີ່ເຫມາະສົມແລະຄໍາອະທິບາຍພວກເຮົາຕ້ອງພິຈາລະນາບໍ່ພຽງແຕ່ຈໍານວນຄໍາຮ້ອງຂໍແຕ່
ຕົວອະທິບາຍໄຟລ໌.

ການປະຕິບັດຂອງ ioctls(2) ສະຫນັບສະຫນູນພາຍໃນຫ້ອງສະຫມຸດ libexplain ແມ່ນການມີຕາຕະລາງຂອງ
ຊີ້ໄປ ioctls(2) ຮ້ອງຂໍໃຫ້ຜູ້ອະທິບາຍ. ແຕ່ລະຕົວອະທິບາຍເຫຼົ່ານີ້ປະກອບມີທາງເລືອກ
ຊີ້ໄປຫາຟັງຊັນ disambiguation.

ແຕ່ລະຄໍາຮ້ອງຂໍແມ່ນປະຕິບັດຕົວຈິງໃນໄຟລ໌ແຫຼ່ງແຍກຕ່າງຫາກ, ດັ່ງນັ້ນມີຄວາມຈໍາເປັນ
ປະ​ກອບ​ມີ​ໄຟລ​໌​ໄດ້​ຖືກ​ປົດ​ປ່ອຍ​ພັນ​ທະ​ທີ່​ຈະ​ຫຼິ້ນ​ງາມ​ກັບ​ຄົນ​ອື່ນ​.

ການເປັນຕົວແທນ
ປັດຊະຍາທີ່ຢູ່ເບື້ອງຫລັງຫ້ອງສະຫມຸດ libexplain ແມ່ນເພື່ອສະຫນອງຂໍ້ມູນຫຼາຍເທົ່າທີ່
ເປັນໄປໄດ້, ລວມທັງການເປັນຕົວແທນທີ່ຖືກຕ້ອງຂອງການໂທລະບົບ. ໃນກໍລະນີຂອງ
ioctls(2) ນີ້ຫມາຍຄວາມວ່າການພິມຈໍານວນຄໍາຮ້ອງຂໍທີ່ຖືກຕ້ອງ (ໂດຍຊື່) ແລະຍັງຖືກຕ້ອງ (ຫຼື
ຢ່າງຫນ້ອຍທີ່ເປັນປະໂຫຍດ) ການເປັນຕົວແທນຂອງການໂຕ້ຖຽງທີສາມ.

ໄດ້ ioctls(2) ຕົ້ນແບບມີລັກສະນະດັ່ງນີ້:
int ioctl(int fildes, int request, ...);
ເຊິ່ງຄວນຈະມີສັນຍານເຕືອນຄວາມປອດໄພປະເພດຂອງເຈົ້າຈະປິດ. ພາຍໃນກັບ [e]glibc, ອັນນີ້ແມ່ນຫັນ
ໃນ​ຫຼາຍ​ຮູບ​ແບບ​:
int __ioctl(int fildes, int request, long arg);
int __ioctl(int fildes, int request, void *arg);
ແລະການໂຕ້ຕອບ syscall kernel Linux ຄາດວ່າຈະ
asmlinkage long sys_ioctl(unsigned int fildes, unsigned int request, unsigned long
arg);
ການປ່ຽນແປງທີ່ຮຸນແຮງຂອງການໂຕ້ຖຽງທີສາມແມ່ນສິ່ງທ້າທາຍ, ໃນເວລາທີ່ຫ້ອງສະຫມຸດ libexplain
ພະຍາຍາມພິມຕົວແທນຂອງການໂຕ້ຖຽງທີສາມນັ້ນ. ຢ່າງໃດກໍຕາມ, ເມື່ອຈໍານວນການຮ້ອງຂໍ
ໄດ້ຖືກ disambiguated, ແຕ່ລະລາຍການໃນຕາຕະລາງ ioctl ຂອງຫ້ອງສະຫມຸດ libexplain ມີ a
ຟັງຊັນ print_data ແບບກຳນົດເອງ (OO ເຮັດດ້ວຍຕົນເອງ).

ຄໍາອະທິບາຍ
ມີບັນຫາຫນ້ອຍໃນການກໍານົດຄໍາອະທິບາຍທີ່ຈະນໍາໃຊ້. ເມື່ອຈໍານວນການຮ້ອງຂໍ
ໄດ້ຖືກ disambiguated, ແຕ່ລະລາຍການໃນຕາຕະລາງ ioctl ຂອງຫ້ອງສະຫມຸດ libexplain ມີ custom
ຟັງຊັນ print_explanation (ອີກເທື່ອຫນຶ່ງ, OO ເຮັດດ້ວຍຕົນເອງ).

ບໍ່ຄືກັບພາກ 2 ແລະພາກ 3 ການໂທລະບົບ, ຫຼາຍທີ່ສຸດ ioctls(2) ຄໍາຮ້ອງຂໍບໍ່ມີຂໍ້ຜິດພາດ
ເອກະສານ. ນີ້ຫມາຍຄວາມວ່າ, ເພື່ອໃຫ້ຄໍາອະທິບາຍຄວາມຜິດພາດທີ່ດີ, ມັນຈໍາເປັນຕ້ອງອ່ານ kernel
ແຫຼ່ງຂໍ້ມູນທີ່ຈະຄົ້ນພົບ

· ແມ່ນ​ຫຍັງ ຜິດພາດ(3) ຄ່າອາດຈະຖືກສົ່ງຄືນ, ແລະ

·ສາເຫດຂອງຄວາມຜິດພາດແຕ່ລະຄົນ.

ເນື່ອງຈາກວ່າລັກສະນະຂອງ OO ຂອງການສົ່ງການໂທຫາຫນ້າທີ່ກັບແກ່ນ, ທ່ານຈໍາເປັນຕ້ອງອ່ານ
ທັງຫມົດ ແຫຼ່ງຂໍ້ມູນທີ່ປະຕິບັດນັ້ນ ioctls(2) ການຮ້ອງຂໍ, ບໍ່ພຽງແຕ່ການປະຕິບັດທົ່ວໄປ. ມັນ
ຄາດວ່າຈະມີ kernels ທີ່ແຕກຕ່າງກັນຈະມີຕົວເລກຄວາມຜິດພາດທີ່ແຕກຕ່າງກັນແລະ subtly
ສາເຫດຂອງຄວາມຜິດພາດທີ່ແຕກຕ່າງກັນ.

EINVAL vs ENTOTTY
ສະຖານະການແມ່ນຮ້າຍແຮງກວ່າເກົ່າສໍາລັບ ioctls(2) ການຮ້ອງຂໍຫຼາຍກ່ວາສໍາລັບການໂທຫາລະບົບ, ກັບ EINVAL ແລະ
ENTOTTY ທັງສອງຖືກໃຊ້ເພື່ອຊີ້ບອກວ່າ an ioctls(2) ຄໍາຮ້ອງຂໍແມ່ນບໍ່ເຫມາະສົມໃນນັ້ນ
ສະພາບການ, ແລະເປັນບາງໂອກາດ ENOSYS, ENOTSUP ແລະ EOPNOTSUPP (ຫມາຍຄວາມວ່າຈະຖືກນໍາໃຊ້ສໍາລັບ sockets) ເປັນ
ດີ. ມີຄວາມຄິດເຫັນໃນແຫຼ່ງ Linux kernel ທີ່ເບິ່ງຄືວ່າຊີ້ໃຫ້ເຫັນເຖິງຄວາມກ້າວຫນ້າ
ການອະນາໄມກຳລັງດຳເນີນຢູ່. ສໍາລັບຄວາມວຸ່ນວາຍພິເສດ, BSD ເພີ່ມ ENIOOCTL ກັບຄວາມສັບສົນ.

ດັ່ງນັ້ນ, ຕ້ອງເອົາໃຈໃສ່ກັບກໍລະນີຄວາມຜິດພາດເຫຼົ່ານີ້ເພື່ອໃຫ້ຖືກຕ້ອງ, ໂດຍສະເພາະ
ເນື່ອງຈາກວ່າ EINVAL ຍັງສາມາດອ້າງອີງເຖິງບັນຫາທີ່ມີຫນຶ່ງຫຼືຫຼາຍການໂຕ້ຖຽງການໂທລະບົບ.

intptr_t
ມາດຕະຖານ C99 ກໍານົດປະເພດຈໍານວນເຕັມທີ່ຮັບປະກັນວ່າສາມາດຖືຕົວຊີ້ໃດໆ
ໂດຍບໍ່ມີການສູນເສຍຕົວແທນ.

ຕົ້ນແບບ syscall ຟັງຊັນຂ້າງເທິງຈະຖືກຂຽນດີກວ່າ
long sys_ioctl(unsigned int fildes, unsigned int request, intptr_t arg);
ບັນຫາແມ່ນຄວາມບໍ່ສອດຄ່ອງທາງດ້ານສະຕິປັນຍາທີ່ເກີດຈາກອຸປະກອນສະເພາະ ຫຼືລະບົບໄຟລ໌ສະເພາະ.
ioctls(2​) ການ​ປະ​ຕິ​ບັດ​ເຊັ່ນ​:
vfs_ioctl ຍາວ(ໄຟລ໌ໂຄງສ້າງ *filp, unsigned int cmd, unsigned long arg);
ສ່ວນໃຫຍ່ຂອງ ioctls(2) ການຮ້ອງຂໍຕົວຈິງມີ int *arg ການໂຕ້ຖຽງທີສາມ. ແຕ່ມີມັນ
ປະກາດຍາວເຮັດໃຫ້ລະຫັດການປິ່ນປົວນີ້ຍາວ * arg. ອັນນີ້ບໍ່ເປັນອັນຕະລາຍໃນ 32-bits
(sizeof(long) == sizeof(int)) ແຕ່ບໍ່ພໍໃຈໃນ 64-bits (sizeof(long) != sizeof(int)).
ຂຶ້ນຢູ່ກັບ endian-ness, ເຈົ້າເຮັດຫຼືບໍ່ໄດ້ຮັບຄ່າທີ່ທ່ານຄາດຫວັງ, ແຕ່ວ່າທ່ານ ສະເຫມີໄປ ໄດ້ຮັບ
scribble ຄວາມຊົງຈໍາຫຼື stack scribble ເຊັ່ນດຽວກັນ.

ຂຽນທັງຫມົດເຫຼົ່ານີ້ເປັນ
int ioctl(int fildes, int request, ...);
int __ioctl(int fildes, int request, intptr_t arg);
long sys_ioctl(unsigned int fildes, unsigned int request, intptr_t arg);
vfs_ioctl ຍາວ(ໄຟລ໌ໂຄງສ້າງ *filp, unsigned int cmd, intptr_t arg);
ເນັ້ນຫນັກວ່າຈໍານວນຈໍານວນແມ່ນພຽງແຕ່ຈໍານວນເຕັມທີ່ຈະເປັນຕົວແທນຂອງປະລິມານທີ່ເກືອບ
ສະເຫມີເປັນປະເພດຕົວຊີ້ທີ່ບໍ່ກ່ຽວຂ້ອງ.

ສະຫຼຸບ


ໃຊ້ libexplain, ຜູ້ໃຊ້ຂອງທ່ານຈະມັກມັນ.

COPYRIGHT


libexplain ເວີຊັ່ນ 1.4
ສະຫງວນລິຂະສິດ (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Peter Miller

ໃຊ້ description_lca2010 ອອນລາຍໂດຍໃຊ້ບໍລິການ onworks.net


ເຊີບເວີ ແລະສະຖານີເຮັດວຽກຟຣີ

ດາວໂຫຼດແອັບ Windows ແລະ Linux

  • 1
    SWIG
    SWIG
    SWIG ເປັນເຄື່ອງມືພັດທະນາຊອບແວ
    ທີ່ເຊື່ອມຕໍ່ບັນດາໂຄງການທີ່ຂຽນໃນ C ແລະ
    C ++ ທີ່ມີຄວາມຫລາກຫລາຍຂອງລະດັບສູງ
    ພາສາການຂຽນໂປຼແກຼມ. SWIG ຖືກນໍາໃຊ້ກັບ
    ແຕກຕ່າງກັນ ...
    ດາວໂຫລດ SWIG
  • 2
    WooCommerce Nextjs React Theme
    WooCommerce Nextjs React Theme
    React WooCommerce ຫົວຂໍ້, ສ້າງຂຶ້ນດ້ວຍ
    JS ຕໍ່ໄປ, Webpack, Babel, Node, ແລະ
    ດ່ວນ, ໃຊ້ GraphQL ແລະ Apollo
    ລູກ​ຄ້າ. ຮ້ານ WooCommerce ໃນ React(
    ປະ​ກອບ​ດ້ວຍ​: ຜະ​ລິດ​ຕະ​ພັນ ...
    ດາວໂຫລດ WooCommerce Nextjs React Theme
  • 3
    archlabs_repo
    archlabs_repo
    Package repo ສໍາລັບ ArchLabs ນີ້ແມ່ນ
    ຄໍາຮ້ອງສະຫມັກທີ່ຍັງສາມາດເອົາມາໄດ້
    ຈາກ
    https://sourceforge.net/projects/archlabs-repo/.
    ມັນໄດ້ຖືກຈັດຢູ່ໃນ OnWorks ໃນ ...
    ດາວໂຫລດ archlabs_repo
  • 4
    ໂຄງການ Zephyr
    ໂຄງການ Zephyr
    ໂຄງການ Zephyr ແມ່ນຄົນຮຸ່ນໃຫມ່
    ລະບົບປະຕິບັດການໃນເວລາຈິງ (RTOS) ນັ້ນ
    ຮອງຮັບຮາດແວຫຼາຍອັນ
    ສະຖາປັດຕະຍະກໍາ. ມັນແມ່ນອີງໃສ່ a
    ແກ່ນຮອຍຕີນນ້ອຍ...
    ດາວໂຫລດໂຄງການ Zephyr
  • 5
    SCons
    SCons
    SCons ເປັນ​ເຄື່ອງ​ມື​ການ​ກໍ່​ສ້າງ​ຊອບ​ແວ​
    ນັ້ນ​ແມ່ນ​ທາງ​ເລືອກ​ທີ່​ດີ​ເລີດ​ຂອງ​
    ຄລາສສິກ "ເຮັດ" ເຄື່ອງມືການກໍ່ສ້າງທີ່
    ພວກເຮົາທຸກຄົນຮູ້ຈັກແລະຮັກ. SCons ແມ່ນ
    ໄດ້​ປະ​ຕິ​ບັດ​ເປັນ ...
    ດາວໂຫລດ SCons
  • 6
    PSeInt
    PSeInt
    PSeInt ເປັນນາຍພາສາ pseudo-code ສໍາລັບ
    ນັກສຶກສາການຂຽນໂປລແກລມທີ່ເວົ້າພາສາສະເປນ.
    ຈຸດ​ປະ​ສົງ​ຕົ້ນ​ຕໍ​ຂອງ​ຕົນ​ແມ່ນ​ເພື່ອ​ເປັນ​ເຄື່ອງ​ມື​ສໍາ​ລັບ​ການ​
    ການຮຽນຮູ້ແລະຄວາມເຂົ້າໃຈພື້ນຖານ
    ແນວຄວາມຄິດ...
    ດາວໂຫລດ PSeInt
  • ເພີ່ມເຕີມ »

Linux ຄຳ ສັ່ງ

  • 1
    7z
    7z
    7z - ແຟ້ມຈັດເກັບໄຟລ໌ທີ່ມີສູງສຸດ
    ອັດ​ຕາ​ສ່ວນ​ການ​ບີບ​ອັດ ...
    ແລ່ນ 7z
  • 2
    7za
    7za
    7za - ແຟ້ມຈັດເກັບໄຟລ໌ທີ່ມີສູງສຸດ
    ອັດ​ຕາ​ສ່ວນ​ການ​ບີບ​ອັດ ...
    ແລ່ນ 7za
  • 3
    creepy
    creepy
    CREEPY - ຂໍ້ມູນສະຖານທີ່ຕັ້ງພູມສາດ
    ລາຍລະອຽດຂອງຕົວສັງລວມ: creepy ແມ່ນ
    ຄໍາຮ້ອງສະຫມັກທີ່ອະນຸຍາດໃຫ້ທ່ານເພື່ອເກັບກໍາ
    ຂໍ້​ມູນ​ກ່ຽວ​ກັບ​ການ​ຕັ້ງ​ພູມ​ສາດ​ກ່ຽວ​ກັບ​ການ​
    ຜູ້​ໃຊ້​ຈາກ ...
    ແລ່ນ creepy
  • 4
    cricket-compile
    cricket-compile
    cricket - ໂຄງ​ການ​ການ​ຄຸ້ມ​ຄອງ​ການ​
    ການເກັບກໍາແລະການສະແດງຊຸດເວລາ
    ຂໍ້ມູນ...
    ແລ່ນ cricket-compile
  • 5
    g-wrap-config
    g-wrap-config
    g-wrap-config - script ເພື່ອໃຫ້ໄດ້ຮັບ
    ຂໍ້ມູນກ່ຽວກັບສະບັບທີ່ຕິດຕັ້ງ
    ຂອງ G-Wrap ...
    ດໍາເນີນການ g-wrap-config
  • 6
    g.accessgrass
    g.accessgrass
    g.access - ຄວບຄຸມການເຂົ້າເຖິງ
    ແຜນ​ທີ່​ໃນ​ປະ​ຈຸ​ບັນ​ສໍາ​ລັບ​ຜູ້​ໃຊ້​ອື່ນໆ​ກ່ຽວ​ກັບ​ການ​
    ລະບົບ. ຖ້າບໍ່ມີທາງເລືອກໃຫ້, ພິມ
    ສະຖານະປັດຈຸບັນ. ຄໍາສໍາຄັນ: ທົ່ວໄປ, ແຜນທີ່
    ການ​ຄຸ້ມ​ຄອງ​, p ...
    ແລ່ນ g.accessgrass
  • ເພີ່ມເຕີມ »

Ad