size_t file_storage::file_size(int file_handle) { if (file_handle == INVALID_HANDLE) return 0; // This is required because off_t is defined as long, which is 32 bits in // msvc and 64 bits in linux/osx, and stat contains off_t. #ifdef _WIN32 #ifdef _WIN64 struct _stat64 sbuf; if (_fstat64(file_handle, &sbuf) == FAIL) return 0; #else struct _stat32 sbuf; if (_fstat32(file_handle, &sbuf) == FAIL) return 0; #endif #else // Limited to 32 bit files on 32 bit systems, see linux.die.net/man/2/open struct stat sbuf; if (fstat(file_handle, &sbuf) == FAIL) return 0; #endif // Convert signed to unsigned size. BITCOIN_ASSERT_MSG(sbuf.st_size > 0, "File size cannot be 0 bytes."); return static_cast<size_t>(sbuf.st_size); }
int __cdecl fstat(int _Desc,struct stat *_Stat) { struct _stat32 st; int ret=_fstat32(_Desc,&st); if (ret == -1) { memset(_Stat,0,sizeof(struct stat)); return -1; } /* struct stat and struct _stat32 are the same for this case. */ memcpy(_Stat, &st, sizeof(struct _stat32)); return ret; }
static int GM_CDECL gmfFileInfo(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_STRING_PARAM(filename, 0); #ifdef IS64BIT // Compatible with 64bit OS struct _stat32 buf; int fh, result; if((fh = _open(filename, _O_RDONLY)) == -1) return GM_OK; // return null result = _fstat32(fh, &buf); // Get data associated with "fh" if(result == 0) //function obtained data correctly (0 == success, -1 == fail) { // create and push a gmFileInfoUser object gmFileInfoUser * fileInfo = (gmFileInfoUser *) a_thread->GetMachine()->Sys_Alloc(sizeof(gmFileInfoUser)); fileInfo->m_creationTime = buf.st_ctime; fileInfo->m_accessedTime = buf.st_atime; fileInfo->m_modifiedTime = buf.st_mtime; fileInfo->m_size = buf.st_size; a_thread->PushNewUser(fileInfo, s_gmFileInfoType); } _close( fh ); #else struct _stat buf; int fh, result; if((fh = _open(filename, _O_RDONLY)) == -1) return GM_OK; // return null result = _fstat(fh, &buf); // Get data associated with "fh" if(result == 0) //function obtained data correctly (0 == success, -1 == fail) { // create and push a gmFileInfoUser object gmFileInfoUser * fileInfo = (gmFileInfoUser *) a_thread->GetMachine()->Sys_Alloc(sizeof(gmFileInfoUser)); fileInfo->m_creationTime = buf.st_ctime; fileInfo->m_accessedTime = buf.st_atime; fileInfo->m_modifiedTime = buf.st_mtime; fileInfo->m_size = buf.st_size; a_thread->PushNewUser(fileInfo, s_gmFileInfoType); } _close( fh ); #endif return GM_OK; }
buf32_t* _read_file(char * file_path) { buf32_t *file_content; uint8_t *pd; struct _stat32 s; FILE* fd; size_t bytes; long l; long rest; fd = fopen(file_path, "rb"); if (fd == 0) { printf("Input file %s does not exist\n", file_path); goto open_failed; } //if (fstat (fd, &s) != 0) if (_fstat32(fd->_file, &s) != 0) { printf("Could not stat input file %s\n", file_path); goto stat_failed; } printf("debug: file size = %d, 0x%x\n",s.st_size, s.st_size); l = s.st_size; if ((file_content = buf32_Create(4 + l)) == NULL) { printf("Could not allocate memory for reading file %s\n", file_path); goto malloc_failed; } pd = file_content->buffer; rest = l; while (rest > 0) { bytes = fread(pd + (l - rest), 1, rest, fd); if (bytes < 0) { printf("Could not read file %s\n", file_path); goto read_failed; } else if (bytes == 0) { break; //end of file } rest -= bytes; } file_content->length = l; // No special error treatment necessary, we need to unmap and close // the file anyway. fclose(fd); return file_content; // Clean up on error. read_failed: free(file_content); malloc_failed: stat_failed: fclose(fd); open_failed: return(0);// NULL; }