এই লিনাক্সহিন্ট আর্টিকেলে, আমরা ব্যাখ্যা করব সিস্টেম কল কী, এগুলো কী জন্য ব্যবহার হয়, এবং স্ট্যান্ডার্ড সি লাইব্রেরির অন্যান্য ফাংশন থেকে এগুলো কীভাবে ভিন্ন। আমরা আপনাকে দেখাব এগুলো সিস্টেমে কার্নেলের জন্য কী ফাংশন सर्व করে এবং প্রসেসগুলো কীভাবে এদের প্রদত্ত সার্ভিস ব্যবহার করে। আমরা সবচেয়ে সাধারণভাবে ব্যবহৃত সিস্টেম কলের একটি তালিকা এবং প্রতিটি ফাংশনের সংক্ষিপ্ত বিবরণ ও সেগুলো যে হেডারে ডিক্লেয়ার করা আছে তা দেখাব। অন্য একটি বিভাগে, আমরা আপনাকে দেখাব কীভাবে কমান্ড কনসোল দিয়ে সিস্টেম কলের অপারেশন মনিটর করা যায়।
কনসেপচুয়ালি, সব সিস্টেম লেয়ার দিয়ে তৈরি হয়েছে যেখানে প্রতিটির নিজস্ব ফাংশন ও প্রিভিলেজ রয়েছে। একটি সিস্টেম গঠনকারী এই লেয়ার স্ট্যাক সবচেয়ে নিচের লেভেলে হার্ডওয়ার কম্পোনেন্ট দিয়ে শুরু হয় এবং সবচেয়ে উপরের লেয়ার যা ইউজার মোড নামে পরিচিত দিয়ে শেষ হয়।
আমরা আমাদের কম্পিউটারে जितने প্রোগ্রাম রান করি এবং যত কোড লিখি ও কম্পাইল করি, ফলাফল একটি প্রসেস যেটি সিস্টেমের ইউজার মোডে রান করে। এই মোডে, ইউজার কাজ করে এবং তার দৈনন্দিন টাস্ক সম্পাদন করে, বিভিন্ন অ্যাপ্লিকেশন লঞ্চ ও ব্যবহার করে, ফাইল ম্যানেজ করে, ইত্যাদি। সিকিউরিটি লেভেলে, এটি সিস্টেমের সবচেয়ে সুপারফিশিয়াল লেয়ার এবং তাই সবচেয়ে সীমাবদ্ধ এবং ডিফল্টভাবে সিস্টেম রিসোর্স সরাসরি ম্যানেজ ও ব্যবহার করার দিক থেকে সম্পূর্ণ সীমাবদ্ধ।
যে bako উল্লেখ করা হয়েছে, হার্ডওয়ার লেয়ার একটি সিস্টেমের সবচেয়ে নিচের লেভেল। তার ঠিক উপরে লিনাক্স কার্নেল রয়েছে। কার্নেল অপারেটিং সিস্টেমের হৃদয় যেখানে এটি হার্ডওয়ারের সাথে ইন্টিগ্রেট হয় এবং কঠোরভাবে সেটি ম্যানেজ করে, একমাত্র যেটি সেটি করার প্রিভিলেজ রাখে। উদাহরণস্বরূপ, প্রসেস ও মেমরি এখানে ম্যানেজ হয়, হার্ড ডিস্ক বা SSD থেকে ডেটা অ্যাক্সেস হয়, নেটওয়ার্ক ডিভাইস কন্ট্রোল হয়, ইত্যাদি। OS এবং প্রসেসগুলো হার্ডওয়ারের সাথে যা কিছু করে সেটি কার্নেলের মাধ্যমে হয়। তাই আপনি বলতে পারেন এটি একরকম ফার্মওয়্যার যা সফটওয়্যার ও হার্ডওয়্যার ইন্টিগ্রেট করে।
ইউজার মোডে রিসোর্স অ্যাক্সেস ও ম্যানেজমেন্টে অপারেটিং সিস্টেম দ্বারা আরোপিত সীমাবদ্ধতা, এবং কারণ এই রিসোর্সগুলো একমাত্র কার্নেলের মাধ্যমে অ্যাক্সেসযোগ্য, একটি মেকানিজম অত্যাবশ্যক যা প্রসেসগুলকে তাদের ফাংশন করার জন্য প্রয়োজনীয় রিসোর্সের সাথে ইন্টারঅ্যাক্ট করতে দেয়।
সিস্টেম কল, বা SysCalls, অপারেটিং সিস্টেম দ্বারা প্রদত্ত ফাংশন들의 একটি সেট যা একটি ইউজার প্রসেস এবং কার্নেলের মধ্যে ইন্টারফেস হিসেবে কাজ করে। এই ফাংশনগুলো আমাদের OS এর সাথে ইন্টারঅ্যাক্ট করতে দেয় এবং এর মাধ্যমে একটি সার্ভিস রিকোয়েস্ট করতে দেয় যেটি সিস্টেম রিসোর্সের ব্যবহার প্রয়োজন। Syscalls রিসোর্স বা তাদের ম্যানেজমেন্টে সরাসরি অ্যাক্সেস দেয় না, বরং কার্নেল সেগুলো ম্যানেজ করে এবং সেটি কল করা প্রসেসে উপলব্ধ করে, কিন্তু সর্বদা তার কঠোর ম্যানেজমেন্টের অধীনে।
প্র্যাকটিক্যালি, সিস্টেম কল ফাংশনগুলো সাধারণ ফাংশনগুলোর মতো দেখে এবং সেইভাবেই বাস্তবায়ন করা হয়। এদের ইনপুট আর্গুমেন্ট থাকে যাতে প্রসেস করা ডেটা পাস করা হয়, এবং আউটপুট আর্গুমেন্ট থাকে যাতে অপারেটিং সিস্টেম ফলাফল রিটার্ন করে।
এই টাইপের ফাংশন কল করার মেথড সি লাইব্রেরিতে পাওয়া যেকোনো অন্যান্য ফাংশনের মতোই। তাই, প্রোগ্রামারের জন্য এটি কলিং ফাংশন কিনা তা প্র্যাকটিক্যালি একটি বিশুদ্ধ কনসেপচুয়াল প্রশ্ন।
এই ফাংশনদের আর্গুমেন্ট সি ভাষার স্ট্যান্ডার্ড টাইপ ব্যবহার করে। যদিও, তাদের টাস্কের প্রকৃতির কারণে, সেগুলো সাধারণত পয়েন্টার যেগুলো মেমরি অ্যাড্রেস, ডেসক্রিপ্টর, পাথ, ইত্যাদি সংরক্ষণ করে।
লিনাক্সে, বর্তমানে প্রায় ৩৫০টি সিস্টেম কল রয়েছে। এছাড়া, প্রচুর ফাংশন রয়েছে যেগুলো সিস্টেম কল নয় কিন্তু সিস্টেম কল ব্যবহার করে রিসোর্স ম্যানেজ করে যেমন malloc(), free(), calloc(), এবং realloc() ফাংশনগুলো যা আপনার কোডে সিস্টেম কল ব্যবহার করে ডাইনামিক্যালি মেমরি ম্যানেজ করে।
লিনাক্স কনসোলে Strace কমান্ড দিয়ে সিস্টেম কল মনিটর করার পদ্ধতি
এখন আপনি জানেন সিস্টেম কল ফাংশনগুলো কী, চলুন আপনাকে দেখাই কীভাবে লিনাক্স কমান্ড কনসোল থেকে রিয়েল টাইমে সেগুলো মনিটর করা যায় "strace" কমান্ড ব্যবহার করে। "strace" কমান্ড খুব ফ্লেক্সিবল। এটি সিস্টেম মনিটর করতে ব্যবহৃত হয় এবং অনেক অপশন প্রদান করে যা আপনি নিচের কমান্ড দিয়ে দেখতে পারেন:
যখন আপনি এই কমান্ড রান করবেন, "strace" দ্বারা প্রদত্ত মনিটরিং অপশন들의 তালিকা কমান্ড কনসোলে প্রদর্শিত হবে।

একটি প্রসেসের syscalls মনিটর করতে, আমাদের নিচের কমান্ড দিয়ে রান করতে হবে:
strace ./process
এটি পরীক্ষা করতে, আমরা নিচের কোড কম্পাইল করি যা আমরা "Connect Function in C language" আর্টিকেলে উদাহরণ হিসেবে দিয়েছিলাম। এই কোড, যদিও খুব সিম্পল, খুব আকর্ষণীয় কারণ এটি আমাদের HTTP সার্ভিস দিয়ে গুগল হোস্টের সাথে সংযুক্ত করে এবং কমান্ড পাঠাতে ও রেসপন্স রিসিভ করতে দেয়।
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
int main (){
//step 1
int socket_id ;
int port = 80;
int error;
char buffer [1025];
struct hostent *server;
struct sockaddr_in client;
memset(&server, 0, sizeof(server));
//step 2
server = gethostbyname ( "www.google.com" );
if(server == NULL)
{
printf("\nError getting domain data.\n");
return 1;
}
//step 3
socket_id = socket ( AF_INET, SOCK_STREAM, 0 );
//step 4
client.sin_family = AF_INET;
client.sin_port = htons(port);
//step 5
bcopy((char *) server->h_addr,
(char *) &client.sin_addr.s_addr,
sizeof(server->h_length));
error=connect(socket_id, (struct sockaddr *) &client, sizeof(client));
if (error <0){
printf ("\nCould not establish connection to the server\n");
close( socket_id);
return 1;
}
printf ("\nConnect to : %s\n", inet_ntoa( client.sin_addr ));
while (1){
printf("To exit press Ctrl+c \nSend http command: ");
fgets(buffer, 1025, stdin);
send(socket_id, buffer, 1025, 0);
memset(&buffer, '\0', 1025);
recv(socket_id, buffer, 1025, 0);
printf("%s", buffer);
memset(&buffer, '\0', 1025);
}
}
আমরা কোড কম্পাইল করি এবং এটিকে "connect" আউটপুট নাম দিয়ে। তারপর, এটি "./connect" কমান্ড দিয়ে এক্সিকিউট করি এবং "strace" কমান্ড প্রিপেন্ড করি যাতে syscalls মনিটর করা যায়।
এই কমান্ড প্রসেসের syscalls কমান্ড কনসোলে প্রদর্শন করে। নিচের ছবিতে দেখা যাচ্ছে, যদিও আমাদের কোড শুধু socket(), connect(), send() এবং recv() syscalls ব্যবহার করল, তার এক্সিকিউশন অন্যান্য সিস্টেম কল প্রয়োজন হয় যেগুলো আমাদের ব্যবহৃত ফাংশনগুলোর কোডে ঘটে।

নিচের কমান্ড একটি প্রসেসের সিস্টেম কলের সামারি প্রদর্শন করে যখন এটি টার্মিনেট হয়:

প্রসেস ম্যানেজমেন্টের জন্য সিস্টেম কল ফাংশন:
| Function | Description | Header |
|---|---|---|
| execl() execlp() execle() execv() execvp() execvpe() |
সিস্টেম ফাংশন কলের একটি ফ্যামিলি যা একটি প্রসেসকে অন্য প্রসেস দিয়ে প্রতিস্থাপন করে প্যারেন্ট প্রসেস থেকে PID এবং রিসোর্স ইনহেরিট করে। | unistd.h |
| fork() | একটি প্রসেস ডুপ্লিকেট করে। | unistd.h |
| getpid() | কলিং প্রসেসের PID পায়। | unistd.h |
| getppid() | কলিং প্রসেসের প্যারেন্ট প্রসেসের PID পায়। | unistd.h |
| exit() | একটি প্রসেসের এক্সিট স্ট্যাটাস রিপোর্ট করে। | stdlib.h |
| getcwd() getwd() |
কলিং প্রসেসের বর্তমান ওয়ার্কিং ডিরেক্টরির সাথে একটি স্ট্রিং রিটার্ন করে। | unistd.h |
| pause() | সিগন্যাল আসা পর্যন্ত প্রসেস পজ করে। | unistd.h |
| wait() | প্যারেন্ট প্রসেস থেকে চাইল্ড প্রসেসের আউটপুটের জন্য ওয়েট করে। | wait.h |
ফাইল ম্যানেজমেন্টের জন্য সিস্টেম কল ফাংশন:
| Function | Description | Header |
|---|---|---|
| open() openat() |
ফাইল খোলে। | fcntl.h |
| close() | ফাইল বন্ধ করে। | unistd.h |
| read() | ফাইল পড়ে। | unistd.h |
| poll() | নির্দিষ্ট অপারেশনের জন্য ফাইল উপলব্ধতা পোল করে। | poll.h |
| write() | ফাইলে লেখে। | unistd.h |
| fcntl() | ফাইল ডেসক্রিপ্টর ম্যানিপুলেট করে। | fcntl.h |
| truncate() ftruncate() |
ফাইলকে নির্দিষ্ট দৈর্ঘ্যে ট্রানকেট করে। | unistd.h |
| creat() | ফাইল তৈরি করে। | fcntl.h |
| chmod() fchmod() |
ফাইলের পারমিশন সেট করে। | sys/stat.h |
| unlink() | ফাইল ডিলিট করে। | unistd.h |
সিগন্যাল হ্যান্ডলিং এর জন্য সিস্টেম কল ফাংশন:
| Function | Description | Header |
|---|---|---|
| signal() | একটি সিগন্যালকে হ্যান্ডলারের সাথে লিঙ্ক করে। | signal.h |
| kill() | একটি প্রসেসে সিগন্যাল পাঠায়। | signal.h |
| killpg() | একটি প্রসেস গ্রুপে সিগন্যাল পাঠায়। | signal.h |
| raise() | কলিং প্রসেসে একটি সিগন্যালের অ্যাকশন সম্পাদন করে। | signal.h |
| sigaction() | একটি সিগন্যালের অ্যাকশন সেট করে। | signal.h |
| sigwait() | নির্দিষ্ট সিগন্যাল আসা পর্যন্ত কলিং থ্রেডের এক্সিকিউশন সাসপেন্ড করে। | signal.h |
| sighold() | কলিং প্রসেসের সিগন্যাল মাস্কে সিগন্যাল যোগ করে। | signal.h |
| sigignore() | একটি সিগন্যাল উপেক্ষা করে। | signal.h |
| sigblock() | একটি সিগন্যাল ব্লক করে। | signal.h |
| psignal() psiginfo() |
একটি সিগন্যালের বর্ণনা সহ একটি মেসেজ প্রিন্ট করে। | signal.h |
সোকেট হ্যান্ডলিং এর জন্য সিস্টেম কল ফাংশন:
| Function | Description | Header |
|---|---|---|
| socket() | একটি সোকেট তৈরি করে। | socket.h |
| bind() | একটি সোকেটের সাথে একটি নাম বাইন্ড করে। | socket.h |
| connect() | একটি সোকেট কানেক্ট করে। | socket.h |
| listen() | একটি সোকেটে কানেকশনের জন্য লিসেন করে। | socket.h |
| accept() | একটি সোকেটে কানেকশন একসেপ্ট করে। | socket.h |
| recv() recvfrom() recvmsg() |
একটি সোকেট থেকে মেসেজ রিসিভ করে। | socket.h |
| send() sendto() sendmsg() |
একটি সোকেট থেকে মেসেজ পাঠায়। | socket.h |
| getsockname() | একটি নির্দিষ্ট সোকেটের অ্যাড্রেস এর ডেসক্রিপ্টর দিয়ে রিটার্ন করে। | socket.h |
| getsockopt() | সোকেটে অপশন সেট বা গেট করে। | socket.h |
উপসংহার
এই লিনাক্সহিন্ট আর্টিকেলে, আমরা ব্যাখ্যা করেছি সিস্টেম কল ফাংশনগুলো কী এবং সিস্টেম রিসোর্সের ব্যবহার জড়িত কার্নেল সার্ভিস রিকোয়েস্ট করার জন্য সেগুলো কীভাবে ব্যবহার হয়। আমরা আপনাকে একটি সংক্ষিপ্ত ব্যাখ্যা দিয়েছি ইউজার প্রসেসগুলো কী এবং সেগুলো কীভাবে সিস্টেম কল দিয়ে কার্নেলের সাথে ইন্টারঅ্যাক্ট করে।
আপনাকে এই ফিচারগুলো দ্রুত প্র্যাকটিসে লाने में সাহায্য করার জন্য, আমরা সবচেয়ে সাধারণভাবে ব্যবহৃত সিস্টেম কলের একটি তালিকা এবং সংক্ষিপ্ত বিবরণ ও আপনার কোডে সেগুলো ব্যবহার করার জন্য যে হেডার ইনক্লুড করতে হবে তা অন্তর্ভুক্ত করেছি। আমরা একটি বিভাগও অন্তর্ভুক্ত করেছি যেখানে আমরা আপনাকে দেখিয়েছি কীভাবে কমান্ড কনসোল দিয়ে একটি প্রসেসের syscalls মনিটর করা যায়।