Forwarded from S.E.Book
• Каждый день тысячи людей используют SSH для подключения к серверам, домашним ПК, роутерам и смартфонам. SSH-клиенты есть для всех сколько-нибудь популярных платформ, а сервер SSH встраивают даже в умные лампочки.• Вашему вниманию предлагается крайне наглядный разбор SSH туннелей. Уж сколько про них уже написано, но такого красиво оформленного материала вроде еще не видел.
Всем начинающим для прочтения строго обязательно.
• В дополнение: Практические примеры SSH.
#SSH #Сети
Please open Telegram to view this post
VIEW IN TELEGRAM
DSP resources and guide
https://github.com/mikeroyal/DSP-Guide#digital-signal-processingdsp-learning-resources
https://github.com/mikeroyal/DSP-Guide#digital-signal-processingdsp-learning-resources
GitHub
GitHub - mikeroyal/DSP-Guide: Digital Signal Processing(DSP) Guide
Digital Signal Processing(DSP) Guide. Contribute to mikeroyal/DSP-Guide development by creating an account on GitHub.
Forwarded from Лаборатория хакера
Linkook — это инструмент OSINT для обнаружения связанных/подключенных учетных записей в социальных сетях и связанных с ними электронных писем на нескольких платформах с использованием одного имени пользователя.
— Данный инструмент также поддерживает экспорт собранных отношений в формате, дружественном к Neo4j, для визуального анализа.
#OSINT #Web #Mail
Please open Telegram to view this post
VIEW IN TELEGRAM
Microwave engineering handouts
The university of Kansas
https://www.ittc.ku.edu/~jstiles/723/handouts/
#microwave
The university of Kansas
https://www.ittc.ku.edu/~jstiles/723/handouts/
#microwave
Process groups and sessions in Linux
توی لینوکس دوتا مفهوم داریم. یکی process group که به یه مجموعه از پراسسها گفته میشه و یه آیدی داره از جنس pid یا همون process id و یدونه هم session که به یه مجموعه از پراسس گروپها گفته میشه و دوباره یه آیدی داره از جنس pid.
آیدی سشنها و پراسس گروپها همون pid کسی(پراسسی) هست که سشن یا پراسس گروپ رو ساخته. و البته ممکنه که درحال حاضر از بین رفته باشه یا به یه گروه دیگه رفته باشه.
هر سشن، یدونه از پراسس گروپهاشو به عنوان پراسس گروپ foreground و بقیه پراسس گروپهاشو به عنوان background process groups تعریف میکنه و سیگنالها(SIGINT, SIGHUP,...) فقط به پراسسهایی که توی پراسس گروپ foreground باشند، ارسال میشه.
هر سشن یه ترمینال (controling terminal) داره که وقتی از بین بره(مثلا ترمینال رو ببندیم)، به پراسسی که سشن رو ساخته یه سیگنال SIGHUP از طرف کرنل ارسال میشه.
مثلا فرض کنید یه ترمینال گرافیکی باز کردیم. این ترمینال میشه یه سشن و هر ترمینال گرافیکی دیگهای میشه یه سشن دیگه. سشن آیدی ترمینال، میشه پراسس آیدی بشی که ترمینال اجرا کرده و دستوراتی که عادی توی ترمینال اجرا میکنیم، هرکدوم میشن یه پراسس گروپ و دستور درحال اجرا، میشه foreground process group سشن ترمینالمون.
اگه آخر یه دستور & اضافه کنیم، دستور توی پس زمینه اجرا خواهد شد و جزو background process ها خواهد بود.
دستوراتی که پایپ میشن، مثل دستورات عادی، هرکدوم توی یه پراسس گروپ قرار میگیرن (البته این کاریه که بش انجام میده و شاید توی شلهای مختلف به شکلهای دیگهای انجام بگیره).
ای پی آی لینوکسی برای پیدا کردن و ست کردن پراسس گروپ و سشن ایدی یه پراسس، مثل همیشه توی هدر unistd.h قرار دارن. برای پیدا کردن process group id یا pgid تابع
getpgrp()
رو داریم که همونطور که گفتیم pid_t بر میگردونه.
برای ست کردن pgid هم، تابع
setpgid()
رو داریم. که یه pid ازمون میگیره و یه pgid و پراسسی که با pid مشخص میشه رو به پراسس گروپی که با pgid مشخص میشه منتقل میکنه.
البته این سیستم کال یه سری شروط داره که در پست بعدی میگم
ادامه دارد...
#Linux
#Programming
توی لینوکس دوتا مفهوم داریم. یکی process group که به یه مجموعه از پراسسها گفته میشه و یه آیدی داره از جنس pid یا همون process id و یدونه هم session که به یه مجموعه از پراسس گروپها گفته میشه و دوباره یه آیدی داره از جنس pid.
آیدی سشنها و پراسس گروپها همون pid کسی(پراسسی) هست که سشن یا پراسس گروپ رو ساخته. و البته ممکنه که درحال حاضر از بین رفته باشه یا به یه گروه دیگه رفته باشه.
هر سشن، یدونه از پراسس گروپهاشو به عنوان پراسس گروپ foreground و بقیه پراسس گروپهاشو به عنوان background process groups تعریف میکنه و سیگنالها(SIGINT, SIGHUP,...) فقط به پراسسهایی که توی پراسس گروپ foreground باشند، ارسال میشه.
هر سشن یه ترمینال (controling terminal) داره که وقتی از بین بره(مثلا ترمینال رو ببندیم)، به پراسسی که سشن رو ساخته یه سیگنال SIGHUP از طرف کرنل ارسال میشه.
مثلا فرض کنید یه ترمینال گرافیکی باز کردیم. این ترمینال میشه یه سشن و هر ترمینال گرافیکی دیگهای میشه یه سشن دیگه. سشن آیدی ترمینال، میشه پراسس آیدی بشی که ترمینال اجرا کرده و دستوراتی که عادی توی ترمینال اجرا میکنیم، هرکدوم میشن یه پراسس گروپ و دستور درحال اجرا، میشه foreground process group سشن ترمینالمون.
اگه آخر یه دستور & اضافه کنیم، دستور توی پس زمینه اجرا خواهد شد و جزو background process ها خواهد بود.
دستوراتی که پایپ میشن، مثل دستورات عادی، هرکدوم توی یه پراسس گروپ قرار میگیرن (البته این کاریه که بش انجام میده و شاید توی شلهای مختلف به شکلهای دیگهای انجام بگیره).
ای پی آی لینوکسی برای پیدا کردن و ست کردن پراسس گروپ و سشن ایدی یه پراسس، مثل همیشه توی هدر unistd.h قرار دارن. برای پیدا کردن process group id یا pgid تابع
getpgrp()
رو داریم که همونطور که گفتیم pid_t بر میگردونه.
برای ست کردن pgid هم، تابع
setpgid()
رو داریم. که یه pid ازمون میگیره و یه pgid و پراسسی که با pid مشخص میشه رو به پراسس گروپی که با pgid مشخص میشه منتقل میکنه.
البته این سیستم کال یه سری شروط داره که در پست بعدی میگم
ادامه دارد...
#Linux
#Programming
اگه مطالب کانال مفیده براتون ممنون میشم به دوستاتون معرفیمون کنین❤️
CRTP in C++
فرض کنید که یه کلاس بیس داریم و چندین کلاس که ازین کلاس ارث بری کردن.
فرض کنید توی کلاس بیس یه تابع virtual و چندتا تابع عادی داشته باشیم و داخل یکی ازین توابع عادی بخواهیم این تابع virtual رو صدا بزنیم. مشکلی که اینجا خواهیم داشت، اینه که صدا زدن تابع virtual با this اتفاق خواهد افتاد و نتیجتا تابع virtual کلاس بیس صدا زده خواهد شد و نه تابع کلاس های ارث بری کرده.
خب حالا فرض کنید لازم داریم که توی کلاس والد، توابع virtual کلاسهای فرزند رو صدا بزنیم. چه کنیم؟
یا فرض کنید درکلاس های فرزند یک تابع استاتیک وجود دارد که پیاده سازی آن توسط کلاس فرزند انجام گرفته است. برای صدا زدن این توابع درون تابع والد باید چه کرد؟
اینجاست که CRTP وارد بحث میشه. توی این پترن، میایم تایپ کلاس های فرزند رو درقالب تمپلت به کلاس بیس پاس میدیم:
اینجوری دیگه توی کلاس بیس میدونم تایپ کلاس فرزند چیه و میتونیم پوینترthis رو بهش کست کنیم و از توابع virtualاش استفاده کنیم یا حتی توابع استاتیکش رو صدا بزنیم.
به این پترن میگن CRTP
#cpp
#programming
فرض کنید که یه کلاس بیس داریم و چندین کلاس که ازین کلاس ارث بری کردن.
فرض کنید توی کلاس بیس یه تابع virtual و چندتا تابع عادی داشته باشیم و داخل یکی ازین توابع عادی بخواهیم این تابع virtual رو صدا بزنیم. مشکلی که اینجا خواهیم داشت، اینه که صدا زدن تابع virtual با this اتفاق خواهد افتاد و نتیجتا تابع virtual کلاس بیس صدا زده خواهد شد و نه تابع کلاس های ارث بری کرده.
class Base{
public:
virtual void virt_func(){
//Base implementation
}
void normal_func(){
virt_func();
}
};خب حالا فرض کنید لازم داریم که توی کلاس والد، توابع virtual کلاسهای فرزند رو صدا بزنیم. چه کنیم؟
یا فرض کنید درکلاس های فرزند یک تابع استاتیک وجود دارد که پیاده سازی آن توسط کلاس فرزند انجام گرفته است. برای صدا زدن این توابع درون تابع والد باید چه کرد؟
اینجاست که CRTP وارد بحث میشه. توی این پترن، میایم تایپ کلاس های فرزند رو درقالب تمپلت به کلاس بیس پاس میدیم:
template <typename T>
class Base{
};
class Derived: public Base<Derived>{
};
اینجوری دیگه توی کلاس بیس میدونم تایپ کلاس فرزند چیه و میتونیم پوینترthis رو بهش کست کنیم و از توابع virtualاش استفاده کنیم یا حتی توابع استاتیکش رو صدا بزنیم.
به این پترن میگن CRTP
#cpp
#programming
Stuff for Geeks
Process groups and sessions in Linux توی لینوکس دوتا مفهوم داریم. یکی process group که به یه مجموعه از پراسسها گفته میشه و یه آیدی داره از جنس pid یا همون process id و یدونه هم session که به یه مجموعه از پراسس گروپها گفته میشه و دوباره یه آیدی داره از جنس…
خب
گفتیم که setpgid چندتا نکته و چندتا محدودیت داره. اول نکته هاش رو میگم:
- اگه آرگومان اولش صفر باشه، pid پراسسی که تابع رو صدا زده استفاده میشه. ینی اگه بگیم
setpgid(0, 100)
منظورمون اینه که پراسسی که این تابع رو داره صدا میزنه به پراسس گروپ با pid صد منتقل کن.
ـ اگه pgid یا آرگومان دوم تابع صفر باشه، پراسس گروپ آیدی پراسسی که تابع رو صدا زده استفاده میشه. یعنی عبارات زیر یک کار انجام میدن:
setpgid(100, 0)
setpgid(100, getpgrp());
که به معنی انتقال دادن پراسسی با pid صد به گروپ پراسس صدا زنندهٔ تابع هست.
اما محدودیت های این تابع:
- باید پراسس مدنظر و پراسس گروپ توی یک سشن باشن.
ـ پراسس مدنظر باید خود پراسس صدا زنندهٔ تابع یا یکی از child هاش باشه.
- پراسس مدنظر نباید سشن لیدر باشه. ینی نباید کسی باشه که یه سشن ساخته.
ـ پراسس مدنظر نباید exec اجرا کرده باشه.
نهایتا اگه تابع بدون مشکل اجرا شه و انتقال پراسس اوکی باشه بهمون صفر وگرنه منفی یک بر میگردونه که میتونیم با perror ارورش رو هم پیدا و پرینت کنیم
ادامه
#Linux
#Programming
گفتیم که setpgid چندتا نکته و چندتا محدودیت داره. اول نکته هاش رو میگم:
- اگه آرگومان اولش صفر باشه، pid پراسسی که تابع رو صدا زده استفاده میشه. ینی اگه بگیم
setpgid(0, 100)
منظورمون اینه که پراسسی که این تابع رو داره صدا میزنه به پراسس گروپ با pid صد منتقل کن.
ـ اگه pgid یا آرگومان دوم تابع صفر باشه، پراسس گروپ آیدی پراسسی که تابع رو صدا زده استفاده میشه. یعنی عبارات زیر یک کار انجام میدن:
setpgid(100, 0)
setpgid(100, getpgrp());
که به معنی انتقال دادن پراسسی با pid صد به گروپ پراسس صدا زنندهٔ تابع هست.
اما محدودیت های این تابع:
- باید پراسس مدنظر و پراسس گروپ توی یک سشن باشن.
ـ پراسس مدنظر باید خود پراسس صدا زنندهٔ تابع یا یکی از child هاش باشه.
- پراسس مدنظر نباید سشن لیدر باشه. ینی نباید کسی باشه که یه سشن ساخته.
ـ پراسس مدنظر نباید exec اجرا کرده باشه.
نهایتا اگه تابع بدون مشکل اجرا شه و انتقال پراسس اوکی باشه بهمون صفر وگرنه منفی یک بر میگردونه که میتونیم با perror ارورش رو هم پیدا و پرینت کنیم
ادامه
#Linux
#Programming
Stuff for Geeks
خب گفتیم که setpgid چندتا نکته و چندتا محدودیت داره. اول نکته هاش رو میگم: - اگه آرگومان اولش صفر باشه، pid پراسسی که تابع رو صدا زده استفاده میشه. ینی اگه بگیم setpgid(0, 100) منظورمون اینه که پراسسی که این تابع رو داره صدا میزنه به پراسس گروپ با pid صد منتقل…
سورس این موارد کتاب the linux programming interface هست که یه مقدار قدیمیه و خب ممکنه یه مقدار اطلاعات ناقص باشه
Stuff for Geeks
خب گفتیم که setpgid چندتا نکته و چندتا محدودیت داره. اول نکته هاش رو میگم: - اگه آرگومان اولش صفر باشه، pid پراسسی که تابع رو صدا زده استفاده میشه. ینی اگه بگیم setpgid(0, 100) منظورمون اینه که پراسسی که این تابع رو داره صدا میزنه به پراسس گروپ با pid صد منتقل…
اما سشن
گفتیم که یه سشن مجموعهای از پراسس گروپهاست. وقتی یه پراسس میسازیم، سشن آیدیش، سشن آیدی والدش میشه.
هر سشنی یه سشن آیدی از جنس pid_t داره که pid پراسس سازندهٔ اون سشن هست و همه پراسسهای موجود در یک سشن، یک controling terminal دارن.
با سیستم کال
getsid(pid_t)
میتونیم سشن آیدی یه پراسس رو پیدا کنیم و با سیستم کال
setsid()
میتونیم یه سشن جدید بسازیم که صدازنندهٔ این تابع میشه سشن لیدر اون سشن و البته سشن جدید هیچ controlling terminalای نخواهد داشت. البته باز نکتهها و محدودیتهایی داریم اینجا که جلوتر میگم.
قبل از اینکه نکته و محدودیتهای این تابع رو بگم، یه کاربردش رو بگم.
فرض کنید بخوایم یه پراسس daemon داشته باشیم. یعنی پراسسی که توی پس زمینه داره اجرا میشه، معمولا با روشن شدن کامپیوتر اجرا میشه و با خاموش شدنش بسته میشه و با یوزر هیچ اینترکشنی نداره. یه چیزی خیلی شبیه به یونیتهای systemd.
اگه بخوایم برناممون یه daemon بشه، یکی از کارهایی که باید انجام بدیم، صدا زدن این تابع setsid هست تا پراسسمون مستقل از هر ترمینالی بشه و سشن خودش رو داشته باشه.
یه محدودیت این تابه که تقریبا باید براتون واضح باشه، اینه که نمیشه برای یه پراسسی که سشن لیدر هست، این تابع رو اجرا کنیم و منتقلش کنیم به یه سشن دیگه. چون در اینصورت، دوتا سشن با آیدیهای یکسان خواهیم داشت(سشن آیدی، پراسس آیدیِ سشن لیدره). پس این یه محدودیت.
یه نکته هم این که با صدا زدن این تابع، یه سشن جدید و یه پراسس گروپ جدید ساخته میشه که هردوتاشون آیدیشون پراسس آیدیِ پراسس صدا زنندهٔ این تابع هست.
خب با یکم دقت باید محدودیت دوم این تابع رو حدس بزنید.
پراسس صدا زنندهٔ این تابع، نباید پراسس گروپ لیدر باشه. چرا؟ چون در اینصورت، دوتا پراسس گروپ با یه آیدی در دو سشن متفاوت خواهیم داشت که نمیشه.
پس محدودیتهای تابع اینه که پراسس صدا زننده نباید سشن لیدر یا پراسس گروپ لیدر باشه.
برای اینکه ازین قضیه مطمئن شیم، کافیه قبل از setsid صدازدن، یه
fork()
بزنیم و یه پراسس فرزند بسازیم. چون پراسس فرزند پراسس آیدی جدید خودش رو داره، قاعدتا دیگه سشن لیدر یا پراسس گروپ لیدر نخواهد بود و setsid میتونه اجرا شه.
#Linux
#Programming
گفتیم که یه سشن مجموعهای از پراسس گروپهاست. وقتی یه پراسس میسازیم، سشن آیدیش، سشن آیدی والدش میشه.
هر سشنی یه سشن آیدی از جنس pid_t داره که pid پراسس سازندهٔ اون سشن هست و همه پراسسهای موجود در یک سشن، یک controling terminal دارن.
با سیستم کال
getsid(pid_t)
میتونیم سشن آیدی یه پراسس رو پیدا کنیم و با سیستم کال
setsid()
میتونیم یه سشن جدید بسازیم که صدازنندهٔ این تابع میشه سشن لیدر اون سشن و البته سشن جدید هیچ controlling terminalای نخواهد داشت. البته باز نکتهها و محدودیتهایی داریم اینجا که جلوتر میگم.
قبل از اینکه نکته و محدودیتهای این تابع رو بگم، یه کاربردش رو بگم.
فرض کنید بخوایم یه پراسس daemon داشته باشیم. یعنی پراسسی که توی پس زمینه داره اجرا میشه، معمولا با روشن شدن کامپیوتر اجرا میشه و با خاموش شدنش بسته میشه و با یوزر هیچ اینترکشنی نداره. یه چیزی خیلی شبیه به یونیتهای systemd.
اگه بخوایم برناممون یه daemon بشه، یکی از کارهایی که باید انجام بدیم، صدا زدن این تابع setsid هست تا پراسسمون مستقل از هر ترمینالی بشه و سشن خودش رو داشته باشه.
یه محدودیت این تابه که تقریبا باید براتون واضح باشه، اینه که نمیشه برای یه پراسسی که سشن لیدر هست، این تابع رو اجرا کنیم و منتقلش کنیم به یه سشن دیگه. چون در اینصورت، دوتا سشن با آیدیهای یکسان خواهیم داشت(سشن آیدی، پراسس آیدیِ سشن لیدره). پس این یه محدودیت.
یه نکته هم این که با صدا زدن این تابع، یه سشن جدید و یه پراسس گروپ جدید ساخته میشه که هردوتاشون آیدیشون پراسس آیدیِ پراسس صدا زنندهٔ این تابع هست.
خب با یکم دقت باید محدودیت دوم این تابع رو حدس بزنید.
پراسس صدا زنندهٔ این تابع، نباید پراسس گروپ لیدر باشه. چرا؟ چون در اینصورت، دوتا پراسس گروپ با یه آیدی در دو سشن متفاوت خواهیم داشت که نمیشه.
پس محدودیتهای تابع اینه که پراسس صدا زننده نباید سشن لیدر یا پراسس گروپ لیدر باشه.
برای اینکه ازین قضیه مطمئن شیم، کافیه قبل از setsid صدازدن، یه
fork()
بزنیم و یه پراسس فرزند بسازیم. چون پراسس فرزند پراسس آیدی جدید خودش رو داره، قاعدتا دیگه سشن لیدر یا پراسس گروپ لیدر نخواهد بود و setsid میتونه اجرا شه.
#Linux
#Programming
A very good explanation on different encoding methods used in different versions of the Ethernet protocol:
https://units.folder101.com/cisco/sem1/Notes/ch7-technologies/encoding.htm
https://units.folder101.com/cisco/sem1/Notes/ch7-technologies/encoding.htm
سیگنالها در لینوکس
احتمالا با مفهوم سیگنال آشنا باشید. سیگنالها یکی از مکانیزمهای قدیمی IPC هستن که تو همه سیستمعاملها وجود دارن. به سیگنالها وقفههای نرمافزاری هم گفته میشه. به این معنی که با ورود یک سیگنال به یک پراسس، اگه برنامه اون سیگنال رو بلاک نکرده باشه، instruction pointer هرجا باشه میره توی تابع handler ای که برای سیگنال مربوطه نوشته شده و اون برنامه رو اجرا میکنه و بعد برمیگرده سرجای قبلیش و ادامهٔ برنامه اجرا میشه.
این میشه مفهوم کلی سیگنال.
اما بذارید ببینیم توی لینوکس برای کار با این مکانیزم چیا داریم.
خب معروف ترین توابعی که داریم signal و kill هستن. تابع اول یه سیگنال و یه فانکشن پوینتر میگیره و باعث میشه برای سیگنال ورودی داده شده بهش، هندلر داده شده اجرا شه.
تابع دوم یا kill همونطور که توی بش هم داریمش، به یه pid یه سیگنال میفرسته.
البته که برای استفاده ازین توابع باید هدر signal.h رو اینکلود کنیم.
توجه کنید که وقتی توی یه سیگنال هندلر هستیم، همهٔ سیگنالهای دیگه بلاک میشن تا موقعی که از سیگنال هندلر خارج شیم. پس خوبه که همیشه سیگنالهندلرامون تا جایی که جا داره خلاصه نوشته بشن تا سریع اجراشون تموم شه.
سه تا نکته برای تابع kill داریم.
۱. اگه pid ورودی به این تابع صفر باشه، سیگنال مشخص شده به همهٔ پراسسهای موجود در پراسس گروپ کسی که تابع رو صدا زده فرستاده میشه. حتی به خود پراسس صدا زنندهٔ این سیستم کال
۲. اگه pid منفی یک باشه، سیگنال مربوطه به همه پراسسهایی که پراسس صدازنندهٔ تابع بهشون دسترسی داره، فرستاده میشه البته بجز init و خود پراسس صدا زنندهٔ تابع.
۳. اگه pid کوچیکتر از منفی یک باشه، مثلا
-۶۴
سیگنال مشخصشده، به همه پراسسهای موجود در پراسس گروپی با آیدی قدرمطلق پارامتر pid فرستاده میشه. ینی تو این مثال، سیگنال مشخص شده به تمام پراسسهای پراسس گروپی با آیدی ۶۴ ارسال میشه.
موضوع دیگه اینکه توی لینوکس دو مدل سیگنال داریم. سیگنالهای real time و سیگنالهای استاندارد. سیگنالهای استاندارد که شمارشون از یک شروع و به ۳۱ ختم میشه، صف نمیشن. ینی اگه یه پراسسی یه سیگنالی رو بلاک کرده باشه و صدبار یه سیگنال براش بفرستیم، بعد از آنبلاک کردن سیگنال، فقط یکبار اون سیگنال به پراسس فرستاده میشه و هندلرش یکبار صدا زده میشه ولی سیگنالهای real time صف میشن.
برای تابع signal هم چندتا نکته داریم. اول از همه اینکه signature این تابع به شکل زیره:
sighandler_t signal(int sig, sighandler_t handler)
تایپ sighandler_t که توی glibc تعریف میشه(لازمه که ماکروی
_GNU_SOURCE
رو دیفاین کنیم)، از نوع پوینتر به یه تابعه که اینت میگیره و void برمیگردونه.
یعنی تابعی که قراره به عنوان سیگنال هندلر ازش استفاده کنیم، باید یه اینت بگیره و void برگردونه:
void handler(int sig_number){
}
دوتا مسئله اینجا هست. یک اینکه اینتیجر ورودی چیه و دوم اینکه چرا تایپ برگردان تابع باید همچین تابعی باشه؟
جواب سوال اول اینه که این اینتیجر،یه عدده که نشون میده برای بار چندم این سیگنال داره به پراسس ارسال میشه. این عدد شماره سیگنالیه که باعث ورود به این هندلر شده (توجه کنید که میشه چندین سیگنال یه هندلر داشته باشن)
و جواب سوال دوم هم اینه که اون چیزی که تابع برمیگردونه، هندلر قبلی این سیگناله که برای ریست کردنِ سیگنال هندلر میتونه مفید باشه.
ادامه دارد...
#Linux
#programming
احتمالا با مفهوم سیگنال آشنا باشید. سیگنالها یکی از مکانیزمهای قدیمی IPC هستن که تو همه سیستمعاملها وجود دارن. به سیگنالها وقفههای نرمافزاری هم گفته میشه. به این معنی که با ورود یک سیگنال به یک پراسس، اگه برنامه اون سیگنال رو بلاک نکرده باشه، instruction pointer هرجا باشه میره توی تابع handler ای که برای سیگنال مربوطه نوشته شده و اون برنامه رو اجرا میکنه و بعد برمیگرده سرجای قبلیش و ادامهٔ برنامه اجرا میشه.
این میشه مفهوم کلی سیگنال.
اما بذارید ببینیم توی لینوکس برای کار با این مکانیزم چیا داریم.
خب معروف ترین توابعی که داریم signal و kill هستن. تابع اول یه سیگنال و یه فانکشن پوینتر میگیره و باعث میشه برای سیگنال ورودی داده شده بهش، هندلر داده شده اجرا شه.
تابع دوم یا kill همونطور که توی بش هم داریمش، به یه pid یه سیگنال میفرسته.
البته که برای استفاده ازین توابع باید هدر signal.h رو اینکلود کنیم.
توجه کنید که وقتی توی یه سیگنال هندلر هستیم، همهٔ سیگنالهای دیگه بلاک میشن تا موقعی که از سیگنال هندلر خارج شیم. پس خوبه که همیشه سیگنالهندلرامون تا جایی که جا داره خلاصه نوشته بشن تا سریع اجراشون تموم شه.
سه تا نکته برای تابع kill داریم.
۱. اگه pid ورودی به این تابع صفر باشه، سیگنال مشخص شده به همهٔ پراسسهای موجود در پراسس گروپ کسی که تابع رو صدا زده فرستاده میشه. حتی به خود پراسس صدا زنندهٔ این سیستم کال
۲. اگه pid منفی یک باشه، سیگنال مربوطه به همه پراسسهایی که پراسس صدازنندهٔ تابع بهشون دسترسی داره، فرستاده میشه البته بجز init و خود پراسس صدا زنندهٔ تابع.
۳. اگه pid کوچیکتر از منفی یک باشه، مثلا
-۶۴
سیگنال مشخصشده، به همه پراسسهای موجود در پراسس گروپی با آیدی قدرمطلق پارامتر pid فرستاده میشه. ینی تو این مثال، سیگنال مشخص شده به تمام پراسسهای پراسس گروپی با آیدی ۶۴ ارسال میشه.
موضوع دیگه اینکه توی لینوکس دو مدل سیگنال داریم. سیگنالهای real time و سیگنالهای استاندارد. سیگنالهای استاندارد که شمارشون از یک شروع و به ۳۱ ختم میشه، صف نمیشن. ینی اگه یه پراسسی یه سیگنالی رو بلاک کرده باشه و صدبار یه سیگنال براش بفرستیم، بعد از آنبلاک کردن سیگنال، فقط یکبار اون سیگنال به پراسس فرستاده میشه و هندلرش یکبار صدا زده میشه ولی سیگنالهای real time صف میشن.
برای تابع signal هم چندتا نکته داریم. اول از همه اینکه signature این تابع به شکل زیره:
sighandler_t signal(int sig, sighandler_t handler)
تایپ sighandler_t که توی glibc تعریف میشه(لازمه که ماکروی
_GNU_SOURCE
رو دیفاین کنیم)، از نوع پوینتر به یه تابعه که اینت میگیره و void برمیگردونه.
یعنی تابعی که قراره به عنوان سیگنال هندلر ازش استفاده کنیم، باید یه اینت بگیره و void برگردونه:
void handler(int sig_number){
}
دوتا مسئله اینجا هست. یک اینکه اینتیجر ورودی چیه و دوم اینکه چرا تایپ برگردان تابع باید همچین تابعی باشه؟
جواب سوال اول اینه که این اینتیجر،
و جواب سوال دوم هم اینه که اون چیزی که تابع برمیگردونه، هندلر قبلی این سیگناله که برای ریست کردنِ سیگنال هندلر میتونه مفید باشه.
ادامه دارد...
#Linux
#programming
❤2
Stuff for Geeks
سیگنالها در لینوکس احتمالا با مفهوم سیگنال آشنا باشید. سیگنالها یکی از مکانیزمهای قدیمی IPC هستن که تو همه سیستمعاملها وجود دارن. به سیگنالها وقفههای نرمافزاری هم گفته میشه. به این معنی که با ورود یک سیگنال به یک پراسس، اگه برنامه اون سیگنال رو بلاک…
سیگنالها در لینوکس
قسمت دوم
تا اینجا kill و signal رو دیدیم. در ادامه، تابع raise رو داریم که یه سیگنال به پراسس صدا زنندش میفرسته. البته دقیقتر بخوایم بگیم به ترد صدا زنندش. درواقع سیگنالها به تردها ارسال میشن و نه پراسسها.
سیگنیچر تابع raise خیلی سادست:
raise(int signal)
تابع دیگهای که داریم، killpg هست. این تابع یه سیگنال رو به یه پراسس گروپ میفرسته. درواقع دو خط زیر یک کار انجام میدن(به پست قبل رجوع کنید):
killpg(pgid, sig)
signal(-pgid, sig)
اگه آرگومان اول این تابع صفر باشه، سیگنال مشخصشده به پراسس گروپ کسی که تابع رو صدا زده ارسال میشه.
و اما یکی از مهم ترین توابعی که داریم sigaction هست. این تابع کارش تنظیم کردن اینه که چجوری پراسس باید به یه سیگنال پاسخ بده(signal deposition)
درواقع نسخهٔ خیلی کاملتر تابع signal میشه این تابع.
سیگنیچر این تابع به شکل زیره:
int sigaction(int signal, const struct sigaction * act, const struct sigaction* oldact)
و استراکچر sigaction هم به شکل زیر تعریف شده:
اولین فیلد استراکچر فانکشن پوینتر به یه سیگنال هندلره که میتونه آدرس یه تابع، SIG_DFL و یا SIG_IGN باشه. فیلد دومش، sa_mask هست که یه مجموعه سیگنال(sigset_t که بعدا بیشتر توضیح میدم) میگیره. این مجموعه سیگنال موقعی که توی هندلر باشیم بلاک خواهند شد (خود اون سیگنالی که باعث وارد شدن به اون هندلر شده هم بلاک میشه بطور پیشفرض).
و فیلد سوم یه بیت مسکه که یه سری فلگها رو باهش میتونیم برای سیگنالمون تنظیم کنیم. مثلا میتونیم تنظیم کنیم که یک سیگنال توی هندلرش خودش رو بلاک نکنه(SA_NODEFER).
یا میتونیم تنظیم کنیم بعد از اینکه هندلر اجرا شد، deposition اون سیگنال بشه SIG_DFL و دیگه هندلرما صدا زده نشه براش(SA_RESETHAND) و یه سری موارد دیگه.
فیلد آخر این استراکچر هم برای استفادههای داخلیه و برای ما کاربردی نداره.
ادامه دارد...
#Linux
#Programming
قسمت دوم
تا اینجا kill و signal رو دیدیم. در ادامه، تابع raise رو داریم که یه سیگنال به پراسس صدا زنندش میفرسته. البته دقیقتر بخوایم بگیم به ترد صدا زنندش. درواقع سیگنالها به تردها ارسال میشن و نه پراسسها.
سیگنیچر تابع raise خیلی سادست:
raise(int signal)
تابع دیگهای که داریم، killpg هست. این تابع یه سیگنال رو به یه پراسس گروپ میفرسته. درواقع دو خط زیر یک کار انجام میدن(به پست قبل رجوع کنید):
killpg(pgid, sig)
signal(-pgid, sig)
اگه آرگومان اول این تابع صفر باشه، سیگنال مشخصشده به پراسس گروپ کسی که تابع رو صدا زده ارسال میشه.
و اما یکی از مهم ترین توابعی که داریم sigaction هست. این تابع کارش تنظیم کردن اینه که چجوری پراسس باید به یه سیگنال پاسخ بده(signal deposition)
درواقع نسخهٔ خیلی کاملتر تابع signal میشه این تابع.
سیگنیچر این تابع به شکل زیره:
int sigaction(int signal, const struct sigaction * act, const struct sigaction* oldact)
و استراکچر sigaction هم به شکل زیر تعریف شده:
struct sigaction{
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}اولین فیلد استراکچر فانکشن پوینتر به یه سیگنال هندلره که میتونه آدرس یه تابع، SIG_DFL و یا SIG_IGN باشه. فیلد دومش، sa_mask هست که یه مجموعه سیگنال(sigset_t که بعدا بیشتر توضیح میدم) میگیره. این مجموعه سیگنال موقعی که توی هندلر باشیم بلاک خواهند شد (خود اون سیگنالی که باعث وارد شدن به اون هندلر شده هم بلاک میشه بطور پیشفرض).
و فیلد سوم یه بیت مسکه که یه سری فلگها رو باهش میتونیم برای سیگنالمون تنظیم کنیم. مثلا میتونیم تنظیم کنیم که یک سیگنال توی هندلرش خودش رو بلاک نکنه(SA_NODEFER).
یا میتونیم تنظیم کنیم بعد از اینکه هندلر اجرا شد، deposition اون سیگنال بشه SIG_DFL و دیگه هندلرما صدا زده نشه براش(SA_RESETHAND) و یه سری موارد دیگه.
فیلد آخر این استراکچر هم برای استفادههای داخلیه و برای ما کاربردی نداره.
ادامه دارد...
#Linux
#Programming