পুরানো আরএইচইএল সিস্টেমে আমি পেয়েছি, লুপ /bin/cat
হয় নাcat x >> x
। cat
"বিড়াল: এক্স: ইনপুট ফাইল আউটপুট ফাইল" ত্রুটি বার্তা দেয়। আমি মূর্খ করতে /bin/cat
এই করে: cat < x >> x
। আমি যখন আপনার কোডটি উপরে চেষ্টা করি তখন আমি আপনার বর্ণিত "লুপিং" পাই। আমি "ক্যাট" ভিত্তিক একটি সিস্টেম কলও লিখেছিলাম:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int
main(int ac, char **av)
{
char buf[4906];
int fd, cc;
fd = open(av[1], O_RDONLY);
while ((cc = read(fd, buf, sizeof(buf))) > 0)
if (cc > 0) write(1, buf, cc);
close(fd);
return 0;
}
এই loops, খুব। এখানে কেবলমাত্র বাফারিং (স্ট্ডিও-ভিত্তিক "মাইকাট" এর বিপরীতে) কার্নেলের মধ্যে যা চলছে।
আমার মনে হয় যা ঘটছে তা ফাইল ডেস্ক্রিপ্টর 3 (এর ফলাফল open(av[1])
) এর 0 টি ফাইলের মধ্যে একটি অফসেট রয়েছে ফাইলড বর্ণনাকারী 1 (স্টাডাউট) এর 3 টি অফসেট রয়েছে কারণ ">>" "ইনভোকিং শেলটি একটি lseek()
করে cat
শিশু প্রক্রিয়াটি হস্তান্তর করার পূর্বে বর্ণনাকারী ফাইল করুন ।
একটি এরকম read()
কিনা একটি stdio বাফারের মধ্যে বা কোন ধরণের, একটি প্লেইন char buf[]
অগ্রগতি ফাইল বর্ননাকারী 3. একটা করছেন অবস্থানে write()
অগ্রগতি ফাইল বর্ননাকারী 1. অবস্থান ঐ দুটি অফসেট বিভিন্ন নম্বর আছে। ">>" এর কারণে, ফাইল বর্ণনাকারী 1 এর সবসময় ফাইল ডেস্ক্রিপ্টরের অফসেটের চেয়ে বড় বা সমান একটি অফসেট থাকে So সুতরাং কোনও "বিড়ালের মতো" প্রোগ্রাম লুপ হয়ে যাবে, যদি না এটি কিছু অভ্যন্তরীণ বাফারিং করে। এটা সম্ভব, এমনকি সম্ভবত একটি একটি stdio বাস্তবায়ন FILE *
(যা চিহ্ন ধরনের stdout
এবং f
যা নিজের বাফার এতে আপনার কোডে)। অভ্যন্তরীণ বাফার ফো পূরণ fread()
করার read()
জন্য একটি সিস্টেম কল আসলেই করতে পারে f
। এটি অভ্যন্তরের অভ্যন্তরে কোনও কিছু পরিবর্তন করতে পারে বা নাও পারে stdout
। কলিং fwrite()
উপরstdout
এর ভিতরে কিছু পরিবর্তন করতে পারে বা নাও পারে f
। সুতরাং একটি স্টিডিও-ভিত্তিক "বিড়াল" লুপ নাও পারে। বা এটি হতে পারে। অনেক কুৎসিত, কুরুচিপূর্ণ লিবিসি কোড না পড়েই বলা শক্ত।
আমি strace
আরএইচইএল cat
- তে একটি করেছি - এটি কেবল উত্তরসূরি read()
এবং write()
সিস্টেম কলগুলি করে। কিন্তু একটি cat
এইভাবে কাজ করতে হবে না। mmap()
ইনপুট ফাইলটিতে এটি সম্ভব হবে, তারপরেও write(1, mapped_address, input_file_size)
। কার্নেলটি সমস্ত কাজ করত। অথবা আপনি sendfile()
লিনাক্স সিস্টেমে ইনপুট এবং আউটপুট ফাইল বর্ণনাকারীদের মধ্যে একটি সিস্টেম কল করতে পারেন । পুরানো সানোস 4.x সিস্টেমগুলি মেমরি ম্যাপিং ট্রিকটি করার জন্য গুজব রইল, তবে আমি জানি না যে কেউ কখনও সেন্ডফিল-ভিত্তিক বিড়ালটি করেছে কিনা। উভয় ক্ষেত্রেই "লুপিং" ঘটবে না, উভয় হিসাবে write()
এবং sendfile()
একটি দৈর্ঘ্য-থেকে-স্থানান্তর প্যারামিটার প্রয়োজন।