क्या सी में फ़ाइल डिस्क्रिप्टर (लिनक्स) का फ़ाइल नाम प्राप्त करना संभव है?
क्या सी में फ़ाइल डिस्क्रिप्टर (लिनक्स) का फ़ाइल नाम प्राप्त करना संभव है?
जवाबों:
आप उपयोग कर सकते हैं readlink
पर /proc/self/fd/NNN
जहां NNN फ़ाइल जानकारी देता है। यह आपको फ़ाइल का नाम देगा जैसा कि इसे खोला गया था - हालांकि, यदि फ़ाइल को तब से स्थानांतरित या हटा दिया गया था, तो यह अब सटीक नहीं हो सकता है (हालांकि लिनक्स कुछ मामलों में नाम बदल सकता है)। सत्यापित करने के लिए, आपके द्वारा stat
दिया गया फ़ाइल नाम और fstat
fd, और सुनिश्चित करें st_dev
और st_ino
समान हैं।
बेशक, सभी फाइल डिस्क्रिप्टर फाइलों को संदर्भित नहीं करते हैं, और उन लोगों के लिए जिन्हें आप कुछ अजीब पाठ स्ट्रिंग देखेंगे, जैसे कि pipe:[1538488]
। चूंकि सभी वास्तविक फ़ाइलनाम पूर्ण पथ होंगे, आप यह निर्धारित कर सकते हैं कि ये आसानी से पर्याप्त हैं। इसके अलावा, जैसा कि अन्य ने नोट किया है, फाइलों में कई हार्डलिंक हैं जो उन्हें इंगित कर सकते हैं - यह केवल उसी के बारे में रिपोर्ट करेगा जिसे इसके साथ खोला गया था। यदि आप किसी दिए गए फ़ाइल के लिए सभी नाम ढूंढना चाहते हैं, तो आपको बस संपूर्ण फाइल सिस्टम को पार करना होगा।
fd
ऐसा संदर्भ होगा), इनोड संख्या का पुन: उपयोग नहीं किया जा सकता है। फ़ाइल बंद करने के बाद या इसे खोलने से पहले इनोड नंबर का उपयोग करने वाला कोई भी सॉफ्टवेयर स्वाभाविक रूप से दौड़ की स्थिति के अधीन है।
setuid()
ट्रिक्स करते हैं , तो /proc/self/fd
आपकी प्रक्रिया द्वारा सुलभ नहीं होना संभव है। देखें: permalink.gmane.org/gmane.linux.kernel/1302546
मुझे मैक ओएस एक्स पर यह समस्या थी। हमारे पास /proc
वर्चुअल फ़ाइल सिस्टम नहीं है, इसलिए स्वीकृत समाधान काम नहीं कर सकता है।
हम, इसके बजाय, के लिए एक F_GETPATH
आदेश है fcntl
:
F_GETPATH Get the path of the file descriptor Fildes. The argu-
ment must be a buffer of size MAXPATHLEN or greater.
तो फाइल डिस्क्रिप्टर से जुड़ी फाइल पाने के लिए, आप इस स्निपेट का उपयोग कर सकते हैं:
#include <sys/syslimits.h>
#include <fcntl.h>
char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
// do something with the file path
}
चूंकि मुझे कभी याद नहीं है कि कहां MAXPATHLEN
परिभाषित किया गया है, मैंने सोचा कि PATH_MAX
सिस्लीमिट्स से ठीक हो जाएगा।
getsockname
।
Windows में, GetFileInformationByHandleEx के साथ , FileNameInfo से गुजरते हुए , आप फ़ाइल का नाम पुनः प्राप्त कर सकते हैं।
जैसा कि टायलर बताते हैं, ऐसा करने का कोई तरीका नहीं है जिसे आपको "सीधे और मज़बूती से" की आवश्यकता है, क्योंकि किसी दिए गए एफडी में 0 फ़ाइल नाम (विभिन्न मामलों में) या> 1 (कई "हार्ड लिंक" के अनुरूप हो सकते हैं कि बाद की स्थिति आम तौर पर कैसे वर्णित है। )। यदि आपको अभी भी सभी सीमाओं के साथ कार्यक्षमता की आवश्यकता है (गति पर और 0, 2, ... 1 के बजाय परिणाम प्राप्त करने की संभावना पर), तो यहां बताया गया है कि आप यह कैसे कर सकते हैं: पहला, एफडीएस एफडी - यह आपको बताता है परिणाम मेंstruct stat
, फ़ाइल किस डिवाइस पर रहती है, उसके पास कितने हार्ड लिंक हैं, क्या यह एक विशेष फ़ाइल है, आदि। यह पहले से ही आपके प्रश्न का उत्तर दे सकता है - उदाहरण के लिए यदि 0 हार्ड लिंक आप जानते हैं कि वास्तव में कोई संगत फ़ाइल नाम नहीं है डिस्क पर।
यदि आंकड़े आपको आशा देते हैं, तो आपको प्रासंगिक डिवाइस पर निर्देशिकाओं के "पेड़ को चलना" पड़ता है जब तक कि आपको सभी हार्ड लिंक नहीं मिलते (या बस पहले एक, यदि आपको एक से अधिक की आवश्यकता नहीं है और कोई भी करेगा )। उस उद्देश्य के लिए, आप का उपयोग readdir (और opendir और निश्चित रूप से ग) रिकर्सिवली उपनिर्देशिका खोलने जब तक आप एक में मिल struct dirent
इस प्रकार प्राप्त एक ही आइनोड संख्या आप मूल में थाstruct stat
(उस समय आपके पास पूरे रास्ते चाहते हैं, बल्कि सिर्फ नाम से, आपको इसे फिर से बनाने के लिए निर्देशिकाओं की श्रृंखला को पीछे की ओर चलना होगा)।
यदि यह सामान्य दृष्टिकोण स्वीकार्य है, लेकिन आपको अधिक विस्तृत सी कोड की आवश्यकता है, तो हमें बताएं, यह लिखना कठिन नहीं होगा (हालांकि मैं इसे बेकार नहीं होने पर नहीं लिखूंगा, अर्थात आप अनिवार्य रूप से धीमा प्रदर्शन या सामना नहीं कर सकते हैं अपने आवेदन के प्रयोजनों के लिए होने की संभावना! = 1 परिणाम ;-)।
यह असंभव के रूप में लिखने से पहले मैं आपको lsof कमांड के स्रोत कोड को देखने का सुझाव देता हूं ।
प्रतिबंध हो सकते हैं लेकिन फ़ाइल डिस्क्रिप्टर और फ़ाइल नाम का निर्धारण करने में lsof सक्षम लगता है। यह जानकारी / proc फाइल सिस्टम में मौजूद है, इसलिए इसे आपके प्रोग्राम से प्राप्त करना संभव है।
आप स्टैटिक स्टेटमेंट द्वारा फाइल के इनकोड को प्राप्त करने के लिए fstat () का उपयोग कर सकते हैं। फिर, रीडडायर () का उपयोग करके आप उन लोगों के साथ मिले इनोड की तुलना कर सकते हैं जो एक निर्देशिका में मौजूद हैं (स्ट्रक्चर डाइरेंट) (यह मानते हुए कि आप डायरेक्टरी को जानते हैं, अन्यथा आपको पूरा फाइल सिस्टम खोजना होगा) और संबंधित फाइल का नाम ढूंढना होगा। बुरा?
असंभव। फ़ाइल डिस्क्रिप्टर में फ़ाइल सिस्टम में कई नाम हो सकते हैं, या इसमें कोई नाम नहीं हो सकता है।
संपादित करें: मान लें कि आप एक सादे पुराने POSIX सिस्टम के बारे में बात कर रहे हैं, बिना किसी OS- विशिष्ट API के, क्योंकि आपने OS निर्दिष्ट नहीं किया था।