2012-12-13 20 views
8

प्रश्न Getting Filename from file descriptor in C का एक संस्करण। यह लिनक्स के बारे में है।फ़ाइल डिस्क्रिप्टर से नाम बदलें?

यदि मेरे पास एक फ़ाइल डिस्क्रिप्टर है जो एक नियमित फ़ाइल को संदर्भित करता है, तो क्या मैं फ़ाइल डिस्क्रिप्टर को एक नया फ़ाइल नाम देकर "सहेज सकता हूं" (कहीं भी उसी डिवाइस पर जहां यह रहता है)? मैं नाम (2) या लिंक (2) के समान कुछ ढूंढ रहा हूं लेकिन यह फ़ाइल नाम के बजाय फ़ाइल डिस्क्रिप्टर इनपुट के रूप में स्वीकार करेगा।

नाम (2) और लिंक (2) के साथ समस्या यह है कि भले ही आप फ़ाइल अवरोधक से फ़ाइल नाम पर जाने का प्रयास कर सकते हैं, यह असफल हो सकता है। मैं उस मामले के बारे में अधिक सटीक सोच रहा हूं जहां खोला गया फ़ाइल डिस्क्रिप्टर एक फ़ाइल को संदर्भित करता है जो पहले से ही अनलिंक था --- इस मामले में, फ़ाइल का कोई और नाम नहीं है। ऐसा लगता है कि फ़ाइल डिस्क्रिप्टर को बंद करते समय फ़ाइल को हटाने से रोकने का कोई तरीका नहीं है। लेकिन क्या मैं गलत हूँ? क्या हम पॉज़िक्स या यहां तक ​​कि लिनक्स एपीआई के साथ भी इसे एक नाम दे सकते हैं?

अद्यतन: हम वास्तव में /proc/<pid>/fd/<fd> में लिनक्स पर एक हटाई गई फ़ाइल की सामग्री देख सकते हैं, भले ही यह एक टूटी प्रतीकात्मक लिंक की तरह दिखता हो। हम ऐसी फ़ाइल को रीमटेरियलाइज़ करने के लिए लिंक (2) या एलएन (1) का उपयोग नहीं कर सकते हैं, हालांकि, ऐसा लगता है कि हम एक क्रॉस-डिवाइस लिंक करने की कोशिश कर रहे हैं।

+0

लेकिन आप सामग्री को fd/ फ़ाइल से कॉपी कर सकते हैं। मूर्खतापूर्ण है कि आप इसे फिर से नहीं जोड़ सकते हैं। –

+1

यहां अच्छे उत्तर के साथ अनिवार्य रूप से एक ही प्रश्न: http://stackoverflow.com/q/4171713/4421 – pixelbeat

उत्तर

3

यदि प्रश्न लिनक्स के बारे में है, और लिनक्स> 2.6.39 के बारे में है, तो आप linkat कमांड को AT_EMPTY_PATH ध्वज फ़ाइल डिस्क्रिप्टर को नाम देने के लिए उपयोग कर सकते हैं। आदमी पेज (http://man7.org/linux/man-pages/man2/link.2.html)

linkat(fd,"",destdirfd,"filename",AT_EMPTY_PATH); 

चेतावनियां देखें:

  • आप AT_EMPTY_PATH के लिए परिभाषा प्राप्त करने _GNU_SOURCE परिभाषित करने की जरूरत,
  • शून्य इस का लिंक गिनती के साथ फ़ाइलों के लिए काम करने के लिए गारंटी नहीं है । मुझे यकीन नहीं है कि मैं समझता हूं कि मैनुअल पेज इसके बारे में क्या कहता है। मेरा अनुमान है कि जब फ़ाइल में शून्य लिंक गिनती है तो फाइल सिस्टम पर इनोड को पहले ही हटा दिया गया है, अगर फाइल सिस्टम क्रैश हो तो असंगतता से बचने के लिए।
  • बेशक मुझे यह काम करने की उम्मीद नहीं है अगर पुरानी फ़ाइल लक्ष्य निर्देशिका पर एक ही फाइल सिस्टम पर नहीं है।

इस विफल हो तो आप कोई अन्य मौका एक नई फ़ाइल बनाना से करने के लिए और यह sendfile का उपयोग करने पर सामग्री की प्रतिलिपि (त्रुटि लोप जाँच, देखना संभव त्रुटि मूल्यों के लिए प्रत्येक कार्य के आदमी पृष्ठों) है:

struct stat s; 
off_t offset = 0; 
int targetfd = open("target/filename", O_WRONLY | O_CREAT | O_EXCL); 
fstat(fd,&s); 
sendfile(targetfd,fd,&offset, s.st_size); 
+0

धन्यवाद! यह अभी भी पूरी तरह से सामान्य नहीं है, लेकिन यह "दाएं" दिशा में एक कदम है - यह नहीं कि मैं यह कह रहा हूं कि जो मैं पूछ रहा हूं वह वास्तव में सही या यहां तक ​​कि आवश्यक होगा। (मेरा मूल प्रश्न केवल जिज्ञासा का मामला था।) –

+0

मुझे लगता है कि लिनक्स वास्तव में "इस फ़ाइल डिस्क्रिप्टर को नाम दें" जेनेरिक एपीआई की मदद करेगा, जो केवल तभी विफल हो सकता है जब फ़ाइल डिस्क्रिप्टर सामान्य फ़ाइल को संदर्भित नहीं करता है या संदर्भित करता है एक और विभाजन में एक फ़ाइल। साथ ही, ऐसा करने पर मौजूदा फ़ाइल को परमाणु रूप से बदलने का तरीका होना चाहिए, जो अब 'नाम बदलें' का उपयोग करके संभव है, लेकिन केवल तभी जब स्रोत फ़ाइल में फाइल सिस्टम नाम हो। – pqnet

2

प्रश्न: एक काल्पनिक सिस्टम कॉल frename है कि एक फ़ाइल वर्णनकर्ता लेता ही अस्तित्व में है, और अगर एक फाइल कई नामों (हार्ड लिंक) है, जो उन लोगों के नामों में से ले जाया जायेगा/नाम दिया जब यह सिस्टम कॉल एक फ़ाइल वर्णनकर्ता पर इस्तेमाल किया गया था है जो इस फाइल को संदर्भित करता है?

उस प्रश्न का कोई अच्छा जवाब नहीं है, और यह कारण है कि यह सिस्टम कॉल मौजूद नहीं है।

rename निर्देशिका प्रविष्टियों के साथ सौदा करता है, जो फ़ाइलों (इनोड्स) के पॉइंटर्स हैं। एक खुली फ़ाइल डिस्क्रिप्टर किसी भी विशेष निर्देशिका प्रविष्टि से जुड़ी नहीं है, केवल फाइल के साथ ही (इनोड)। उस परिप्रेक्ष्य से, जिस सिस्टम कॉल के लिए आप पूछ रहे हैं वह वास्तव में समझ में नहीं आता है। निर्देशिका प्रविष्टि में एक इनोड का पालन करने के लिए कोई पोर्टेबल तरीका नहीं है जो इंगित करता है (और, फिर से, उनमें से एक से अधिक हो सकता है)। कुछ ऑपरेटिंग सिस्टम इस पिछड़े लिंक को खोजने के लिए विभिन्न गैर पोर्टेबल माध्यम प्रदान कर सकते हैं जो हमेशा परिणाम (आमतौर पर गारंटी नहीं) के साथ आने की गारंटी नहीं दे सकते हैं, लेकिन इनका मतलब है कि किस निर्देशिका प्रविष्टि को वापस करने के लिए सवाल नहीं है जब एक से अधिक होते हैं, और मेरे ज्ञान के लिए उनमें से कोई भी सिस्टम कॉल में विस्तारित नहीं किया गया है जैसा आप खोज रहे हैं।

+0

भ्रम के लिए खेद है। यह मेरे लिए स्पष्ट था, इसलिए मैंने सुझाव दिया कि 'झुकाव() '। मुझे 'frename() 'का उल्लेख नहीं किया जाना चाहिए था। –

+2

'झुकाव()' वास्तव में अच्छा होगा। यह एकमात्र चीज है जो फ़ाइल को दोबारा जोड़ना संभव बनाता है जिसमें 0 लिंक हैं लेकिन अभी भी मौजूद हैं। लेकिन हाँ ... यह किसी भी ओएस के तहत मौजूद नहीं है जिसे मैं जानता हूं। – Celada

संबंधित मुद्दे