2015-04-18 6 views
17

write(2) के लिए फ़ंक्शन हस्ताक्षर ssize_t write(int fd, const void *buf, size_t count) है। आम तौर पर, size_t का अधिकतम मान ssize_t से अधिक है। क्या इसका मतलब यह है कि write वास्तव में लिखने वाले डेटा की मात्रा SIZE_MAX के बजाय वास्तव में SSIZE_MAX है? यदि ऐसा नहीं है, तो क्या होता है जब ओवरफ्लो के संबंध में लिखित बाइट्स की संख्या SSIZE_MAX से अधिक होती है?लिखेंगे (2) हमेशा SSIZE_MAX से कम या बराबर लिखते हैं?

मैं अनिवार्य रूप से सोच रहा हूं कि write द्वारा लिखे गए डेटा की मात्रा SSIZE_MAX या SIZE_MAX से घिरा हुआ है।

+0

प्रक्रियाओं में भी सीमाएं हैं। एक प्रक्रिया जो 'प्रक्रिया की फ़ाइल आकार सीमा' से अधिक है, विफल हो जाएगी (त्रुटि 'EFBIG'), इस प्रकार यह सीमा yeyo

+0

SSIZE_T साइन किए गए आकार के लिए खड़ा है और इसका अर्थ है कि यह एक हस्ताक्षरित नंबर है। जब मामला सिस्टम कॉल के दौरान कुछ त्रुटि हुई तो मामले की बात है। इसलिए लिखने की अधिकतम संख्या अधिक हस्ताक्षरित नहीं हो सकती है Size_t – madz

+0

पेंड्रिव, मुझे उतना ही पता है। यह मेरे प्रश्न को बिल्कुल संबोधित नहीं करता है। रिटर्न वैल्यू 'ssize_t' है जिसमें अधिकांश सिस्टम पर 'size_t' की तुलना में अधिक सीमित सीमा होती है, इसलिए मैं अनिवार्य रूप से पूछ रहा हूं कि क्या लिखियां' SSIZE_MAX' या 'SIZE_MAX' द्वारा बाध्य हैं। –

उत्तर

15

टाइप ssize_t टाइप पॉसिक्स द्वारा हस्ताक्षरित प्रकार के रूप में परिभाषित किया गया है ताकि कम से कम 32767 (_POSIX_SSIZE_MAX) को अन्य गारंटी के साथ स्टोर करने में सक्षम हो सके। तो इसका अधिकतम मूल्य size_t के अधिकतम मूल्य से कम हो सकता है।

ssize_t के POSIX परिभाषा:

ssize_t 

बाइट्स की गिनती या कोई त्रुटि संकेत के लिए प्रयुक्त।

तो संभव है कि आपके द्वारा लिखे गए बाइट्स की संख्या ssize_t से अधिक हो सकती है। उस स्थिति में, POSIX इसे कार्यान्वयन के लिए छोड़ देता है।

write() के POSIX कल्पना से:

ssize_t write(int fildes, const void *buf, size_t nbyte); 

तो nbyte का मूल्य {SSIZE_MAX}, परिणाम से अधिक है कार्यान्वयन परिभाषित किया गया है।

+0

मुझे पता है कि यह थोड़ा घूम रहा है, लेकिन यदि '-ansi' का उपयोग किया जाता है, तो' SSIZE_MAX' और '_POSIX_SSIZE_MAX' को जीएनयू सिस्टम पर परिभाषित नहीं किया जा सकता है। यह भी देखें [ia64 पर SSIZE_MAX] (https://sourceware.org/ml/libc-hacker/2002-08/msg00031.html)। चर्चा सभी ग्लिबैक सिस्टम को शामिल करने के लिए तेजी से विस्तारित हुई। – jww

+0

लिनक्स 'EINVAL' वापस लौटाता है अगर' nbyte> SSIZE_MAX + 1'। (यह 'SSIZE_MAX + 1' स्वीकार करता है, '0' लौटाता है) यह दुर्भाग्यपूर्ण है कि इसे अधिकांश' SSIZE_MAX' बाइट्स पर आंशिक लेखन को अनिवार्य रूप से मानक में संभाला नहीं गया है। – PSkocik

2

हां, लिखने के लिए एक कॉल में लिखा जा सकता डेटा की मात्रा ssize_t में क्या हो सकती है, इस तक ही सीमित है। स्पष्टीकरण के लिए, the relevant glibc documentation page देखें। उस पृष्ठ को उद्धृत करने के लिए, "आपका प्रोग्राम हमेशा लूप में कॉल लिखना चाहिए, जब तक कि सभी डेटा लिखे गए हों।" (जोर जोड़ा गया) वह पृष्ठ यह भी स्पष्ट करता है कि ssize_t का उपयोग ब्लॉक के आकार का प्रतिनिधित्व करने के लिए किया जाता है जिसे एक ही ऑपरेशन में पढ़ा या लिखा जा सकता है।

+0

क्या आपको पता है कि पीओएसईक्स स्पेक में कहीं इसका उल्लेख किया गया है कि 'लिखने' द्वारा लिखे गए डेटा की मात्रा 'size_t' के बजाय' ssize_t' द्वारा बाध्य है? –

+0

मुझे यकीन नहीं है, मैं पॉज़िक्स स्पेक से अपरिचित हूं। –

+4

असल में, मुझे लगता है कि जवाब यह है कि व्यवहार कार्यान्वयन-परिभाषित है: [लिखने वाला पृष्ठ] (http://pubs.opengroup.org/onlinepubs/009695399/functions/write.html) कहता है कि "यदि मूल्य nbyte {SSIZE_MAX} से बड़ा है, परिणाम कार्यान्वयन-परिभाषित है। " यह मेरे लिए मूर्खतापूर्ण प्रतीत होता है: क्यों कुछ उचित करने के लिए लिखना परिभाषित नहीं करता है: यानी केवल इतना ही लिखें कि सुरक्षित रूप से क्या किया जा सकता है? –

13

write() के लिए POSIX विनिर्देशन का कहना है:

तो nbyte का मूल्य {SSIZE_MAX} से अधिक है, परिणाम कार्यान्वयन परिभाषित किया गया है।

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

यदि आपके पास 64-बिट सिस्टम है, तो SSIZE_MAX दुनिया के सबसे बड़े एकल डेटा केंद्र में संभवतः डिस्क स्पेस की मात्रा से अधिक संभव है (संभवतः परिमाण या अधिक के क्रम से, यहां तक ​​कि एनएसए की अनुमति भी देता है और Google), इसलिए आप इसके साथ वास्तविक समस्याओं में भाग लेने में असमर्थ होने की संभावना नहीं रखते हैं, लेकिन 32-बिट सिस्टम पर, आप आसानी से 2 जीबी स्पेस से अधिक हो सकते हैं और यदि ssize_t 32-बिट है, तो आपको सभी से निपटना होगा इस। (मैक ओएस एक्स 10.10.3 पर, 32-बिट बिल्ड में 4-बाइट size_t और ssize_t है, कम से कम डिफ़ॉल्ट रूप से।)

+0

* दुनिया में डिस्क स्थान की मात्रा से अधिक (परिमाण के कुछ आदेशों से) *। हर्गिज नहीं! यह दूसरी तरफ है: इसमें 2^63 बाइट्स से अधिक होने के लिए केवल 20 मिलियन 500 जीबी हार्ड ड्राइव लगती हैं। – chqrlie

+0

@chqrlie '9223372036854775808 'बाइट्स gibibyte =' 8589934592' में बाइट्स। उस राशि को 500 (500 हार्ड ड्राइव) से विभाजित करें। '17 17 9 869.184' 500 जीबी हार्ड ड्राइव। यद्यपि आप सही हैं, दुनिया में मेरे पास अधिक डिस्क स्थान है। – yeyo

+0

@chqrlie: हम्म .. आप इतने करीब हैं कि मैंने दावा कम कर दिया है। और जो भी डेटा उस प्रतिलिपि बनाने की कोशिश कर रहा है, उसे 'कहां से पढ़ा जा रहा है और लिखा है' और 'क्या आपको उस डेटा को एक साथ पढ़ने और लिखने की अनुमति है' - और जवाब होगा 'नहीं, आप होंगे _not_ को उस डेटा को एक बार में लिखने की अनुमति है '। –

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