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"
47 #include <sys/types.h>
60 #ifdef GMX_NATIVE_WINDOWS
65 /* Windows file stuff, only necessary for visual studio */
70 #include "thread_mpi/threads.h"
72 #include "gromacs/utility/cstringutil.h"
73 #include "gromacs/utility/exceptions.h"
74 #include "gromacs/utility/fatalerror.h"
75 #include "gromacs/utility/path.h"
76 #include "gromacs/utility/programcontext.h"
77 #include "gromacs/utility/smalloc.h"
78 #include "gromacs/utility/stringutil.h"
80 /* we keep a linked list of all files opened through pipes (i.e.
81 compressed or .gzipped files. This way we can distinguish between them
82 without having to change the semantics of reading from/writing to files)
84 typedef struct t_pstack {
86 struct t_pstack *prev;
89 static t_pstack *pstack = NULL;
90 static gmx_bool bUnbuffered = FALSE;
92 /* this linked list is an intrinsically globally shared object, so we have
93 to protect it with mutexes */
94 static tMPI_Thread_mutex_t pstack_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
101 void push_ps(FILE *fp)
105 tMPI_Thread_mutex_lock(&pstack_mutex);
112 tMPI_Thread_mutex_unlock(&pstack_mutex);
116 /* don't use pipes!*/
117 #define popen fah_fopen
118 #define pclose fah_fclose
124 #if (!defined(HAVE_PIPES) && !defined(__native_client__))
125 static FILE *popen(const char *nm, const char *mode)
127 gmx_impl("Sorry no pipes...");
132 static int pclose(FILE *fp)
134 gmx_impl("Sorry no pipes...");
138 #endif /* !defined(HAVE_PIPES) && !defined(__native_client__) */
139 #endif /* GMX_FAHCORE */
141 int gmx_ffclose(FILE *fp)
149 tMPI_Thread_mutex_lock(&pstack_mutex);
159 else if (ps->fp == fp)
165 pstack = pstack->prev;
170 while ((ps->prev != NULL) && (ps->prev->fp != fp))
174 if ((ps->prev != NULL) && ps->prev->fp == fp)
176 if (ps->prev->fp != NULL)
178 ret = pclose(ps->prev->fp);
181 ps->prev = ps->prev->prev;
193 tMPI_Thread_mutex_unlock(&pstack_mutex);
199 void frewind(FILE *fp)
201 tMPI_Thread_mutex_lock(&pstack_mutex);
203 t_pstack *ps = pstack;
208 fprintf(stderr, "Cannot rewind compressed file!\n");
209 tMPI_Thread_mutex_unlock(&pstack_mutex);
215 tMPI_Thread_mutex_unlock(&pstack_mutex);
218 int gmx_fseek(FILE *stream, gmx_off_t offset, int whence)
221 return fseeko(stream, offset, whence);
223 #ifdef HAVE__FSEEKI64
224 return _fseeki64(stream, offset, whence);
226 return fseek(stream, offset, whence);
231 gmx_off_t gmx_ftell(FILE *stream)
234 return ftello(stream);
236 #ifdef HAVE__FSEEKI64
237 return _ftelli64(stream);
239 return ftell(stream);
244 static FILE *uncompress(const char *fn, const char *mode)
249 sprintf(buf, "uncompress -c < %s", fn);
250 fprintf(stderr, "Going to execute '%s'\n", buf);
251 if ((fp = popen(buf, mode)) == NULL)
260 static FILE *gunzip(const char *fn, const char *mode)
265 sprintf(buf, "gunzip -c < %s", fn);
266 fprintf(stderr, "Going to execute '%s'\n", buf);
267 if ((fp = popen(buf, mode)) == NULL)
276 gmx_bool gmx_fexist(const char *fname)
284 test = fopen(fname, "r");
287 /*Windows doesn't allow fopen of directory - so we need to check this seperately */
288 #ifdef GMX_NATIVE_WINDOWS
289 DWORD attr = GetFileAttributes(fname);
290 return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
302 static char *backup_fn(const char *file, int count_max)
304 /* Use a reasonably low value for countmax; we might
305 * generate 4-5 files in each round, and we dont
306 * want to hit directory limits of 1024 or 2048 files.
310 char *directory, *fn;
315 count_max = COUNTMAX;
318 smalloc(buf, GMX_PATH_MAX);
320 for (i = strlen(file)-1; ((i > 0) && (file[i] != DIR_SEPARATOR)); i--)
324 /* Must check whether i > 0, i.e. whether there is a directory
325 * in the file name. In that case we overwrite the / sign with
326 * a '\0' to end the directory string .
330 directory = gmx_strdup(file);
332 fn = gmx_strdup(file+i+1);
336 directory = gmx_strdup(".");
337 fn = gmx_strdup(file);
341 sprintf(buf, "%s/#%s.%d#", directory, fn, count);
344 while ((count <= count_max) && gmx_fexist(buf));
346 /* Arbitrarily bail out */
347 if (count > count_max)
349 gmx_fatal(FARGS, "Won't make more than %d backups of %s for you.\n"
350 "The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
360 gmx_bool make_backup(const char * name)
367 return FALSE; /* skip making backups */
370 if (gmx_fexist(name))
372 env = getenv("GMX_MAXBACKUP");
375 count_max = strtol(env, NULL, 10);
378 /* Do not make backups and possibly overwrite old files */
384 /* Use the default maximum */
387 backup = backup_fn(name, count_max);
388 if (rename(name, backup) == 0)
390 fprintf(stderr, "\nBack Off! I just backed up %s to %s\n",
395 fprintf(stderr, "Sorry couldn't backup %s to %s\n", name, backup);
404 FILE *gmx_ffopen(const char *file, const char *mode)
407 return fopen(file, mode);
410 char buf[256], *bufsize = 0, *ptr;
425 bRead = (mode[0] == 'r' && mode[1] != '+');
427 if (!bRead || gmx_fexist(buf))
429 if ((ff = fopen(buf, mode)) == NULL)
434 /* Check whether we should be using buffering (default) or not
437 if (bUnbuffered || ((bufsize = getenv("GMX_LOG_BUFFER")) != NULL))
439 /* Check whether to use completely unbuffered */
446 bs = strtol(bufsize, NULL, 10);
455 if (setvbuf(ff, ptr, _IOFBF, bs) != 0)
457 gmx_file("Buffering File");
465 sprintf(buf, "%s.Z", file);
468 ff = uncompress(buf, mode);
472 sprintf(buf, "%s.gz", file);
475 ff = gunzip(buf, mode);
487 /* Our own implementation of dirent-like functionality to scan directories. */
492 #elif (defined GMX_NATIVE_WINDOWS)
493 intptr_t windows_handle;
494 struct _finddata_t finddata;
503 gmx_directory_open(gmx_directory_t *p_gmxdir, const char *dirname)
505 struct gmx_directory * gmxdir;
513 if ( (gmxdir->dirent_handle = opendir(dirname)) != NULL)
523 #elif (defined GMX_NATIVE_WINDOWS)
525 if (dirname != NULL && strlen(dirname) > 0)
530 len = strlen(dirname);
531 snew(tmpname, len+3);
533 strncpy(tmpname, dirname, len+1);
535 /* Remove possible trailing directory separator */
536 if (tmpname[len] == '/' || tmpname[len] == '\\')
542 strcat(tmpname, "/*");
545 if ( (gmxdir->windows_handle = _findfirst(tmpname, &gmxdir->finddata)) > 0L)
569 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n"
570 "In the very unlikely event this is not a compile-time mistake you could consider\n"
571 "implementing support for your platform in futil.c, but contact the developers\n"
572 "to make sure it's really necessary!\n");
580 gmx_directory_nextfile(gmx_directory_t gmxdir, char *name, int maxlength_name)
586 struct dirent * direntp_large;
590 if (gmxdir != NULL && gmxdir->dirent_handle != NULL)
592 /* On some platforms no space is present for d_name in dirent.
593 * Since d_name is guaranteed to be the last entry, allocating
594 * extra space for dirent will allow more size for d_name.
595 * GMX_MAX_PATH should always be >= the max possible d_name.
597 smalloc(direntp_large, sizeof(*direntp_large) + GMX_PATH_MAX);
598 rc = readdir_r(gmxdir->dirent_handle, direntp_large, &p);
600 if (p != NULL && rc == 0)
602 strncpy(name, direntp_large->d_name, maxlength_name);
609 sfree(direntp_large);
617 #elif (defined GMX_NATIVE_WINDOWS)
621 if (gmxdir->windows_handle <= 0)
627 else if (gmxdir->first == 1)
629 strncpy(name, gmxdir->finddata.name, maxlength_name);
635 if (_findnext(gmxdir->windows_handle, &gmxdir->finddata) == 0)
637 strncpy(name, gmxdir->finddata.name, maxlength_name);
650 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
658 gmx_directory_close(gmx_directory_t gmxdir)
662 rc = (gmxdir != NULL) ? closedir(gmxdir->dirent_handle) : EINVAL;
663 #elif (defined GMX_NATIVE_WINDOWS)
664 rc = (gmxdir != NULL) ? _findclose(gmxdir->windows_handle) : EINVAL;
667 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
676 char *low_gmxlibfn(const char *file, gmx_bool bAddCWD, gmx_bool bFatal)
678 bool bEnvIsSet = false;
681 if (bAddCWD && gmx_fexist(file))
683 return gmx_strdup(file);
688 // GMXLIB can be a path.
689 const char *lib = getenv("GMXLIB");
697 libpath = gmx::getProgramContext().defaultLibraryDataPath();
700 std::vector<std::string> pathEntries;
701 gmx::Path::splitPathEnvironment(libpath, &pathEntries);
702 std::vector<std::string>::const_iterator i;
703 for (i = pathEntries.begin(); i != pathEntries.end(); ++i)
705 std::string testPath = gmx::Path::join(*i, file);
706 if (gmx::Path::exists(testPath))
708 return gmx_strdup(testPath.c_str());
713 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
719 "Library file %s not found %sin your GMXLIB path.",
720 file, bAddCWD ? "in current dir nor " : "");
725 "Library file %s not found %sin default directories.\n"
726 "(You can set the directories to search with the GMXLIB path variable)",
727 file, bAddCWD ? "in current dir nor " : "");
733 FILE *low_libopen(const char *file, gmx_bool bFatal)
738 fn = low_gmxlibfn(file, TRUE, bFatal);
748 fprintf(debug, "Opening library file %s\n", fn);
757 char *gmxlibfn(const char *file)
759 return low_gmxlibfn(file, TRUE, TRUE);
762 FILE *libopen(const char *file)
764 return low_libopen(file, TRUE);
767 void gmx_tmpnam(char *buf)
771 if ((len = strlen(buf)) < 7)
773 gmx_fatal(FARGS, "Buf passed to gmx_tmpnam must be at least 7 bytes long");
775 for (i = len-6; (i < len); i++)
779 /* mktemp is dangerous and we should use mkstemp instead, but
780 * since windows doesnt support it we have to separate the cases.
781 * 20090307: mktemp deprecated, use iso c++ _mktemp instead.
783 #ifdef GMX_NATIVE_WINDOWS
786 int fd = mkstemp(buf);
791 gmx_fatal(FARGS, "Invalid template %s for mkstemp", buf);
794 gmx_fatal(FARGS, "mkstemp created existing file", buf);
797 gmx_fatal(FARGS, "Permission denied for opening %s", buf);
804 /* name in Buf should now be OK */
807 int gmx_file_rename(const char *oldname, const char *newname)
809 #ifndef GMX_NATIVE_WINDOWS
810 /* under unix, rename() is atomic (at least, it should be). */
811 return rename(oldname, newname);
813 if (MoveFileEx(oldname, newname,
814 MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH))
825 int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_empty)
827 /* the full copy buffer size: */
828 #define FILECOPY_BUFSIZE (1<<16)
833 snew(buf, FILECOPY_BUFSIZE);
835 in = fopen(oldname, "rb");
841 /* If we don't copy when empty, we postpone opening the file
842 until we're actually ready to write. */
845 out = fopen(newname, "wb");
856 nread = fread(buf, sizeof(char), FILECOPY_BUFSIZE, in);
862 /* so this is where we open when copy_if_empty is false:
863 here we know we read something. */
864 out = fopen(newname, "wb");
870 ret = fwrite(buf, sizeof(char), nread, out);
896 #undef FILECOPY_BUFSIZE
900 int gmx_fsync(FILE *fp)
905 /* the fahcore defines its own os-independent fsync */
907 #else /* GMX_FAHCORE */
911 /* get the file number */
912 #if defined(HAVE_FILENO)
914 #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",