static gmx_bool gmx_one_before_eof(FILE *fp) { char data[4]; gmx_bool beof; if ((beof = fread(data, 1, 1, fp)) == 1) { gmx_fseek(fp, -1, SEEK_CUR); } return !beof; }
gmx_bool gmx_eof(FILE *fp) { char data[4]; gmx_bool beof; if (is_pipe(fp)) return feof(fp); else { if ((beof=fread(data,1,1,fp))==1) gmx_fseek(fp,-1,SEEK_CUR); return !beof; } }
int gmx_fio_seek(t_fileio* fio, gmx_off_t fpos) { int rc; gmx_fio_lock(fio); if (fio->fp) { rc = gmx_fseek(fio->fp, fpos, SEEK_SET); } else { gmx_file(fio->fn); rc = -1; } gmx_fio_unlock(fio); return rc; }
/* internal variant of get_file_md5 that operates on a locked file */ static int gmx_fio_int_get_file_md5(t_fileio *fio, gmx_off_t offset, unsigned char digest[]) { /*1MB: large size important to catch almost identical files */ #define CPT_CHK_LEN 1048576 md5_state_t state; unsigned char buf[CPT_CHK_LEN]; gmx_off_t read_len; gmx_off_t seek_offset; int ret = -1; seek_offset = offset - CPT_CHK_LEN; if (seek_offset < 0) { seek_offset = 0; } read_len = offset - seek_offset; if (fio->fp && fio->bReadWrite) { ret = gmx_fseek(fio->fp, seek_offset, SEEK_SET); if (ret) { gmx_fseek(fio->fp, 0, SEEK_END); } } if (ret) /*either no fp, not readwrite, or fseek not successful */ { return -1; } /* the read puts the file position back to offset */ if ((gmx_off_t)fread(buf, 1, read_len, fio->fp) != read_len) { /* not fatal: md5sum check to prevent overwriting files * works (less safe) without * */ if (ferror(fio->fp)) { fprintf(stderr, "\nTrying to get md5sum: %s: %s\n", fio->fn, strerror(errno)); } else if (feof(fio->fp)) { /* * For long runs that checkpoint frequently but write e.g. logs * infrequently we don't want to issue lots of warnings before we * have written anything to the log. */ if (0) { fprintf(stderr, "\nTrying to get md5sum: EOF: %s\n", fio->fn); } } else { fprintf( stderr, "\nTrying to get md5sum: Unknown reason for short read: %s\n", fio->fn); } gmx_fseek(fio->fp, 0, SEEK_END); ret = -1; } gmx_fseek(fio->fp, 0, SEEK_END); /*is already at end, but under windows it gives problems otherwise*/ if (debug) { fprintf(debug, "chksum %s readlen %ld\n", fio->fn, (long int)read_len); } if (!ret) { md5_init(&state); md5_append(&state, buf, read_len); md5_finish(&state, digest); return read_len; } else { return ret; } }
/***************************************************************** * * EXPORTED SECTION * *****************************************************************/ t_fileio *gmx_fio_open(const char *fn, const char *mode) { t_fileio *fio = NULL; int i; char newmode[5]; gmx_bool bRead, bReadWrite; int xdrid; if (fn2ftp(fn) == efTPA) { strcpy(newmode, mode); } else { /* sanitize the mode string */ if (strncmp(mode, "r+", 2) == 0) { strcpy(newmode, "r+"); } else if (mode[0] == 'r') { strcpy(newmode, "r"); } else if (strncmp(mode, "w+", 2) == 0) { strcpy(newmode, "w+"); } else if (mode[0] == 'w') { strcpy(newmode, "w"); } else if (strncmp(mode, "a+", 2) == 0) { strcpy(newmode, "a+"); } else if (mode[0] == 'a') { strcpy(newmode, "a"); } else { gmx_fatal(FARGS, "DEATH HORROR in gmx_fio_open, mode is '%s'", mode); } } /* Check if it should be opened as a binary file */ if (strncmp(ftp2ftype(fn2ftp(fn)), "ASCII", 5)) { /* Not ascii, add b to file mode */ if ((strchr(newmode, 'b') == NULL) && (strchr(newmode, 'B') == NULL)) { strcat(newmode, "b"); } } snew(fio, 1); #ifdef GMX_THREAD_MPI tMPI_Lock_init(&(fio->mtx)); #endif bRead = (newmode[0] == 'r' && newmode[1] != '+'); bReadWrite = (newmode[1] == '+'); fio->fp = NULL; fio->xdr = NULL; if (fn) { fio->iFTP = fn2ftp(fn); fio->fn = strdup(fn); fio->bStdio = FALSE; /* If this file type is in the list of XDR files, open it like that */ if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR)) { /* First check whether we have to make a backup, * only for writing, not for read or append. */ if (newmode[0] == 'w') { #ifndef GMX_FAHCORE /* only make backups for normal gromacs */ make_backup(fn); #endif } else { /* Check whether file exists */ if (!gmx_fexist(fn)) { gmx_open(fn); } } /* Open the file */ fio->fp = ffopen(fn, newmode); /* determine the XDR direction */ if (newmode[0] == 'w' || newmode[0] == 'a') { fio->xdrmode = XDR_ENCODE; } else { fio->xdrmode = XDR_DECODE; } snew(fio->xdr, 1); xdrstdio_create(fio->xdr, fio->fp, fio->xdrmode); } else { /* If it is not, open it as a regular file */ fio->fp = ffopen(fn, newmode); } /* for appending seek to end of file to make sure ftell gives correct position * important for checkpointing */ if (newmode[0] == 'a') { gmx_fseek(fio->fp, 0, SEEK_END); } } else { /* Use stdin/stdout for I/O */ fio->iFTP = efTPA; fio->fp = bRead ? stdin : stdout; fio->fn = strdup("STDIO"); fio->bStdio = TRUE; } fio->bRead = bRead; fio->bReadWrite = bReadWrite; fio->bDouble = (sizeof(real) == sizeof(double)); fio->bDebug = FALSE; fio->bOpen = TRUE; fio->bLargerThan_off_t = FALSE; /* set the reader/writer functions */ gmx_fio_set_iotype(fio); /* and now insert this file into the list of open files. */ gmx_fio_insert(fio); return fio; }
static gmx_bool do_binread(t_fileio *fio, void *item, int nitem, int eio, const char *desc, const char *srcfile, int line) { size_t size = 0, rsize; int ssize; gmx_fio_check_nitem(fio, eio, nitem, srcfile, line); switch (eio) { case eioREAL: if (fio->bDouble) { size = sizeof(double); } else { size = sizeof(float); } break; case eioFLOAT: size = sizeof(float); break; case eioDOUBLE: size = sizeof(double); break; case eioINT: size = sizeof(int); break; case eioGMX_LARGE_INT: size = sizeof(gmx_large_int_t); break; case eioUCHAR: size = sizeof(unsigned char); break; case eioNUCHAR: size = sizeof(unsigned char); break; case eioUSHORT: size = sizeof(unsigned short); break; case eioRVEC: case eioNRVEC: if (fio->bDouble) { size = sizeof(double) * DIM; } else { size = sizeof(float) * DIM; } break; case eioIVEC: size = sizeof(ivec); break; case eioSTRING: do_binread(fio, &ssize, 1, eioINT, desc, srcfile, line); size = ssize; break; default: gmx_fio_fe(fio, eio, desc, srcfile, line); } if (item) { rsize = fread(item, size, nitem, fio->fp); } else { /* Skip over it if we have a NULL pointer here */ gmx_fseek(fio->fp, (gmx_off_t)(size*nitem), SEEK_CUR); rsize = nitem; } if ((rsize != nitem) && (fio->bDebug)) { fprintf(stderr, "Error reading %s %s from file %s (source %s, line %d)\n", eioNames[eio], desc, fio->fn, srcfile, line); } return (rsize == nitem); }