2015-04-16 8 views
6

मान लें कि मेरे पास दो प्रोग्राम हैं - input.c & output.c मैं बस इतना करना चाहता हूं कि "आधा पिरामिड" प्रारूप में कुछ पेलोड/वर्णों को execl() फ़ंक्शन का उपयोग करके किसी अन्य में भेज दें ।सी - आउटपुट पर जंक वर्ण

input.c

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 

#define SIZE 1024 

int length; 

int main(int argc, char *argv[]) 
{ 
    pid_t pid; 
    char *target; 
    //char payload[length+1]; 
    char payload[SIZE + 1]; 
    int status; 
    int i = 0; 

    if(argc < 2) 
    { 
     printf("Usage %s <length> <target>\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 

    length = atoi(argv[1]); 
    target = argv[2]; 

    while(i < length) 
    { 
     pid = fork(); 

     if(pid != 0) 
     { 
      waitpid(-1, &status, 0); 
      //exit(0); 
     } 

     if(pid == 0) 
     { 
      payload[i] = 'A'; 
      payload[i + 1] = '\0'; 
      execl(target, target, payload, NULL); 
      //printf("%s\n", payload); 
     } 
     ++i; 
    } 
    return 0; 
} 

टिप्पणी मार्ग सिर्फ डीबगिंग उद्देश्यों के लिए कर रहे हैं। क्योंकि जैसा कि आप देख सकते हैं (कोशिश करते समय), जब आप इसे प्रिंट करना चाहते हैं, तो सब ठीक से काम करता है।

output.c (या अगर आप चाहते हैं 'target.c')

#include <stdio.h> 
#include <string.h> 

int main(int argc, char *argv[]) 
{ 
    char buffer[30]; 
    strncpy(buffer, argv[1], sizeof(buffer)); 
    printf("Output: %s\n", buffer); 

    return 0; 
} 

जब मैं की तरह input.c संकलन:

gcc input.c -o input 

& output.c :

gcc output.c -o output 

ठीक है। अब, सब कुछ तैयार है। मान लीजिए, मैं एक पेलोड भेजने के लिए चाहते हैं - लंबाई 6

./input 6 ./output 

लेकिन सभी मैं उत्पादन पर मिलता है (एक और junks पात्रों के साथ या बस) बस यह है:

Output: A 
Output: 0A 
Output: 0,A 
Output: 0,�A 
Output: 0,�8A 
Output: 0,�8�A 

मैंने कई की कोशिश की चीजें, लेकिन उनमें से सभी विफल हो गए और आउटपुट अभी भी वही था, जैसा कि आप ऊपर देख सकते हैं।

यदि कोई मेरी मदद कर सकता है और संभवतः मुझे दिखा सकता है कि समस्या कहां है तो मैं बहुत आभारी हूं। कांटा() और execl() कार्यों का एक साथ उपयोग करने में समस्या हो सकती है?

उत्तर

5

समझ लिया, आप बच्चे ब्लॉक कोड में payloadअद्यतन नहीं चाहिए ...

यहाँ एक ठीक है (अब यह परीक्षण नहीं कर सकते):

while(i < length) 
    { 
     pid = fork(); 
     payload[i] = 'A'; 
     payload[i + 1] = '\0'; 

     if(pid != 0) 
     { 
      waitpid(-1, &status, 0); 
      //exit(0); 
     } 

     if(pid == 0) 
     { 
      execl(target, target, payload, NULL); 
      //printf("%s\n", payload); 
     } 
     ++i; 
    } 

[हटाया असंबंधित वाक्य]

संपादित करें (अतिरिक्त स्पष्टीकरण): payload अद्यतन दोनों माता-पिता और बाल कोड में होना चाहिए। अगर आपको समझ में नहीं आता है, तो मैं और स्पष्टीकरण जोड़ सकता हूं।

EDIT2 (अनुरोध के रूप में)। आप अगली फोर्कड बाल प्रक्रिया के लिए अद्यतन पेलोड चाहते हैं। आपके कोड में, सभी बच्चे कोड को execl()target कोड में बदल दिया गया है। तो fork() को केवलनिष्पादित किया गया है केवल पहली मूल प्रक्रिया (रूट एक) द्वारा।

आपको पहले माता-पिता द्वारा पेलोड अपडेट करना होगा और इसे सभी बच्चों को भी सुलभ बनाना होगा।यह इस ब्लॉक में लाना या तो काम करेंगे नहीं:

// block only executed by the first parent. 
if(pid != 0) 
{ 
    waitpid(-1, &status, 0); 
} 

इसलिए, आप इसे दोनों माता पिता और बच्चे के द्वारा पहुँचा जा सकता एक जगह में अपडेट करना होगा: fork() के बाद, if(pid == 0) ब्लॉक से पहले।

अपने कोड में, आप सामान्य ब्लॉक में i बढ़ाते हैं, लेकिन माता-पिता के payload को कभी अपडेट नहीं किया गया है। इसलिए execl() से पहले, बच्चे ब्लॉक में, के अंत में सी स्ट्रिंग के अंत में 'A\0' जोड़ना' शामिल है।

+0

आप एक आदमी कर रहे हैं! हाँ, यह एक आकर्षण की तरह काम करता आपकी मदद के लिए बहुत बहुत धन्यवाद। और हाँ, अगर यह आपके लिए कोई समस्या नहीं है, तो मैं कुछ और विस्तृत स्पष्टीकरण के लिए आभारी हूं, क्योंकि मुझे नहीं लगता कि मैं इसे 100% पर समझता हूं और मैं कुछ नहीं करना चाहता भविष्य में इसी तरह की त्रुटि। – Yeez

+0

ठीक है, मैं कुछ स्पष्टीकरण जोड़ता हूं। यह एक अच्छा "ताज़ा था एच "मेरे लिए कसरत। – Amessihel

+0

हे, मुझे खुशी है कि ऐसा था। वैसे भी, अब मैं इसे एक और बार देख रहा हूं और मेरे पास एक अतिरिक्त प्रश्न है - यदि आप उत्तर दे सकते हैं। यदि मैं strcpy के साथ strncpy को प्रतिस्थापित करता हूं और "./input 80 ./output" करता हूं, तो मैं आउटपुट "सेगमेंटेशन गलती" पर कहीं और क्यों नहीं देख सकता? मैं सिर्फ उत्सुक हूँ। – Yeez

2

जब आपका प्रोग्राम फोर्क करता है, तो यह एक नई प्रक्रिया बनाता है। if(pid == 0) के बाद, यह नई प्रक्रिया payload बदलती है, और निष्पादन चलाती है (यानी output निष्पादित करता है, जो तब मर जाता है। यानी, आपका पेलोड में परिवर्तन बच्चे में रहता है, और माता-पिता की प्रक्रिया को प्रभावित नहीं करता है। केवल ++i करता है, यही कारण है कि आप '(या बच्चों के केवल ब्लॉक से बाहर कम से कम) कांटा से पहले unitialized डेटा दिखाई कर रहे हैं।

ले जाएँ पेलोड परिवर्तन, तो यह रूप में अच्छी तरह माता-पिता में है।

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