/*** *gets.c - read a line from stdin * * Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: * defines gets() and getws() - read a line from stdin into buffer * *******************************************************************************/ #include #include #include #include #include #include #include #include #include #ifdef _UNICODE #define _getchar_helper _getwchar_nolock #else /* _UNICODE */ #define _getchar_helper _getchar_nolock #endif /* _UNICODE */ _TCHAR * __cdecl _getts_helper ( _TCHAR *string, size_t bufferSize, int earlyOutIfEOFIsFirstChar ) { int ch = 0; _TCHAR *pointer = string; _TCHAR *retval = string; _VALIDATE_RETURN( (string != NULL), EINVAL, NULL); _VALIDATE_RETURN( (bufferSize > 0), EINVAL, NULL); /* The C Standard states the input buffer should remain unchanged if EOF is encountered immediately. Hence we do not blank out the input buffer here */ _lock_str2(0, stdin); __try { #ifndef _UNICODE _VALIDATE_STREAM_ANSI_SETRET(stdin, EINVAL, retval, NULL); if (retval == NULL) { goto done; } #endif /* _UNICODE */ /* special case: check if the first char is EOF and treat it differently if the user requested so */ ch = _getchar_helper(); if (ch == _TEOF) { retval = NULL; if (earlyOutIfEOFIsFirstChar) goto done; } if (bufferSize == (size_t)-1) { /* insecure case: no buffer size check, no debug filling */ while (ch != _T('\n') && ch != _TEOF) { *pointer++ = (_TCHAR)ch; ch = _getchar_helper(); } *pointer = 0; } else { /* secure case, check buffer size; if buffer overflow, keep on reading until /n or EOF */ size_t available = bufferSize; while (ch != _T('\n') && ch != _TEOF) { if (available > 0) { --available; *pointer++ = (_TCHAR)ch; } ch = _getchar_helper(); } if (available == 0) { _RESET_STRING(string, bufferSize); _RETURN_BUFFER_TOO_SMALL_ERROR(string, bufferSize, NULL); } *pointer = 0; _FILL_STRING(string, bufferSize, bufferSize - available + 1); } /* Common return */ done: ; } __finally { _unlock_str2(0, stdin); } return retval; } /*** *errno_t gets_s(string, sz) - read a line from stdin * *Purpose: * * *Entry: * char *string - place to store read string. * size_t bufferSize - length of dest buffer * *Exit: * returns string, filled in with the line of input * null string if \n found immediately or if EOF found immediately *Exceptions: * *******************************************************************************/ _TCHAR * __cdecl _getts_s ( _TCHAR *string, size_t bufferSize ) { return _getts_helper(string, bufferSize, 0 /* treat first EOF as \n */); } /*** *char *gets(string) - read a line from stdin * *Purpose: * Gets a string from stdin terminated by '\n' or EOF; don't include '\n'; * append '\0'. * *Entry: * char *string - place to store read string, assumes enough room. * *Exit: * returns string, filled in with the line of input * null string if \n found immediately * NULL if EOF found immediately * *Exceptions: * *******************************************************************************/ _TCHAR * __cdecl _getts ( _TCHAR *string ) { return _getts_helper(string, (size_t)-1, 1 /* early out if EOF is first char read */); }