c सी में फाइल डिस्क्रिप्टर से फ़ाइल नाम प्राप्त करना




linux (6)

Windows में, GetFileInformationByHandleEx साथ, FileNameInfo पास करने के साथ, आप फ़ाइल नाम पुनर्प्राप्त कर सकते हैं।

क्या सी में फाइल डिस्क्रिप्टर (लिनक्स) का फ़ाइल नाम प्राप्त करना संभव है?


इसे असंभव के रूप में लिखने से पहले मुझे सुझाव है कि आप lsof कमांड के स्रोत कोड को देखें।

प्रतिबंध हो सकते हैं लेकिन lsof फ़ाइल डिस्क्रिप्टर और फ़ाइल नाम निर्धारित करने में सक्षम लगता है। यह जानकारी / proc फाइल सिस्टम में मौजूद है, इसलिए आपके प्रोग्राम से प्राप्त करना संभव होना चाहिए।


जैसा कि टायलर बताते हैं, आपको "सीधे और भरोसेमंद" की आवश्यकता होती है, ऐसा करने का कोई तरीका नहीं है, क्योंकि दिया गया एफडी 0 फाइलनामों (विभिन्न मामलों में) या> 1 (एकाधिक "हार्ड लिंक" के अनुरूप हो सकता है कि बाद की स्थिति का वर्णन आमतौर पर किया जाता है )। यदि आपको अभी भी सभी सीमाओं (गति पर और 0, 2, ... के बजाय परिणाम प्राप्त करने की संभावना पर) की आवश्यकता है, तो यहां आप यह कैसे कर सकते हैं: सबसे पहले, एफडी को fstat - यह आपको बताता है , परिणामस्वरूप struct stat , फ़ाइल किस डिवाइस पर रहती है, कितनी मुश्किल लिंक है, चाहे वह एक विशेष फ़ाइल हो, आदि। यह आपके प्रश्न का उत्तर दे सकता है - उदाहरण के लिए यदि 0 हार्ड लिंक आपको पता चलेगा तो वास्तव में कोई नहीं है डिस्क पर संबंधित फ़ाइल नाम।

यदि आंकड़े आपको आशा देते हैं, तो आपको प्रासंगिक डिवाइस पर निर्देशिकाओं के "पेड़ पर चलना" होगा जब तक आपको सभी हार्ड लिंक नहीं मिलते (या केवल पहले, यदि आपको एक से अधिक की आवश्यकता नहीं है और कोई भी करेगा )। उस उद्देश्य के लिए, आप रीडडियर (और ऑपेन्डर और सी पाठ्यक्रम) को उपरोक्त रूप से उपनिर्देशिका खोलने तक उपयोग करते हैं जब तक कि आपको struct dirent में कोई struct dirent इस प्रकार मूल struct stat में आपके पास एक ही struct dirent नंबर प्राप्त होता है (उस समय यदि आप पूरा पथ चाहते हैं, सिर्फ नाम, आपको इसे पुनर्निर्माण के लिए निर्देशिकाओं की श्रृंखला को पीछे की ओर चलने की आवश्यकता होगी)।

यदि यह सामान्य दृष्टिकोण स्वीकार्य है, लेकिन आपको अधिक विस्तृत सी कोड की आवश्यकता है, तो हमें बताएं, लिखना मुश्किल नहीं होगा (हालांकि मैं इसे बेकार नहीं होने पर लिखूंगा, यानी आप अनिवार्य रूप से धीमी प्रदर्शन का सामना नहीं कर सकते हैं या प्राप्त करने की संभावना! = 1 परिणाम आपके आवेदन के प्रयोजनों के लिए ;-)।


असंभव। फ़ाइल डिस्क्रिप्टर में फाइल सिस्टम में एकाधिक नाम हो सकते हैं, या इसका कोई नाम नहीं हो सकता है।

संपादित करें: मान लें कि आप एक ओएस-विशिष्ट एपीआई के बिना, एक सादे पुराने POSIX सिस्टम के बारे में बात कर रहे हैं, क्योंकि आपने ओएस निर्दिष्ट नहीं किया है।


आप /proc/self/fd/NNN पर readlink उपयोग कर सकते हैं जहां एनएनएन फाइल डिस्क्रिप्टर है। यह आपको फ़ाइल का नाम देगा क्योंकि यह खोला गया था - हालांकि, अगर फ़ाइल तब से स्थानांतरित या हटा दी गई थी, तो यह अब सटीक नहीं हो सकती है (हालांकि लिनक्स कुछ मामलों में नामों को ट्रैक कर सकता है)। सत्यापित करने के लिए, दिए गए फ़ाइल नाम को stat करें और आपके पास st_dev करें, और सुनिश्चित करें कि st_dev और st_ino समान हैं।

बेशक, सभी फाइल डिस्क्रिप्टर फाइलों को संदर्भित नहीं करते हैं, और उन लोगों के लिए आपको pipe:[1538488] जैसे कुछ विषम टेक्स्ट स्ट्रिंग दिखाई देंगे pipe:[1538488] । चूंकि सभी वास्तविक फ़ाइल नाम पूर्ण पथ होंगे, आप यह निर्धारित कर सकते हैं कि ये आसानी से पर्याप्त हैं। इसके अलावा, जैसा कि अन्य ने ध्यान दिया है, फाइलों को इंगित करने वाले कई हार्डलिंक्स हो सकते हैं - यह केवल उस व्यक्ति की रिपोर्ट करेगा जो इसे खोला गया था। यदि आप किसी दिए गए फ़ाइल के लिए सभी नाम ढूंढना चाहते हैं, तो आपको केवल संपूर्ण फाइल सिस्टम को पार करना होगा।


मैक ओएस एक्स पर मुझे यह समस्या थी। हमारे पास एक /proc वर्चुअल फ़ाइल सिस्टम नहीं है, इसलिए स्वीकृत समाधान काम नहीं कर सकता है।

हम करते हैं, इसके बजाय, fcntl लिए एक F_GETPATH कमांड है:

 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 से PATH_MAX ठीक होगा।





linux