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.
37 #include "gromacs/utility/futil.h"
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/utility/cstringutil.h"
71 #include "gromacs/utility/exceptions.h"
72 #include "gromacs/utility/fatalerror.h"
73 #include "gromacs/utility/path.h"
74 #include "gromacs/utility/programcontext.h"
75 #include "gromacs/utility/smalloc.h"
76 #include "gromacs/utility/stringutil.h"
78 /* we keep a linked list of all files opened through pipes (i.e.
79 compressed or .gzipped files. This way we can distinguish between them
80 without having to change the semantics of reading from/writing to files)
82 typedef struct t_pstack {
84 struct t_pstack *prev;
87 static t_pstack *pstack = NULL;
88 static bool bUnbuffered = false;
90 /* this linked list is an intrinsically globally shared object, so we have
91 to protect it with mutexes */
92 static tMPI_Thread_mutex_t pstack_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
94 void gmx_disable_file_buffering(void)
99 void push_ps(FILE *fp)
103 tMPI_Thread_mutex_lock(&pstack_mutex);
110 tMPI_Thread_mutex_unlock(&pstack_mutex);
114 /* don't use pipes!*/
115 #define popen fah_fopen
116 #define pclose fah_fclose
122 #if (!defined(HAVE_PIPES) && !defined(__native_client__))
123 static FILE *popen(const char *nm, const char *mode)
125 gmx_impl("Sorry no pipes...");
130 static int pclose(FILE *fp)
132 gmx_impl("Sorry no pipes...");
136 #endif /* !defined(HAVE_PIPES) && !defined(__native_client__) */
137 #endif /* GMX_FAHCORE */
139 int gmx_ffclose(FILE *fp)
147 tMPI_Thread_mutex_lock(&pstack_mutex);
157 else if (ps->fp == fp)
163 pstack = pstack->prev;
168 while ((ps->prev != NULL) && (ps->prev->fp != fp))
172 if ((ps->prev != NULL) && ps->prev->fp == fp)
174 if (ps->prev->fp != NULL)
176 ret = pclose(ps->prev->fp);
179 ps->prev = ps->prev->prev;
191 tMPI_Thread_mutex_unlock(&pstack_mutex);
197 void frewind(FILE *fp)
199 tMPI_Thread_mutex_lock(&pstack_mutex);
201 t_pstack *ps = pstack;
206 fprintf(stderr, "Cannot rewind compressed file!\n");
207 tMPI_Thread_mutex_unlock(&pstack_mutex);
213 tMPI_Thread_mutex_unlock(&pstack_mutex);
216 int gmx_fseek(FILE *stream, gmx_off_t offset, int whence)
219 return fseeko(stream, offset, whence);
221 #ifdef HAVE__FSEEKI64
222 return _fseeki64(stream, offset, whence);
224 return fseek(stream, offset, whence);
229 gmx_off_t gmx_ftell(FILE *stream)
232 return ftello(stream);
234 #ifdef HAVE__FSEEKI64
235 return _ftelli64(stream);
237 return ftell(stream);
242 static FILE *uncompress(const char *fn, const char *mode)
247 sprintf(buf, "uncompress -c < %s", fn);
248 fprintf(stderr, "Going to execute '%s'\n", buf);
249 if ((fp = popen(buf, mode)) == NULL)
258 static FILE *gunzip(const char *fn, const char *mode)
263 sprintf(buf, "gunzip -c < %s", fn);
264 fprintf(stderr, "Going to execute '%s'\n", buf);
265 if ((fp = popen(buf, mode)) == NULL)
274 gmx_bool gmx_fexist(const char *fname)
282 test = fopen(fname, "r");
285 /*Windows doesn't allow fopen of directory - so we need to check this seperately */
286 #ifdef GMX_NATIVE_WINDOWS
287 DWORD attr = GetFileAttributes(fname);
288 return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
300 static char *backup_fn(const char *file, int count_max)
302 /* Use a reasonably low value for countmax; we might
303 * generate 4-5 files in each round, and we dont
304 * want to hit directory limits of 1024 or 2048 files.
308 char *directory, *fn;
313 count_max = COUNTMAX;
316 smalloc(buf, GMX_PATH_MAX);
318 for (i = strlen(file)-1; ((i > 0) && (file[i] != DIR_SEPARATOR)); i--)
322 /* Must check whether i > 0, i.e. whether there is a directory
323 * in the file name. In that case we overwrite the / sign with
324 * a '\0' to end the directory string .
328 directory = gmx_strdup(file);
330 fn = gmx_strdup(file+i+1);
334 directory = gmx_strdup(".");
335 fn = gmx_strdup(file);
339 sprintf(buf, "%s/#%s.%d#", directory, fn, count);
342 while ((count <= count_max) && gmx_fexist(buf));
344 /* Arbitrarily bail out */
345 if (count > count_max)
347 gmx_fatal(FARGS, "Won't make more than %d backups of %s for you.\n"
348 "The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
358 gmx_bool make_backup(const char * name)
365 return FALSE; /* skip making backups */
368 if (gmx_fexist(name))
370 env = getenv("GMX_MAXBACKUP");
373 count_max = strtol(env, NULL, 10);
376 /* Do not make backups and possibly overwrite old files */
382 /* Use the default maximum */
385 backup = backup_fn(name, count_max);
386 if (rename(name, backup) == 0)
388 fprintf(stderr, "\nBack Off! I just backed up %s to %s\n",
393 fprintf(stderr, "Sorry couldn't backup %s to %s\n", name, backup);
402 FILE *gmx_ffopen(const char *file, const char *mode)
405 return fopen(file, mode);
408 char buf[256], *bufsize = 0, *ptr;
423 bRead = (mode[0] == 'r' && mode[1] != '+');
425 if (!bRead || gmx_fexist(buf))
427 if ((ff = fopen(buf, mode)) == NULL)
432 /* Check whether we should be using buffering (default) or not
435 if (bUnbuffered || ((bufsize = getenv("GMX_LOG_BUFFER")) != NULL))
437 /* Check whether to use completely unbuffered */
444 bs = strtol(bufsize, NULL, 10);
453 if (setvbuf(ff, ptr, _IOFBF, bs) != 0)
455 gmx_file("Buffering File");
463 sprintf(buf, "%s.Z", file);
466 ff = uncompress(buf, mode);
470 sprintf(buf, "%s.gz", file);
473 ff = gunzip(buf, mode);
485 /* Our own implementation of dirent-like functionality to scan directories. */
490 #elif (defined GMX_NATIVE_WINDOWS)
491 intptr_t windows_handle;
492 struct _finddata_t finddata;
501 gmx_directory_open(gmx_directory_t *p_gmxdir, const char *dirname)
503 struct gmx_directory * gmxdir;
511 if ( (gmxdir->dirent_handle = opendir(dirname)) != NULL)
521 #elif (defined GMX_NATIVE_WINDOWS)
523 if (dirname != NULL && strlen(dirname) > 0)
528 len = strlen(dirname);
529 snew(tmpname, len+3);
531 strncpy(tmpname, dirname, len+1);
533 /* Remove possible trailing directory separator */
534 if (tmpname[len] == '/' || tmpname[len] == '\\')
540 strcat(tmpname, "/*");
543 if ( (gmxdir->windows_handle = _findfirst(tmpname, &gmxdir->finddata)) > 0L)
567 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n"
568 "In the very unlikely event this is not a compile-time mistake you could consider\n"
569 "implementing support for your platform in futil.c, but contact the developers\n"
570 "to make sure it's really necessary!\n");
578 gmx_directory_nextfile(gmx_directory_t gmxdir, char *name, int maxlength_name)
584 struct dirent * direntp_large;
588 if (gmxdir != NULL && gmxdir->dirent_handle != NULL)
590 /* On some platforms no space is present for d_name in dirent.
591 * Since d_name is guaranteed to be the last entry, allocating
592 * extra space for dirent will allow more size for d_name.
593 * GMX_MAX_PATH should always be >= the max possible d_name.
595 smalloc(direntp_large, sizeof(*direntp_large) + GMX_PATH_MAX);
596 rc = readdir_r(gmxdir->dirent_handle, direntp_large, &p);
598 if (p != NULL && rc == 0)
600 strncpy(name, direntp_large->d_name, maxlength_name);
607 sfree(direntp_large);
615 #elif (defined GMX_NATIVE_WINDOWS)
619 if (gmxdir->windows_handle <= 0)
625 else if (gmxdir->first == 1)
627 strncpy(name, gmxdir->finddata.name, maxlength_name);
633 if (_findnext(gmxdir->windows_handle, &gmxdir->finddata) == 0)
635 strncpy(name, gmxdir->finddata.name, maxlength_name);
648 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
656 gmx_directory_close(gmx_directory_t gmxdir)
660 rc = (gmxdir != NULL) ? closedir(gmxdir->dirent_handle) : EINVAL;
661 #elif (defined GMX_NATIVE_WINDOWS)
662 rc = (gmxdir != NULL) ? _findclose(gmxdir->windows_handle) : EINVAL;
665 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
674 char *low_gmxlibfn(const char *file, gmx_bool bAddCWD, gmx_bool bFatal)
676 bool bEnvIsSet = false;
679 if (bAddCWD && gmx_fexist(file))
681 return gmx_strdup(file);
686 // GMXLIB can be a path.
687 const char *lib = getenv("GMXLIB");
695 libpath = gmx::getProgramContext().defaultLibraryDataPath();
698 std::vector<std::string> pathEntries;
699 gmx::Path::splitPathEnvironment(libpath, &pathEntries);
700 std::vector<std::string>::const_iterator i;
701 for (i = pathEntries.begin(); i != pathEntries.end(); ++i)
703 std::string testPath = gmx::Path::join(*i, file);
704 if (gmx::Path::exists(testPath))
706 return gmx_strdup(testPath.c_str());
711 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
717 "Library file %s not found %sin your GMXLIB path.",
718 file, bAddCWD ? "in current dir nor " : "");
723 "Library file %s not found %sin default directories.\n"
724 "(You can set the directories to search with the GMXLIB path variable)",
725 file, bAddCWD ? "in current dir nor " : "");
731 FILE *low_libopen(const char *file, gmx_bool bFatal)
736 fn = low_gmxlibfn(file, TRUE, bFatal);
746 fprintf(debug, "Opening library file %s\n", fn);
755 char *gmxlibfn(const char *file)
757 return low_gmxlibfn(file, TRUE, TRUE);
760 FILE *libopen(const char *file)
762 return low_libopen(file, TRUE);
765 void gmx_tmpnam(char *buf)
769 if ((len = strlen(buf)) < 7)
771 gmx_fatal(FARGS, "Buf passed to gmx_tmpnam must be at least 7 bytes long");
773 for (i = len-6; (i < len); i++)
777 /* mktemp is dangerous and we should use mkstemp instead, but
778 * since windows doesnt support it we have to separate the cases.
779 * 20090307: mktemp deprecated, use iso c++ _mktemp instead.
781 #ifdef GMX_NATIVE_WINDOWS
784 int fd = mkstemp(buf);
789 gmx_fatal(FARGS, "Invalid template %s for mkstemp", buf);
792 gmx_fatal(FARGS, "mkstemp created existing file", buf);
795 gmx_fatal(FARGS, "Permission denied for opening %s", buf);
802 /* name in Buf should now be OK */
805 int gmx_file_rename(const char *oldname, const char *newname)
807 #ifndef GMX_NATIVE_WINDOWS
808 /* under unix, rename() is atomic (at least, it should be). */
809 return rename(oldname, newname);
811 if (MoveFileEx(oldname, newname,
812 MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH))
823 int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_empty)
825 /* the full copy buffer size: */
826 #define FILECOPY_BUFSIZE (1<<16)
831 snew(buf, FILECOPY_BUFSIZE);
833 in = fopen(oldname, "rb");
839 /* If we don't copy when empty, we postpone opening the file
840 until we're actually ready to write. */
843 out = fopen(newname, "wb");
854 nread = fread(buf, sizeof(char), FILECOPY_BUFSIZE, in);
860 /* so this is where we open when copy_if_empty is false:
861 here we know we read something. */
862 out = fopen(newname, "wb");
868 ret = fwrite(buf, sizeof(char), nread, out);
894 #undef FILECOPY_BUFSIZE
898 int gmx_fsync(FILE *fp)
903 /* the fahcore defines its own os-independent fsync */
905 #else /* GMX_FAHCORE */
909 /* get the file number */
910 #if defined(HAVE_FILENO)
912 #elif defined(HAVE__FILENO)
918 /* do the actual fsync */
921 #if (defined(HAVE_FSYNC))
923 #elif (defined(HAVE__COMMIT))
928 #endif /* GMX_FAHCORE */
930 /* We check for these error codes this way because POSIX requires them
931 to be defined, and using anything other than macros is unlikely: */
933 /* we don't want to report an error just because fsync() caught a signal.
934 For our purposes, we can just ignore this. */
935 if (rc && errno == EINTR)
941 /* we don't want to report an error just because we tried to fsync()
942 stdout, a socket or a pipe. */
943 if (rc && errno == EINVAL)
951 void gmx_chdir(const char *directory)
953 #ifdef GMX_NATIVE_WINDOWS
954 int rc = _chdir(directory);
956 int rc = chdir(directory);
960 gmx_fatal(FARGS, "Cannot change directory to '%s'. Reason: %s",
961 directory, strerror(errno));
965 void gmx_getcwd(char *buffer, size_t size)
967 #ifdef GMX_NATIVE_WINDOWS
968 char *pdum = _getcwd(buffer, size);
970 char *pdum = getcwd(buffer, size);
974 gmx_fatal(FARGS, "Cannot get working directory. Reason: %s",