2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
45 #include <sys/types.h>
58 #ifdef GMX_NATIVE_WINDOWS
63 /* Windows file stuff, only necessary for visual studio */
68 #include "thread_mpi/threads.h"
70 #include "gromacs/legacyheaders/gmx_fatal.h"
71 #include "gromacs/legacyheaders/types/commrec.h"
72 #include "gromacs/legacyheaders/network.h"
73 #include "gromacs/legacyheaders/smalloc.h"
74 #include "gromacs/legacyheaders/string2.h"
76 #include "gromacs/fileio/futil.h"
77 #include "gromacs/utility/exceptions.h"
78 #include "gromacs/utility/path.h"
79 #include "gromacs/utility/programcontext.h"
80 #include "gromacs/utility/stringutil.h"
82 /* we keep a linked list of all files opened through pipes (i.e.
83 compressed or .gzipped files. This way we can distinguish between them
84 without having to change the semantics of reading from/writing to files)
86 typedef struct t_pstack {
88 struct t_pstack *prev;
91 static t_pstack *pstack = NULL;
92 static gmx_bool bUnbuffered = FALSE;
94 /* this linked list is an intrinsically globally shared object, so we have
95 to protect it with mutexes */
96 static tMPI_Thread_mutex_t pstack_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
103 void push_ps(FILE *fp)
107 tMPI_Thread_mutex_lock(&pstack_mutex);
114 tMPI_Thread_mutex_unlock(&pstack_mutex);
118 /* don't use pipes!*/
119 #define popen fah_fopen
120 #define pclose fah_fclose
126 #if (!defined(HAVE_PIPES) && !defined(__native_client__))
127 static FILE *popen(const char *nm, const char *mode)
129 gmx_impl("Sorry no pipes...");
134 static int pclose(FILE *fp)
136 gmx_impl("Sorry no pipes...");
140 #endif /* !defined(HAVE_PIPES) && !defined(__native_client__) */
141 #endif /* GMX_FAHCORE */
143 int gmx_ffclose(FILE *fp)
151 tMPI_Thread_mutex_lock(&pstack_mutex);
161 else if (ps->fp == fp)
167 pstack = pstack->prev;
172 while ((ps->prev != NULL) && (ps->prev->fp != fp))
176 if ((ps->prev != NULL) && ps->prev->fp == fp)
178 if (ps->prev->fp != NULL)
180 ret = pclose(ps->prev->fp);
183 ps->prev = ps->prev->prev;
195 tMPI_Thread_mutex_unlock(&pstack_mutex);
205 void frewind(FILE *fp)
207 tMPI_Thread_mutex_lock(&pstack_mutex);
209 t_pstack *ps = pstack;
214 fprintf(stderr, "Cannot rewind compressed file!\n");
215 tMPI_Thread_mutex_unlock(&pstack_mutex);
221 tMPI_Thread_mutex_unlock(&pstack_mutex);
224 int gmx_fseek(FILE *stream, gmx_off_t offset, int whence)
227 return fseeko(stream, offset, whence);
229 #ifdef HAVE__FSEEKI64
230 return _fseeki64(stream, offset, whence);
232 return fseek(stream, offset, whence);
237 gmx_off_t gmx_ftell(FILE *stream)
240 return ftello(stream);
242 #ifdef HAVE__FSEEKI64
243 return _ftelli64(stream);
245 return ftell(stream);
251 gmx_bool is_pipe(FILE *fp)
253 tMPI_Thread_mutex_lock(&pstack_mutex);
255 t_pstack *ps = pstack;
260 tMPI_Thread_mutex_unlock(&pstack_mutex);
265 tMPI_Thread_mutex_unlock(&pstack_mutex);
270 static FILE *uncompress(const char *fn, const char *mode)
275 sprintf(buf, "uncompress -c < %s", fn);
276 fprintf(stderr, "Going to execute '%s'\n", buf);
277 if ((fp = popen(buf, mode)) == NULL)
286 static FILE *gunzip(const char *fn, const char *mode)
291 sprintf(buf, "gunzip -c < %s", fn);
292 fprintf(stderr, "Going to execute '%s'\n", buf);
293 if ((fp = popen(buf, mode)) == NULL)
302 gmx_bool gmx_fexist(const char *fname)
310 test = fopen(fname, "r");
313 /*Windows doesn't allow fopen of directory - so we need to check this seperately */
314 #ifdef GMX_NATIVE_WINDOWS
315 DWORD attr = GetFileAttributes(fname);
316 return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
329 gmx_bool gmx_fexist_master(const char *fname, t_commrec *cr)
335 bExist = gmx_fexist(fname);
339 gmx_bcast(sizeof(bExist), &bExist, cr);
344 gmx_bool gmx_eof(FILE *fp)
355 if ((beof = fread(data, 1, 1, fp)) == 1)
357 gmx_fseek(fp, -1, SEEK_CUR);
363 static char *backup_fn(const char *file, int count_max)
365 /* Use a reasonably low value for countmax; we might
366 * generate 4-5 files in each round, and we dont
367 * want to hit directory limits of 1024 or 2048 files.
371 char *directory, *fn;
376 count_max = COUNTMAX;
379 smalloc(buf, GMX_PATH_MAX);
381 for (i = strlen(file)-1; ((i > 0) && (file[i] != DIR_SEPARATOR)); i--)
385 /* Must check whether i > 0, i.e. whether there is a directory
386 * in the file name. In that case we overwrite the / sign with
387 * a '\0' to end the directory string .
391 directory = gmx_strdup(file);
393 fn = gmx_strdup(file+i+1);
397 directory = gmx_strdup(".");
398 fn = gmx_strdup(file);
402 sprintf(buf, "%s/#%s.%d#", directory, fn, count);
405 while ((count <= count_max) && gmx_fexist(buf));
407 /* Arbitrarily bail out */
408 if (count > count_max)
410 gmx_fatal(FARGS, "Won't make more than %d backups of %s for you.\n"
411 "The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
421 gmx_bool make_backup(const char * name)
428 return FALSE; /* skip making backups */
431 if (gmx_fexist(name))
433 env = getenv("GMX_MAXBACKUP");
436 count_max = strtol(env, NULL, 10);
439 /* Do not make backups and possibly overwrite old files */
445 /* Use the default maximum */
448 backup = backup_fn(name, count_max);
449 if (rename(name, backup) == 0)
451 fprintf(stderr, "\nBack Off! I just backed up %s to %s\n",
456 fprintf(stderr, "Sorry couldn't backup %s to %s\n", name, backup);
465 FILE *gmx_ffopen(const char *file, const char *mode)
468 return fopen(file, mode);
471 char buf[256], *bufsize = 0, *ptr;
486 bRead = (mode[0] == 'r' && mode[1] != '+');
488 if (!bRead || gmx_fexist(buf))
490 if ((ff = fopen(buf, mode)) == NULL)
495 /* Check whether we should be using buffering (default) or not
498 if (bUnbuffered || ((bufsize = getenv("LOG_BUFS")) != NULL))
500 /* Check whether to use completely unbuffered */
507 bs = strtol(bufsize, NULL, 10);
516 if (setvbuf(ff, ptr, _IOFBF, bs) != 0)
518 gmx_file("Buffering File");
526 sprintf(buf, "%s.Z", file);
529 ff = uncompress(buf, mode);
533 sprintf(buf, "%s.gz", file);
536 ff = gunzip(buf, mode);
548 /* Our own implementation of dirent-like functionality to scan directories. */
553 #elif (defined GMX_NATIVE_WINDOWS)
554 intptr_t windows_handle;
555 struct _finddata_t finddata;
564 gmx_directory_open(gmx_directory_t *p_gmxdir, const char *dirname)
566 struct gmx_directory * gmxdir;
574 if ( (gmxdir->dirent_handle = opendir(dirname)) != NULL)
584 #elif (defined GMX_NATIVE_WINDOWS)
586 if (dirname != NULL && strlen(dirname) > 0)
591 len = strlen(dirname);
592 snew(tmpname, len+3);
594 strncpy(tmpname, dirname, len+1);
596 /* Remove possible trailing directory separator */
597 if (tmpname[len] == '/' || tmpname[len] == '\\')
603 strcat(tmpname, "/*");
606 if ( (gmxdir->windows_handle = _findfirst(tmpname, &gmxdir->finddata)) > 0L)
630 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n"
631 "In the very unlikely event this is not a compile-time mistake you could consider\n"
632 "implementing support for your platform in futil.c, but contact the developers\n"
633 "to make sure it's really necessary!\n");
641 gmx_directory_nextfile(gmx_directory_t gmxdir, char *name, int maxlength_name)
647 struct dirent * direntp_large;
651 if (gmxdir != NULL && gmxdir->dirent_handle != NULL)
653 /* On some platforms no space is present for d_name in dirent.
654 * Since d_name is guaranteed to be the last entry, allocating
655 * extra space for dirent will allow more size for d_name.
656 * GMX_MAX_PATH should always be >= the max possible d_name.
658 smalloc(direntp_large, sizeof(*direntp_large) + GMX_PATH_MAX);
659 rc = readdir_r(gmxdir->dirent_handle, direntp_large, &p);
661 if (p != NULL && rc == 0)
663 strncpy(name, direntp_large->d_name, maxlength_name);
670 sfree(direntp_large);
678 #elif (defined GMX_NATIVE_WINDOWS)
682 if (gmxdir->windows_handle <= 0)
688 else if (gmxdir->first == 1)
690 strncpy(name, gmxdir->finddata.name, maxlength_name);
696 if (_findnext(gmxdir->windows_handle, &gmxdir->finddata) == 0)
698 strncpy(name, gmxdir->finddata.name, maxlength_name);
711 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
719 gmx_directory_close(gmx_directory_t gmxdir)
723 rc = (gmxdir != NULL) ? closedir(gmxdir->dirent_handle) : EINVAL;
724 #elif (defined GMX_NATIVE_WINDOWS)
725 rc = (gmxdir != NULL) ? _findclose(gmxdir->windows_handle) : EINVAL;
728 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
737 char *low_gmxlibfn(const char *file, gmx_bool bAddCWD, gmx_bool bFatal)
739 bool bEnvIsSet = false;
742 if (bAddCWD && gmx_fexist(file))
744 return gmx_strdup(file);
749 // GMXLIB can be a path.
750 const char *lib = getenv("GMXLIB");
758 libpath = gmx::getProgramContext().defaultLibraryDataPath();
761 std::vector<std::string> pathEntries;
762 gmx::Path::splitPathEnvironment(libpath, &pathEntries);
763 std::vector<std::string>::const_iterator i;
764 for (i = pathEntries.begin(); i != pathEntries.end(); ++i)
766 std::string testPath = gmx::Path::join(*i, file);
767 if (gmx::Path::exists(testPath))
769 return gmx_strdup(testPath.c_str());
774 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
780 "Library file %s not found %sin your GMXLIB path.",
781 file, bAddCWD ? "in current dir nor " : "");
786 "Library file %s not found %sin default directories.\n"
787 "(You can set the directories to search with the GMXLIB path variable)",
788 file, bAddCWD ? "in current dir nor " : "");
794 FILE *low_libopen(const char *file, gmx_bool bFatal)
799 fn = low_gmxlibfn(file, TRUE, bFatal);
809 fprintf(debug, "Opening library file %s\n", fn);
818 char *gmxlibfn(const char *file)
820 return low_gmxlibfn(file, TRUE, TRUE);
823 FILE *libopen(const char *file)
825 return low_libopen(file, TRUE);
828 void gmx_tmpnam(char *buf)
832 if ((len = strlen(buf)) < 7)
834 gmx_fatal(FARGS, "Buf passed to gmx_tmpnam must be at least 7 bytes long");
836 for (i = len-6; (i < len); i++)
840 /* mktemp is dangerous and we should use mkstemp instead, but
841 * since windows doesnt support it we have to separate the cases.
842 * 20090307: mktemp deprecated, use iso c++ _mktemp instead.
844 #ifdef GMX_NATIVE_WINDOWS
847 int fd = mkstemp(buf);
852 gmx_fatal(FARGS, "Invalid template %s for mkstemp", buf);
855 gmx_fatal(FARGS, "mkstemp created existing file", buf);
858 gmx_fatal(FARGS, "Permission denied for opening %s", buf);
865 /* name in Buf should now be OK */
868 int gmx_truncatefile(char *path, gmx_off_t length)
871 /* Microsoft visual studio does not have "truncate" */
873 LARGE_INTEGER win_length;
875 win_length.QuadPart = length;
877 fh = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
878 OPEN_EXISTING, 0, NULL);
879 SetFilePointerEx(fh, win_length, NULL, FILE_BEGIN);
885 return truncate(path, length);
890 int gmx_file_rename(const char *oldname, const char *newname)
892 #ifndef GMX_NATIVE_WINDOWS
893 /* under unix, rename() is atomic (at least, it should be). */
894 return rename(oldname, newname);
896 if (MoveFileEx(oldname, newname,
897 MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH))
908 int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_empty)
910 /* the full copy buffer size: */
911 #define FILECOPY_BUFSIZE (1<<16)
916 snew(buf, FILECOPY_BUFSIZE);
918 in = fopen(oldname, "rb");
924 /* If we don't copy when empty, we postpone opening the file
925 until we're actually ready to write. */
928 out = fopen(newname, "wb");
939 nread = fread(buf, sizeof(char), FILECOPY_BUFSIZE, in);
945 /* so this is where we open when copy_if_empty is false:
946 here we know we read something. */
947 out = fopen(newname, "wb");
953 ret = fwrite(buf, sizeof(char), nread, out);
979 #undef FILECOPY_BUFSIZE
983 int gmx_fsync(FILE *fp)
988 /* the fahcore defines its own os-independent fsync */
990 #else /* GMX_FAHCORE */
994 /* get the file number */
995 #if defined(HAVE_FILENO)
997 #elif defined(HAVE__FILENO)
1001 /* do the actual fsync */
1004 #if (defined(HAVE_FSYNC))
1006 #elif (defined(HAVE__COMMIT))
1011 #endif /* GMX_FAHCORE */
1013 /* We check for these error codes this way because POSIX requires them
1014 to be defined, and using anything other than macros is unlikely: */
1016 /* we don't want to report an error just because fsync() caught a signal.
1017 For our purposes, we can just ignore this. */
1018 if (rc && errno == EINTR)
1024 /* we don't want to report an error just because we tried to fsync()
1025 stdout, a socket or a pipe. */
1026 if (rc && errno == EINVAL)
1034 void gmx_chdir(const char *directory)
1036 #ifdef GMX_NATIVE_WINDOWS
1037 int rc = _chdir(directory);
1039 int rc = chdir(directory);
1043 gmx_fatal(FARGS, "Cannot change directory to '%s'. Reason: %s",
1044 directory, strerror(errno));
1048 void gmx_getcwd(char *buffer, size_t size)
1050 #ifdef GMX_NATIVE_WINDOWS
1051 char *pdum = _getcwd(buffer, size);
1053 char *pdum = getcwd(buffer, size);
1057 gmx_fatal(FARGS, "Cannot get working directory. Reason: %s",