1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROningen Mixture of Alchemy and Childrens' Stories
43 #include <sys/types.h>
56 #ifdef GMX_NATIVE_WINDOWS
65 #include "gmx_fatal.h"
71 #include "thread_mpi.h"
74 /* Windows file stuff, only necessary for visual studio */
79 /* we keep a linked list of all files opened through pipes (i.e.
80 compressed or .gzipped files. This way we can distinguish between them
81 without having to change the semantics of reading from/writing to files)
83 typedef struct t_pstack {
85 struct t_pstack *prev;
88 static t_pstack *pstack=NULL;
89 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;
102 void push_ps(FILE *fp)
106 #ifdef GMX_THREAD_MPI
107 tMPI_Thread_mutex_lock(&pstack_mutex);
114 #ifdef GMX_THREAD_MPI
115 tMPI_Thread_mutex_unlock(&pstack_mutex);
120 /* don't use pipes!*/
121 #define popen fah_fopen
122 #define pclose fah_fclose
132 static FILE *popen(const char *nm,const char *mode)
134 gmx_impl("Sorry no pipes...");
139 static int pclose(FILE *fp)
141 gmx_impl("Sorry no pipes...");
148 int ffclose(FILE *fp)
155 #ifdef GMX_THREAD_MPI
156 tMPI_Thread_mutex_lock(&pstack_mutex);
164 else if (ps->fp == fp) {
171 while ((ps->prev != NULL) && (ps->prev->fp != fp))
173 if ((ps->prev != NULL) && ps->prev->fp == fp) {
174 if (ps->prev->fp != NULL)
175 ret = pclose(ps->prev->fp);
177 ps->prev=ps->prev->prev;
185 #ifdef GMX_THREAD_MPI
186 tMPI_Thread_mutex_unlock(&pstack_mutex);
197 void frewind(FILE *fp)
200 #ifdef GMX_THREAD_MPI
201 tMPI_Thread_mutex_lock(&pstack_mutex);
207 fprintf(stderr,"Cannot rewind compressed file!\n");
208 #ifdef GMX_THREAD_MPI
209 tMPI_Thread_mutex_unlock(&pstack_mutex);
216 #ifdef GMX_THREAD_MPI
217 tMPI_Thread_mutex_unlock(&pstack_mutex);
221 int gmx_fseek(FILE *stream, gmx_off_t offset, int whence)
224 return fseeko(stream, offset, whence);
226 #ifdef HAVE__FSEEKI64
227 return _fseeki64(stream, offset, whence);
229 return fseek(stream, offset, whence);
234 gmx_off_t gmx_ftell(FILE *stream)
237 return ftello(stream);
239 #ifdef HAVE__FSEEKI64
240 return _ftelli64(stream);
242 return ftell(stream);
248 gmx_bool is_pipe(FILE *fp)
251 #ifdef GMX_THREAD_MPI
252 tMPI_Thread_mutex_lock(&pstack_mutex);
258 #ifdef GMX_THREAD_MPI
259 tMPI_Thread_mutex_unlock(&pstack_mutex);
265 #ifdef GMX_THREAD_MPI
266 tMPI_Thread_mutex_unlock(&pstack_mutex);
272 static FILE *uncompress(const char *fn,const char *mode)
277 sprintf(buf,"uncompress -c < %s",fn);
278 fprintf(stderr,"Going to execute '%s'\n",buf);
279 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)
300 gmx_bool gmx_fexist(const char *fname)
306 test=fopen(fname,"r");
308 /*Windows doesn't allow fopen of directory - so we need to check this seperately */
309 #ifdef GMX_NATIVE_WINDOWS
310 DWORD attr = GetFileAttributes(fname);
311 return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
321 static gmx_bool gmx_is_file(const char *fname)
327 test=fopen(fname,"r");
335 /*Windows doesn't allow fopen of directory - so we don't need to check this seperately */
336 #if (!((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__))
341 status = lstat (fname, &st_buf);
343 status = stat (fname, &st_buf);
345 if (status != 0 || !S_ISREG(st_buf.st_mode))
356 gmx_bool gmx_fexist_master(const char *fname, t_commrec *cr)
362 bExist = gmx_fexist(fname);
366 gmx_bcast(sizeof(bExist),&bExist,cr);
371 gmx_bool gmx_eof(FILE *fp)
379 if ((beof=fread(data,1,1,fp))==1)
380 gmx_fseek(fp,-1,SEEK_CUR);
385 static char *backup_fn(const char *file,int count_max)
387 /* Use a reasonably low value for countmax; we might
388 * generate 4-5 files in each round, and we dont
389 * want to hit directory limits of 1024 or 2048 files.
398 count_max = COUNTMAX;
401 smalloc(buf, GMX_PATH_MAX);
403 for(i=strlen(file)-1; ((i > 0) && (file[i] != DIR_SEPARATOR)); i--)
405 /* Must check whether i > 0, i.e. whether there is a directory
406 * in the file name. In that case we overwrite the / sign with
407 * a '\0' to end the directory string .
410 directory = gmx_strdup(file);
412 fn = gmx_strdup(file+i+1);
415 directory = gmx_strdup(".");
416 fn = gmx_strdup(file);
419 sprintf(buf,"%s/#%s.%d#",directory,fn,count);
421 } while ((count <= count_max) && gmx_fexist(buf));
423 /* Arbitrarily bail out */
424 if (count > count_max)
425 gmx_fatal(FARGS,"Won't make more than %d backups of %s for you.\n"
426 "The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
435 gmx_bool make_backup(const char * name)
442 return FALSE; /* skip making backups */
445 if (gmx_fexist(name))
447 env = getenv("GMX_MAXBACKUP");
451 sscanf(env,"%d",&count_max);
454 /* Do not make backups and possibly overwrite old files */
460 /* Use the default maximum */
463 backup = backup_fn(name,count_max);
464 if(rename(name, backup) == 0) {
465 fprintf(stderr, "\nBack Off! I just backed up %s to %s\n",
468 fprintf(stderr, "Sorry couldn't backup %s to %s\n", name, backup);
477 FILE *ffopen(const char *file,const char *mode)
480 return fopen(file,mode);
483 char buf[256],*bf,*bufsize=0,*ptr;
497 bRead= (mode[0]=='r'&&mode[1]!='+');
499 if (!bRead || gmx_fexist(buf)) {
500 if ((ff=fopen(buf,mode))==NULL)
503 /* Check whether we should be using buffering (default) or not
506 if (bUnbuffered || ((bufsize=getenv("LOG_BUFS")) != NULL)) {
507 /* Check whether to use completely unbuffered */
511 bs=strtol(bufsize, NULL, 10);
516 if (setvbuf(ff,ptr,_IOFBF,bs) != 0)
517 gmx_file("Buffering File");
523 sprintf(buf,"%s.Z",file);
524 if (gmx_fexist(buf)) {
525 ff=uncompress(buf,mode);
528 sprintf(buf,"%s.gz",file);
529 if (gmx_fexist(buf)) {
540 /* Our own implementation of dirent-like functionality to scan directories. */
545 #elif (defined GMX_NATIVE_WINDOWS)
546 intptr_t windows_handle;
547 struct _finddata_t finddata;
556 gmx_directory_open(gmx_directory_t *p_gmxdir,const char *dirname)
558 struct gmx_directory * gmxdir;
566 if( (gmxdir->dirent_handle = opendir(dirname)) != NULL)
576 #elif (defined GMX_NATIVE_WINDOWS)
578 if(dirname!=NULL && strlen(dirname)>0)
584 len = strlen(dirname);
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)
623 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n"
624 "In the very unlikely event this is not a compile-time mistake you could consider\n"
625 "implementing support for your platform in futil.c, but contact the developers\n"
626 "to make sure it's really necessary!\n");
634 gmx_directory_nextfile(gmx_directory_t gmxdir,char *name,int maxlength_name)
640 struct dirent * direntp_large;
644 if(gmxdir!=NULL && gmxdir->dirent_handle!=NULL)
646 /* On some platforms no space is present for d_name in dirent.
647 * Since d_name is guaranteed to be the last entry, allocating
648 * extra space for dirent will allow more size for d_name.
649 * GMX_MAX_PATH should always be >= the max possible d_name.
651 smalloc(direntp_large, sizeof(*direntp_large) + GMX_PATH_MAX);
652 rc = readdir_r(gmxdir->dirent_handle,direntp_large,&p);
656 strncpy(name,direntp_large->d_name,maxlength_name);
663 sfree(direntp_large);
671 #elif (defined GMX_NATIVE_WINDOWS)
675 if(gmxdir->windows_handle<=0)
681 else if(gmxdir->first==1)
683 strncpy(name,gmxdir->finddata.name,maxlength_name);
689 if(_findnext(gmxdir->windows_handle,&gmxdir->finddata)==0)
691 strncpy(name,gmxdir->finddata.name,maxlength_name);
704 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
712 gmx_directory_close(gmx_directory_t gmxdir)
716 rc = (gmxdir != NULL) ? closedir(gmxdir->dirent_handle) : EINVAL;
717 #elif (defined GMX_NATIVE_WINDOWS)
718 rc = (gmxdir != NULL) ? _findclose(gmxdir->windows_handle) : EINVAL;
721 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
730 static gmx_bool search_subdirs(const char *parent, char *libdir)
735 /* Search a few common subdirectory names for the gromacs library dir */
736 sprintf(libdir,"%s%cshare%ctop%cgurgle.dat",parent,
737 DIR_SEPARATOR,DIR_SEPARATOR,DIR_SEPARATOR);
738 found=gmx_fexist(libdir);
740 sprintf(libdir,"%s%cshare%cgromacs%ctop%cgurgle.dat",parent,
741 DIR_SEPARATOR,DIR_SEPARATOR,
742 DIR_SEPARATOR,DIR_SEPARATOR);
743 found=gmx_fexist(libdir);
746 sprintf(libdir,"%s%cshare%cgromacs-%s%ctop%cgurgle.dat",parent,
747 DIR_SEPARATOR,DIR_SEPARATOR,VERSION,
748 DIR_SEPARATOR,DIR_SEPARATOR);
749 found=gmx_fexist(libdir);
752 sprintf(libdir,"%s%cshare%cgromacs%cgromacs-%s%ctop%cgurgle.dat",parent,
753 DIR_SEPARATOR,DIR_SEPARATOR,DIR_SEPARATOR,
754 VERSION,DIR_SEPARATOR,DIR_SEPARATOR);
755 found=gmx_fexist(libdir);
758 /* Remove the gurgle.dat part from libdir if we found something */
760 ptr=strrchr(libdir,DIR_SEPARATOR); /* slash or backslash always present, no check necessary */
767 /* Check if the program name begins with "/" on unix/cygwin, or
768 * with "\" or "X:\" on windows. If not, the program name
769 * is relative to the current directory.
771 static gmx_bool filename_is_absolute(char *name)
773 #ifdef GMX_NATIVE_WINDOWS
774 return ((name[0] == DIR_SEPARATOR) || ((strlen(name)>3) && strncmp(name+1,":\\",2)) == 0);
776 return (name[0] == DIR_SEPARATOR);
780 gmx_bool get_libdir(char *libdir)
782 #define GMX_BINNAME_MAX 512
783 char bin_name[GMX_BINNAME_MAX];
784 char buf[GMX_BINNAME_MAX];
785 char full_path[GMX_PATH_MAX+GMX_BINNAME_MAX];
786 char system_path[GMX_PATH_MAX];
787 char *dir,*ptr,*s,*pdum;
788 gmx_bool found=FALSE;
791 if (Program() != NULL)
794 /* First - detect binary name */
795 if (strlen(Program()) >= GMX_BINNAME_MAX)
797 gmx_fatal(FARGS,"The name of the binary is longer than the allowed buffer size (%d):\n'%s'",GMX_BINNAME_MAX,Program());
799 strncpy(bin_name,Program(),GMX_BINNAME_MAX-1);
801 /* On windows & cygwin we need to add the .exe extension
802 * too, or we wont be able to detect that the file exists
804 #if (defined GMX_NATIVE_WINDOWS || defined GMX_CYGWIN)
805 if(strlen(bin_name)<3 || gmx_strncasecmp(bin_name+strlen(bin_name)-4,".exe",4))
806 strcat(bin_name,".exe");
809 /* Only do the smart search part if we got a real name */
810 if (NULL!=bin_name && strncmp(bin_name,"GROMACS",GMX_BINNAME_MAX)) {
812 if (!strchr(bin_name,DIR_SEPARATOR)) {
813 /* No slash or backslash in name means it must be in the path - search it! */
814 /* Add the local dir since it is not in the path on windows */
815 gmx_getcwd(system_path, sizeof(system_path));
816 sprintf(full_path,"%s%c%s",system_path,DIR_SEPARATOR,bin_name);
817 found = gmx_is_file(full_path);
818 if (!found && (s=getenv("PATH")) != NULL)
822 dupped=gmx_strdup(s);
824 while(!found && (dir=gmx_strsep(&s, PATH_SEPARATOR)) != NULL)
826 sprintf(full_path,"%s%c%s",dir,DIR_SEPARATOR,bin_name);
827 found = gmx_is_file(full_path);
835 } else if (!filename_is_absolute(bin_name)) {
836 /* name contains directory separators, but
837 * it does not start at the root, i.e.
838 * name is relative to the current dir
840 gmx_getcwd(buf, sizeof(buf));
841 sprintf(full_path,"%s%c%s",buf,DIR_SEPARATOR,bin_name);
843 strncpy(full_path,bin_name,GMX_PATH_MAX);
846 /* Now we should have a full path and name in full_path,
847 * but on unix it might be a link, or a link to a link to a link..
849 #ifndef GMX_NATIVE_WINDOWS
850 while( (i=readlink(full_path,buf,sizeof(buf)-1)) > 0 ) {
852 /* If it doesn't start with "/" it is relative */
853 if (buf[0]!=DIR_SEPARATOR) {
854 strncpy(strrchr(full_path,DIR_SEPARATOR)+1,buf,GMX_PATH_MAX);
856 strncpy(full_path,buf,GMX_PATH_MAX);
860 /* If running directly from the build tree, try to use the source
863 #if (defined CMAKE_SOURCE_DIR && defined CMAKE_BINARY_DIR)
864 if (strncmp(full_path, CMAKE_BINARY_DIR, strlen(CMAKE_BINARY_DIR)) == 0)
866 if (search_subdirs(CMAKE_SOURCE_DIR, libdir))
873 /* Remove the executable name - it always contains at least one slash */
874 *(strrchr(full_path,DIR_SEPARATOR)+1)='\0';
875 /* Now we have the full path to the gromacs executable.
876 * Use it to find the library dir.
879 while(!found && ( (ptr=strrchr(full_path,DIR_SEPARATOR)) != NULL ) ) {
881 found=search_subdirs(full_path,libdir);
885 /* End of smart searching. If we didn't find it in our parent tree,
886 * or if the program name wasn't set, at least try some standard
887 * locations before giving up, in case we are running from e.g.
888 * a users home directory. This only works on unix or cygwin...
890 #ifndef GMX_NATIVE_WINDOWS
892 found=search_subdirs("/usr/local",libdir);
894 found=search_subdirs("/usr",libdir);
896 found=search_subdirs("/opt",libdir);
902 char *low_gmxlibfn(const char *file, gmx_bool bAddCWD, gmx_bool bFatal)
907 char libpath[GMX_PATH_MAX];
908 gmx_bool env_is_set=FALSE;
909 char *s,tmppath[GMX_PATH_MAX];
911 /* GMXLIB can be a path now */
912 lib=getenv("GMXLIB");
916 strncpy(libpath,lib,GMX_PATH_MAX);
918 else if (!get_libdir(libpath))
920 strncpy(libpath,GMXLIBDIR,GMX_PATH_MAX);
924 if (bAddCWD && gmx_fexist(file))
926 ret = gmx_strdup(file);
930 strncpy(tmppath,libpath,GMX_PATH_MAX);
932 while(ret == NULL && (dir=gmx_strsep(&s, PATH_SEPARATOR)) != NULL )
934 sprintf(buf,"%s%c%s",dir,DIR_SEPARATOR,file);
937 ret = gmx_strdup(buf);
940 if (ret == NULL && bFatal)
945 "Library file %s not found %sin your GMXLIB path.",
946 file, bAddCWD ? "in current dir nor " : "");
951 "Library file %s not found %sin default directories.\n"
952 "(You can set the directories to search with the GMXLIB path variable)",
953 file, bAddCWD ? "in current dir nor " : "");
965 FILE *low_libopen(const char *file,gmx_bool bFatal)
970 fn=low_gmxlibfn(file,TRUE,bFatal);
976 fprintf(debug,"Opening library file %s\n",fn);
984 char *gmxlibfn(const char *file)
986 return low_gmxlibfn(file,TRUE,TRUE);
989 FILE *libopen(const char *file)
991 return low_libopen(file,TRUE);
994 void gmx_tmpnam(char *buf)
998 if ((len = strlen(buf)) < 7)
999 gmx_fatal(FARGS,"Buf passed to gmx_tmpnam must be at least 7 bytes long");
1000 for(i=len-6; (i<len); i++) {
1003 /* mktemp is dangerous and we should use mkstemp instead, but
1004 * since windows doesnt support it we have to separate the cases.
1005 * 20090307: mktemp deprecated, use iso c++ _mktemp instead.
1007 #ifdef GMX_NATIVE_WINDOWS
1014 gmx_fatal(FARGS,"Invalid template %s for mkstemp",buf);
1017 gmx_fatal(FARGS,"mkstemp created existing file",buf);
1020 gmx_fatal(FARGS,"Permission denied for opening %s",buf);
1027 /* name in Buf should now be OK */
1030 int gmx_truncatefile(char *path, gmx_off_t length)
1033 /* Microsoft visual studio does not have "truncate" */
1035 LARGE_INTEGER win_length;
1037 win_length.QuadPart = length;
1039 fh = CreateFile(path,GENERIC_READ | GENERIC_WRITE,0,NULL,
1040 OPEN_EXISTING,0,NULL);
1041 SetFilePointerEx(fh,win_length,NULL,FILE_BEGIN);
1047 return truncate(path,length);
1052 int gmx_file_rename(const char *oldname, const char *newname)
1054 #ifndef GMX_NATIVE_WINDOWS
1055 /* under unix, rename() is atomic (at least, it should be). */
1056 return rename(oldname, newname);
1058 if (MoveFileEx(oldname, newname,
1059 MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH))
1066 int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_empty)
1068 /* the full copy buffer size: */
1069 #define FILECOPY_BUFSIZE (1<<16)
1074 snew(buf, FILECOPY_BUFSIZE);
1076 in=fopen(oldname, "rb");
1080 /* If we don't copy when empty, we postpone opening the file
1081 until we're actually ready to write. */
1084 out=fopen(newname, "wb");
1093 nread=fread(buf, sizeof(char), FILECOPY_BUFSIZE, in);
1099 /* so this is where we open when copy_if_empty is false:
1100 here we know we read something. */
1101 out=fopen(newname, "wb");
1105 ret=fwrite(buf, sizeof(char), nread, out);
1125 #undef FILECOPY_BUFSIZE
1129 int gmx_fsync(FILE *fp)
1134 /* the fahcore defines its own os-independent fsync */
1136 #else /* GMX_FAHCORE */
1140 /* get the file number */
1141 #if defined(HAVE_FILENO)
1143 #elif defined(HAVE__FILENO)
1147 /* do the actual fsync */
1150 #if (defined(HAVE_FSYNC))
1152 #elif (defined(HAVE__COMMIT))
1157 #endif /* GMX_FAHCORE */
1159 /* We check for these error codes this way because POSIX requires them
1160 to be defined, and using anything other than macros is unlikely: */
1162 /* we don't want to report an error just because fsync() caught a signal.
1163 For our purposes, we can just ignore this. */
1164 if (rc && errno==EINTR)
1168 /* we don't want to report an error just because we tried to fsync()
1169 stdout, a socket or a pipe. */
1170 if (rc && errno==EINVAL)
1176 void gmx_chdir(const char *directory)
1178 #ifdef GMX_NATIVE_WINDOWS
1179 int rc = _chdir(directory);
1181 int rc = chdir(directory);
1185 gmx_fatal(FARGS, "Cannot change directory to '%s'. Reason: %s",
1186 directory, strerror(errno));
1190 void gmx_getcwd(char *buffer, size_t size)
1192 #ifdef GMX_NATIVE_WINDOWS
1193 char *pdum = _getcwd(buffer, size);
1195 char *pdum = getcwd(buffer, size);
1199 gmx_fatal(FARGS, "Cannot get working directory. Reason: %s",