2010-09-06 8 views
7

निम्नलिखित सी फ़ाइल एक फर्जी परिणाम जब NUL इसे करने के लिए पहुंचाया जाता है देता है:का पता लगाने NUL फ़ाइल वर्णनकर्ता (isatty फर्जी है)

int main() 
{ 
    printf("_isatty = %d\n", _isatty(0)); 
} 

परिणाम है:

C:\Users\Edward\Dev\nulltest> test.exe < NUL 
_isatty = 64 

मैं बहुत यकीन है कि एनयूएल (उर्फ/देव/शून्य) टर्मिनल डिवाइस नहीं है! इसलिए मुझे किसी अन्य तरीके से पता लगाने की आवश्यकता है कि फाइल डिस्क्रिप्टर एनयूएल के अनुरूप है या नहीं। संख्या का कोई विशिष्ट अर्थ नहीं है; मैं इसे देखता हूं जब वास्तव में एक टर्मिनल संलग्न होता है।

मुझे क्या करना चाहिए? This question अंतर्निहित नाम प्राप्त करने के लिए एक स्केची अनियंत्रित फ़ंक्शन का उपयोग करने का सुझाव देता है, संभवतः इसे एनयूएल से तुलना कर रहा है, लेकिन यह मेरे लिए आदर्श से कम महसूस करता है। क्या कोई बेहतर तरीका है?

पीएस इससे this GHC bug हल करने में मदद मिलेगी।

+0

(और मैं यह नहीं कह रहा हूँ कि तुम क्या कर रहे हैं गलत है): तुम क्यों परवाह करते हैं जहां इनपुट आ से? – paxdiablo

+0

ऐसे कई एप्लिकेशन हैं जो टर्मिनल का पता लगाने पर अलग-अलग चीजें करते हैं। उदाहरण के लिए, यदि आप 'पायथन' टाइप करते हैं, तो यह इंटरैक्टिव मोड में जाएगा, लेकिन 'echo "प्रिंट \" bar \ "" | पायथन 'प्रारंभिक स्क्रीन में से कोई भी नहीं दिखाएगा। –

+0

मैं _hate_ उन कार्यक्रमों :-) – paxdiablo

उत्तर

4

msdn से:

_isatty एक अशून्य मान देता है यदि वर्णनकर्ता एक चरित्र डिवाइस के साथ जुड़ा हुआ है। अन्यथा, _isatty रिटर्न 0.

एनयूएल यूनिक्स पर/dev/null जैसा है, यह एक चार डिवाइस है।

ध्यान दें कि लिनक्स पर, isatty अलग है:

isatty() समारोह परीक्षण है कि क्या fd एक खुली फ़ाइल वर्णनकर्ता एक टर्मिनल के लिए जिक्र है।

आप क्या कर सकते हैं STDIN_FILENO (0) $ {cwd}/NUL (स्टेट या स्टेट का उपयोग करके) की तुलना करने का प्रयास करें।

अद्यतन:

int ret = GetFileType(GetStdHandle(STD_INPUT_HANDLE)); 

यह NUL या tty के लिए FILE_TYPE_CHAR वापस आ जाएगी।

अन्य मूल्यों के लिए GetFileType दस्तावेज़ीकरण देखें। आप फाइल/चार डिवाइस/पाइप का पता लगा सकते हैं।

अपडेट अंतिम:

उपयोग इनपुट के लिए GetConsoleMode और आउटपुट के लिए GetConsoleScreenBufferInfo

CONSOLE_SCREEN_BUFFER_INFO sbi; 
DWORD mode; 
if (!GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode)) 
    fprintf(stderr, "not console\n"); 
else 
    fprintf(stderr, "console\n"); 
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &sbi)) 
    fprintf(stderr, "not console\n"); 
else 
    fprintf(stderr, "console\n"); 
+0

दिलचस्प! इसका तात्पर्य है कि टर्मिनल होने पर हमें यह पता लगाने के लिए वास्तव में इसाटी का उपयोग नहीं करना चाहिए। क्या विंडोज़ पर समकक्ष कार्यक्षमता उपलब्ध है? –

+0

_isatty खराब है, यह पता लगाना चाहिए कि क्या आप टर्मिनल का उपयोग कर रहे हैं, भले ही एफडी एक चरित्र डिवाइस न हो। मुझे यकीन नहीं है कि विंडोज़ पर ऐसा करने का सबसे अच्छा तरीका क्या है। आप साइगविन/मिंगवे आइसटी कार्यान्वयन की जांच करने का प्रयास कर सकते हैं। आप एक रैपर ब्लैकलिस्टिंग $ (सीडब्ल्यूडी)/एनयूएल भी बना सकते हैं, क्योंकि यह शायद एकमात्र वर्ण डिवाइस है जिसे आप आसानी से विंडोज़ पर उपयोग करेंगे। – iksaif

+0

ठीक है, मुझे असली समाधान मिला, मैंने अपना उत्तर – iksaif

-2

आप फ़ाइल डिस्क्रिप्टर पर fstat का उपयोग कर सकते हैं और परिणामी stat संरचना के डिवाइस सदस्य की तुलना /dev/null के साथ कर सकते हैं और देख सकते हैं कि वे मेल खाते हैं या नहीं।

+1

काम नहीं करता है। _stat हमेशा 2 देता है, जबकि _fstat हमेशा वापसी करता है 0. –

0

यहां एक संभावित समाधान है, लेकिन मुझे विश्वास नहीं है कि यह हर समय काम करता है।मेरा मानना ​​है कि यह एक NUL फ़ाइल वर्णनकर्ता के विशिष्ट मामले के लिए काम करेंगे:

 
int real_isatty(int fd) { 
    DWORD st; 
    HANDLE h; 
    if (!_isatty(fd)) { 
     /* TTY must be a character device */ 
     return 0; 
    } 
    h = (HANDLE)_get_osfhandle(fd); 
    if (h == INVALID_HANDLE_VALUE) { 
     /* Broken handle can't be terminal */ 
     return 0; 
    } 
    if (!GetConsoleMode(h, &st)) { 
     /* GetConsoleMode appears to fail when it's not a TTY. */ 
     return 0; 
    } 
    return 1; 
} 
बस ब्याज से बाहर
संबंधित मुद्दे