انگلیسیفرانسویاسپانیایی

Ad


فاویکون OnWorks

توضیح_lca2010 - آنلاین در ابر

توضیح_lca2010 را در ارائه دهنده هاست رایگان OnWorks از طریق Ubuntu Online، Fedora Online، شبیه ساز آنلاین ویندوز یا شبیه ساز آنلاین MAC OS اجرا کنید.

این دستور توضیح_lca2010 است که می تواند در ارائه دهنده هاست رایگان OnWorks با استفاده از یکی از چندین ایستگاه کاری آنلاین رایگان ما مانند Ubuntu Online، Fedora Online، شبیه ساز آنلاین ویندوز یا شبیه ساز آنلاین MAC OS اجرا شود.

برنامه:

نام


توضیح_lca2010 - هیچ رسانه ای یافت نشد: زمانی که زمان آن است که تلاش برای خواندن را متوقف کنید استررور(3).
ذهن

انگیزش


ایده libexplain در اوایل دهه 1980 به ذهنم خطور کرد. هر زمان که یک سیستم تماس بگیرد
یک خطا را برمی‌گرداند، هسته دقیقاً می‌داند چه مشکلی رخ داده است... و آن را فشرده می‌کند
کمتر از 8 بیت ارنو. فضای کاربر به همان داده‌های هسته دسترسی دارد
باید برای فضای کاربر این امکان وجود داشته باشد که دقیقاً بفهمد چه اتفاقی برای ایجاد خطا رخ داده است
برگردید و از این برای نوشتن پیام های خطای خوب استفاده کنید.

آیا می تواند به همین سادگی باشد؟

خطا پیام as نکته بینی
پیام های خطای خوب اغلب آن دسته از وظایف «یک درصدی» هستند که در زمان برنامه حذف می شوند
فشار پروژه شما را تحت فشار قرار می دهد. با این حال، یک پیام خطای خوب می تواند باعث ایجاد یک پیام بزرگ شود،
بهبود نامتناسب با تجربه کاربر، زمانی که کاربر به سمت ترسناکی سرگردان می شود
قلمرو ناشناخته ای که معمولاً با آن مواجه نمی شود. این کار آسانی نیست.

نویسنده به عنوان یک برنامه نویس لارو، مشکل را با خطا (کاملا دقیق) ندید
پیام هایی مثل این:
استثناء شناور (هسته تخلیه شده)
تا زمانی که به تفسیر غیر برنامه نویس جایگزین اشاره شد. اما این نیست
تنها مشکل پیام های خطای یونیکس است. هر چند وقت یکبار پیام های خطایی مانند:
$ ./احمق
نمی توان فایل را باز کرد
$
در این مرحله دو گزینه برای یک توسعه دهنده وجود دارد:

1.
شما می توانید یک دیباگر را اجرا کنید، مانند gdb(1) ، یا

2.
شما می توانید استفاده کنید تسمه(1) یا تراس(1) به داخل نگاه کنید.

· به یاد داشته باشید که کاربران شما حتی ممکن است به این ابزارها دسترسی نداشته باشند، چه برسد به این توانایی
برای استفاده از آنها (از آن زمان خیلی وقت است یونیکس مبتدی به معنای «فقط نوشته است یک
درایور دستگاه")

در این مثال اما با استفاده از تسمه(1) آشکار می کند
$ تسمه -e ردیابی = باز ./احمق
open("some/file", O_RDONLY) = -1 ENOENT (هیچ فایل یا دایرکتوری وجود ندارد)
نمی توان فایل را باز کرد
$
این به طور قابل توجهی بیشتر از اطلاعاتی است که پیام خطا ارائه می دهد. به طور معمول،
کد منبع احمقانه شبیه این است
int fd = open("چیزی/چیزی"، O_RDONLY)؛
اگر (fd < 0)
{
fprintf(stderr، "نمی توان فایل را باز کرد\n");
خروج(1)؛
}
به کاربر گفته نشده است که فایل، و همچنین به کاربر اطلاع نمی دهد که خطا فایل بود
حتی آنجا؟ آیا مشکل مجوز وجود داشت؟ این به شما می گوید که سعی می کرد a را باز کند
فایل، اما احتمالاً تصادفی بوده است.

چوب سرنخ خود را بگیرید و با آن برنامه نویس لارو را بزنید. در موردش بهش بگو اشتباه(3).
دفعه بعد که از برنامه استفاده می کنید یک پیغام خطای متفاوت می بینید:
$ ./احمق
open: چنین فایل یا فهرستی وجود ندارد
$
پیشرفت کرد، اما نه آن چیزی که انتظار داشتیم. چگونه کاربر می تواند مشکل را در صورت پیام خطا برطرف کند
بهش نمیگه مشکل چی بوده؟ با نگاهی به منبع، می بینیم
int fd = open("چیزی/چیزی"، O_RDONLY)؛
اگر (fd < 0)
{
perror ("باز");
خروج(1)؛
}
زمان برای یک دویدن دیگر با چوب سرنخ است. این بار پیام خطا یک مرحله طول می کشد
به جلو و یک قدم به عقب:
$ ./احمق
چیزی/چیزی: این چنین فایل و یا مسیری وجود ندارد
$
اکنون ما فایلی را که می‌خواست باز کند می‌دانیم، اما دیگر از آن مطلع نیستیم باز کن(2)
که شکست خورد. در این مورد احتمالاً مهم نیست، اما می تواند برای آن مهم باشد
سایر تماس های سیستمی می توانست باشد خالق(2) در عوض، عملیاتی که دلالت بر آن دارد
مجوزهای مختلف لازم است.
const char *filename = "چیزی/چیزی";
int fd = open (نام فایل، O_RDONLY);
اگر (fd < 0)
{
خطا (نام فایل)؛
خروج(1)؛
}
کد مثال بالا متأسفانه برای برنامه نویسان غیر لارو نیز معمول است. زمان
به فراگیر پادوان خود در مورد استررور(3) تماس سیستمی.
$ ./احمق
باز کن چیزی/چیزی: این چنین فایل و یا مسیری وجود ندارد
$
این اطلاعاتی را که می توان به کاربر ارائه داد به حداکثر می رساند. کد به نظر می رسد
این:
const char *filename = "چیزی/چیزی";
int fd = open (نام فایل، O_RDONLY);
اگر (fd < 0)
{
fprintf(stderr، "باز کردن %s: %s\n"، نام فایل، strerror(errno));
خروج(1)؛
}
اکنون فراخوانی سیستم، نام فایل و رشته خطا را داریم. این شامل همه
اطلاعاتی که تسمه(1) چاپ شده است. این به همان اندازه خوب است.

یا آن؟

محدودیت ها of اشتباه و استررور
مشکلی که نویسنده در دهه 1980 دید، این بود که پیام خطا ناقص است.
آیا «هیچ فایل یا فهرستی وجود ندارد» به «برخی ازدایرکتوری یا بهچیز” فایل در
"برخی از" فهرست راهنما؟

نگاهی گذرا به صفحه مرد برای استررور(3) می گوید:
strerror - رشته بازگشتی که شماره خطا را توصیف می کند
خوب توجه کنید: این خطا را توصیف می کند عدد، نه خطا.

از سوی دیگر، هسته می داند چه خطایی بود نکته خاصی در آن وجود داشت
کد هسته، ناشی از یک شرایط خاص، جایی که کد هسته منشعب می شود و می گوید "نه".
آیا یک برنامه فضای کاربر می تواند شرایط خاص را دریابد و خطای بهتری بنویسد
پیام؟

با این حال، مشکل عمیق تر می شود. چه می شود اگر مشکل در طول دوره رخ دهد خواندن(2) سیستم
تماس بگیرید، به جای باز کن(2) تماس بگیرید؟ برای پیام خطای مرتبط با آن ساده است
باز کن(2) برای گنجاندن نام فایل، درست همانجا است. اما برای اینکه بتوان نام فایل را درج کرد
در خطای مرتبط با خواندن(2) تماس سیستم، شما باید همه نام فایل را منتقل کنید
پایین تر از پشته تماس، و همچنین توصیف کننده فایل.

و در اینجا بیتی است که رنده می کند: هسته از قبل می داند که فایل چه نام فایلی را دارد
توصیفگر با. چرا یک برنامه نویس باید همه داده های اضافی را ارسال کند
آیا برای بهبود پیام خطایی که ممکن است هرگز صادر نشود، پشته تماس پایین می آید؟ که در
واقعیت، بسیاری از برنامه نویسان زحمت نمی کشند، و پیام های خطا در نتیجه بدتر هستند
آن است.

اما این دهه 1980 بود، در یک PDP11، با منابع محدود و بدون کتابخانه مشترک. بازگشت
سپس، هیچ طعمی از یونیکس گنجانده نشده است / پروسه حتی به شکل ابتدایی، و lsof(1) برنامه
بیش از یک دهه فاصله داشت بنابراین این ایده به عنوان غیر عملی کنار گذاشته شد.

سطح ابدیت پشتیبــانی
تصور کنید که در سطح بی نهایت پشتیبانی هستید. شرح شغل شما می گوید که هرگز
همیشه باید با کاربران صحبت کرد پس چرا هنوز یک جریان دائمی از افراد خواهان وجود دارد
شما، استاد محلی یونیکس، می خواهید پیام خطای دیگری را رمزگشایی کنید؟

عجیب است، 25 سال بعد، با وجود یک سیستم مجوز ساده، با کامل اجرا شد
سازگاری، اکثر کاربران یونیکس هنوز هیچ ایده ای برای رمزگشایی "فایل یا دایرکتوری وجود ندارد" ندارند.
یا هر یک از پیام های خطای مرموز دیگری که هر روز می بینند. یا، حداقل، مرموز به
آنها.

آیا اگر پشتیبانی فنی سطح اول نیازی به رمزگشایی پیام های خطا نداشته باشد، خوب نیست؟
آیا خوب نیست که پیام های خطایی داشته باشیم که کاربران بتوانند بدون تماس آن را درک کنند
پشتیبانی فنی؟

این روزها / پروسه در لینوکس بیش از حد قادر به ارائه اطلاعات لازم برای رمزگشایی است
اکثریت قریب به اتفاق پیام های خطا، و کاربر را به علت نزدیکی آنها راهنمایی می کند
مسئله. در سیستم هایی با محدودیت / پروسه اجرا، lsof(1) دستور می تواند پر شود
بسیاری از شکاف ها

در سال 2008، جریان درخواست های ترجمه به دفعات برای نویسنده اتفاق افتاد. بود
وقت آن است که این ایده 25 ساله را دوباره بررسی کنیم و نتیجه آن را توضیح دهیم.

استفاده كردن L' کتابخانه


رابط کتابخانه سعی می کند تا جایی که ممکن است سازگار باشد. بیایید با یک شروع کنیم
مثال با استفاده از استررور(3):
if (تغییر نام (مسیر_قدیمی، مسیر_جدید) < 0)
{
fprintf(stderr، "تغییر نام %s %s: %s\n"، old_path، new_path،
strerror (errno));
خروج(1)؛
}
ایده پشت libexplain این است که a استررور(3) معادل برای هر تماس سیستمی،
به طور خاص برای آن تماس سیستمی تنظیم شده است، به طوری که می تواند خطای دقیق تری ارائه دهد
پیام، حاوی بسیاری از اطلاعاتی است که در عنوان "خطا" بخش می بینید
2 و 3 مرد صفحات، تکمیل شده با اطلاعات در مورد شرایط واقعی، استدلال واقعی
ارزش ها و محدودیت های سیستم

La ساده مورد
La استررور(3) جایگزینی:
if (تغییر نام (مسیر_قدیمی، مسیر_جدید) < 0)
{
fprintf(stderr، "%s\n"، توضیح_rename(old_path، new_path));
خروج(1)؛
}

La ارنو مورد
امکان عبور صریح نیز وجود دارد ارنو(3) ارزش، اگر ابتدا باید مقداری را انجام دهید
پردازشی که مزاحم می شود ارنومانند بازیابی خطا:
if (تغییر نام (مسیر_قدیمی، مسیر_جدید < 0))
{
int old_errno = errno;
...رمز که مزاحم می شود ارنو...
fprintf(stderr، "%s\n"، توضیح_errno_rename(old_errno،
مسیر_قدیمی، مسیر_جدید));
خروج(1)؛
}

La چند رشته ای موارد
برخی از برنامه‌ها چند رشته‌ای هستند و بنابراین نمی‌توانند محتوای داخلی libexplain را به اشتراک بگذارند.
بافر شما می توانید بافر خود را با استفاده از آن تامین کنید
اگر (لغو پیوند (نام مسیر))
{
پیام کاراکتر[3000];
توضیح_پیام_unlink(پیام، اندازه(پیام)، نام مسیر)؛
error_dialog(پیام)؛
بازگشت -1 ؛
}
و برای کامل شدن، هر دو ارنو(3) و ایمن با نخ:
ssize_t nbytes = read(fd, data, sizeof(data));
اگر (nbytes < 0)
{
پیام کاراکتر[3000];
int old_errno = errno;
...خطا بهبود...
description_message_errno_read(پیام، اندازه(پیام)
old_errno, fd, data, sizeof(data));
error_dialog(پیام)؛
بازگشت -1 ؛
}

اینها جایگزینی برای strerror_r(3)، در سیستم هایی که آن را دارند.

رابط قند
مجموعه ای از توابع اضافه شده به عنوان توابع راحتی، برای جذب برنامه نویسان به استفاده از
کتابخانه libexplain، مشخص شد که متداول ترین توابع استفاده شده نویسنده در Libexplain در
برنامه های خط فرمان:
int fd = توضیح_creat_or_die(نام فایل، 0666);
این تابع سعی می کند یک فایل جدید ایجاد کند. اگر نتواند، پیغام خطا را چاپ می کند و
با EXIT_FAILURE خارج می شود. اگر خطایی وجود نداشته باشد، توصیفگر فایل جدید را برمی گرداند.

یک تابع مرتبط:
int fd = توضیح_creat_on_error(نام فایل، 0666);
پیغام خطا را در صورت شکست چاپ می کند، اما نتیجه خطای اصلی را نیز برمی گرداند، و
ارنو(3) نیز بدون مزاحمت است.

معرفی la دیگر سیستم تماس
به طور کلی، هر فراخوانی سیستمی دارای فایل شامل خود است
#عبارتند ازنام.h>
که نمونه های اولیه تابع را برای شش تابع تعریف می کند:

· توضیح_نام,

· توضیح_errno_نام,

· توضیح_پیام_نام,

· توضیح_پیام_ارو_نام,

· توضیح_نام_یا_بمیر و

· توضیح_نام_در_خطا.

هر نمونه اولیه تابع دارای مستندات Doxygen و این مستندات است is نه خرد شده
زمانی که فایل های شامل نصب می شوند.

La صبر کنيد(2) فراخوانی سیستم (و دوستان) انواع دیگری دارند که شکست را نیز تفسیر می کنند
وضعیت خروجی باشد که EXIT_SUCCESS نیست. این مربوط به سیستم(3) و نزدیک(3) به عنوان
خوب.

پوشش شامل 221 تماس سیستمی و 547 درخواست ioctl است. سیستم های بسیار بیشتری وجود دارد
فراخوان هایی که هنوز اجرا نشده اند تماس های سیستمی که هرگز باز نمی گردند، مانند خروج(2)، حضور ندارند
در کتابخانه، و هرگز نخواهد بود. در exec خانواده تماس های سیستمی هستند پشتیبانی می شود، زیرا
هنگامی که خطایی وجود دارد برمی گردند.

گربه
این همان چیزی است که یک برنامه فرضی "گربه" می تواند شبیه باشد، با گزارش کامل خطا،
با استفاده از libexplain
#عبارتند از
#عبارتند از
#عبارتند از
یک شامل برای libexplain، به علاوه مظنونین معمولی وجود دارد. (اگر می خواهید کاهش دهید
بار پیش پردازنده، شما می توانید خاص استفاده کنیدنام.h> شامل.)
باطل استاتیک
فرآیند (FILE *fp)
{
برای (؛؛)
{
بافر char[4096];
size_t n = توضیح_fread_or_die(بافر، 1، sizeof(بافر)، fp);
اگر (!n)
زنگ تفريح؛
توضیح_fwrite_or_die(بافر، 1، n، stdout);
}
}
La روند تابع یک جریان فایل را در خروجی استاندارد کپی می کند. اگر خطایی رخ دهد
برای خواندن یا نوشتن، گزارش می شود (و نام مسیر در آن گنجانده می شود
خطا) و دستور با EXIT_FAILURE خارج می شود. ما حتی نگران ردیابی آن نیستیم
نام های مسیر، یا ارسال آنها به پشته تماس.
INT
اصلی (int argc، char **argv)
{
برای (؛؛)
{
int c = getopt(argc, argv, "o:");
اگر (c == EOF)
زنگ تفريح؛
سوئیچ (ج)
{
مورد "o":
توضیح_freopen_or_die(optarg، "w"، stdout);
زنگ تفريح؛
بخش جالب این کد این است که libexplain می تواند خطاها را گزارش کند شامل la نام خانوادگی حتی
اگر شما نکن همانطور که در اینجا انجام می شود، به صراحت stdout را دوباره باز کنید. ما حتی نگران نیستیم
ردیابی نام فایل
پیش فرض:
fprintf(stderr، "استفاده: %ss [ -o ] ...\n"
argv[0])؛
بازگشت EXIT_FAILURE؛
}
}
اگر (optind == argc)
فرآیند (stdin);
دیگر
{
در حالی که (optind < argc)
{
FILE *fp = توضیح_fopen_or_die(argv[optind]++، "r");
فرآیند (fp)؛
توضیح_fclose_or_die(fp);
}
}
خروجی استاندارد به طور ضمنی بسته می شود، اما برای گزارش خطا بسیار دیر است
صادر شده است، بنابراین ما این کار را اینجا انجام می دهیم، فقط در صورتی که I/O بافر هنوز چیزی ننوشته باشد، و
یک خطای ENOSPC یا چیزی مشابه وجود دارد.
توضیح_flush_or_die(stdout);
بازگشت EXIT_SUCCESS؛
}
همین. گزارش کامل خطا، کد پاک.

زنگ زده مقیاس of رابط خوبی
برای کسانی از شما که با آن آشنایی ندارید، «چگونه سوءاستفاده از این را سخت کنم؟» اثر Rusty Russel.
خواندن صفحه برای طراحان API ضروری است.
http://ozlabs.org/~rusty/index.cgi/tech/2008-03-30.html

10. این غیر ممکن به دریافت کنید اشتباه.

اهداف باید بلند و بلندپروازانه تعیین شوند تا مبادا به آنها برسید و فکر کنید که هستید
وقتی که نیستی تمام شد

کتابخانه libexplain نشانگرهای جعلی و بسیاری دیگر از پارامترهای فراخوانی سیستم جعلی را شناسایی می کند.
و به طور کلی سعی می کند حتی در سخت ترین شرایط از اشتباهات خودداری کند.

کتابخانه libexplain به گونه ای طراحی شده است که ایمن باشد. استفاده بیشتر در دنیای واقعی احتمالاً خواهد بود
مکان‌هایی را که می‌توان آن را بهبود بخشید، نشان دهد.

بزرگترین مشکل مربوط به نام های واقعی توابع است. چون C ندارد
name-space ها، کتابخانه libexplain همیشه از پیشوند توضیح_نام استفاده می کند. این است
روش سنتی ایجاد یک فضای نام شبه به منظور جلوگیری از تضاد نمادها.
با این حال، منجر به برخی نام‌های غیرطبیعی می‌شود.

9. La کامپایلر or ها نخواهد بود اجازه شما دریافت کنید it اشتباه.

یک اشتباه رایج استفاده از توضیح_open در جایی که توضیح_open_or_die در نظر گرفته شده است.
خوشبختانه، کامپایلر اغلب در این مرحله یک خطای نوع (به عنوان مثال نمی تواند اختصاص دهد
const char * rvalue به int lvalue).

8. La کامپایلر اراده هشدار دادن if شما دریافت کنید it اشتباه.

اگر توضیح_rename زمانی استفاده شود که توضیح_rename_or_die در نظر گرفته شده است، این می تواند باعث ایجاد موارد دیگر شود
چالش ها و مسائل. GCC دارای یک ویژگی کاربردی warn_unused_result و libexplain است
کتابخانه آن را به همه توضیحات پیوست می کند_نام هنگامی که شما یک اخطار ایجاد می کند، تابع را فرا می خواند
این اشتباه را بکن این را با gcc -خطا برای ارتقاء این به سطح 9 خوبی.

7. La واضح استفاده کنید is (شاید) la اصلاح یک.

نام توابع برای بیان معنای خود انتخاب شده اند، اما همیشه اینطور نیست
موفقیت آمیز. ضمن توضیح _نام_یا_بمیر و توضیح بده_نام_on_error نسبتاً توصیفی هستند،
رمزگشایی انواع ایمن رشته ای که کمتر مورد استفاده قرار می گیرند، سخت تر است. نمونه های اولیه تابع کمک می کند
کامپایلر به سمت درک، و نظرات Doxygen در فایل های هدر به کاربر کمک می کند
به سمت درک

6. La نام می گوید شما چگونه به استفاده کنید آن است.

خواندن توضیح بسیار مهم استنام_or_die به عنوان "توضیح (نام یا بمیر)».
استفاده از پیشوند منسجم توضیح_نام-فضای دارای عوارض جانبی ناخوشایندی است
بخش آشکارسازی نیز

ترتیب کلمات در نام ها نیز نشان دهنده ترتیب استدلال ها است. بحث و جدل
همیشه لیست می کند پایان با همان آرگومان هایی که به فراخوانی سیستم منتقل شد. تمام of آنها را. اگر
_errno_ در نام ظاهر می شود، آرگومان آن همیشه مقدم بر آرگومان های فراخوانی سیستم است. اگر
_message_ در نام ظاهر می شود، دو آرگومان آن همیشه اول هستند.

5. Do it راست or it اراده شکستن at زمان اجرا

کتابخانه libexplain نشانگرهای جعلی و بسیاری دیگر از پارامترهای فراخوانی سیستم جعلی را شناسایی می کند.
و به طور کلی سعی می کند حتی در سخت ترین شرایط از اشتباهات خودداری کند. باید
هرگز در زمان اجرا خراب نمی شود، اما استفاده بیشتر در دنیای واقعی بدون شک این را بهبود می بخشد.

برخی از پیام های خطا به جای کاربران نهایی، توسعه دهندگان و نگهبانان را هدف قرار می دهند
می تواند به حل اشکال کمک کند. نه آنقدر "وقفه در زمان اجرا" که "در زمان آموزنده بودن".
runtime” (پس از فراخوانی سیستم barfs).

4. دنبال کردن مشترک مجمع و شما دریافت کنید it درست.

از آنجایی که C فضای نامی ندارد، کتابخانه libexplain همیشه از یک توضیح_نام استفاده می کند
پیشوند این روش سنتی ایجاد یک فضای شبه نام به منظور اجتناب است
درگیری نمادها

آرگومان های انتهایی همه فراخوانی های libexplain با سیستم فراخوانی آنها یکسان است
در حال توصیف هستند. این به منظور ارائه یک کنوانسیون منسجم مشترک با
سیستم خود را صدا می کند.

3. خواندن la مستندات و شما دریافت کنید it درست.

هدف کتابخانه libexplain این است که مستندات کامل Doxygen را برای هر یک از آنها داشته باشد
تماس API عمومی (و همچنین داخلی).

MESSAGE مطالب و محتوا


کار بر روی libexplain کمی شبیه به نگاه کردن به قسمت زیرین ماشین شما وقتی روشن است
بالابر در مکانیک چیزهای زشتی در زیر وجود دارد، به علاوه گل و لای خام، و
کاربران به ندرت آن را می بینند. یک پیام خطای خوب باید آموزنده باشد، حتی برای کاربری که
به اندازه کافی خوش شانس بوده که مجبور نیست اغلب به قسمت زیرین نگاه کند و همچنین
آموزنده برای مکانیک گوش دادن به توضیحات کاربر از طریق تلفن. این هست
کار آسانی نیست

با بررسی مجدد اولین مثال خود، در صورتی که کد از libexplain استفاده کند، این را دوست دارد:
int fd = description_open_or_die("some/thing", O_RDONLY, 0);
با پیغام خطایی مانند این شکست خواهد خورد
open(pathname = "some/file", flags = O_RDONLY) ناموفق بود، چنین فایل یا فهرستی وجود ندارد
(2، ENOENT) زیرا هیچ دایرکتوری "some" در فهرست فعلی وجود ندارد
این به سه قسمت تقسیم می شود
تماس سیستمی ناموفق، خطای سیستم زیرا
توضیح

قبل از زیرا
ممکن است بخشی از پیام را قبل از "زیرا" به عنوان بیش از حد فنی تا غیر غیر فنی مشاهده کرد.
کاربران فنی، بیشتر در نتیجه چاپ دقیق سیستم خود را در
ابتدای پیام خطا و به نظر می رسد تسمه(1) خروجی، برای گیک جایزه
نقاط.
open(pathname = "some/file", flags = O_RDONLY) ناموفق بود، چنین فایل یا فهرستی وجود ندارد
(2، ENOENT)
این قسمت از پیام خطا برای توسعه دهنده هنگام نوشتن کد ضروری است.
و به همان اندازه برای نگهدارنده ای که باید گزارش های اشکال را بخواند و اشکالات موجود در آن را برطرف کند، مهم است
کد دقیقا می گوید چه چیزی شکست خورده است.

اگر این متن به کاربر ارائه نشود، کاربر نمی تواند آن را در یک کپی و جایگذاری کند
گزارش اشکال، و اگر در گزارش اشکال نباشد، نگهدارنده نمی‌تواند بداند واقعاً چه اتفاقی افتاده است
اشتباه.

اغلب کارکنان فنی استفاده خواهند کرد تسمه(1) یا تراس(1) برای به دست آوردن این اطلاعات دقیق، اما
این راه هنگام خواندن گزارش‌های اشکال باز نیست. سیستم گزارشگر اشکال بسیار دور است
دور، و، در حال حاضر، در یک وضعیت بسیار متفاوت است. بنابراین، این اطلاعات باید در
گزارش اشکال، به این معنی که باید در پیام خطا باشد.

نمایش فراخوانی سیستم همچنین زمینه را به بقیه پیام می دهد. در صورت نیاز
به وجود می آید، آرگومان فراخوانی سیستم متخلف ممکن است با نام در توضیح ذکر شود
بعد از "چون". علاوه بر این، تمام رشته ها به طور کامل نقل قول شده و از رشته های C فرار کرده اند، بنابراین
خطوط جدید جاسازی شده و کاراکترهای غیرچاپی باعث از بین رفتن ترمینال کاربر نمی شوند
سیم یونجه

La خطای سیستم چیزی است که از آن بیرون می آید استررور(2)، به علاوه نماد خطا. بی حوصله و
Sysadmin های متخصص می توانند در این مرحله مطالعه را متوقف کنند، اما تجربه نویسنده تا به امروز چنین است
که خواندن بیشتر پاداش دارد. (اگر مفید نیست، احتمالاً بخشی از آن است
libeexplain که می تواند بهبود یابد. البته از مشارکت کد استقبال می شود.)

پس از زیرا
این بخشی از پیام خطا است که کاربران غیر فنی را هدف قرار می دهد. فراتر به نظر می رسد
سیستم ساده آرگومان ها را صدا می کند و به دنبال چیزی خاص تر می گردد.
هیچ دایرکتوری "some" در فهرست فعلی وجود ندارد
این بخش تلاش می کند تا علت نزدیکی خطا را به زبان ساده توضیح دهد
اینجاست که بین المللی شدن ضروری است.

به طور کلی، سیاست این است که تا حد امکان اطلاعات را درج کند تا کاربر
نیازی به جستجوی آن نیست (و آن را از گزارش اشکال حذف نمی کند).

بین المللی کردن
بیشتر پیام های خطا در کتابخانه libexplain بین المللی شده اند. آنجا
هنوز محلی سازی نشده است، بنابراین اگر می خواهید توضیحات را به زبان مادری خود ارائه دهید،
لطفا مشارکت کنید

واجد شرایط "بیشترین"، در بالا، به این واقعیت مربوط می شود که اثبات مفهوم
اجرا شامل حمایت بین المللی سازی نمی شد. پایه کد در حال بودن است
به تدریج اصلاح می شود، معمولاً در نتیجه تغییر مجدد پیام ها به طوری که هر خطا
رشته پیام دقیقاً یک بار در کد ظاهر می شود.

تمهیداتی برای زبان‌هایی که نیاز به جمع‌آوری بخش‌هایی از آن دارند فراهم شده است
تماس سیستمی ناموفق، خطای سیستم زیرا توضیح
به ترتیب های مختلف برای دستور زبان صحیح در پیام های خطای محلی.

پس از مرگ
مواقعی وجود دارد که برنامه ای هنوز از libexplain استفاده نکرده است و شما نمی توانید از آن استفاده کنید تسمه(1)
یا یک ... وجود دارد توضیح دادن(1) دستور همراه با libexplain که می توان از آن استفاده کرد
اگر وضعیت سیستم اصلی تغییر زیادی نکرده باشد، پیام های خطا را رمزگشایی کنید.
$ توضیح دادن تغییر نام دهید فو /tmp/bar/baz -e ENOENT
تغییر نام (oldpath = "foo", newpath = "/tmp/bar/baz") ناموفق بود، چنین فایل یا فهرستی وجود ندارد
(2، ENOENT) زیرا هیچ دایرکتوری "bar" در مسیر جدید وجود ندارد "دایرکتوری / tmp" فهرست راهنما
$
توجه داشته باشید که چگونه ابهام مسیر با استفاده از نام آرگومان فراخوانی سیستم برطرف می شود. از
البته، شما باید خطا را بدانید و سیستم برای آن تماس می گیرد توضیح دادن(1) مفید بودن به عنوان یک
علاوه بر این، این یکی از راه‌هایی است که مجموعه تست خودکار libexplain برای تأیید آن استفاده می‌کند
libexplain کار می کند.

فلسفه
"همه چیز را به من بگو، از جمله چیزهایی که نمی دانستم دنبالش بگردم."

کتابخانه به گونه‌ای پیاده‌سازی می‌شود که وقتی به صورت ایستا پیوند داده می‌شود، فقط شما را کد می‌کند
در واقع استفاده لینک خواهد شد. این با داشتن یک تابع در هر فایل منبع به دست می آید،
هر زمان که امکان پذیر باشد

در صورت امکان ارائه اطلاعات بیشتر، libexplain این کار را انجام می دهد. هر چه کاربر کمتر باشد
باید برای خود ردیابی کنند، بهتر است. این به این معنی است که UID ها با
نام کاربری، GID ها با نام گروه، PID ها با فرآیند همراه هستند
نام، توصیفگرهای فایل و جریان ها با نام مسیر همراه هستند، و غیره.

هنگام حل مسیرها، اگر جزء مسیر وجود نداشته باشد، libexplain به دنبال مشابه خواهد بود
نام ها، به منظور پیشنهاد جایگزین برای اشتباهات تایپی.

کتابخانه libexplain سعی می کند تا حد امکان از پشته های کمتری استفاده کند و معمولاً هیچ. این هست
تا جایی که ممکن است از ایجاد اختلال در وضعیت فرآیند جلوگیری شود، اگرچه گاهی اوقات چنین است
اجتناب ناپذیر.

کتابخانه libexplain سعی می کند با اجتناب از متغیرهای سراسری، ایمن باشد.
تا حد امکان روی پشته قرار دهید. یک بافر پیام مشترک وجود دارد، و
توابعی که از آن استفاده می‌کنند به‌عنوان ایمن نیستند.

کتابخانه libexplain کنترل کننده سیگنال یک فرآیند را مختل نمی کند. این باعث می شود
تعیین اینکه آیا یک اشاره گر یک چالش را خطا می کند، اما غیرممکن نیست.

هنگامی که اطلاعات از طریق تماس سیستمی و همچنین از طریق a در دسترس است / پروسه
ورود، تماس سیستم ترجیح داده می شود. این برای جلوگیری از ایجاد اختلال در وضعیت فرآیند است.
همچنین مواقعی وجود دارد که هیچ توصیفگر فایلی در دسترس نیست.

کتابخانه libexplain با پشتیبانی از فایل های بزرگ کامپایل شده است. بزرگ/کوچک وجود ندارد
جنون جوانی. در جایی که این روی آرگومان در API تأثیر می‌گذارد، خطا صادر می‌شود
اگر فایل بزرگ لازم وجود نداشته باشد.

FIXME: برای اطمینان از اینکه سهمیه های سیستم فایل در کد مدیریت می شود، کار لازم است. این
برای برخی اعمال می شود getrlimit(2) مرزها، و همچنین.

مواردی وجود دارد که مسیرهای خویشاوندان بی اطلاع هستند. به عنوان مثال: شیاطین سیستم،
سرورها و فرآیندهای پس زمینه در این موارد از مسیرهای مطلق در خطا استفاده می شود
توضیحات.

PATH وضوح


نسخه کوتاه: ببینید path_resolution(7).

نسخه طولانی: اکثر کاربران هرگز چیزی نشنیده اند path_resolution(7) و بسیاری از کاربران پیشرفته
هرگز آن را نخوانده اند در اینجا یک نسخه مشروح است:

گام 1: آغاز of la حل روند
اگر نام مسیر با کاراکتر اسلش (“/”) شروع شود، دایرکتوری جستجوی شروع است
دایرکتوری ریشه فرآیند فراخوانی

اگر نام مسیر با کاراکتر اسلش («/») شروع نشود، جستجوی شروع
فهرست راهنمای فرآیند حل، دایرکتوری کاری فعلی فرآیند است.

گام 2: راه رفتن در امتداد la مسیر
فهرست جستجوی فعلی را روی فهرست جستجوی شروع تنظیم کنید. اکنون برای هر غیر
جزء نهایی نام مسیر، که در آن یک جزء یک رشته فرعی است که با اسلش ("/") مشخص شده است.
کاراکترها، این جزء در فهرست جستجوی فعلی جستجو می شود.

اگر فرآیند مجوز جستجو در فهرست جستجوی فعلی را نداشته باشد، یک EACCES
خطا برگردانده شده است ("مجوز رد شد").
open(pathname = "/home/archives/.ssh/private_key"، flags = O_RDONLY) ناموفق،
مجوز رد شد (13، EACCES) زیرا فرآیند مجوز جستجو ندارد
به نام مسیر "/home/archives/.ssh" دایرکتوری، فرآیند GID 1000 موثر است.
"pmiller" با مالک دایرکتوری 1001 "بایگانی" مطابقت ندارد بنابراین مالک
حالت مجوز "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) زیرا هیچ دایرکتوری "user" در نام مسیر "/" وجود ندارد
دایرکتوری، آیا به جای آن منظورتان دایرکتوری "usr" است؟

اگر کامپوننت پیدا شد، اما نه یک دایرکتوری است و نه یک پیوند نمادین، یک ENOTDIR
خطا برگردانده شده است ("نه دایرکتوری").
open(pathname = "/home/pmiller/.netrc/lca", flags = O_RDONLY) ناموفق بود، نه
دایرکتوری (20، ENOTDIR) زیرا فایل منظم ".netrc" در نام مسیر وجود دارد
دایرکتوری "/home/pmiller" به عنوان دایرکتوری استفاده می شود در حالی که نیست

اگر کامپوننت پیدا شد و یک دایرکتوری است، دایرکتوری جستجوی فعلی را روی آن تنظیم می کنیم
دایرکتوری، و به مؤلفه بعدی بروید.

اگر جزء پیدا شد و یک پیوند نمادین (symlink) باشد، ابتدا این نماد را حل می کنیم
پیوند (با فهرست جستجوی فعلی به عنوان فهرست جستجوی شروع). پس از خطا، که
خطا برگردانده می شود. اگر نتیجه یک دایرکتوری نباشد، یک خطای ENOTDIR برگردانده می شود.
unlink (pathname = "/tmp/dangling/rubbish") ناموفق بود، چنین فایل یا فهرستی وجود ندارد (2،
ENOENT) زیرا پیوند نمادین "آویزان" در نام مسیر "دایرکتوری / tmp" فهرست راهنما
اشاره به "هیچ جا" است که وجود ندارد
اگر وضوح سیملینک موفقیت آمیز باشد و دایرکتوری را برگرداند، جریان را تنظیم می کنیم
به آن دایرکتوری مراجعه کنید و به مؤلفه بعدی بروید. توجه داشته باشید که
فرآیند حل در اینجا شامل بازگشت است. به منظور محافظت از هسته در برابر پشته
سرریز، و همچنین برای محافظت در برابر انکار سرویس، محدودیت هایی در حداکثر وجود دارد
عمق بازگشت، و بر روی حداکثر تعداد پیوندهای نمادین دنبال شده است. یک خطای ELOOP است
هنگامی که از حداکثر فراتر رفت، برگردانده می شود ("سطوح بسیار زیاد پیوندهای نمادین").
open(pathname = "/tmp/dangling", flags = O_RDONLY) ناموفق بود، سطوح بیش از حد
پیوندهای نمادین (40، ELOOP) زیرا یک حلقه پیوند نمادین در آن مواجه شد
نام مسیر، با "/tmp/dangling" شروع می شود
همچنین ممکن است در صورت وجود پیوندهای نمادین زیاد، خطای ELOOP یا EMLINK دریافت کنید، اما خیر
حلقه شناسایی شد
open(pathname = "/tmp/rabbit-hole"، flags = O_RDONLY) ناموفق بود، سطوح بیش از حد
پیوندهای نمادین (40، ELOOP) زیرا پیوندهای نمادین بیش از حد در آن مواجه شد
نام مسیر (8)
توجه داشته باشید که محدودیت واقعی چگونه چاپ می شود.

گام 3: پیدا کردن la نهایی ورود
جستجوی مولفه نهایی نام مسیر دقیقاً مانند سایر اجزا انجام می شود
اجزاء، همانطور که در مرحله قبل توضیح داده شد، با دو تفاوت:

(i) مؤلفه نهایی لازم نیست یک دایرکتوری باشد (حداقل تا آنجا که وضوح مسیر).
فرآیند مربوط می شود. ممکن است به دلیل این امر باید یک دایرکتوری یا غیر دایرکتوری باشد
الزامات فراخوان سیستم خاص).

(II)
اگر جزء نهایی پیدا نشود، لزوماً خطا نیست. شاید ما فقط هستیم
ایجاد آن جزئیات در مورد درمان ورودی نهایی در شرح داده شده است
صفحات دستی تماس های سیستمی خاص

(iii)
همچنین ممکن است مولفه آخر اگر لینک نمادین باشد مشکل داشته باشد
و نباید دنبال شود. به عنوان مثال، با استفاده از باز کن(2) پرچم O_NOFOLLOW:
open (نام مسیر = "a‐symlink"، پرچم‌ها = O_RDONLY | O_NOFOLLOW) ناموفق بود، سطوح بسیار زیادی از
پیوندهای نمادین (ELOOP) زیرا O_NOFOLLOW مشخص شده بود اما نام مسیر به a اشاره دارد
لینک نمادین

(iv)
معمولاً کاربران هنگام تایپ نام مسیرها اشتباه می کنند. کتابخانه libexplain
زمانی که ENOENT برگردانده می شود، سعی می کند پیشنهاداتی ارائه دهد، به عنوان مثال:
open(pathname = "/usr/include/filecontrl.h", flags = O_RDONLY) ناموفق بود، چنین فایلی وجود ندارد یا
دایرکتوری (2، ENOENT) زیرا هیچ فایل معمولی "filecontrl.h" در نام مسیر وجود ندارد
"/ usr / شاملدایرکتوری، آیا منظورتان فایل معمولی "fcntl.h" بود؟

(v) همچنین ممکن است لازم باشد جزء نهایی چیزی غیر از الف باشد
فایل معمولی:
پیوند خواندن (نام مسیر = "فقط یک فایل"، داده = 0x7F930A50، اندازه_داده = 4097) ناموفق،
آرگومان نامعتبر (22، EINVAL) زیرا نام مسیر یک فایل معمولی است، نه یک پیوند نمادین

(vi)
FIXME: مدیریت بیت "t".

محدودیت
تعدادی محدودیت در مورد نام مسیر و نام فایل وجود دارد.

محدودیت طول نام مسیر
حداکثر طول برای نام مسیرها وجود دارد. اگر نام مسیر (یا مقداری واسطه
نام مسیری که هنگام حل پیوندهای نمادین به دست می آید) خیلی طولانی است، یک ENAMETOOLONG
خطا برگردانده شده است ("نام فایل خیلی طولانی است"). توجه داشته باشید که محدودیت سیستم چگونه گنجانده شده است
در پیام خطا
open(pathname = "بسیار طولانی"، flags = O_RDONLY) ناموفق بود، نام فایل خیلی طولانی است (36،
ENAMETOOLONG) زیرا نام مسیر از حداکثر طول مسیر سیستم بیشتر است (4096)

محدودیت طول نام فایل
برخی از انواع یونیکس محدودیتی در تعداد بایت ها در هر جزء مسیر دارند.
برخی از آنها بی سر و صدا با این موضوع برخورد می کنند و برخی ENAMETOOLONG را ارائه می دهند. توضیح آزاد
استفاده های کتابخانه ای pathconf(3) _PC_NO_TRUNC برای تشخیص کدام. اگر این خطا رخ دهد،
کتابخانه libexplain محدودیت را در پیام خطا بیان می کند
به دست آمده از pathconf(3) _PC_NAME_MAX. توجه داشته باشید که محدودیت سیستم چگونه گنجانده شده است
در پیام خطا
open(pathname = "system7/only-had-14-characters"، flags = O_RDONLY) شکست خورد، فایل
نام خیلی طولانی است (36، ENAMETOOLONG) زیرا جزء "only-had-14-characters" است
بیشتر از حد مجاز سیستم (14)

نام مسیر خالی
در یونیکس اصلی، نام مسیر خالی به دایرکتوری فعلی اشاره دارد.
امروزه POSIX حکم می‌کند که یک مسیر خالی نباید با موفقیت حل شود.
open(pathname = ""، flags = O_RDONLY) ناموفق بود، چنین فایل یا دایرکتوری وجود ندارد (2،
ENOENT) زیرا POSIX حکم می‌کند که یک مسیر خالی نباید حل شود
موفقیت

ویرایش
بیت های مجوز یک فایل از سه گروه سه بیتی تشکیل شده است. گروه اول از
سه زمانی استفاده می شود که شناسه کاربر موثر فرآیند فراخوانی با شناسه مالک آن برابر باشد
فایل. گروه دوم سه تایی زمانی استفاده می شود که شناسه گروه فایل برابر باشد
شناسه گروه موثر فرآیند فراخوانی، یا یکی از شناسه های گروه تکمیلی است
فرآیند فراخوانی هنگامی که هیچ کدام برقرار نیست، از گروه سوم استفاده می شود.
open(pathname = "/ etc / passwd"، flags = O_WRONLY) ناموفق بود، مجوز رد شد (13،
EACCES) زیرا پروسه مجوز نوشتن برای "passwd" معمولی ندارد
فایل در نام مسیر "/و غیرهدایرکتوری، فرآیند موثر UID 1000 "pmiller"
با مالک فایل معمولی 0 "root" مطابقت ندارد، بنابراین حالت مجوز مالک "rw-"
نادیده گرفته می شود، حالت مجوز دیگران "r--" است، و این فرآیند دارای امتیاز نیست
(قابلیت DAC_OVERRIDE را ندارد)
فضای قابل توجهی به این توضیح داده شده است، زیرا اکثر کاربران این را نمی دانند
این است که چگونه سیستم مجوز کار می کند. به ویژه: مالک، گروه و غیره
مجوزها انحصاری هستند، آنها با هم "OR" نیستند.

عجیب و جالب هست SYSTEM تماس می گیرد


فرآیند نوشتن یک کنترل کننده خطای خاص برای هر فراخوانی سیستم اغلب آشکار می شود
ویژگی های جالب و شرایط مرزی، یا مبهم ارنو(3) مقادیر

انومدیوم، نه متوسط یافت
عمل کپی کردن یک سی دی منبع عنوان این مقاله بود.
$ dd if=/dev/cdrom of=fubar.iso
dd: باز کردن "/dev/cdrom": هیچ رسانه ای یافت نشد
$
نویسنده تعجب کرد که چرا کامپیوترش به او می گوید چیزی به نام روانی وجود ندارد
متوسط. جدا از این واقعیت که تعداد زیادی از انگلیسی زبانان بومی نیستند
حتی آگاه باشید که "رسانه" جمع است، چه رسد به اینکه "رسانه" مفرد آن، رشته است.
توسط استررور(3) برای ENOMEDIUM آنقدر مختصر است که تقریباً کاملاً عاری از آن است
محتوا.

چه زمانی باز کن(2) ENOMEDIUM را برمی گرداند، خوب است اگر کتابخانه libexplain بتواند a را گسترش دهد
کمی در این مورد، بر اساس نوع درایو آن. مثلا:
... چون دیسکی در فلاپی درایو وجود ندارد
... زیرا هیچ دیسکی در درایو CD-ROM وجود ندارد
... چون هیچ نواری در درایو نوار وجود ندارد
... زیرا در کارت خوان هیچ حافظه ای وجود ندارد

و پس از آن به تصویب رسید...
open(pathname = "/dev/cdrom"، flags = O_RDONLY) ناموفق بود، هیچ رسانه ای یافت نشد (123،
ENOMEDIUM) زیرا ظاهراً دیسکی در درایو CD-ROM وجود ندارد
ترفندی که نویسنده قبلاً از آن بی اطلاع بود، باز کردن دستگاه با استفاده از آن بود
پرچم O_NONBLOCK، که به شما امکان می دهد یک درایو را بدون هیچ رسانه ای در آن باز کنید. پس تو
مشکل دستگاه خاص ioctls(2) درخواست می کند تا زمانی که بفهمید چه هک است. (نه
مطمئن باشید که آیا این POSIX است، اما به نظر می رسد که در BSD و Solaris نیز به همین شکل عمل می کند
la وودیم(1) منابع.)

همچنین به کاربردهای متفاوت "دیسک" و "دیسک" در زمینه توجه کنید. استاندارد CD ایجاد شد
در فرانسه، اما هر چیز دیگری یک "k" دارد.

EFAULT، بد نشانی
هر فراخوانی سیستمی که آرگومان اشاره گر را بگیرد می تواند EFAULT را برگرداند. کتابخانه libexplain
می تواند تشخیص دهد که کدام آرگومان مقصر است و این کار را بدون ایجاد اختلال در روند انجام می دهد
مدیریت سیگنال (یا نخ).

در صورت موجود بودن، کوچک(2) از فراخوانی سیستم برای پرسیدن اینکه آیا منطقه حافظه معتبر است یا خیر استفاده می شود.
می تواند سه نتیجه را به دست آورد: نقشه برداری شده اما نه در حافظه فیزیکی، نقشه برداری شده و در فیزیکی
حافظه، و نقشه برداری نشده است. هنگام آزمایش اعتبار یک اشاره گر، دو مورد اول "بله" هستند.
و آخرین مورد "نه" است.

بررسی رشته های C دشوارتر است، زیرا به جای نشانگر و اندازه، ما فقط
یک اشاره گر داشته باشید برای تعیین اندازه باید NUL را پیدا کنیم، و این می تواند
segfault، catch-22.

برای حل این مشکل، کتابخانه libexplain از lstat(2) فراخوانی سیستم (با یک مشخصه
آرگومان دوم خوب) برای تست رشته های C برای اعتبار. بازگشت شکست && errno == EFAULT
"نه" است، و هر چیز دیگری "بله" است. البته این رشته ها را به PATH_MAX محدود می کند
کاراکترها، اما معمولاً برای کتابخانه libexplain مشکلی ایجاد نمی کند، زیرا اینطور است
تقریباً همیشه طولانی ترین رشته هایی است که به آن اهمیت می دهد.

EMFILE، هم بسیاری باز کن فایل ها
این خطا زمانی رخ می دهد که یک فرآیند از قبل دارای حداکثر تعداد توصیف کننده فایل باز باشد.
اگر قرار است محدودیت واقعی چاپ شود، و کتابخانه libexplain تلاش کند، نمی‌توانید باز کنید
یک فایل در / پروسه برای خواندن چیست.
open_max = sysconf(_SC_OPEN_MAX);
این یکی خیلی سخت نیست، وجود دارد sysconf(3) راه به دست آوردن حد.

ENFILE، هم بسیاری باز کن فایل ها in سیستم
این خطا زمانی رخ می دهد که محدودیت سیستم در تعداد کل فایل های باز شده باشد
رسیده است. در این مورد هیچ دستی وجود ندارد sysconf(3) راه به دست آوردن حد.

با حفاری عمیق تر، ممکن است متوجه شوید که در لینوکس یک وجود دارد / پروسه ورودی که می توانستیم برای آن بخوانیم
این مقدار را بدست آورید Catch-22: ما فاقد توصیف کننده فایل هستیم، بنابراین نمی توانیم فایلی را به آن باز کنیم
حد را بخوانید

در لینوکس یک فراخوانی سیستمی برای به دست آوردن آن وجود دارد، اما عملکرد بسته بندی [e]glibc ندارد، بنابراین
شما باید همه چیز را با دقت انجام دهید:
طولانی
توضیح_مکس فایل (باطل)
{
#ifdef __linux__
struct __sysctl_args args;
int32_t maxfile;
size_t maxfile_size = اندازه(مکس فایل)؛
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;
if (sycall(SYS__sysctl، &args) >= 0)
بازگشت حداکثر فایل؛
# اندیف
بازگشت -1 ؛
}
این اجازه می دهد تا در صورت وجود محدودیت در پیام خطا گنجانده شود.

EINVAL "بی اعتبار بحث و جدل" vs ENOSYS "عملکرد نه اجرا شد”
اقدامات پشتیبانی نشده (مانند Symlink(2) در یک سیستم فایل FAT) گزارش نشده است
به طور مداوم از یک فراخوانی به سیستم دیگر. ممکن است EINVAL یا
ENOSYS بازگشت.

در نتیجه، به خصوص باید به این موارد خطا توجه شود تا به درستی انجام شود
همانطور که EINVAL همچنین می تواند به مشکلات یک یا چند آرگومان فراخوانی سیستم اشاره کند.

توجه داشته باشید که ارنو(3) is نه همیشه تنظیم
مواقعی وجود دارد که لازم است منابع [e]glibc را برای تعیین چگونگی و مطالعه بخوانید
هنگامی که خطاها برای برخی از تماس های سیستمی برگردانده می شوند.

feof(3) فایل(3)
اغلب فرض می شود که این توابع نمی توانند خطا را برگردانند. این تنها در صورتی صادق است که
la جریان استدلال معتبر است، با این حال آنها قادر به تشخیص نامعتبر هستند
اشاره گر

fpathconf(3) pathconf(3)
مقدار بازگشتی از fpathconf(2) و pathconf(2) به طور قانونی می تواند -1 باشد، پس همینطور است
لازم است ببینیم آیا ارنو(3) به صراحت تنظیم شده است.

ioctls(2)
مقدار بازگشتی از ioctls(2) می تواند به طور قانونی -1 باشد، بنابراین لازم است ببینیم که آیا
ارنو(3) به صراحت تنظیم شده است.

readdir(3)
مقدار بازگشتی از readdir(3) هم برای خطاها و هم برای پایان فایل NULL است. این است
لازم است ببینیم آیا ارنو(3) به صراحت تنظیم شده است.

setbuf(3) تنظیم بافر(3) setlinebuf(3) setvbuf(3)
همه این توابع به جز آخرین توابع، void برمی گردند. و setvbuf(3) فقط به عنوان مستند است
برگرداندن "غیر صفر" در صورت خطا. باید دید که آیا ارنو(3) به صراحت بوده است
تنظیم شده است.

strtod(3) strtol(3) strtold(3) strtoll(3) strtoul(3) strtoull(3)
این توابع در صورت خطا 0 را برمی‌گردانند، اما این یک مقدار بازگشتی قانونی نیز هست. این است
لازم است ببینیم آیا ارنو(3) به صراحت تنظیم شده است.

ungetc(3)
در حالی که تنها یک کاراکتر از نسخه پشتیبان توسط استاندارد ANSI C الزامی شده است
معلوم است که [e]glibc بیشتر اجازه می دهد... اما این بدان معناست که می تواند با ENOMEM شکست بخورد. می تواند
همچنین با EBADF اگر fp ساختگی است از همه سخت تر، اگر خطای EOF را رد کنید
بازگشت رخ می دهد، اما errno تنظیم نشده است.

کتابخانه libexplain همه این خطاها را به درستی تشخیص می دهد، حتی در مواردی که
مقادیر خطا، اگر اصلاً وجود داشته باشد، به خوبی مستند نشده اند.

ENOSPC، نه فضا ترک کرد on دستگاه
هنگامی که این خطا به یک فایل در یک سیستم فایل اشاره می کند، کتابخانه libexplain mount را چاپ می کند.
نقطه فایل سیستم با مشکل این می تواند منبع خطا را زیاد کند
واضح تر
نوشتن (fildes = 1 "مثال"، داده = 0xbfff2340، data_size = 5) ناموفق بود، فضایی باقی نمانده است
در دستگاه (28، ENOSPC) زیرا سیستم فایل حاوی فایل‌ها ("/ صفحه اصلی") ندارد
فضای بیشتر برای داده ها
همانطور که پشتیبانی ویژه دستگاه اضافه می شود، انتظار می رود پیام های خطا شامل دستگاه شود
نام و اندازه واقعی دستگاه

EROFS، فقط خواندنی پرونده سیستم
هنگامی که این خطا به یک فایل در یک سیستم فایل اشاره می کند، کتابخانه libexplain mount را چاپ می کند.
نقطه فایل سیستم با مشکل این می تواند منبع خطا را زیاد کند
واضح تر

همانطور که پشتیبانی ویژه دستگاه اضافه می شود، انتظار می رود پیام های خطا شامل دستگاه شود
نام و نوع
open(pathname = "/dev/fd0", O_RDWR, 0666) ناموفق بود، سیستم فایل فقط خواندنی (30، EROFS)
زیرا فلاپی دیسک دارای مجموعه تب حفاظت از نوشتن است

... چون CD-ROM قابل نوشتن نیست
... چون کارت حافظه دارای برگه حفاظت از نوشتن است
چون نوار مغناطیسی ½ اینچی حلقه نوشتن ندارد

تغییر نام دهید
La تغییر نام دهید(2) فراخوانی سیستم برای تغییر مکان یا نام یک فایل و انتقال آن استفاده می شود
در صورت نیاز بین دایرکتوری ها اگر نام مسیر مقصد از قبل وجود داشته باشد، خواهد بود
به صورت اتمی جایگزین می شود، به طوری که هیچ نقطه ای وجود ندارد که در آن فرآیند دیگری تلاش کند
با دسترسی به آن، گم شدن آن را پیدا خواهید کرد.

با این حال محدودیت‌هایی وجود دارد: شما فقط می‌توانید نام یک فهرست را در بالای فهرست دیگر تغییر دهید
اگر دایرکتوری مقصد خالی نباشد.
تغییر نام (oldpath = "foo"، newpath = "bar") ناموفق، دایرکتوری خالی نیست (39،
ENOTEMPTY) زیرا newpath یک دایرکتوری خالی نیست. یعنی حاوی مدخل هایی است
غیر از "." و ".."
همچنین نمی توانید نام یک فهرست را در بالای یک غیر دایرکتوری تغییر دهید.
تغییر نام (oldpath = "foo"، newpath = "bar") ناموفق، نه یک فهرست (20، ENOTDIR)
زیرا oldpath یک دایرکتوری است، اما newpath یک فایل معمولی است، نه یک دایرکتوری
برعکس آن نیز مجاز نیست
تغییر نام (oldpath = "foo"، newpath = "bar") ناموفق، یک دایرکتوری است (21، EISDIR)
زیرا newpath یک دایرکتوری است، اما oldpath یک فایل معمولی است، نه یک دایرکتوری

این، البته، کار کتابخانه libexplain را پیچیده تر می کند، زیرا
لغو ارتباط(2) یا rm است(2) فراخوانی سیستم به طور ضمنی توسط تغییر نام دهید(2) و به همین ترتیب همه
لغو ارتباط(2) یا rm است(2) خطاها نیز باید شناسایی و رسیدگی شوند.

dup2
La dup2(2) فراخوانی سیستم برای ایجاد یک توصیفگر فایل دوم که به آن ارجاع می دهد استفاده می شود
همان شیء توصیف کننده فایل اول. به طور معمول از این برای پیاده سازی ورودی پوسته استفاده می شود
و تغییر مسیر خروجی

چیز سرگرم کننده این است که، به همان اندازه تغییر نام دهید(2) می تواند به صورت اتمی یک فایل را در بالای یک تغییر نام دهد
فایل موجود و حذف فایل قدیمی، dup2(2) می تواند این کار را روی یک فایل از قبل باز شده انجام دهد
توصیف کننده

یک بار دیگر، این کار کتابخانه libexplain را پیچیده تر می کند، زیرا نزدیک(2)
فراخوانی سیستم به طور ضمنی توسط dup2(2)، و به همین ترتیب همه نزدیکخطاهای (2) باید باشد
شناسایی و رسیدگی می شود.

ماجراهای IN IOCTL پشتیبانی


La ioctls(2) تماس سیستم راهی برای برقراری ارتباط با نویسندگان درایور دستگاه فراهم می کند
فضای کاربری که با API هسته موجود مطابقت ندارد. دیدن ioctl_list(2).

رمز گشایی درخواست تعداد
از نگاهی گذرا به ioctls(2) رابط، به نظر می رسد بزرگ اما محدود وجود دارد
تعداد ممکن ioctls(2) درخواست ها هر کدام متفاوت است ioctls(2) درخواست به طور موثر است
یک تماس سیستمی دیگر، اما بدون هیچ گونه ایمنی نوع - کامپایلر نمی تواند کمک کند
برنامه نویس اینها را درست می فهمد. احتمالاً این انگیزه پشت سر بوده است tcflush(3) و
دوستان.

تصور اولیه این است که شما می توانید رمزگشایی کنید ioctls(2) درخواست با استفاده از یک سوئیچ بزرگ
بیانیه. به نظر می رسد که این غیرممکن است زیرا شخص خیلی سریع متوجه می شود که چنین است
گنجاندن تمام هدرهای ضروری سیستم که انواع مختلف را تعریف می کنند غیرممکن است ioctls(2)
درخواست ها، زیرا آنها برای بازی خوب با یکدیگر مشکل دارند.

یک نگاه عمیق تر نشان می دهد که طیفی از شماره های درخواست "خصوصی" و دستگاه وجود دارد
نویسندگان درایور تشویق می شوند از آنها استفاده کنند. این بدان معنی است که امکان بسیار بزرگتری وجود دارد
مجموعه ای از درخواست ها، با شماره درخواست مبهم، که بلافاصله آشکار می شود. همچنین،
ابهامات تاریخی نیز وجود دارد.

ما قبلاً می‌دانستیم که سوئیچ غیرعملی است، اما اکنون می‌دانیم که باید آن را انتخاب کنیم
نام و توضیح درخواست مناسب ما باید نه تنها شماره درخواست را در نظر بگیریم بلکه
همچنین توصیفگر فایل

اجرای ioctls(2) پشتیبانی در کتابخانه libexplain داشتن جدولی از
اشاره گر به ioctls(2) توصیف کننده های درخواست. هر یک از این توصیفگرها شامل یک گزینه اختیاری است
اشاره گر به یک تابع ابهام‌زدایی

هر درخواست در واقع در یک فایل منبع جداگانه پیاده سازی می شود، به طوری که لازم است
شامل فایل ها از تعهد بازی زیبا با دیگران رها می شوند.

نمایندگی
فلسفه پشت کتابخانه libexplain ارائه اطلاعات به همان اندازه است
ممکن است، از جمله نمایش دقیق تماس سیستم. در شرایطی که
ioctls(2) این به معنای چاپ شماره درخواست صحیح (با نام) و همچنین یک (یا) صحیح است
حداقل مفید) نمایش آرگومان سوم.

La ioctls(2) نمونه اولیه به صورت زیر است:
int ioctl(int fildes, int request, ...);
که باید آلارم های ایمنی نوع شما خاموش شود. داخلی به [e]glibc، این تبدیل شده است
به اشکال مختلف:
int __ioctl(int fildes, int request, long arg);
int __ioctl(int filedes, int request, void *arg);
و رابط syscall هسته لینوکس انتظار دارد
asmlinkage long sys_ioctl(int filedes بدون علامت، درخواست int بدون علامت، طولانی بدون امضا
arg)؛
تغییرپذیری شدید آرگومان سوم زمانی که کتابخانه libexplain یک چالش است
سعی می کند نمایشی از آرگومان سوم را چاپ کند. با این حال، یک بار شماره درخواست
ابهام‌زدایی شده است، هر ورودی در جدول ioctl کتابخانه libexplain دارای یک
تابع print_data سفارشی (OO به صورت دستی انجام می شود).

توضیحات
مشکلات کمتری در تعیین توضیح مورد استفاده وجود دارد. یک بار شماره درخواست
ابهام‌زدایی شده است، هر ورودی در جدول ioctl کتابخانه libexplain یک سفارشی دارد
تابع print_explanation (دوباره، OO به صورت دستی انجام می شود).

برخلاف تماس‌های سیستمی بخش 2 و بخش 3، بیشتر ioctls(2) درخواست ها هیچ خطایی ندارند
ثبت شده. این بدان معناست که برای ارائه توضیحات خوب خطا، خواندن کرنل ضروری است
منابع برای کشف

· چی ارنو(3) مقادیر ممکن است برگردانده شوند، و

· علت هر خطا.

به دلیل ماهیت OO ارسال فراخوانی تابع در هسته، باید مطالعه کنید
تمام منابع اجرا کننده آن ioctls(2) درخواست، نه فقط اجرای عمومی. آی تی
انتظار می رود که هسته های مختلف دارای اعداد خطای متفاوت و به طور ماهرانه باشند
علل مختلف خطا

EINVAL vs ENOTTY
وضعیت از این هم بدتر است ioctls(2) درخواست ها نسبت به تماس های سیستمی، با EINVAL و
ENOTTY هر دو برای نشان دادن این مورد استفاده می شوند ioctls(2) درخواست در آن نامناسب است
زمینه، و گاهی اوقات ENOSYS، ENOTSUP و EOPNOTSUPP (برای استفاده برای سوکت ها) به عنوان
خوب. نظراتی در منابع هسته لینوکس وجود دارد که به نظر می رسد نشان دهنده یک پیشرفت است
پاکسازی در حال انجام است برای هرج و مرج بیشتر، BSD ENOIOCTL را به سردرگمی اضافه می کند.

در نتیجه، به خصوص باید به این موارد خطا توجه شود تا به درستی انجام شود
همانطور که EINVAL همچنین می تواند به مشکلات یک یا چند آرگومان فراخوانی سیستم اشاره کند.

intptr_t
استاندارد C99 یک نوع عدد صحیح را تعریف می کند که تضمین شده است که می تواند هر اشاره گر را نگه دارد
بدون از دست دادن نمایندگی

تابع فوق نمونه اولیه syscall بهتر است نوشته شود
long sys_ioctl(int filedes بدون علامت، درخواست int بدون علامت، intptr_t arg);
مشکل ناهماهنگی شناختی ناشی از دستگاه خاص یا سیستم فایل خاص است
ioctls(2) پیاده سازی ها مانند:
long vfs_ioctl(فایل ساختار *filp، int cmd بدون علامت، arg طولانی بدون علامت);
اکثریت ioctls(2) درخواست ها در واقع یک آرگومان سوم int *arg دارند. اما داشتنش
طولانی اعلام شده منجر به کدی می شود که این را طولانی *arg می کند. این در 32 بیت بی ضرر است
(sizeof(long) == sizeof(int)) اما در 64 بیت بد است (sizeof(long)!= sizeof(int)).
بسته به نیاز، شما ارزشی را که انتظار دارید، اما خودتان را دریافت می‌کنید یا نمی‌گیرید همیشه دریافت کنید
یک خط خطی حافظه یا خط خطی پشته ای نیز.

نوشتن همه اینها به عنوان
int ioctl(int fildes, int request, ...);
int __ioctl(int fildes، int request، intptr_t arg);
long sys_ioctl(int filedes بدون علامت، درخواست int بدون علامت، intptr_t arg);
طولانی vfs_ioctl (فایل ساختار *filp، int cmd بدون علامت، intptr_t arg)؛
تأکید می کند که عدد صحیح فقط یک عدد صحیح برای نمایش کمیتی است که تقریباً است
همیشه یک نوع اشاره گر نامربوط

نتیجه گیری


از libexplain استفاده کنید، کاربران شما آن را دوست خواهند داشت.

کپی رایت


libexplain نسخه 1.4
حق چاپ (C) 2008، 2009، 2010، 2011، 2012، 2013، 2014 پیتر میلر

با استفاده از خدمات onworks.net به صورت آنلاین از توضیح_lca2010 استفاده کنید


سرورها و ایستگاه های کاری رایگان

دانلود برنامه های ویندوز و لینوکس

  • 1
    سوئیچ
    سوئیچ
    SWIG یک ابزار توسعه نرم افزار است
    که برنامه های نوشته شده به زبان C و را به هم متصل می کند
    C++ با انواع سطح بالا
    زبانهای برنامه نویسی. SWIG با استفاده می شود
    ناهمسان...
    SWIG را دانلود کنید
  • 2
    تم ووکامرس Nextjs React
    تم ووکامرس Nextjs React
    موضوع React WooCommerce، ساخته شده با
    Next JS، Webpack، Babel، Node و
    Express با استفاده از GraphQL و Apollo
    مشتری. فروشگاه ووکامرس در React(
    شامل: محصولات ...
    دانلود قالب WooCommerce Nextjs React
  • 3
    archlabs_repo
    archlabs_repo
    مخزن بسته برای ArchLabs این یک است
    برنامه ای که می توان آن را نیز واکشی کرد
    از جانب
    https://sourceforge.net/projects/archlabs-repo/.
    در OnWorks در...
    دانلود archlabs_repo
  • 4
    پروژه زفیر
    پروژه زفیر
    پروژه Zephyr یک نسل جدید است
    سیستم عامل بلادرنگ (RTOS) که
    از چندین سخت افزار پشتیبانی می کند
    معماری ها بر اساس الف است
    هسته با ردپای کوچک ...
    دانلود پروژه Zephyr
  • 5
    جواهرات
    جواهرات
    SCons یک ابزار ساخت نرم افزار است
    که جایگزینی برتر برای
    کلاسیک "ساخت" ابزار ساخت که
    همه ما می دانیم و دوست داریم. SCons است
    یک ...
    SCons را دانلود کنید
  • 6
    PSeInt
    PSeInt
    PSeInt یک مفسر شبه کد برای است
    دانشجویان برنامه نویسی اسپانیایی زبان
    هدف اصلی آن این است که ابزاری برای
    یادگیری و درک اصول اولیه
    مفهوم ...
    PSeInt را دانلود کنید
  • بیشتر "

دستورات لینوکس

Ad