void COutputBuffer::Flush() { FILE* fp; if (_type == OUT_FILE) { Flush(_pfile); } else { ASSERTNR(_type == OUT_FILENAME); if (_filename != NULL) { fp = fopen_unsafe(_filename, "a"); if (fp == NULL) { // We might not be able to open the log or full log output // files because someone is grepping or otherwise looking // through them while rl is active. In that case, we don't // want to just kill rl, so just keep accumulating output // and try again next time. Output a warning to the log so // they know it happened (but they won't see it unless the // output is flushed). We could consider having a maximum, // after which we "turn off" this output buffer, but we're // unlikely to ever have so much output that it causes a // problem. Warning("Cannot open '%s' for appending with error '%s'", _filename, strerror_unsafe(errno)); } else { Flush(fp); fclose(fp); } } } }
BOOL CheckForPass(char * filename, char * optReportBuf, char * cmdbuf, BOOL fDumpOutputFile = TRUE) { FILE * fp; char buf[BUFFER_SIZE]; // Check to see if the exe ran at all. fp = fopen_unsafe(filename, "r"); if (fp == NULL) { LogOut("ERROR: Test failed to run. Unable to open file '%s', error '%s' (%s):", filename, strerror_unsafe(errno), optReportBuf); LogOut(" %s", cmdbuf); return FALSE; } // Parse the output file and verify that all lines must be pass/passed, or empty lines BOOL pass = FALSE; while(fgets(buf, BUFFER_SIZE, fp) != NULL) { if(!_strcmpi(buf, "pass\n") || !_strcmpi(buf, "passed\n")) { // Passing strings were found - pass pass = TRUE; } else if(_strcmpi(buf, "\n") != 0) { // Something else other than a newline was found - this is a failure. pass = FALSE; break; } } fclose(fp); if (!pass) { LogOut("ERROR: Test failed to run correctly: pass not found in output file (%s):", optReportBuf); LogOut(" %s", cmdbuf); if (fDumpOutputFile) { DumpFileToLog(filename); } } return pass; }
void DumpFileToLog( char* path ) { FILE* fp; char buf[BUFFER_SIZE]; char* p; fp = fopen_unsafe(path, "r"); if (fp == NULL) { LogError("ERROR: DumpFileToLog couldn't open file '%s' with error '%s'", path, strerror_unsafe(errno)); } else { int fd = _fileno(fp); struct _stat64 fileStats; if (fd != -1 && _fstat64(fd, &fileStats) != -1) { char creationTime[256]; char accessTime[256]; char currTime[256]; __time64_t now = _time64(NULL); _ctime64_s(currTime, &now); _ctime64_s(creationTime, &fileStats.st_ctime); _ctime64_s(accessTime, &fileStats.st_atime); auto stripNewline = [](char *buf) { if (char *ptr = strchr(buf, '\n')) *ptr = '\0'; }; stripNewline(creationTime); stripNewline(accessTime); stripNewline(currTime); LogOut("ERROR: name of output file: %s; size: %I64d; creation: %s, last access: %s, now: %s", path, fileStats.st_size, creationTime, accessTime, currTime); } if (!FNoProgramOutput) { bool printlines = !FOnlyAssertOutput; if (printlines) { LogOut("ERROR: bad output file follows ============"); } while (fgets(buf, BUFFER_SIZE, fp) != NULL) { // Strip the newline, since LogOut adds one p = strchr(buf, '\n'); if (p != NULL) { *p = '\0'; } if (!printlines && strlen(buf) > 8 && buf[0] == 'A' && buf[1] == 'S' && buf[2] == 'S' && buf[3] == 'E' && buf[4] == 'R' && buf[5] == 'T') { printlines = true; LogOut("ERROR: bad output file follows ============"); } if (printlines) { LogOut("%s", buf); } } if (printlines) { LogOut("ERROR: end of bad output file ============"); } } fclose(fp); } }