এই পৃষ্ঠায়, আপনি কীভাবে Sandboxed API (SAPI)-এর সাহায্যে নিজের স্যান্ডবক্স করা C/C++ লাইব্রেরি তৈরি করতে হয় তা জানবেন। হেডার ফাইলে দেওয়াউদাহরণ ও কোড ডকুমেন্টেশনের সাথে এটি গাইড হিসেবে ব্যবহার করুন।
ডিপেন্ডেন্সি তৈরি করুন
সিস্টেমে নিম্নলিখিত ডিপেন্ডেন্সি ইনস্টল করা থাকতে হবে:
- UTS, IPC, ব্যবহারকারী, PID ও নেটওয়ার্ক নেমস্পেসের জন্য সহায়তা সহ Linux কার্নেল
- Linux ইউজারস্পেস API হেডার
- আপনার কোড কম্পাইল করতে: GCC 6 (ভার্সন 7 বা তার পরবর্তী ভার্সন হলে ভালো হয়) অথবা Clang 7 (বা তার পরবর্তী ভার্সন)
- হেডার ফাইল অটোমেটিক জেনারেট করার জন্য: Clang Python Bindings
- Python 3.5 বা তার পরবর্তী যেকোনও ভার্সন
- Bazel ভার্সন 2.2.0 বা CMake ভার্সন 3.12 বা তার পরবর্তী যেকোনও ভার্সন।
Bazel ব্যবহার করা
Bazel হল সাজেস্ট করা বিল্ড সিস্টেম এবং এটি ইন্টিগ্রেট করা সবচেয়ে সহজ।
আমাদের ডকুমেন্টেশনে Clang কম্পাইলার ব্যবহার করা হয়। আপনার যদি কোনও নির্দিষ্ট টুলচেন (যেমন, কম্পাইলার, লিঙ্কার ইত্যাদি) প্রয়োজন হয়, তাহলে ডিফল্ট কম্পাইলার টুলচেন কীভাবে পরিবর্তন করতে হয় সেই সম্পর্কে তথ্য পেতে Bazel ডকুমেন্টেশন দেখুন।
Debian 10 (Buster)
বিল্ড ডিপেন্ডেন্সি ইনস্টল করতে:
echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \ sudo tee /etc/apt/sources.list.d/bazel.listwget -qO - https://releases.bazel.build/bazel-release.pub.gpg | sudo apt-key add -sudo apt-get updatesudo apt-get install -qy build-essential linux-libc-dev bazel python3 \ python3-pip libclang-devpip3 install clang
Gentoo
প্রয়োজনীয় কার্নেল বিকল্প:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
বিল্ড ডিপেন্ডেন্সি ইনস্টল করতে:
emerge dev-util/bazel dev-python/typing dev-python/clang-pythonCMake ব্যবহার করা
CMake হল একটি জনপ্রিয় ওপেন-সোর্স মেটা বিল্ড সিস্টেম যা Ninja বা Make-এর মতো বিল্ড টুলের জন্য প্রোজেক্ট ফাইল তৈরি করে।
Debian 10 (Buster)
বিল্ড ডিপেন্ডেন্সি ইনস্টল করতে:
sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \ python3 python3-pip libclang-dev libcap-devpip3 install absl-py clang
Gentoo
প্রয়োজনীয় কার্নেল বিকল্প:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
বিল্ড ডিপেন্ডেন্সি ইনস্টল করতে:
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-pythonডেভেলপমেন্ট প্রসেস
C/C++ লাইব্রেরি স্যান্ডবক্স করতে, আপনাকে প্রোজেক্টের জন্য দুটি আইটেম প্রস্তুত করতে হবে:
- Sandboxed Library
- হোস্ট কোড যা আপনার স্যান্ডবক্স লাইব্রেরির মাধ্যমে প্রকাশ করা ফাংশনালিটি ব্যবহার করবে। SAPI বিল্ড প্রসেস চলাকালীন আপনার জন্য অটোমেটিক SAPI অবজেক্ট এবং RPC স্টাব জেনারেট করবে।
আপনি হয়ত Sandbox2 উদাহরণ থেকে zlib সম্পর্কে জানেন, এখানে একটি সম্পূর্ণ প্রোগ্রাম (zpipe.c) স্যান্ডবক্স করা হয়েছে। নিচের ধাপগুলি থেকে আপনি জানতে পারবেন যে কীভাবে SAPI ব্যবহার করে zlib লাইব্রেরি স্যান্ডবক্স করা যায় এবং স্যান্ডবক্স করা লাইব্রেরি ব্যবহার করা যায়।
১. কোন কোন ফাংশন প্রয়োজন তা নির্ধারণ করা
আপনি যদি zlib হোস্ট কোড
(main_zlib.cc) দেখেন,
তাহলে দেখতে পাবেন যে টুলের কার্যকারিতা হল stdin থেকে ডেটা পড়া এবং
zlib-এর deflate() ফাংশন ব্যবহার করে ডেটা কম্প্রেস করা যতক্ষণ না একটি EOF মার্কার পড়া হয়।
মোট, প্রোগ্রামটি zlib থেকে তিনটি ফাংশন ব্যবহার করে:
deflateInit_(): কম্প্রেশনের জন্য শুরু করতেdeflate(): ডেটা চঙ্কে কম্প্রেশন অপারেশন পারফর্ম করতেdeflateEnd(): কম্প্রেশন শেষ করতে এবং ডাইনামিক্যালি বরাদ্দ করা ডেটা স্ট্রাকচার খালি করতে
বাস্তব জীবনের উদাহরণে, আপনি C/C++ লাইব্রেরি পর্যালোচনা করবেন এবং কোন ফাংশন প্রয়োজন তা নির্ধারণ করবেন। একটি সম্ভাব্য কৌশল হল হোস্ট কোড দিয়ে শুরু করা এবং লাইব্রেরি আনস্যান্ডবক্সড ব্যবহার করা। তারপরে, দ্বিতীয় ধাপে, আপনি স্যান্ডবক্সড লাইব্রেরি তৈরি করতে এবং স্যান্ডবক্সড ফাংশন কল ব্যবহার করার জন্য হোস্ট কোড অ্যাডাপ্ট করতে পারবেন।
২. sapi_library বিল্ড রুল লিখুন
আপনি স্যান্ডবক্স করা zlib লাইব্রেরি থেকে প্রয়োজনীয় তিনটি zlib ফাংশন শনাক্ত করার পরে, BUILD
ফাইলে বিল্ড রুল নির্ধারণ করতে পারবেন। sapi_library বিল্ড রুলের ডকুমেন্টেশন
বিল্ড রুল পৃষ্ঠায় পাওয়া যাবে।
নিচে দেওয়া কোড স্নিপেট zlib SAPI উদাহরণের জন্য sapi_library-এর সংজ্ঞা দেখায়। lib অ্যাট্রিবিউট ব্যবহার করে, Bazel-কে zlib লাইব্রেরির জন্য
WORKSPACE ফাইলে
দেখতে বলা হয়েছে।
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
এর ফলে স্যান্ডবক্স করা zlib লাইব্রেরি তৈরি হয়। আউটপুট হল SAPI অবজেক্ট যা হোস্ট কোডে অন্তর্ভুক্ত করা যেতে পারে এবং RPC কল ব্যবহার করে স্যান্ডবক্সড লাইব্রেরির সাথে যোগাযোগ করতে ব্যবহার করা যেতে পারে।
এই উদাহরণে
DefaultConfig
(sapi::SandboxConfig::DefaultConfig()) দ্বারা প্রদান করা ডিফল্ট স্যান্ডবক্স কনফিগারেশন ব্যবহার করা হয়েছে।
৩. হোস্ট কোড লেখা বা পরিবর্তন করা
এবার হোস্ট কোডে জেনারেট করা SAPI লাইব্রেরি যোগ করার সময় এসেছে।
স্যান্ডবক্স তৈরি করা
sapi::zlib::ZlibSandbox sandbox; ব্যবহার করে
স্যান্ডবক্স অবজেক্ট তৈরি করুন।
SAPI অবজেক্ট ইনস্ট্যানশিয়েট করতে sapi::zlib::ZlibApi api(&sandbox); ব্যবহার করুন এবং এর ফলে
স্যান্ডবক্স করা ফাংশন ব্যবহার করার জন্য উপলভ্য হবে।
স্যান্ডবক্স নীতি, ফ্ল্যাগ, এনভায়রনমেন্ট ভেরিয়েবেল বা সীমা কাস্টমাইজ করতে,
sapi::SandboxConfig::DefaultConfig() থেকে শুরু করুন, প্রাসঙ্গিক ফিল্ড পরিবর্তন করুন (sapi::Sandbox2Config::DefaultPolicyBuilder(),
sapi::SandboxConfig::DefaultFlags() বা
sapi::SandboxConfig::DefaultEnvironmentVariables() ব্যবহার করে যাতে বেসলাইন সেটিংস
সংরক্ষিত থাকে) এবং স্যান্ডবক্স কনস্ট্রাক্টরে sapi::SandboxConfig পাস করুন:
sapi::SandboxConfig config = sapi::SandboxConfig::DefaultConfig();
config.sandbox2.policy = sapi::Sandbox2Config::DefaultPolicyBuilder()
.AddFile("/path/to/file")
.BuildOrDie();
auto flags = sapi::SandboxConfig::DefaultFlags();
flags["my_flag"] = "value";
config.command_line_flags = std::move(flags);
sapi::zlib::ZlibSandbox sandbox(std::move(config));
SAPI-এর ধরন ব্যবহার করুন
SAPI-এর ধরন হল C++ ক্লাসের বিশেষ ধরন যা SAPI প্রদান করে কারণ কখনও কখনও সাধারণ C-এর ধরন কাজ করে না।
strm-এর ঘোষণায় SAPI টাইপের প্রথম ব্যবহার দেখা যায়, যেখানে
একটি SAPI স্ট্রাকচার ব্যবহার করা হয়: sapi::v::Struct<sapi::zlib::z_stream> strm;
বিল্ড রুল দ্বারা অটোমেটিক জেনারেট করা কোডের একটি ভালো উদাহরণ হল
টেমপ্লেটের ধরন (sapi::zlib::z_stream)।
আরও বিবরণের জন্য ভেরিয়েবল পৃষ্ঠা দেখুন।
API কল করা
defalteInit_, deflate অথবা deflateEnd-এর মধ্যে যেকোনও একটিতে কল করতে, SAPI
অবজেক্ট ব্যবহার করুন। আপনি যদি 'পরিবর্তন করুন' পদ্ধতি ব্যবহার করার সিদ্ধান্ত নেন, তাহলে আপনাকে নিশ্চিত করতে হবে যে
ফাংশন প্যারামিটারগুলি প্রত্যাশিত মানের সাথে মিলছে।
zlib example-এ প্রতিটি কলের একটি করে উদাহরণ:
api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION, version.PtrBefore(), sizeof(sapi::zlib::z_stream));
api.deflate(strm.PtrBoth(), flush);
api.deflateEnd(strm.PtrBoth()).IgnoreError();
SAPI ট্রানজ্যাকশন ব্যবহার করা হচ্ছে
SAPI স্যান্ডবক্সড লাইব্রেরি থেকে হোস্ট কোডকে আলাদা করে এবং কলারকে সমস্যাযুক্ত ডেটা প্রসেসিং অনুরোধ রিস্টার্ট বা বাতিল করার ক্ষমতা দেয়। SAPI ট্রানজ্যাকশন আরও এক ধাপ এগিয়ে যায় এবং ব্যর্থ প্রসেস অটোমেটিক রিপিট করে।
আরও বিবরণের জন্য SAPI ট্রানজ্যাকশন পৃষ্ঠা দেখুন।
উদাহরণ
উদাহরণ বিকল্পের মধ্যে আপনি SAPI টিমের তৈরি করা কিছু লাইব্রেরি দেখতে পাবেন।