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
64 /* Windows file stuff, only necessary for visual studio */
69 #include "thread_mpi/threads.h"
71 #include "gromacs/legacyheaders/gmx_fatal.h"
72 #include "gromacs/legacyheaders/types/commrec.h"
73 #include "gromacs/legacyheaders/network.h"
75 #include "gromacs/fileio/futil.h"
76 #include "gromacs/fileio/path.h"
77 #include "gromacs/utility/cstringutil.h"
78 #include "gromacs/utility/exceptions.h"
79 #include "gromacs/utility/programcontext.h"
80 #include "gromacs/utility/smalloc.h"
81 #include "gromacs/utility/stringutil.h"
83 /* we keep a linked list of all files opened through pipes (i.e.
84 compressed or .gzipped files. This way we can distinguish between them
85 without having to change the semantics of reading from/writing to files)
87 typedef struct t_pstack {
89 struct t_pstack *prev;
92 static t_pstack *pstack = NULL;
93 static gmx_bool bUnbuffered = FALSE;
95 /* this linked list is an intrinsically globally shared object, so we have
96 to protect it with mutexes */
97 static tMPI_Thread_mutex_t pstack_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
104 void push_ps(FILE *fp)
108 tMPI_Thread_mutex_lock(&pstack_mutex);
115 tMPI_Thread_mutex_unlock(&pstack_mutex);
119 /* don't use pipes!*/
120 #define popen fah_fopen
121 #define pclose fah_fclose
127 #if (!defined(HAVE_PIPES) && !defined(__native_client__))
128 static FILE *popen(const char *nm, const char *mode)
130 gmx_impl("Sorry no pipes...");
135 static int pclose(FILE *fp)
137 gmx_impl("Sorry no pipes...");
141 #endif /* !defined(HAVE_PIPES) && !defined(__native_client__) */
142 #endif /* GMX_FAHCORE */
144 int gmx_ffclose(FILE *fp)
152 tMPI_Thread_mutex_lock(&pstack_mutex);
162 else if (ps->fp == fp)
168 pstack = pstack->prev;
173 while ((ps->prev != NULL) && (ps->prev->fp != fp))
177 if ((ps->prev != NULL) && ps->prev->fp == fp)
179 if (ps->prev->fp != NULL)
181 ret = pclose(ps->prev->fp);
184 ps->prev = ps->prev->prev;
196 tMPI_Thread_mutex_unlock(&pstack_mutex);
206 void frewind(FILE *fp)
208 tMPI_Thread_mutex_lock(&pstack_mutex);
210 t_pstack *ps = pstack;
215 fprintf(stderr, "Cannot rewind compressed file!\n");
216 tMPI_Thread_mutex_unlock(&pstack_mutex);
222 tMPI_Thread_mutex_unlock(&pstack_mutex);
225 int gmx_fseek(FILE *stream, gmx_off_t offset, int whence)
228 return fseeko(stream, offset, whence);
230 #ifdef HAVE__FSEEKI64
231 return _fseeki64(stream, offset, whence);
233 return fseek(stream, offset, whence);
238 gmx_off_t gmx_ftell(FILE *stream)
241 return ftello(stream);
243 #ifdef HAVE__FSEEKI64
245 return _ftelli64(stream);
247 return ftello64(stream);
250 return ftell(stream);
256 gmx_bool is_pipe(FILE *fp)
258 tMPI_Thread_mutex_lock(&pstack_mutex);
260 t_pstack *ps = pstack;
265 tMPI_Thread_mutex_unlock(&pstack_mutex);
270 tMPI_Thread_mutex_unlock(&pstack_mutex);
275 static FILE *uncompress(const char *fn, const char *mode)
280 sprintf(buf, "uncompress -c < %s", fn);
281 fprintf(stderr, "Going to execute '%s'\n", buf);
282 if ((fp = popen(buf, mode)) == NULL)
291 static FILE *gunzip(const char *fn, const char *mode)
296 sprintf(buf, "gunzip -c < %s", fn);
297 fprintf(stderr, "Going to execute '%s'\n", buf);
298 if ((fp = popen(buf, mode)) == NULL)
307 gmx_bool gmx_fexist(const char *fname)
315 test = fopen(fname, "r");
318 /*Windows doesn't allow fopen of directory - so we need to check this seperately */
319 #ifdef GMX_NATIVE_WINDOWS
320 DWORD attr = GetFileAttributes(fname);
321 return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
334 gmx_bool gmx_fexist_master(const char *fname, t_commrec *cr)
340 bExist = gmx_fexist(fname);
344 gmx_bcast(sizeof(bExist), &bExist, cr);
349 gmx_bool gmx_eof(FILE *fp)
360 if ((beof = fread(data, 1, 1, fp)) == 1)
362 gmx_fseek(fp, -1, SEEK_CUR);
368 static char *backup_fn(const char *file, int count_max)
370 /* Use a reasonably low value for countmax; we might
371 * generate 4-5 files in each round, and we dont
372 * want to hit directory limits of 1024 or 2048 files.
376 char *directory, *fn;
381 count_max = COUNTMAX;
384 smalloc(buf, GMX_PATH_MAX);
386 for (i = strlen(file)-1; ((i > 0) && (file[i] != DIR_SEPARATOR)); i--)
390 /* Must check whether i > 0, i.e. whether there is a directory
391 * in the file name. In that case we overwrite the / sign with
392 * a '\0' to end the directory string .
396 directory = gmx_strdup(file);
398 fn = gmx_strdup(file+i+1);
402 directory = gmx_strdup(".");
403 fn = gmx_strdup(file);
407 sprintf(buf, "%s/#%s.%d#", directory, fn, count);
410 while ((count <= count_max) && gmx_fexist(buf));
412 /* Arbitrarily bail out */
413 if (count > count_max)
415 gmx_fatal(FARGS, "Won't make more than %d backups of %s for you.\n"
416 "The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
426 gmx_bool make_backup(const char * name)
433 return FALSE; /* skip making backups */
436 if (gmx_fexist(name))
438 env = getenv("GMX_MAXBACKUP");
441 count_max = strtol(env, NULL, 10);
444 /* Do not make backups and possibly overwrite old files */
450 /* Use the default maximum */
453 backup = backup_fn(name, count_max);
454 if (rename(name, backup) == 0)
456 fprintf(stderr, "\nBack Off! I just backed up %s to %s\n",
461 fprintf(stderr, "Sorry couldn't backup %s to %s\n", name, backup);
470 FILE *gmx_ffopen(const char *file, const char *mode)
473 return fopen(file, mode);
476 char buf[256], *bufsize = 0, *ptr;
491 bRead = (mode[0] == 'r' && mode[1] != '+');
493 if (!bRead || gmx_fexist(buf))
495 if ((ff = fopen(buf, mode)) == NULL)
500 /* Check whether we should be using buffering (default) or not
503 if (bUnbuffered || ((bufsize = getenv("GMX_LOG_BUFFER")) != NULL))
505 /* Check whether to use completely unbuffered */
512 bs = strtol(bufsize, NULL, 10);
521 if (setvbuf(ff, ptr, _IOFBF, bs) != 0)
523 gmx_file("Buffering File");
531 sprintf(buf, "%s.Z", file);
534 ff = uncompress(buf, mode);
538 sprintf(buf, "%s.gz", file);
541 ff = gunzip(buf, mode);
553 /* Our own implementation of dirent-like functionality to scan directories. */
556 #if defined(GMX_NATIVE_WINDOWS)
557 intptr_t windows_handle;
558 struct _finddata_t finddata;
560 #elif defined(HAVE_DIRENT_H)
569 gmx_directory_open(gmx_directory_t *p_gmxdir, const char *dirname)
571 struct gmx_directory * gmxdir;
578 #if defined(GMX_NATIVE_WINDOWS)
579 if (dirname != NULL && strlen(dirname) > 0)
584 len = strlen(dirname);
585 snew(tmpname, len+3);
587 strncpy(tmpname, dirname, len+1);
589 /* Remove possible trailing directory separator */
590 if (tmpname[len] == '/' || tmpname[len] == '\\')
596 strcat(tmpname, "/*");
599 if ( (gmxdir->windows_handle = _findfirst(tmpname, &gmxdir->finddata)) > 0L)
621 #elif defined(HAVE_DIRENT_H)
622 if ( (gmxdir->dirent_handle = opendir(dirname)) != NULL)
634 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n"
635 "In the very unlikely event this is not a compile-time mistake you could consider\n"
636 "implementing support for your platform in futil.c, but contact the developers\n"
637 "to make sure it's really necessary!\n");
645 gmx_directory_nextfile(gmx_directory_t gmxdir, char *name, int maxlength_name)
649 #if defined(GMX_NATIVE_WINDOWS)
652 if (gmxdir->windows_handle <= 0)
658 else if (gmxdir->first == 1)
660 strncpy(name, gmxdir->finddata.name, maxlength_name);
666 if (_findnext(gmxdir->windows_handle, &gmxdir->finddata) == 0)
668 strncpy(name, gmxdir->finddata.name, maxlength_name);
683 #elif defined(HAVE_DIRENT_H)
684 struct dirent * direntp_large;
688 if (gmxdir != NULL && gmxdir->dirent_handle != NULL)
690 /* On some platforms no space is present for d_name in dirent.
691 * Since d_name is guaranteed to be the last entry, allocating
692 * extra space for dirent will allow more size for d_name.
693 * GMX_MAX_PATH should always be >= the max possible d_name.
695 smalloc(direntp_large, sizeof(*direntp_large) + GMX_PATH_MAX);
696 rc = readdir_r(gmxdir->dirent_handle, direntp_large, &p);
698 if (p != NULL && rc == 0)
700 strncpy(name, direntp_large->d_name, maxlength_name);
707 sfree(direntp_large);
716 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
724 gmx_directory_close(gmx_directory_t gmxdir)
727 #if defined(GMX_NATIVE_WINDOWS)
728 rc = (gmxdir != NULL) ? _findclose(gmxdir->windows_handle) : EINVAL;
729 #elif defined(HAVE_DIRENT_H)
730 rc = (gmxdir != NULL) ? closedir(gmxdir->dirent_handle) : EINVAL;
733 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
742 char *low_gmxlibfn(const char *file, gmx_bool bAddCWD, gmx_bool bFatal)
744 bool bEnvIsSet = false;
747 if (bAddCWD && gmx_fexist(file))
749 return gmx_strdup(file);
754 // GMXLIB can be a path.
755 const char *lib = getenv("GMXLIB");
763 libpath = gmx::getProgramContext().defaultLibraryDataPath();
766 std::vector<std::string> pathEntries;
767 gmx::Path::splitPathEnvironment(libpath, &pathEntries);
768 std::vector<std::string>::const_iterator i;
769 for (i = pathEntries.begin(); i != pathEntries.end(); ++i)
771 std::string testPath = gmx::Path::join(*i, file);
772 if (gmx::Path::exists(testPath))
774 return gmx_strdup(testPath.c_str());
779 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
785 "Library file %s not found %sin your GMXLIB path.",
786 file, bAddCWD ? "in current dir nor " : "");
791 "Library file %s not found %sin default directories.\n"
792 "(You can set the directories to search with the GMXLIB path variable)",
793 file, bAddCWD ? "in current dir nor " : "");
799 FILE *low_libopen(const char *file, gmx_bool bFatal)
804 fn = low_gmxlibfn(file, TRUE, bFatal);
814 fprintf(debug, "Opening library file %s\n", fn);
823 char *gmxlibfn(const char *file)
825 return low_gmxlibfn(file, TRUE, TRUE);
828 FILE *libopen(const char *file)
830 return low_libopen(file, TRUE);
833 void gmx_tmpnam(char *buf)
837 if ((len = strlen(buf)) < 7)
839 gmx_fatal(FARGS, "Buf passed to gmx_tmpnam must be at least 7 bytes long");
841 for (i = len-6; (i < len); i++)
845 /* mktemp is dangerous and we should use mkstemp instead, but
846 * since windows doesnt support it we have to separate the cases.
847 * 20090307: mktemp deprecated, use iso c++ _mktemp instead.
849 #ifdef GMX_NATIVE_WINDOWS
852 int fd = mkstemp(buf);
857 gmx_fatal(FARGS, "Invalid template %s for mkstemp", buf);
860 gmx_fatal(FARGS, "mkstemp created existing file", buf);
863 gmx_fatal(FARGS, "Permission denied for opening %s", buf);
870 /* name in Buf should now be OK */
873 int gmx_truncatefile(char *path, gmx_off_t length)
875 #ifdef GMX_NATIVE_WINDOWS
876 /* Microsoft visual studio does not have "truncate" */
878 LARGE_INTEGER win_length;
880 win_length.QuadPart = length;
882 fh = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
883 OPEN_EXISTING, 0, NULL);
884 SetFilePointerEx(fh, win_length, NULL, FILE_BEGIN);
890 return truncate(path, length);
895 int gmx_file_rename(const char *oldname, const char *newname)
897 #ifndef GMX_NATIVE_WINDOWS
898 /* under unix, rename() is atomic (at least, it should be). */
899 return rename(oldname, newname);
901 if (MoveFileEx(oldname, newname,
902 MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH))
913 int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_empty)
915 /* the full copy buffer size: */
916 #define FILECOPY_BUFSIZE (1<<16)
921 snew(buf, FILECOPY_BUFSIZE);
923 in = fopen(oldname, "rb");
929 /* If we don't copy when empty, we postpone opening the file
930 until we're actually ready to write. */
933 out = fopen(newname, "wb");
944 nread = fread(buf, sizeof(char), FILECOPY_BUFSIZE, in);
950 /* so this is where we open when copy_if_empty is false:
951 here we know we read something. */
952 out = fopen(newname, "wb");
958 ret = fwrite(buf, sizeof(char), nread, out);
984 #undef FILECOPY_BUFSIZE
988 int gmx_fsync(FILE *fp)
993 /* the fahcore defines its own os-independent fsync */
995 #else /* GMX_FAHCORE */
999 /* get the file number */
1000 #if defined(HAVE_FILENO)
1002 #elif defined(HAVE__FILENO)
1006 /* do the actual fsync */
1009 #if (defined(HAVE_FSYNC))
1011 #elif (defined(HAVE__COMMIT))
1016 #endif /* GMX_FAHCORE */
1018 /* We check for these error codes this way because POSIX requires them
1019 to be defined, and using anything other than macros is unlikely: */
1021 /* we don't want to report an error just because fsync() caught a signal.
1022 For our purposes, we can just ignore this. */
1023 if (rc && errno == EINTR)
1029 /* we don't want to report an error just because we tried to fsync()
1030 stdout, a socket or a pipe. */
1031 if (rc && errno == EINVAL)
1039 void gmx_chdir(const char *directory)
1041 #ifdef GMX_NATIVE_WINDOWS
1042 int rc = _chdir(directory);
1044 int rc = chdir(directory);
1048 gmx_fatal(FARGS, "Cannot change directory to '%s'. Reason: %s",
1049 directory, strerror(errno));
1053 void gmx_getcwd(char *buffer, size_t size)
1055 #ifdef GMX_NATIVE_WINDOWS
1056 char *pdum = _getcwd(buffer, size);
1058 char *pdum = getcwd(buffer, size);
1062 gmx_fatal(FARGS, "Cannot get working directory. Reason: %s",