2008-11-06 11 views
11

जब हम यूनिक्स में एक कांटा करते हैं, खुले फ़ाइल हैंडल विरासत में प्राप्त होते हैं, और यदि हमें उनका उपयोग करने की आवश्यकता नहीं है तो हमें उन्हें बंद करना चाहिए। हालांकि, जब हम पुस्तकालयों का उपयोग करते हैं, तो फाइल हैंडल खोला जा सकता है जिसके लिए हमारे पास हैंडल तक पहुंच नहीं है। हम इन खुले फ़ाइल हैंडल की जांच कैसे करते हैं?मुझे फ़ाइल हैंडल कैसे मिलती है कि मेरी प्रक्रिया लिनक्स में खोली गई है?

उत्तर

14

यदि पुस्तकालय उन फाइलें खोल रहे हैं जिन्हें आप नहीं जानते हैं, तो आप कैसे जानते हैं कि उन्हें एक कांटा के बाद उनकी आवश्यकता नहीं है? अप्रत्याशित हैंडल एक आंतरिक लाइब्रेरी विवरण हैं, यदि लाइब्रेरी उन्हें बंद करना चाहती है तो यह उन्हें बंद करने के लिए एक atfork() हैंडलर पंजीकृत करेगा। कोड के कुछ टुकड़े के पीछे घूमते हुए इसकी फाइल को पीछे छोड़कर उसकी पीठ के पीछे हैंडल समस्याओं को डीबग करने के लिए सूक्ष्म कड़ी हो जाएगी क्योंकि लाइब्रेरी अनपेक्षित रूप से त्रुटि करेगी जब यह एक हैंडल के साथ काम करने का प्रयास करेगी, यह जानता है कि यह सही ढंग से खोला गया है, लेकिन बंद नहीं हुआ।

0

उचित पुस्तकालयों में हमेशा ऐसे कार्य होंगे जो संसाधनों (जैसे फ़ाइल हैंडल) को आवंटित करते हैं।

0

बस एक लिंक है, लेकिन यह मददगार लगता है: How many open files? netadmintools.com पर। ऐसा लगता है कि एक प्रक्रिया 'खुली फाइलों के बारे में जानने के लिए/proc जांचों का उपयोग करना, यह सुनिश्चित नहीं है कि यह एकमात्र तरीका है या यदि कोई एपीआई है। इस प्रकार की जानकारी के लिए फ़ाइलों को पार्स करना थोड़ा सा हो सकता है ... गन्दा। इसके अलावा,/proc को भी बहिष्कृत किया जा सकता है, कुछ जांचने के लिए।

16

लिनक्स में आप /proc/<pid>/fd निर्देशिका देख सकते हैं - प्रत्येक खुले एफडी के लिए एक फ़ाइल होगी, जिसे हैंडल के नाम से रखा जाएगा। मुझे यकीन है कि इस तरह से गैर पोर्टेबल है।

वैकल्पिक रूप से आप lsof का उपयोग कर सकते हैं - लिनक्स, एईक्स, फ्रीबीएसडी और नेटबीएसडी के लिए उपलब्ध, man lsof के अनुसार।

1

मैं सहमत हूं कि अन्य लोगों ने यादृच्छिक फाइलों को खतरनाक होने के बारे में क्या कहा है। आप अपने सभी तृतीय-पक्ष टूल के लिए कुछ सुंदर रोचक रिपोर्ट दर्ज कर सकते हैं।

यही कारण है, ने कहा कि अगर आप आप उन फ़ाइलों को खुले होने की जरूरत नहीं होगी पता , आप हमेशा मान्य फ़ाइल वर्णनकर्ता (65535, IIRC के लिए 1) और करीब सब कुछ आप को पहचान नहीं सभी के माध्यम से चल सकता है।

+0

आप प्रक्रिया की फ़ाइल डिस्क्रिप्टर तालिका में प्रविष्टियों की संख्या प्राप्त करने के लिए getdtablesize (2) कॉल का उपयोग कर सकते हैं। –

0

क्या यह एक डिज़ाइन मुद्दा नहीं है? क्या उन फ़ाइलों को खोलने वाले libs को शुरू करने से पहले आपकी प्रक्रिया को फोर्क करना संभव है?

2

आरंभ करने के लिए, आपको खुले फ़ाइल डिस्क्रिप्टरों के बारे में पूरी तरह से देखभाल करने की ज़रूरत नहीं है, जिन्हें आप नहीं जानते हैं। यदि आप जानते हैं कि आप उन्हें फिर से लिखने वाले नहीं हैं, तो उन्हें बंद करना एक अच्छा विचार है और चोट नहीं पहुंचाता है - आपने अभी तक एक कांटा() किया है, एफडीएस दो बार खुलते हैं। लेकिन इसी तरह, यदि आप उन्हें खुले छोड़ देते हैं, तो वे आपको परेशान नहीं करेंगे - आखिरकार, आप उनके बारे में नहीं जानते हैं, संभवतः आप उन्हें यादृच्छिक रूप से लिख नहीं पाएंगे।

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

जो भी कहा गया, मूल प्रश्न का उत्तर देने की भावना में, विशेष रूप से अच्छा तरीका नहीं है। आप फाइल डिस्क्रिप्टर पर dup() या dup2() पर कॉल कर सकते हैं; अगर यह बंद हो गया है, तो कॉल EBADF के साथ विफल हो जाएगा।तो आप कह सकते हैं:

int newfd = dup(oldfd); 
if (newfd > 0) 
{ 
    close(newfd); 
    close(oldfd); 
} 

लेकिन उस बिंदु पर आप पहली जगह में close(oldfd) कह और किसी भी EBADFs अनदेखी बंद बस के रूप में अच्छी तरह से कर रहे हैं।

मान लीजिए कि आप अभी भी सबकुछ बंद करने के परमाणु विकल्प को लेना चाहते हैं, तो आपको अधिकतम खुली फ़ाइल डिस्क्रिप्टरों को संभवतः खोजने की आवश्यकता है। 1 से 65,535 मानना ​​अच्छा विचार नहीं है। सबसे पहले, एफडीएस निश्चित रूप से 0 से शुरू होता है, लेकिन कोई विशेष ऊपरी सीमा परिभाषित नहीं होती है। पोर्टेबल होने के लिए, POSIX के sysconf(_SC_OPEN_MAX) आपको किसी भी सचेत POSIX सिस्टम पर बताएंगे, हालांकि सख्ती से यह वैकल्पिक है। यदि आप पागलपन महसूस कर रहे हैं, तो -1 के लिए रिटर्न वैल्यू की जांच करें, हालांकि उस बिंदु पर आपको ज्यादातर हार्डकोडेड वैल्यू पर वापस गिरना होगा (1024 ठीक होना चाहिए जब तक कि आप कुछ अजीब कुछ नहीं कर रहे हों)। या यदि आप लिनक्स-विशिष्ट होने के साथ ठीक हैं, तो आप आसपास/proc में खोद सकते हैं।

एफडीएस 0, 1, और 2 बंद न करें - जो वास्तव में चीजों को भ्रमित कर सकते हैं।

+0

खैर, आम तौर पर आप तब तक परवाह नहीं करते जब तक कि आप कम तक पहुंच न जाएं और बहुत सी खुली फाइल त्रुटियों को शुरू करना शुरू करें। – philant

5

जैसा कि @ लुइस गेरबर्ग के उत्तर पर बताया गया है, पुस्तकालय शायद fork() पर फ़ाइल हैंडल को खोलने की उम्मीद कर रहे हैं (जो बाद में, मूल प्रक्रिया की लगभग समान प्रतिलिपि माना जाता है)।

अधिकांश लोगों की समस्या exec() पर है जो अक्सर fork() का पालन करती है। यहां, सही समाधान लाइब्रेरी के लिए है जिसने उन्हें हैंडल बनाया है ताकि उन्हें क्लोज-ऑन-exec (FD_CLOEXEC) के रूप में चिह्नित किया जा सके।

मल्टीथ्रेड प्रोग्राम द्वारा उपयोग की जाने वाली पुस्तकालयों पर, एक फ़ाइल हैंडल बनाने वाली लाइब्रेरी के बीच दौड़ की स्थिति है और FD_CLOEXEC पर सेटिंग (अन्य थ्रेड fork() दोनों परिचालनों के बीच हो सकता है)। उस समस्या को ठीक करने के लिए, लिनक्स कर्नेल में O_CLOEXEC पेश किया गया था।

14

आप एक खोल से कर सकते हैं:

lsof -P -n -p _PID_

कहाँ पीआईडी ​​ अपनी प्रक्रिया पीआईडी ​​है।

+0

खोल पर इसे करने का क्या मतलब है? मुझे इसे बंद करने के लिए अपने फोर्कड बाल प्रक्रिया में कैसे जाना चाहिए? – sep

+1

@sep: आपकी समस्या के विवरण पर विचार करते समय यह उत्तर शायद सबसे अच्छा नहीं है, लेकिन यह निश्चित रूप से वास्तविक प्रश्न को नाखून करता है। तो, मेरी प्रक्रिया के हैंडल खोजने में मेरी सहायता के लिए फेलिप धन्यवाद :) – Superole

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

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