লিনাক্স এক্সেক সিস্টেম কল

Linux Exec System Call



এক্সিকিউট সিস্টেম কল একটি ফাইল চালানোর জন্য ব্যবহৃত হয় যা একটি সক্রিয় প্রক্রিয়ায় থাকে। যখন exec বলা হয় আগের এক্সিকিউটেবল ফাইলটি প্রতিস্থাপিত হয় এবং নতুন ফাইল এক্সিকিউট হয়।

আরও স্পষ্টভাবে, আমরা বলতে পারি যে এক্সিকিউটিভ সিস্টেম কল ব্যবহার করে প্রক্রিয়া থেকে পুরানো ফাইল বা প্রোগ্রামকে নতুন ফাইল বা প্রোগ্রামের সাথে প্রতিস্থাপন করা হবে। প্রক্রিয়ার সম্পূর্ণ বিষয়বস্তু একটি নতুন প্রোগ্রাম দ্বারা প্রতিস্থাপিত হয়।







ব্যবহারকারীর ডেটা সেগমেন্ট যা এক্সিকিউট () সিস্টেম কল চালায় সেই ডেটা ফাইলের সাথে প্রতিস্থাপিত হয় যার নাম এক্সিকিউট () কল করার সময় যুক্তিতে দেওয়া আছে।



নতুন প্রোগ্রাম একই প্রক্রিয়ায় লোড করা হয়। বর্তমান প্রক্রিয়াটি কেবল একটি নতুন প্রক্রিয়ায় পরিণত হয়েছে এবং সেইজন্য প্রসেস আইডি পিআইডি পরিবর্তন করা হয়নি, এর কারণ হল আমরা একটি নতুন প্রক্রিয়া তৈরি করছি না আমরা একটি প্রক্রিয়ার পরিবর্তে অন্য একটি প্রক্রিয়ার সাথে এক্সিকিউটে প্রতিস্থাপন করছি।



যদি বর্তমানে চলমান প্রক্রিয়াটিতে একাধিক থ্রেড থাকে তবে সমস্ত থ্রেড বন্ধ হয়ে যাবে এবং নতুন প্রক্রিয়া চিত্রটি লোড হবে এবং তারপর কার্যকর করা হবে। এমন কোন ধ্বংসকারী ফাংশন নেই যা বর্তমান প্রক্রিয়ার থ্রেড সমাপ্ত করে।





প্রক্রিয়ার PID পরিবর্তন করা হয় না কিন্তু প্রক্রিয়ার ডাটা, কোড, স্ট্যাক, হিপ ইত্যাদি পরিবর্তন করা হয় এবং নতুন লোড করা প্রক্রিয়ার সাথে প্রতিস্থাপিত হয়। প্রবেশ প্রক্রিয়া থেকে নতুন প্রক্রিয়া সম্পাদন করা হয়।

এক্সিক সিস্টেম কল ফাংশনগুলির একটি সংগ্রহ এবং সি প্রোগ্রামিং ভাষায়, এই ফাংশনগুলির জন্য মানক নামগুলি নিম্নরূপ:



  1. উদাহরণস্বরূপ
  2. execle
  3. execlp
  4. execv
  5. চালানো
  6. execvp


এখানে উল্লেখ করা উচিত যে এই ফাংশনগুলির একই ভিত্তি রয়েছে এক্সিকিউট এর পরে এক বা একাধিক অক্ষর। এগুলি নীচে ব্যাখ্যা করা হয়েছে:

এবং: এটি পয়েন্টারগুলির একটি অ্যারে যা পরিবেশের ভেরিয়েবলের দিকে নির্দেশ করে এবং স্পষ্টভাবে নতুন লোড করা প্রক্রিয়ায় প্রেরণ করা হয়।

দ্য: l কমান্ড লাইন আর্গুমেন্টের জন্য ফাংশনে একটি তালিকা পাস করেছে

p: p হল পাথ এনভায়রনমেন্ট ভেরিয়েবল যা প্রসেসে লোড হওয়ার জন্য যুক্তি হিসেবে পাস করা ফাইলটি খুঁজে পেতে সাহায্য করে।

v: v কমান্ড লাইন আর্গুমেন্টের জন্য। এইগুলি ফাংশনের পয়েন্টারগুলির একটি অ্যারে হিসাবে পাস করা হয়।

কেন exec ব্যবহার করা হয়?

exec ব্যবহার করা হয় যখন ব্যবহারকারী একই প্রক্রিয়ায় একটি নতুন ফাইল বা প্রোগ্রাম চালু করতে চায়।

এক্সিকিউটের অভ্যন্তরীণ কাজ

এক্সিকিউটের কাজ বুঝতে নিম্নলিখিত বিষয়গুলি বিবেচনা করুন:

  1. বর্তমান প্রসেস ইমেজ একটি নতুন প্রসেস ইমেজ দিয়ে ওভাররাইট করা হয়।
  2. এক্সিকিউটিভ আর্গুমেন্ট হিসাবে আপনি যেটি পাস করেছেন তা হল নতুন প্রসেস ইমেজ
  3. বর্তমানে চলমান প্রক্রিয়া শেষ
  4. নতুন প্রসেস ইমেজে একই প্রসেস আইডি, একই পরিবেশ এবং একই ফাইল ডেস্ক্রিপ্টর আছে (কারণ প্রসেস প্রতিস্থাপিত হয় না প্রসেস ইমেজ প্রতিস্থাপিত হয়)
  5. CPU স্ট্যাট এবং ভার্চুয়াল মেমরি প্রভাবিত হয়। বর্তমান প্রসেস ইমেজের ভার্চুয়াল মেমরি ম্যাপিং নতুন প্রসেস ইমেজের ভার্চুয়াল মেমরি দ্বারা প্রতিস্থাপিত হয়।

এক্সিকিউটিভ ফ্যামিলি ফাংশনের সিনট্যাক্স:

এক্সিকিউটের প্রতিটি ফাংশনের জন্য সিনট্যাক্স নিম্নরূপ:

int execl (const char* path, const char* arg,…)
int execlp (const char* file, const char* arg,…)
int execle (const char* path, const char* arg,…, char* const envp [])
int execv (const char* path, const char* argv [])
int execvp (const char* file, const char* argv [])
int execvpe (const char* file, const char* argv [], char* const envp [])

বর্ণনা:

এই ফাংশনগুলির রিটার্ন টাইপ হল Int। যখন প্রক্রিয়া চিত্রটি সফলভাবে প্রতিস্থাপিত হয় তখন কলিং ফাংশনে কিছুই ফেরত দেওয়া হয় না কারণ যে প্রক্রিয়াটি এটিকে বলা হয় তা আর চলছে না। কিন্তু যদি কোন ত্রুটি থাকে -1 ফেরত দেওয়া হবে। যদি কোন ত্রুটি ঘটে থাকে a ভুল সেট করা হয়

সিনট্যাক্সে:

  1. পথ যে ফাইলটি চালানো হবে তার সম্পূর্ণ পাথের নাম উল্লেখ করতে ব্যবহৃত হয়।
  1. রাগী যুক্তি পাস হয়েছে এটি আসলে সেই ফাইলের নাম যা প্রক্রিয়াটিতে কার্যকর করা হবে। বেশিরভাগ সময় আর্গ এবং পাথের মান একই।
  1. const char* arg ফাংশনে execl (), execlp () এবং execle () arg0, arg1, arg2,…, argn হিসাবে বিবেচিত হয়। এটি মূলত নিষ্ক্রিয় স্ট্রিংগুলির পয়েন্টারগুলির একটি তালিকা। এখানে প্রথম যুক্তি ফাইলের নাম নির্দেশ করে যা বিন্দু 2 এ বর্ণিত হিসাবে কার্যকর করা হবে।
  1. envp একটি অ্যারে যা পয়েন্টার ধারণ করে যা পরিবেশের ভেরিয়েবলগুলিকে নির্দেশ করে।
  1. ফাইল পাথের নাম নির্দিষ্ট করতে ব্যবহৃত হয় যা নতুন প্রসেস ইমেজ ফাইলের পথ চিহ্নিত করবে।
  1. Exec কল এর ফাংশন যা দিয়ে শেষ হয় এবং নতুন প্রক্রিয়া চিত্রের জন্য পরিবেশ পরিবর্তন করতে ব্যবহৃত হয়। এই ফাংশন যুক্তি ব্যবহার করে পরিবেশ সেটিং তালিকা পাস envp । এই যুক্তিটি অক্ষরগুলির একটি অ্যারে যা নল সমাপ্ত স্ট্রিংকে নির্দেশ করে এবং পরিবেশ পরিবর্তনশীলকে সংজ্ঞায়িত করে।

এক্সিকিউটিভ ফ্যামিলি ফাংশন ব্যবহার করতে, আপনাকে আপনার সি প্রোগ্রামে নিম্নলিখিত হেডার ফাইলটি অন্তর্ভুক্ত করতে হবে:

#অন্তর্ভুক্ত

উদাহরণ 1: সি প্রোগ্রামে এক্সিকিউট সিস্টেম কল ব্যবহার করা

নিচের উদাহরণটি বিবেচনা করুন যেখানে আমরা লিনাক্স, উবুন্টুতে সি প্রোগ্রামিং এ এক্সিকিউটিভ সিস্টেম কল ব্যবহার করেছি: আমাদের এখানে দুটি সি ফাইল আছে example.c এবং hello.c:

উদাহরণ

কোড:

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
intপ্রধান(intargc, গৃহস্থালি *argv[])
{
printf ('Example.c = %d এর PIDn',getpid());
গৃহস্থালি *যুক্তি[] = {'হ্যালো', 'সি', 'প্রোগ্রামিং',খালি};
execv('./হ্যালো',যুক্তি);
printf ('Example.c' এ ফিরে যান);
প্রত্যাবর্তন 0;
}

hello.c

কোড:

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
intপ্রধান(intargc, গৃহস্থালি *argv[])
{
printf (আমরা Hello.c এ আছিn');
printf ('Hello.c = %d এর PIDn',getpid());
প্রত্যাবর্তন 0;
}

আউটপুট:

Example.c = 4733 এর PID
আমরা Hello.c এ আছি
Hello.c = 4733 এর PID

উপরের উদাহরণে আমাদের একটি example.c ফাইল এবং hello.c ফাইল আছে। .C ফাইলের উদাহরণে প্রথমে আমরা বর্তমান প্রক্রিয়ার আইডি প্রিন্ট করেছি (ফাইল example.c বর্তমান প্রক্রিয়ায় চলছে)। তারপর পরবর্তী লাইনে আমরা অক্ষর পয়েন্টারগুলির একটি অ্যারে তৈরি করেছি। এই অ্যারের শেষ উপাদানটি শেষ বিন্দু হিসাবে শূন্য হওয়া উচিত।

তারপর আমরা ফাংশন execv () ব্যবহার করেছি যা ফাইলের নাম এবং অক্ষর পয়েন্টার অ্যারেকে তার যুক্তি হিসেবে নেয়। এখানে উল্লেখ করা উচিত যে আমরা ./ ফাইলের নামের সাথে ব্যবহার করেছি, এটি ফাইলের পথ নির্দিষ্ট করে। যেহেতু ফাইলটি সেই ফোল্ডারে আছে যেখানে example.c থাকে তাই সম্পূর্ণ পথ নির্দিষ্ট করার প্রয়োজন নেই।

যখন execv () ফাংশন বলা হয়, তখন আমাদের প্রসেস ইমেজ প্রতিস্থাপিত হবে এখন ফাইল example.c প্রক্রিয়ায় নেই কিন্তু hello.c ফাইলটি প্রক্রিয়াধীন। এটা দেখা যায় যে প্রসেস আইডি একই কিনা হ্যালো.সি প্রসেস ইমেজ বা উদাহরণ সি।প্রক্রিয়া ইমেজ কারণ প্রক্রিয়া একই এবং প্রক্রিয়া ইমেজ শুধুমাত্র প্রতিস্থাপিত হয়।

তারপরে আমাদের এখানে আরেকটি বিষয় লক্ষ্য করতে হবে যা হল execv () কার্যকর হওয়ার পরে printf () স্টেটমেন্ট। এর কারণ হল, নতুন প্রক্রিয়ার ইমেজ প্রতিস্থাপন করার পর নিয়ন্ত্রণ কখনও পুরানো প্রসেস ইমেজে ফিরে আসে না। কন্ট্রোল শুধুমাত্র কলিং ফাংশনে ফিরে আসে যখন প্রক্রিয়া ইমেজ প্রতিস্থাপন অসফল হয়। (রিটার্ন মান এই ক্ষেত্রে -1)।

ফর্ক () এবং exec () সিস্টেম কলগুলির মধ্যে পার্থক্য:

ফর্ক () সিস্টেম কল একটি চলমান প্রক্রিয়ার সঠিক কপি তৈরি করতে ব্যবহৃত হয় এবং তৈরি করা কপিটি শিশু প্রক্রিয়া এবং চলমান প্রক্রিয়াটি মূল প্রক্রিয়া। যেখানে, এক্সিকিউট () সিস্টেম কলটি একটি প্রসেস ইমেজকে একটি নতুন প্রসেস ইমেজের সাথে প্রতিস্থাপন করতে ব্যবহৃত হয়। অতএব এক্সিকিউটিভ (এবং) সিস্টেম কলের মধ্যে পিতামাতা এবং শিশু প্রক্রিয়ার কোন ধারণা নেই।

ফর্ক () সিস্টেমে পিতামাতার কল এবং শিশু প্রক্রিয়াগুলি একই সময়ে কার্যকর করা হয়। কিন্তু এক্সিকিউট () সিস্টেম কলে, যদি প্রসেস ইমেজের প্রতিস্থাপন সফল হয়, তাহলে কন্ট্রোল যেখানে এক্সিকিউশন ফাংশন বলা হয়েছিল সেখানে ফিরে আসে না বরং এটি নতুন প্রক্রিয়াটি চালাবে। কোনো ত্রুটি হলেই নিয়ন্ত্রণটি ফেরত পাঠানো হবে।

উদাহরণ 2: ফর্ক () এবং এক্সিকিউট () সিস্টেম কলগুলির সমন্বয়

নিম্নলিখিত উদাহরণটি বিবেচনা করুন যেখানে আমরা একই প্রোগ্রামে ফর্ক () এবং এক্সিকিউট () উভয় সিস্টেম কল ব্যবহার করেছি:

উদাহরণ

কোড:

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
intপ্রধান(intargc, গৃহস্থালি *argv[])
{
printf ('Example.c = %d এর PIDn',getpid());
pid_t p;
পৃ=কাঁটা();
যদি(পৃ== -)
{
printf ('ফর্ক () কল করার সময় একটি ত্রুটি আছে');
}
যদি(পৃ==0)
{
printf ('আমরা শিশু প্রক্রিয়ায় আছিn');
printf (শিশু প্রক্রিয়া থেকে hello.c কল করাn');
গৃহস্থালি *যুক্তি[] = {'হ্যালো', 'সি', 'প্রোগ্রামিং',খালি};
execv('./হ্যালো',যুক্তি);
}
অন্য
{
printf ('আমরা মূল প্রক্রিয়াতে আছি');
}
প্রত্যাবর্তন 0;
}

hello.c:

কোড:

#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
#অন্তর্ভুক্ত
intপ্রধান(intargc, গৃহস্থালি *argv[])
{
printf (আমরা Hello.c এ আছিn');
printf ('Hello.c = %d এর PIDn',getpid());
প্রত্যাবর্তন 0;
}

আউটপুট:

Example.c = 4790 এর PID
আমরা প্যারেন্ট প্রসেসে আছি
আমরা শিশু প্রক্রিয়ায় আছি
শিশু প্রক্রিয়া থেকে hello.c কল করা
আমরা hello.c এ আছি
Hello.c = 4791 এর PID

এই উদাহরণে আমরা ফর্ক () সিস্টেম কল ব্যবহার করেছি। যখন শিশু প্রক্রিয়াটি তৈরি করা হবে তখন 0 কে p তে বরাদ্দ করা হবে এবং তারপর আমরা শিশু প্রক্রিয়ায় চলে যাব। এখন if (p == 0) দিয়ে স্টেটমেন্টের ব্লক কার্যকর করা হবে। একটি বার্তা প্রদর্শিত হয় এবং আমরা execv () সিস্টেম কল এবং বর্তমান চাইল্ড প্রসেস ইমেজ ব্যবহার করেছি যা example.c- কে hello.c দিয়ে প্রতিস্থাপন করা হবে। Execv () কল করার আগে শিশু এবং পিতামাতার প্রক্রিয়া একই ছিল।

এটা দেখা যায় যে example.c এবং hello.c এর PID এখন ভিন্ন। এর কারণ হল example.c হল প্যারেন্ট প্রসেস ইমেজ এবং hello.c হল চাইল্ড প্রসেস ইমেজ।