2009-11-14 10 views
15

मैं popen() का उपयोग करके एक पाइप खोलना चाहता हूं और इसमें गैर-अवरुद्ध 'पढ़ने' तक पहुंच नहीं है।पॉप-अप का उपयोग करके गैर-अवरुद्ध पाइप?

मैं इसे कैसे प्राप्त कर सकता हूं?

(उदाहरण मैंने पाया थे सभी को अवरुद्ध/तुल्यकालिक)

उत्तर

25

सेटअप इस तरह:

FILE *f = popen("./output", "r"); 
int d = fileno(f); 
fcntl(d, F_SETFL, O_NONBLOCK); 

अब आप पढ़ सकते हैं:

ssize_t r = read(d, buf, count); 
if (r == -1 && errno == EAGAIN) 
    no data yet 
else if (r > 0) 
    received data 
else 
    pipe closed 

जब आप ' फिर से किया गया, सफाई:

pclose(f); 
+0

खूबसूरती से काम करता है ... धन्यवाद! – jldupont

+0

पाइप, एक फ़ाइल सूचक होने के नाते, स्वाभाविक रूप से buffered है, क्या कोई आश्वासन है कि फ़ाइल डिस्क्रिप्टर का उपयोग करके आप सीधे फ़ाइल बफर में खींचा गया कुछ याद नहीं करेंगे, या जब तक आप डॉन करते हैं तब तक इसकी गारंटी दी जा सकती है पहले fget/fread/etc कॉल नहीं करते? – stu

0

आप "यह भी देखना" popen के लिए आदमी पृष्ठ के अनुभाग (को देखा है)?

त्वरित Google खोज ने इस पृष्ठ को प्रकट किया: http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#blocking फाइल डिस्क्रिप्टरों को अवरुद्ध करने और गैर-अवरुद्ध करने के बारे में बात करते हैं।

2

कभी कोशिश नहीं की लेकिन मुझे नहीं पता कि आप फ़ाइल डिस्क्रिप्टर को fileno() के साथ क्यों नहीं ले सकते हैं, fcntl() का उपयोग गैर-अवरुद्ध करने के लिए सेट करने के लिए, और पढ़ने()/लिखें() का उपयोग करें। एक कोशिश के काबिल है।

+0

मैं यह करूँगा! धन्यवाद! – jldupont

+2

मैं पुष्टि कर सकता हूं कि यह प्रक्रिया काम करती है। – jldupont

4

popen() आंतरिक pipe(), fork(), dup2() और execve() (बच्चे प्रक्रिया के एफडी पाइप 0/1/2 बात करने के लिए) कहते हैं। क्या आपने इनका उपयोग करने पर विचार किया है? उस स्थिति में, आप पाइप को fcntl() का उपयोग करके गैर-अवरुद्ध करने के लिए पढ़ सकते हैं।

अद्यतन: यहाँ सिर्फ निदर्शी प्रयोजनों के लिए एक उदाहरण है,:

int read_pipe_for_command(const char **argv) 
{ 
    int p[2]; 

    /* Create the pipe. */ 
    if (pipe(p)) 
    { 
     return -1; 
    } 

    /* Set non-blocking on the readable end. */ 
    if (fcntl(p[0], F_SETFL, O_NONBLOCK)) 
    { 
     close(p[0]); 
     close(p[1]); 
     return -1; 
    } 

    /* Create child process. */ 
    switch (fork()) 
    { 
     case -1: 
      close(p[0]); 
      close(p[1]); 
      return -1; 
     case 0: 
      /* We're the parent process, close the writable part of the pipe */ 
      close(p[1]); 
      return p[0]; 
     default: 
      /* Close readable end of pipe */ 
      close(p[0]); 
      /* Make stdout into writable end */ 
      dup2(p[1], 1); 
      /* Run program */ 
      execvp(*argv, argv); 
      /* If we got this far there was an error... */ 
      perror(*argv); 
      exit(-1); 
    } 
} 
+0

ऐसा नहीं होना चाहिए: अगर (पाइप (पी) <0) वापसी -1; ? – Aktau

+1

@Aktau मुझे अपने संस्करण को बेहतर पसंद है। सफलता पर 0 एसएसकॉल वापस आ जाएगा। गैर शून्य के लिए अगर कथन परीक्षण। – asveikau

+1

आप सही हैं, आपका संस्करण भी पूरी तरह से सही है, मैं अन्य सिस्कोल के बारे में सोच रहा था! – Aktau

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