2011-10-22 30 views
17

मुझे पता है कि डुप्लिक, डुप् 2, डुप् 3 "फाइल डिस्क्रिप्टर oldfd" (मैन पेज से) की एक प्रति बनाएं। हालांकि मैं इसे पच नहीं सकता।क्या कोई बता सकता है कि सी में क्या डुप्ली() करता है?

जैसा कि मुझे पता है कि फाइल डिस्क्रिप्टर फ़ाइल स्थान और उनकी दिशा (इनपुट/आउटपुट) का ट्रैक रखने के लिए संख्या हैं।

fd=fd2; 

जब भी हम एक फ़ाइल वर्णनकर्ता को डुप्लिकेट करना चाहते हैं, तो यह आसान नहीं होगा?

और कुछ और ..

dup() नई वर्णनकर्ता के लिए सबसे कम गिने अप्रयुक्त वर्णनकर्ता का उपयोग करता है।

मतलब यह है कि है कि यह भी है कि अगर हम मान लेते हैं कि हम पास() उन में से एक एड है मूल्य stdin, stdout या stderr के रूप में ले जा सकते हैं?

+3

:

कुछ यूनिक्स सिस्टम पर (लेकिन जीएनयू/लिनक्स)

fd = open("/dev/fd/1", O_WRONLY); 

यह के बराबर है खुली फ़ाइल हैंडल। 'डुप्ली' कर्नेल को बताने का आपका तरीका है कि आप इसे उस फ़ाइल हैंडल (उसी फ़ाइल का जिक्र करते हुए) का ट्रैक ट्रैक रखना चाहते हैं जब तक कि आप इसे बंद न करें। – user786653

उत्तर

12

बस थोड़ा प्रयोग करने के बाद दूसरे प्रश्न पर खुद को जवाब देना चाहता था।

उत्तर हाँ है। एक फ़ाइल डिस्क्रिप्टर जो आप बनाते हैं वह मान 0, 1, 2 ले सकता है यदि stdin, stdout या stderr बंद हैं।

उदाहरण:

close(1);  //closing stdout 
newfd=dup(1); //newfd takes value of least available fd number 

जहां इस वर्णनकर्ता दायर करने के लिए होता है:

0 stdin  .--------------.  0 stdin  .--------------.  0 stdin 
1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 
2 stderr '--------------'     '--------------'  2 stderr 
+1

एक सवाल फिर से उठ गया: मैं एक फाइल डिस्क्रिप्टर को कैसे डुप्लिकेट कर सकता हूं जिसे मैंने पहले ही बंद कर दिया है? – Pithikos

+0

परिभाषा से, डुप्लिक() नए वर्णनकर्ता के लिए निम्नतम क्रमांकित अप्रयुक्त वर्णनकर्ता का उपयोग करता है। और जब आप एक फ़ाइल डिस्क्रिप्टर बंद करते हैं, तो इसका मतलब है कि यह उपयोग के लिए उपलब्ध है। –

2

देखते हैं कि यह page, stdout dup(1) के रूप में एलियास जा सकता है ...

+0

+1। भयानक लिंक –

5

मान लीजिए कि आप एक खोल कार्यक्रम लिख रहे हैं और आप एक प्रोग्राम आप चलाना चाहते हैं में stdin और stdout रीडायरेक्ट करना चाहते हैं। यह कुछ इस तरह दिखाई दे सकता है:

dup2(fdin, 0); 
dup2(fdout, 1); 

कारण आप क्यों चाहते हैं:)

fdin = open(infile, O_RDONLY); 
fdout = open(outfile, O_WRONLY); 
// Check for errors, send messages to stdout. 
... 
int pid = fork(0); 
if(pid == 0) { 
    close(0); 
    dup(fdin); 
    close(fdin); 
    close(1); 
    dup(fdout); 
    close(fdout); 
    execvp(program, argv); 
} 
// Parent process cleans up, maybe waits for child. 
... 

dup2 (यह करीब() dup करने के लिए एक छोटे से अधिक सुविधाजनक तरीका है() द्वारा बदला जा सकता है ऐसा करने के लिए आप stdout (या stderr) में त्रुटियों की रिपोर्ट करना चाहते हैं ताकि आप उन्हें बंद न कर सकें और बाल प्रक्रिया में एक नई फ़ाइल खोल सकें। दूसरा, अगर खुले() कॉल ने एक त्रुटि लौटा दी तो यह कांटा करना कचरा होगा।

9

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

+1

यह। "संख्या" कर्नेल द्वारा बनाए गए डेटा संरचना में एक अनुक्रमणिका है। फ़ंक्शन के 'डुप्पी 'परिवार ने उस डेटा संरचना में नोड की स्थिति क्लोन की है और आपको इंडेक्स को नए नोड में सौंप दिया है। – dmckee

+3

@ डीएमकी: "कर्नेल" और "इंडेक्स" कार्यान्वयन विवरण हैं। "संख्या" से जुड़े कुछ डेटा हैं जिन्हें सीधे प्रोग्राम द्वारा छेड़छाड़ नहीं किया जा सकता है, और जिसे 'dup() 'द्वारा क्लोन किया गया है। यह सभी प्रोग्रामर को जानने की जरूरत है। वैसे यह डेटा का एक बहुत ही दिलचस्प टुकड़ा नहीं है, यह वास्तव में दिलचस्प डेटा (खुली फ़ाइल विवरण) के लिए कुछ झंडे और एक सूचकांक है जो ** ** ** 'dup()' द्वारा क्लोन नहीं किया गया है। –

5

dup के बारे में सबसे महत्वपूर्ण बात यह है कि() यह छोटी से छोटी पूर्णांक एक नई फ़ाइल वर्णनकर्ता के लिए उपलब्ध रिटर्न है।

int fd_redirect_to = open("file", O_CREAT); 
close(1); /* stdout */ 
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */ 
close(fd_redirect_to); /* we don't need this */ 

इस कुछ भी दायर करने के लिए वर्णनकर्ता 1 (stdout) लिखा के बाद, जादुई "फाइल" में चला जाता है: यह पुनर्निर्देशन के आधार है।

+0

मानना ​​(अनुचित नहीं) कि फाइल डिस्क्रिप्टर 0 वर्तमान में खुला है। '200> somefile 'जैसे पुनर्निर्देशन के लिए समर्थन' dup2() '(या' dup3() 'के बिना बहुत असुविधाजनक है, लेकिन यह सिस्टम के लिए हालिया जोड़ा है)। –

0

"मानक आउटपुट डुप्लिकेट करने के बारे में बस एक युक्ति"। पहला सवाल आप को याद है कि कर्नेल की संख्या का ट्रैक रखता है की जरूरत के लिए

fd = dup(1);