2016-08-28 8 views
9

मैं असेंबली (नासम का उपयोग करके) में शुरुआत कर रहा हूं। मैं एक कॉलेज कोर्स के माध्यम से असेंबली सीख रहा हूँ।sys_read सिस्टम कॉल क्यों समाप्त होता है जब यह एक नई रेखा का पता लगाता है?

मैं इसे लागू होने पर sys_read linux सिस्टम कॉल के व्यवहार को समझने की कोशिश कर रहा हूं। विशेष रूप से, sys_read रोकता है जब यह एक नई लाइन या लाइन फ़ीड पढ़ता है। जो मैंने सिखाया है उसके मुताबिक, यह सच है। यह online tutorial article भी तथ्य/दावा की पुष्टि करता है।

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

मैंने sys_read कॉल के लिए लिनक्स प्रोग्रामर के मैनुअल की जांच की ("मैन 2 रीड" के माध्यम से)। यह व्यवहार का जिक्र नहीं करता है जब यह माना जाता है, है ना?

पढ़ें() फ़ाइल डिस्क्रिप्टर एफडी से बाइट पर शुरू होने वाले बफर में गिनती गिनने के लिए पढ़ने का प्रयास करता है।

मांग करने वाली फ़ाइलों पर, पढ़ने का ऑपरेशन फ़ाइल ऑफसेट पर शुरू होता है, और फ़ाइल ऑफसेट बाइट्स की संख्या से बढ़ता है। अगर फ़ाइल ऑफ़सेट फ़ाइल के अंत में या उसके पीछे है, तो कोई बाइट पढ़ा नहीं जाता है, और पढ़ता है() शून्य देता है।

यदि गिनती शून्य है, तो पढ़ें() नीचे वर्णित त्रुटियों का पता लगा सकता है। में किसी भी त्रुटि की अनुपस्थिति, या यदि पढ़ा जाता है() त्रुटियों की जांच नहीं करता है, तो 0 (0) की गिनती के साथ पढ़ने() को शून्य देता है और इसका कोई अन्य प्रभाव नहीं होता है।

यदि गणना SSIZE_MAX से अधिक है, तो परिणाम निर्दिष्ट नहीं है।

तो मेरा प्रश्न वास्तव में है, व्यवहार क्यों होता है? क्या यह लिनक्स कर्नेल में एक विनिर्देश है कि यह होना चाहिए या यह किसी और चीज का परिणाम है?

उत्तर

8

ऐसा इसलिए है क्योंकि आप POSIX tty in canonical mode से पढ़ रहे हैं (जहां बैकस्पेस लाइन को "सबमिट" करने के लिए वापस प्रेस करने से पहले काम करता है; यह सब कर्नेल के tty ड्राइवर द्वारा संभाला जाता है)। POSIX tty semantics/stty/ioctl देखें। यदि आप ./a.out < input.txt चलाते हैं, तो आपको यह व्यवहार नहीं दिखाई देगा।

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

यह मानते हुए कि read() पूरे लाइनों पढ़ता एक खिलौना कार्यक्रम के लिए ठीक है, लेकिन है। मैं भूल जाता हूं कि क्या होता है यदि उपयोगकर्ता टर्मिनल एमुलेटर में टेक्स्ट की कई पंक्तियों को चिपकाता है। काफी संभवतः वे सभी एक read() बफर में समाप्त होते हैं।


भी my answer on a question about small read()s leaving unread data on the terminal देखें: अगर आप read() बफर आकार की तुलना में एक लाइन के बारे में अधिक वर्णों को लिखें, आप इनपुट बाहर खाली करने के लिए कम से कम एक पढ़ा सिस्टम कॉल की आवश्यकता होगी।


आप बताया गया है, read(2) libc समारोह sys_read चारों ओर एक पतली आवरण है। इस प्रश्न का उत्तर वास्तव में असेंबली भाषा से कोई लेना देना नहीं है, और सी (या किसी अन्य भाषा) में सिस्टम प्रोग्रामिंग के लिए समान है।

अतिरिक्त पठन:

  • stty(1) आदमी पेज: आप बदल सकते हैं, जहां जो को नियंत्रित चरित्र क्या करता है।
  • The TTY demystified: कुछ इतिहास, और कुछ आरेख दिखाते हैं कि कैसे xterm, कर्नेल, और tty से पढ़ने की प्रक्रिया सभी इंटरैक्ट करते हैं। और सत्र प्रबंधन, और सिग्नल के बारे में सामान।
  • https://en.wikipedia.org/wiki/POSIX_terminal_interface#Canonical_mode_processing और उस लेख के संबंधित भागों।
+0

स्पष्टीकरण और संदर्भों के लिए बहुत बहुत धन्यवाद! – Mercado

3

यह read() सिस्टम कॉल की विशेषता नहीं है, बल्कि टर्मिनल ड्राइवर termios की संपत्ति है। डिफ़ॉल्ट कॉन्फ़िगरेशन में, टर्मियोस आने वाले वर्णों (यानी आप जो टाइप करते हैं) बफर करते हैं जब तक आप दर्ज करें, जिसके बाद संपूर्ण पंक्ति टर्मिनल से पढ़ने वाले प्रोग्राम को भेजी जाती है। यह सुविधा के लिए है ताकि आप इसे भेजने से पहले लाइन को संपादित कर सकें।

जैसा पीटर पीटर ने पहले ही कहा था, यह व्यवहार अन्य प्रकार की फ़ाइलों (नियमित फ़ाइलों की तरह) से पढ़ने पर मौजूद नहीं है और टर्मियो को कॉन्फ़िगर करके बंद कर दिया जा सकता है।

ट्यूटोरियल कहता है कि कचरा क्या है, कृपया इसे अवहेलना करें।

+0

मुझे अंतिम स्टेटमेंट पसंद है: डी धन्यवाद स्पष्टीकरण के लिए बहुत कुछ :) – Mercado

+0

@Mercado यह मेरे लिए एक खुशी है! – fuz

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

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