سلام! این بار که دیر نرسیدم نه؟ ۶ روز از قسمت ۳ این آموزش می گذرد و من در حال نوشتن اولین خط قسمت بعد هستم!
از آنجایی که خیلی بی حوصله شدم فقط کار با تابع atexit رو یاد می دهم بنابراین قرار نیست پُست بلندی بشود
قسمت سوم virgool.io | vrgl.ir
دوست من، یکی از برنامه نویسان این کره آبی (اشتباه نکنید ۷۰٪ معادل ۳/۵ و یا تقریبا ۲/۳ رو از ::سطح:: {باز هم اشتباه نکنید، ۷۰٪ از سطح کره زمین رو آب تشکیل داده، مثلا هسته زمین از آب هست؟ (باز دوباره هم اشتباه نکنید، هسته زمین از خاک نیست! بلکه از نیکل و آهن هست!)} بنابراین کل زمین رو که آب نپوشانده!)
<چقدر حرف اضافه زدم>
خود نویسنده آموزش به انگلیسی می گوید:
بیایید با کاربر خوب باشیم (منظورش این هست که و روی کاربر کخ هایمان را خالی نکنیم) و خودمون اتوماتیک هر وقت برنامه خارج شد، ترمینال این بنده خدا را reset کنیم (تو قسمت قبلی راجع به دستور reset گفتم)
دو تابع اضافه کن به نام های enableRawMode که وظیفه فعال کردن حالت raw را دارد و دیگری به نام disableRawMode که مسئول خاموش کردن این حالت هست، به برنامه اضافه می کنیم
همچنین یک struct termios دیگر به برنامه اضافه می کنیم که مسئول نگه داشتن یک کپی ا وضعیت معمولی ترمینال هست
#include <unistd.h> #include <termios.h> #include <stdlib.h> struct termios orig_termios; void enableRawMode(){ tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios); } void disableRawMode(){ tcgetattr(STDIN_FILENO, &orig_termios); atexit(disableRawMode); structtermios raw = orig_termios; raw.c_lflag &= ~(ECHO); tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); } int main(){ char ch; enableRawMode(); while(read(STDIN_FILENO,&ch,1) == 1 && ch != 'q'); return 0; }
این تابع atexit از هدر stdlib.h می آید
ما یک عدد struct termios به نام orig_termios رو با مقدار اولیه یا معمولیترمینال ذخیره می کنیم تا هر وقت خواستیم از برنامه خارج بشویم این متغییر رو به عنوان حالت ترمینال تنظیم کنیم. ما یک struct دیگر به نام raw از روی همین می سازیم و از raw به عنوان struct termiosای استفاده می کنیم که قرار هست حالت raw را داشته باشه
این declaration تابع هست:
int atexit(void (*function)(void));
این تابع، function داده شده را ثبت می کند تا فراخوانی/اجرا شود هر وقت که برنامه kill شد، چه با تابع exit و چه با برگرداندن مقدار از تابع main.
شما می توانید توابع مختلفی به این تابع پاس دهید و همه آنها هنگام kill برنامه اجرا شوند.
استاندارد POSIX حداکثر می تواند ATEXIT_MAX تابع برای اجرا هنگام خروج را قبول کند که معمولا ATEXIT_MAX برابر با ۳۲ هست.
من به شخصه ماکرو ATEXIT_MAX رو نداشتم، همچنین باید بگویم اگر از ()abort استفاده کنید ایت تابع اجرا نمی شوند
خوب خلاصه اش عکس زیر هست:
همین؟ خوب نه، هنوز یکم ادامه دارد ولی فقط یکم!
احتمالا متوجه شدید که حروف اضافه به shell پاس داده نشده؟ مثل عکس زیر:
(لازم به ذکر هست من عبارت سبز رنگ رو بعد اجرا کردن برنامه s نوشتم)
دلیل اش همون TCSAFLUSH بود که در قسمت دوم{virgool.io | vrgl.ir} گفتم!