2013-08-24 10 views
18

मुझे किसी कारण से -EINVAL मिल रहा है, और यह मुझे स्पष्ट नहीं है कि क्यों।पढ़ने-लिखने mmap के लिए अवैध तर्क?

if ((fd = open(argv[1], O_RDWR)) < 0) 
{ 
    fprintf(stderr, "Failed to open %s: %s\n", argv[1], strerror(errno)); 
    return 1; 
} 

struct stat statbuf; 
if (fstat(fd, &statbuf)) 
{ 
    fprintf(stderr, "stat filed: %s\n", strerror(errno)); 
    return 1; 
} 

char* fbase = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
if (fbase == MAP_FAILED) 
{ 
    fprintf(stderr, "mmap failed: %s\n", strerror(errno)); 
    return 1; 
} 

संपादित करें: मैं जोड़ने चाहिए, त्रुटि mmap में हो रहा है यहाँ मैं कहाँ mmap लिए फ़ाइल को खोलने और प्रयास है।

+0

आपका क्या मतलब है? यह कुछ जो मैं लिख रहा हूं उससे एक स्निपेट है। – Alex

+0

सवाल यह है कि "कहां" आपके कोड की कौन सी रेखा EINVAL घटनाओं को स्निपेट करती है। – alk

+0

क्षमा करें, मैं निर्दिष्ट करना भूल गया। त्रुटि mmap में है। – Alex

उत्तर

49

बदलते MAP_PRIVATE को MAP_SHARED इस सफल होने के लिए अनुमति देता है बाहर कर देता है।

इस कारण यह विफल रहा था सूक्ष्म: मेरा कोड वर्चुअलबॉक्स वीएम के अंदर चल रहा है, और जिस फ़ाइल को मैं mmap पर होस्ट कर रहा था, मेरी मेजबान मशीन पर साझा निर्देशिका में था। वर्चुअलबॉक्स आभासी फाइल सिस्टम स्पष्ट रूप से mmap को हाइपरवाइजर की सीमा में MAP_SHARED विकल्प के साथ लागू नहीं करता है।

यदि आप मेरे प्रश्न और उसके उत्तर दोनों पर jxh की सहायक टिप्पणियां पढ़ेंगे, तो यह पता चला है कि यह कोड उनके लिए काम कर रहा था क्योंकि वह मेजबान स्मृति में एक होस्ट फाइल सिस्टम फ़ाइल mmap करने का प्रयास कर रहा था।

मेरा अवलोकन MAP_SHARED से MAP_PRIVATE पर स्विच करने से भी यह संगत है: चूंकि निजी रूप से मैप की गई मेमोरी अन्य प्रक्रियाओं के लिए अदृश्य है, वर्चुअल फाइल सिस्टम ड्राइवर को स्मृति को मैप करने के लिए शायद कोई आपत्ति नहीं होगी।

समाधान उस फ़ाइल को स्थानांतरित करना था जिसे मैं अतिथि की हार्ड ड्राइव में मैप करना चाहता था और वहां से हेरफेर करना चाहता था।

+2

यह एक अच्छा खोज है, +1। – jxh

+2

यह मेरे लिए हल हो गया! – arnoapp

+2

यही कारण है कि मैं stackoverflow प्यार करता हूँ। – Claudiu

13

आपका statbuf.st_size0 है। mmap() विफल होगा यदि लंबाई पैरामीटर 0 है।

वहाँ EINVAL त्रुटि mmap() के लिए 3 सूचीबद्ध कारण हैं:

void *mmap(void *addr, size_t length, int prot, int flags, 
      int fd, off_t offset); 

...

  • हम पसंद नहीं है addr, length, या offset (जैसे, वे बहुत बड़ी हैं , या एक पृष्ठ सीमा पर गठबंधन नहीं)।
  • (लिनक्स 2.6.12 के बाद से) length 0.
  • flagsMAP_PRIVATE या MAP_SHARED निहित, या इन मूल्यों के दोनों निहित था।
+0

मुझे एक मूर्खता की तरह लगता है, लेकिन: यह शून्य था, मैंने खाली फ़ाइल को बदल दिया है, और यह पता चला है कि समस्या बनी हुई है। – Alex

+0

जबकि लंबाई पहले शून्य थी, मैंने यह सुनिश्चित किया कि फ़ाइल अपर्याप्त थी, और समस्या अभी भी मौजूद है। यह सवाल एक गड़बड़ है, मैं अधिक जानकारी के साथ एक नया खोलूंगा। – Alex

+0

मैंने संकलित किया और अपने कोड को मेरे लिनक्स सिस्टम पर ठीक से चलाया। – jxh

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