* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team,
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "gmxpre.h"
+
+#include "config.h"
-#include <ctype.h>
-#include <stdio.h>
#include <errno.h>
+#include <stdio.h>
+#include <string.h>
#ifdef HAVE_IO_H
#include <io.h>
#endif
#include <unistd.h>
#endif
-#include "gmx_fatal.h"
-#include "macros.h"
-#include "smalloc.h"
-#include "futil.h"
+#include "thread_mpi/threads.h"
+
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/legacyheaders/macros.h"
+#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/futil.h"
#include "filenm.h"
-#include "string2.h"
+#include "gromacs/utility/cstringutil.h"
#include "gmxfio.h"
#include "md5.h"
-#ifdef GMX_THREAD_MPI
-#include "thread_mpi.h"
-#endif
-
#include "gmxfio_int.h"
/* This is the new improved and thread safe version of gmxfio. */
static t_fileio *open_files = NULL;
-#ifdef GMX_THREAD_MPI
/* this mutex locks the open_files structure so that no two threads can
modify it.
iterating along all open files. All these cases should be rare
during the simulation. */
static tMPI_Thread_mutex_t open_file_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
-#endif
/* These simple lists define the I/O type for these files */
static const int ftpXDR[] =
-{ efTPR, efTRR, efEDR, efXTC, efMTX, efCPT };
+{ efTPR, efTRR, efEDR, efXTC, efTNG, efMTX, efCPT };
static const int ftpASC[] =
-{ efTPA, efGRO, efPDB };
+{ efGRO, efPDB, efG96 };
static const int ftpBIN[] =
-{ efTPB, efTRJ };
+{ efTNG };
#ifdef HAVE_XML
static const int ftpXML[] =
{ efXML};
#endif
-const char *itemstr[eitemNR] =
-{
- "[header]", "[inputrec]", "[box]", "[topology]", "[coordinates]",
- "[velocities]", "[forces]"
-};
-
const char *eioNames[eioNR] =
{
"REAL", "INT", "GMX_STE_T", "UCHAR", "NUCHAR", "USHORT", "RVEC", "NRVEC",
"IVEC", "STRING"
};
-
-
-/* Comment strings for TPA only */
-const char *comment_str[eitemNR] = {
- "; The header holds information on the number of atoms etc. and on whether\n"
- "; certain items are present in the file or not.\n"
- "; \n"
- "; WARNING\n"
- "; DO NOT EDIT THIS FILE BY HAND\n"
- "; The GROMACS preprocessor performs a lot of checks on your input that\n"
- "; you ignore when editing this. Your simulation may crash because of this\n",
- "; The inputrec holds the parameters for MD such as the number of steps,\n"
- "; the timestep and the cut-offs.\n",
- "; The simulation box in nm.\n",
- "; The topology section describes the topology of the molecules\n"
- "; i.e. bonds, angles and dihedrals etc. and also holds the force field\n"
- "; parameters.\n",
- "; The atomic coordinates in nm\n",
- "; The atomic velocities in nm/ps\n",
- "; The forces on the atoms in nm/ps^2\n"
-};
-
-
-
-
/******************************************************************
*
* Internal functions:
type of access to the fio's elements. */
void gmx_fio_lock(t_fileio *fio)
{
-#ifdef GMX_THREAD_MPI
tMPI_Lock_lock(&(fio->mtx));
-#endif
}
/* unlock the mutex associated with this fio. */
void gmx_fio_unlock(t_fileio *fio)
{
-#ifdef GMX_THREAD_MPI
tMPI_Lock_unlock(&(fio->mtx));
-#endif
}
/* make a dummy head element, assuming we locked everything. */
open_files->fn = NULL;
open_files->next = open_files;
open_files->prev = open_files;
-#ifdef GMX_THREAD_MPI
tMPI_Lock_init(&(open_files->mtx));
-#endif
}
}
static void gmx_fio_insert(t_fileio *fio)
{
t_fileio *prev;
-#ifdef GMX_THREAD_MPI
/* first lock the big open_files mutex. */
tMPI_Thread_mutex_lock(&open_file_mutex);
-#endif
/* now check whether the dummy element has been allocated,
and allocate it if it hasn't */
gmx_fio_make_dummy();
gmx_fio_unlock(open_files);
gmx_fio_unlock(fio);
-#ifdef GMX_THREAD_MPI
/* now unlock the big open_files mutex. */
tMPI_Thread_mutex_unlock(&open_file_mutex);
-#endif
}
/* remove a t_fileio into the list. We assume the fio is locked, and we leave
t_fileio *ret;
/* first lock the big open_files mutex and the dummy's mutex */
-#ifdef GMX_THREAD_MPI
/* first lock the big open_files mutex. */
tMPI_Thread_mutex_lock(&open_file_mutex);
-#endif
gmx_fio_make_dummy();
gmx_fio_lock(open_files);
if (fio->next == open_files)
{
ret = NULL;
-#ifdef GMX_THREAD_MPI
tMPI_Thread_mutex_unlock(&open_file_mutex);
-#endif
}
else
{
static void gmx_fio_stop_getting_next(t_fileio *fio)
{
gmx_fio_unlock(fio);
-#ifdef GMX_THREAD_MPI
tMPI_Thread_mutex_unlock(&open_file_mutex);
-#endif
}
gmx_bool bRead, bReadWrite;
int xdrid;
- if (fn2ftp(fn) == efTPA)
+ /* 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, mode);
+ strcpy(newmode, "w");
+ }
+ else if (strncmp(mode, "a+", 2) == 0)
+ {
+ strcpy(newmode, "a+");
+ }
+ else if (mode[0] == 'a')
+ {
+ strcpy(newmode, "a");
}
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);
- }
+ gmx_fatal(FARGS, "DEATH HORROR in gmx_fio_open, mode is '%s'", mode);
}
/* Check if it should be opened as a binary file */
}
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;
if (fn)
{
fio->iFTP = fn2ftp(fn);
- fio->fn = strdup(fn);
+ fio->fn = gmx_strdup(fn);
fio->bStdio = FALSE;
/* If this file type is in the list of XDR files, open it like that */
gmx_open(fn);
}
}
+ if (fn2ftp(fn) == efTNG)
+ {
+ gmx_incons("gmx_fio_open may not be used to open TNG files");
+ }
/* Open the file */
- fio->fp = ffopen(fn, newmode);
+ fio->fp = gmx_ffopen(fn, newmode);
/* determine the XDR direction */
if (newmode[0] == 'w' || newmode[0] == 'a')
else
{
/* If it is not, open it as a regular file */
- fio->fp = ffopen(fn, newmode);
+ fio->fp = gmx_ffopen(fn, newmode);
}
/* for appending seek to end of file to make sure ftell gives correct position
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);
/* Don't close stdin and stdout! */
if (!fio->bStdio && fio->fp != NULL)
{
- rc = ffclose(fio->fp); /* fclose returns 0 if happy */
+ rc = gmx_ffclose(fio->fp); /* fclose returns 0 if happy */
}
fio->bOpen = FALSE;
{
int rc = 0;
-#ifdef GMX_THREAD_MPI
/* first lock the big open_files mutex. */
/* We don't want two processes operating on the list at the same time */
tMPI_Thread_mutex_lock(&open_file_mutex);
-#endif
+ if (fio->iFTP == efTNG)
+ {
+ gmx_incons("gmx_fio_close should not be called on a TNG file");
+ }
gmx_fio_lock(fio);
/* first remove it from the list */
gmx_fio_remove(fio);
sfree(fio->fn);
sfree(fio);
-#ifdef GMX_THREAD_MPI
tMPI_Thread_mutex_unlock(&open_file_mutex);
-#endif
return rc;
}
gmx_fio_lock(fio);
if (!in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR) && !fio->bStdio)
{
- rc = ffclose(fio->fp); /* fclose returns 0 if happy */
+ rc = gmx_ffclose(fio->fp); /* fclose returns 0 if happy */
fio->fp = NULL;
}
gmx_fio_unlock(fio);
{
/*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;
+ md5_state_t state;
+ unsigned char *buf;
+ gmx_off_t read_len;
+ gmx_off_t seek_offset;
+ int ret = -1;
seek_offset = offset - CPT_CHK_LEN;
if (seek_offset < 0)
return -1;
}
+ snew(buf, CPT_CHK_LEN);
/* the read puts the file position back to offset */
if ((gmx_off_t)fread(buf, 1, read_len, fio->fp) != read_len)
{
if (!ret)
{
- md5_init(&state);
- md5_append(&state, buf, read_len);
- md5_finish(&state, digest);
- return read_len;
- }
- else
- {
- return ret;
+ gmx_md5_init(&state);
+ gmx_md5_append(&state, buf, read_len);
+ gmx_md5_finish(&state, digest);
+ ret = read_len;
}
+ sfree(buf);
+ return ret;
}
return 0;
}
-int gmx_fio_check_file_position(t_fileio gmx_unused *fio)
-{
- /* If gmx_off_t is 4 bytes we can not store file offset > 2 GB.
- * If we do not have ftello, we will play it safe.
- */
-#if (SIZEOF_GMX_OFF_T == 4 || !defined HAVE_FSEEKO)
- gmx_off_t offset;
-
- gmx_fio_lock(fio);
- gmx_fio_int_get_file_position(fio, &offset);
- /* We have a 4 byte offset,
- * make sure that we will detect out of range for all possible cases.
- */
- if (offset < 0 || offset > 2147483647)
- {
- fio->bLargerThan_off_t = TRUE;
- }
- gmx_fio_unlock(fio);
-#endif
-
- return 0;
-}
-
int gmx_fio_get_output_file_positions(gmx_file_position_t **p_outputfiles,
int *p_nfiles)
{
strncpy(outputfiles[nfiles].filename, cur->fn, STRLEN - 1);
/* Get the file position */
- if (cur->bLargerThan_off_t)
- {
- /* -1 signals out of range */
- outputfiles[nfiles].offset = -1;
- outputfiles[nfiles].chksum_size = -1;
- }
- else
- {
- gmx_fio_int_get_file_position(cur, &outputfiles[nfiles].offset);
+ gmx_fio_int_get_file_position(cur, &outputfiles[nfiles].offset);
#ifndef GMX_FAHCORE
- outputfiles[nfiles].chksum_size
- = gmx_fio_int_get_file_md5(cur,
- outputfiles[nfiles].offset,
- outputfiles[nfiles].chksum);
+ outputfiles[nfiles].chksum_size
+ = gmx_fio_int_get_file_md5(cur,
+ outputfiles[nfiles].offset,
+ outputfiles[nfiles].chksum);
#endif
- }
-
nfiles++;
}