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.
49 #include <sys/types.h>
60 #ifdef GMX_NATIVE_WINDOWS
66 /* Windows file stuff, only necessary for visual studio */
71 #include "thread_mpi/threads.h"
73 #include "gromacs/utility/cstringutil.h"
74 #include "gromacs/utility/exceptions.h"
75 #include "gromacs/utility/fatalerror.h"
76 #include "gromacs/utility/path.h"
77 #include "gromacs/utility/programcontext.h"
78 #include "gromacs/utility/smalloc.h"
79 #include "gromacs/utility/stringutil.h"
81 /* we keep a linked list of all files opened through pipes (i.e.
82 compressed or .gzipped files. This way we can distinguish between them
83 without having to change the semantics of reading from/writing to files)
85 typedef struct t_pstack {
87 struct t_pstack *prev;
90 static t_pstack *pstack = NULL;
91 static bool bUnbuffered = false;
93 /* this linked list is an intrinsically globally shared object, so we have
94 to protect it with mutexes */
95 static tMPI_Thread_mutex_t pstack_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
97 void gmx_disable_file_buffering(void)
102 void push_ps(FILE *fp)
106 tMPI_Thread_mutex_lock(&pstack_mutex);
113 tMPI_Thread_mutex_unlock(&pstack_mutex);
117 /* don't use pipes!*/
118 #define popen fah_fopen
119 #define pclose fah_fclose
125 #if (!defined(HAVE_PIPES) && !defined(__native_client__))
126 static FILE *popen(const char *nm, const char *mode)
128 gmx_impl("Sorry no pipes...");
133 static int pclose(FILE *fp)
135 gmx_impl("Sorry no pipes...");
139 #endif /* !defined(HAVE_PIPES) && !defined(__native_client__) */
140 #endif /* GMX_FAHCORE */
142 int gmx_ffclose(FILE *fp)
150 tMPI_Thread_mutex_lock(&pstack_mutex);
160 else if (ps->fp == fp)
166 pstack = pstack->prev;
171 while ((ps->prev != NULL) && (ps->prev->fp != fp))
175 if ((ps->prev != NULL) && ps->prev->fp == fp)
177 if (ps->prev->fp != NULL)
179 ret = pclose(ps->prev->fp);
182 ps->prev = ps->prev->prev;
194 tMPI_Thread_mutex_unlock(&pstack_mutex);
200 void frewind(FILE *fp)
202 tMPI_Thread_mutex_lock(&pstack_mutex);
204 t_pstack *ps = pstack;
209 fprintf(stderr, "Cannot rewind compressed file!\n");
210 tMPI_Thread_mutex_unlock(&pstack_mutex);
216 tMPI_Thread_mutex_unlock(&pstack_mutex);
219 int gmx_fseek(FILE *stream, gmx_off_t offset, int whence)
222 return fseeko(stream, offset, whence);
224 #ifdef HAVE__FSEEKI64
225 return _fseeki64(stream, offset, whence);
227 return fseek(stream, offset, whence);
232 gmx_off_t gmx_ftell(FILE *stream)
235 return ftello(stream);
237 #ifdef HAVE__FSEEKI64
239 return _ftelli64(stream);
241 return ftello64(stream);
244 return ftell(stream);
249 static FILE *uncompress(const char *fn, const char *mode)
254 sprintf(buf, "uncompress -c < %s", fn);
255 fprintf(stderr, "Going to execute '%s'\n", buf);
256 if ((fp = popen(buf, mode)) == NULL)
265 static FILE *gunzip(const char *fn, const char *mode)
270 sprintf(buf, "gunzip -c < %s", fn);
271 fprintf(stderr, "Going to execute '%s'\n", buf);
272 if ((fp = popen(buf, mode)) == NULL)
281 gmx_bool gmx_fexist(const char *fname)
289 test = fopen(fname, "r");
292 /*Windows doesn't allow fopen of directory - so we need to check this seperately */
293 #ifdef GMX_NATIVE_WINDOWS
294 DWORD attr = GetFileAttributes(fname);
295 return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
307 static char *backup_fn(const char *file, int count_max)
309 /* Use a reasonably low value for countmax; we might
310 * generate 4-5 files in each round, and we dont
311 * want to hit directory limits of 1024 or 2048 files.
315 char *directory, *fn;
320 count_max = COUNTMAX;
323 smalloc(buf, GMX_PATH_MAX);
325 for (i = strlen(file)-1; ((i > 0) && (file[i] != DIR_SEPARATOR)); i--)
329 /* Must check whether i > 0, i.e. whether there is a directory
330 * in the file name. In that case we overwrite the / sign with
331 * a '\0' to end the directory string .
335 directory = gmx_strdup(file);
337 fn = gmx_strdup(file+i+1);
341 directory = gmx_strdup(".");
342 fn = gmx_strdup(file);
346 sprintf(buf, "%s/#%s.%d#", directory, fn, count);
349 while ((count <= count_max) && gmx_fexist(buf));
351 /* Arbitrarily bail out */
352 if (count > count_max)
354 gmx_fatal(FARGS, "Won't make more than %d backups of %s for you.\n"
355 "The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
365 gmx_bool make_backup(const char * name)
372 return FALSE; /* skip making backups */
375 if (gmx_fexist(name))
377 env = getenv("GMX_MAXBACKUP");
380 count_max = strtol(env, NULL, 10);
383 /* Do not make backups and possibly overwrite old files */
389 /* Use the default maximum */
392 backup = backup_fn(name, count_max);
393 if (rename(name, backup) == 0)
395 fprintf(stderr, "\nBack Off! I just backed up %s to %s\n",
400 fprintf(stderr, "Sorry couldn't backup %s to %s\n", name, backup);
409 FILE *gmx_ffopen(const char *file, const char *mode)
412 return fopen(file, mode);
415 char buf[256], *bufsize = 0, *ptr;
430 bRead = (mode[0] == 'r' && mode[1] != '+');
432 if (!bRead || gmx_fexist(buf))
434 if ((ff = fopen(buf, mode)) == NULL)
439 /* Check whether we should be using buffering (default) or not
442 if (bUnbuffered || ((bufsize = getenv("GMX_LOG_BUFFER")) != NULL))
444 /* Check whether to use completely unbuffered */
451 bs = strtol(bufsize, NULL, 10);
460 if (setvbuf(ff, ptr, _IOFBF, bs) != 0)
462 gmx_file("Buffering File");
470 sprintf(buf, "%s.Z", file);
473 ff = uncompress(buf, mode);
477 sprintf(buf, "%s.gz", file);
480 ff = gunzip(buf, mode);
492 /* Our own implementation of dirent-like functionality to scan directories. */
495 #if defined(GMX_NATIVE_WINDOWS)
496 intptr_t windows_handle;
497 struct _finddata_t finddata;
499 #elif defined(HAVE_DIRENT_H)
508 gmx_directory_open(gmx_directory_t *p_gmxdir, const char *dirname)
510 struct gmx_directory * gmxdir;
517 #if defined(GMX_NATIVE_WINDOWS)
518 if (dirname != NULL && strlen(dirname) > 0)
523 len = strlen(dirname);
524 snew(tmpname, len+3);
526 strncpy(tmpname, dirname, len+1);
528 /* Remove possible trailing directory separator */
529 if (tmpname[len] == '/' || tmpname[len] == '\\')
535 strcat(tmpname, "/*");
538 if ( (gmxdir->windows_handle = _findfirst(tmpname, &gmxdir->finddata)) > 0L)
560 #elif defined(HAVE_DIRENT_H)
561 if ( (gmxdir->dirent_handle = opendir(dirname)) != NULL)
573 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n"
574 "In the very unlikely event this is not a compile-time mistake you could consider\n"
575 "implementing support for your platform in futil.c, but contact the developers\n"
576 "to make sure it's really necessary!\n");
584 gmx_directory_nextfile(gmx_directory_t gmxdir, char *name, int maxlength_name)
588 #if defined(GMX_NATIVE_WINDOWS)
591 if (gmxdir->windows_handle <= 0)
597 else if (gmxdir->first == 1)
599 strncpy(name, gmxdir->finddata.name, maxlength_name);
605 if (_findnext(gmxdir->windows_handle, &gmxdir->finddata) == 0)
607 strncpy(name, gmxdir->finddata.name, maxlength_name);
622 #elif defined(HAVE_DIRENT_H)
623 struct dirent * direntp_large;
627 if (gmxdir != NULL && gmxdir->dirent_handle != NULL)
629 /* On some platforms no space is present for d_name in dirent.
630 * Since d_name is guaranteed to be the last entry, allocating
631 * extra space for dirent will allow more size for d_name.
632 * GMX_MAX_PATH should always be >= the max possible d_name.
634 smalloc(direntp_large, sizeof(*direntp_large) + GMX_PATH_MAX);
635 rc = readdir_r(gmxdir->dirent_handle, direntp_large, &p);
637 if (p != NULL && rc == 0)
639 strncpy(name, direntp_large->d_name, maxlength_name);
646 sfree(direntp_large);
655 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
663 gmx_directory_close(gmx_directory_t gmxdir)
666 #if defined(GMX_NATIVE_WINDOWS)
667 rc = (gmxdir != NULL) ? _findclose(gmxdir->windows_handle) : EINVAL;
668 #elif defined(HAVE_DIRENT_H)
669 rc = (gmxdir != NULL) ? closedir(gmxdir->dirent_handle) : EINVAL;
672 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
681 char *low_gmxlibfn(const char *file, gmx_bool bAddCWD, gmx_bool bFatal)
683 bool bEnvIsSet = false;
686 if (bAddCWD && gmx_fexist(file))
688 return gmx_strdup(file);
693 // GMXLIB can be a path.
694 const char *lib = getenv("GMXLIB");
702 libpath = gmx::getProgramContext().defaultLibraryDataPath();
705 std::vector<std::string> pathEntries;
706 gmx::Path::splitPathEnvironment(libpath, &pathEntries);
707 std::vector<std::string>::const_iterator i;
708 for (i = pathEntries.begin(); i != pathEntries.end(); ++i)
710 std::string testPath = gmx::Path::join(*i, file);
711 if (gmx::Path::exists(testPath))
713 return gmx_strdup(testPath.c_str());
718 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
724 "Library file %s not found %sin your GMXLIB path.",
725 file, bAddCWD ? "in current dir nor " : "");
730 "Library file %s not found %sin default directories.\n"
731 "(You can set the directories to search with the GMXLIB path variable)",
732 file, bAddCWD ? "in current dir nor " : "");
738 FILE *low_libopen(const char *file, gmx_bool bFatal)
743 fn = low_gmxlibfn(file, TRUE, bFatal);
753 fprintf(debug, "Opening library file %s\n", fn);
762 char *gmxlibfn(const char *file)
764 return low_gmxlibfn(file, TRUE, TRUE);
767 FILE *libopen(const char *file)
769 return low_libopen(file, TRUE);
772 void gmx_tmpnam(char *buf)
776 if ((len = strlen(buf)) < 7)
778 gmx_fatal(FARGS, "Buf passed to gmx_tmpnam must be at least 7 bytes long");
780 for (i = len-6; (i < len); i++)
784 /* mktemp is dangerous and we should use mkstemp instead, but
785 * since windows doesnt support it we have to separate the cases.
786 * 20090307: mktemp deprecated, use iso c++ _mktemp instead.
788 #ifdef GMX_NATIVE_WINDOWS
791 int fd = mkstemp(buf);
796 gmx_fatal(FARGS, "Invalid template %s for mkstemp", buf);
799 gmx_fatal(FARGS, "mkstemp created existing file", buf);
802 gmx_fatal(FARGS, "Permission denied for opening %s", buf);
809 /* name in Buf should now be OK */
812 int gmx_file_rename(const char *oldname, const char *newname)
814 #ifndef GMX_NATIVE_WINDOWS
815 /* under unix, rename() is atomic (at least, it should be). */
816 return rename(oldname, newname);
818 if (MoveFileEx(oldname, newname,
819 MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH))
830 int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_empty)
832 /* the full copy buffer size: */
833 #define FILECOPY_BUFSIZE (1<<16)
838 snew(buf, FILECOPY_BUFSIZE);
840 in = fopen(oldname, "rb");
846 /* If we don't copy when empty, we postpone opening the file
847 until we're actually ready to write. */
850 out = fopen(newname, "wb");
861 nread = fread(buf, sizeof(char), FILECOPY_BUFSIZE, in);
867 /* so this is where we open when copy_if_empty is false:
868 here we know we read something. */
869 out = fopen(newname, "wb");
875 ret = fwrite(buf, sizeof(char), nread, out);
901 #undef FILECOPY_BUFSIZE
905 int gmx_fsync(FILE *fp)
910 /* the fahcore defines its own os-independent fsync */
912 #else /* GMX_FAHCORE */
916 /* get the file number */
917 #if defined(HAVE_FILENO)
919 #elif defined(HAVE__FILENO)
925 /* do the actual fsync */
928 #if (defined(HAVE_FSYNC))
930 #elif (defined(HAVE__COMMIT))
935 #endif /* GMX_FAHCORE */
937 /* We check for these error codes this way because POSIX requires them
938 to be defined, and using anything other than macros is unlikely: */
940 /* we don't want to report an error just because fsync() caught a signal.
941 For our purposes, we can just ignore this. */
942 if (rc && errno == EINTR)
948 /* we don't want to report an error just because we tried to fsync()
949 stdout, a socket or a pipe. */
950 if (rc && errno == EINVAL)
958 void gmx_chdir(const char *directory)
960 #ifdef GMX_NATIVE_WINDOWS
961 int rc = _chdir(directory);
963 int rc = chdir(directory);
967 gmx_fatal(FARGS, "Cannot change directory to '%s'. Reason: %s",
968 directory, strerror(errno));
972 void gmx_getcwd(char *buffer, size_t size)
974 #ifdef GMX_NATIVE_WINDOWS
975 char *pdum = _getcwd(buffer, size);
977 char *pdum = getcwd(buffer, size);
981 gmx_fatal(FARGS, "Cannot get working directory. Reason: %s",