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>
53 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
62 #include "gmx_fatal.h"
68 #include "thread_mpi.h"
71 /* Windows file stuff, only necessary for visual studio */
76 /* we keep a linked list of all files opened through pipes (i.e.
77 compressed or .gzipped files. This way we can distinguish between them
78 without having to change the semantics of reading from/writing to files)
80 typedef struct t_pstack
{
82 struct t_pstack
*prev
;
85 static t_pstack
*pstack
=NULL
;
86 static bool bUnbuffered
=FALSE
;
89 /* this linked list is an intrinsically globally shared object, so we have
90 to protect it with mutexes */
91 static tMPI_Thread_mutex_t pstack_mutex
=TMPI_THREAD_MUTEX_INITIALIZER
;
99 void push_ps(FILE *fp
)
104 tMPI_Thread_mutex_lock(&pstack_mutex
);
112 tMPI_Thread_mutex_unlock(&pstack_mutex
);
117 /* don't use pipes!*/
118 #define popen fah_fopen
119 #define pclose fah_fclose
129 static FILE *popen(const char *nm
,const char *mode
)
131 gmx_impl("Sorry no pipes...");
136 static int pclose(FILE *fp
)
138 gmx_impl("Sorry no pipes...");
145 int ffclose(FILE *fp
)
153 tMPI_Thread_mutex_lock(&pstack_mutex
);
161 else if (ps
->fp
== fp
) {
168 while ((ps
->prev
!= NULL
) && (ps
->prev
->fp
!= fp
))
170 if (ps
->prev
->fp
== fp
) {
171 if (ps
->prev
->fp
!= NULL
)
172 ret
= pclose(ps
->prev
->fp
);
174 ps
->prev
=ps
->prev
->prev
;
183 tMPI_Thread_mutex_unlock(&pstack_mutex
);
194 void frewind(FILE *fp
)
198 tMPI_Thread_mutex_lock(&pstack_mutex
);
204 fprintf(stderr
,"Cannot rewind compressed file!\n");
206 tMPI_Thread_mutex_unlock(&pstack_mutex
);
214 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
);
245 bool is_pipe(FILE *fp
)
249 tMPI_Thread_mutex_lock(&pstack_mutex
);
256 tMPI_Thread_mutex_unlock(&pstack_mutex
);
263 tMPI_Thread_mutex_unlock(&pstack_mutex
);
269 static FILE *uncompress(const char *fn
,const char *mode
)
274 sprintf(buf
,"uncompress -c < %s",fn
);
275 fprintf(stderr
,"Going to execute '%s'\n",buf
);
276 if ((fp
=popen(buf
,mode
)) == NULL
)
283 static FILE *gunzip(const char *fn
,const char *mode
)
288 sprintf(buf
,"gunzip -c < %s",fn
);
289 fprintf(stderr
,"Going to execute '%s'\n",buf
);
290 if ((fp
=popen(buf
,mode
)) == NULL
)
297 bool gmx_fexist(const char *fname
)
303 test
=fopen(fname
,"r");
305 /*Windows doesn't allow fopen of directory - so we need to check this seperately */
306 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
307 DWORD attr
= GetFileAttributes(fname
);
308 return (attr
!= INVALID_FILE_ATTRIBUTES
) && (attr
& FILE_ATTRIBUTE_DIRECTORY
);
319 bool gmx_fexist_master(const char *fname
, t_commrec
*cr
)
325 bExist
= gmx_fexist(fname
);
329 gmx_bcast(sizeof(bExist
),&bExist
,cr
);
334 bool gmx_eof(FILE *fp
)
342 if ((beof
=fread(data
,1,1,fp
))==1)
343 gmx_fseek(fp
,-1,SEEK_CUR
);
348 static char *backup_fn(const char *file
,int count_max
)
350 /* Use a reasonably low value for countmax; we might
351 * generate 4-5 files in each round, and we dont
352 * want to hit directory limits of 1024 or 2048 files.
361 count_max
= COUNTMAX
;
364 smalloc(buf
, GMX_PATH_MAX
);
366 for(i
=strlen(file
)-1; ((i
> 0) && (file
[i
] != DIR_SEPARATOR
)); i
--)
368 /* Must check whether i > 0, i.e. whether there is a directory
369 * in the file name. In that case we overwrite the / sign with
370 * a '\0' to end the directory string .
373 directory
= strdup(file
);
375 fn
= strdup(file
+i
+1);
378 directory
= strdup(".");
382 sprintf(buf
,"%s/#%s.%d#",directory
,fn
,count
);
384 } while ((count
<= count_max
) && gmx_fexist(buf
));
386 /* Arbitrarily bail out */
387 if (count
> count_max
)
388 gmx_fatal(FARGS
,"Won't make more than %d backups of %s for you.\n"
389 "The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
398 bool make_backup(const char * name
)
405 return FALSE
; /* skip making backups */
408 if (gmx_fexist(name
))
410 env
= getenv("GMX_MAXBACKUP");
414 sscanf(env
,"%d",&count_max
);
417 /* Do not make backups and possibly overwrite old files */
423 /* Use the default maximum */
426 backup
= backup_fn(name
,count_max
);
427 if(rename(name
, backup
) == 0) {
428 fprintf(stderr
, "\nBack Off! I just backed up %s to %s\n",
431 fprintf(stderr
, "Sorry couldn't backup %s to %s\n", name
, backup
);
440 FILE *ffopen(const char *file
,const char *mode
)
443 return fopen(file
,mode
);
446 char buf
[256],*bf
,*bufsize
=0,*ptr
;
455 bRead
= (mode
[0]=='r'&&mode
[1]!='+');
457 if (gmx_fexist(buf
) || !bRead
) {
458 if ((ff
=fopen(buf
,mode
))==NULL
)
461 /* Check whether we should be using buffering (default) or not
464 if (bUnbuffered
|| ((bufsize
=getenv("LOG_BUFS")) != NULL
)) {
465 /* Check whether to use completely unbuffered */
469 bs
=strtol(bufsize
, NULL
, 10);
474 if (setvbuf(ff
,ptr
,_IOFBF
,bs
) != 0)
475 gmx_file("Buffering File");
481 sprintf(buf
,"%s.Z",file
);
482 if (gmx_fexist(buf
)) {
483 ff
=uncompress(buf
,mode
);
486 sprintf(buf
,"%s.gz",file
);
487 if (gmx_fexist(buf
)) {
498 /* Our own implementation of dirent-like functionality to scan directories. */
503 #elif (defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64)
504 intptr_t windows_handle
;
505 struct _finddata_t finddata
;
514 gmx_directory_open(gmx_directory_t
*p_gmxdir
,const char *dirname
)
516 struct gmx_directory
* gmxdir
;
524 if( (gmxdir
->dirent_handle
= opendir(dirname
)) != NULL
)
534 #elif (defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64)
536 if(dirname
!=NULL
&& strlen(dirname
)>0)
542 len
= strlen(dirname
);
545 strncpy(tmpname
,dirname
,len
+1);
547 /* Remove possible trailing directory separator */
548 if(tmpname
[len
]=='/' || tmpname
[len
]=='\\')
554 strcat(tmpname
,"/*");
557 if( (gmxdir
->windows_handle
=_findfirst(tmpname
,&gmxdir
->finddata
))>0L)
581 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n"
582 "In the very unlikely event this is not a compile-time mistake you could consider\n"
583 "implementing support for your platform in futil.c, but contact the developers\n"
584 "to make sure it's really necessary!\n");
592 gmx_directory_nextfile(gmx_directory_t gmxdir
,char *name
,int maxlength_name
)
598 struct dirent tmp_dirent
;
602 if(gmxdir
!=NULL
&& gmxdir
->dirent_handle
!=NULL
)
604 rc
= readdir_r(gmxdir
->dirent_handle
,&tmp_dirent
,&p
);
607 strncpy(name
,tmp_dirent
.d_name
,maxlength_name
);
621 #elif (defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64)
625 if(gmxdir
->windows_handle
<=0)
631 else if(gmxdir
->first
==1)
633 strncpy(name
,gmxdir
->finddata
.name
,maxlength_name
);
639 if(_findnext(gmxdir
->windows_handle
,&gmxdir
->finddata
)==0)
641 strncpy(name
,gmxdir
->finddata
.name
,maxlength_name
);
654 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
662 gmx_directory_close(gmx_directory_t gmxdir
)
666 rc
= (gmxdir
!= NULL
) ? closedir(gmxdir
->dirent_handle
) : EINVAL
;
667 #elif (defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64)
668 rc
= (gmxdir
!= NULL
) ? _findclose(gmxdir
->windows_handle
) : EINVAL
;
671 "Source compiled without POSIX dirent or windows support - cannot scan directories.\n");
682 bool search_subdirs(const char *parent
, char *libdir
)
687 /* Search a few common subdirectory names for the gromacs library dir */
688 sprintf(libdir
,"%s%cshare%ctop%cgurgle.dat",parent
,
689 DIR_SEPARATOR
,DIR_SEPARATOR
,DIR_SEPARATOR
);
690 found
=gmx_fexist(libdir
);
692 sprintf(libdir
,"%s%cshare%cgromacs%ctop%cgurgle.dat",parent
,
693 DIR_SEPARATOR
,DIR_SEPARATOR
,
694 DIR_SEPARATOR
,DIR_SEPARATOR
);
695 found
=gmx_fexist(libdir
);
698 sprintf(libdir
,"%s%cshare%cgromacs-%s%ctop%cgurgle.dat",parent
,
699 DIR_SEPARATOR
,DIR_SEPARATOR
,VERSION
,
700 DIR_SEPARATOR
,DIR_SEPARATOR
);
701 found
=gmx_fexist(libdir
);
704 sprintf(libdir
,"%s%cshare%cgromacs%cgromacs-%s%ctop%cgurgle.dat",parent
,
705 DIR_SEPARATOR
,DIR_SEPARATOR
,DIR_SEPARATOR
,
706 VERSION
,DIR_SEPARATOR
,DIR_SEPARATOR
);
707 found
=gmx_fexist(libdir
);
710 /* Remove the gurgle.dat part from libdir if we found something */
712 ptr
=strrchr(libdir
,DIR_SEPARATOR
); /* slash or backslash always present, no check necessary */
719 /* Check if the program name begins with "/" on unix/cygwin, or
720 * with "\" or "X:\" on windows. If not, the program name
721 * is relative to the current directory.
723 static bool filename_is_absolute(char *name
)
725 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
726 return ((name
[0] == DIR_SEPARATOR
) || ((strlen(name
)>3) && strncmp(name
+1,":\\",2)) == 0);
728 return (name
[0] == DIR_SEPARATOR
);
732 bool get_libdir(char *libdir
)
734 #define GMX_BINNAME_MAX 512
735 char bin_name
[GMX_BINNAME_MAX
];
736 char buf
[GMX_BINNAME_MAX
];
737 char full_path
[GMX_PATH_MAX
+GMX_BINNAME_MAX
];
738 char system_path
[GMX_PATH_MAX
];
739 char *dir
,*ptr
,*s
,*pdum
;
743 if (Program() != NULL
)
746 /* First - detect binary name */
747 if (strlen(Program()) >= GMX_BINNAME_MAX
)
749 gmx_fatal(FARGS
,"The name of the binary is longer than the allowed buffer size (%d):\n'%s'",GMX_BINNAME_MAX
,Program());
751 strncpy(bin_name
,Program(),GMX_BINNAME_MAX
-1);
753 /* On windows & cygwin we need to add the .exe extension
754 * too, or we wont be able to detect that the file exists
756 #if (defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64 || defined __CYGWIN__ || defined __CYGWIN32__)
757 if(strlen(bin_name
)<3 || strncasecmp(bin_name
+strlen(bin_name
)-4,".exe",4))
758 strcat(bin_name
,".exe");
761 /* Only do the smart search part if we got a real name */
762 if (NULL
!=bin_name
&& strncmp(bin_name
,"GROMACS",GMX_BINNAME_MAX
)) {
764 if (!strchr(bin_name
,DIR_SEPARATOR
)) {
765 /* No slash or backslash in name means it must be in the path - search it! */
766 /* Add the local dir since it is not in the path on windows */
767 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
768 pdum
=_getcwd(system_path
,sizeof(system_path
)-1);
770 pdum
=getcwd(system_path
,sizeof(system_path
)-1);
772 sprintf(full_path
,"%s%c%s",system_path
,DIR_SEPARATOR
,bin_name
);
773 found
= gmx_fexist(full_path
);
774 if (!found
&& (s
=getenv("PATH")) != NULL
)
778 dupped
=gmx_strdup(s
);
780 while(!found
&& (dir
=gmx_strsep(&s
, PATH_SEPARATOR
)) != NULL
)
782 sprintf(full_path
,"%s%c%s",dir
,DIR_SEPARATOR
,bin_name
);
783 found
= gmx_fexist(full_path
);
791 } else if (!filename_is_absolute(bin_name
)) {
792 /* name contains directory separators, but
793 * it does not start at the root, i.e.
794 * name is relative to the current dir
796 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
797 pdum
=_getcwd(buf
,sizeof(buf
)-1);
799 pdum
=getcwd(buf
,sizeof(buf
)-1);
801 sprintf(full_path
,"%s%c%s",buf
,DIR_SEPARATOR
,bin_name
);
803 strncpy(full_path
,bin_name
,GMX_PATH_MAX
);
806 /* Now we should have a full path and name in full_path,
807 * but on unix it might be a link, or a link to a link to a link..
809 #if (!defined WIN32 && !defined _WIN32 && !defined WIN64 && !defined _WIN64)
810 while( (i
=readlink(full_path
,buf
,sizeof(buf
)-1)) > 0 ) {
812 /* If it doesn't start with "/" it is relative */
813 if (buf
[0]!=DIR_SEPARATOR
) {
814 strncpy(strrchr(full_path
,DIR_SEPARATOR
)+1,buf
,GMX_PATH_MAX
);
816 strncpy(full_path
,buf
,GMX_PATH_MAX
);
820 /* Remove the executable name - it always contains at least one slash */
821 *(strrchr(full_path
,DIR_SEPARATOR
)+1)='\0';
822 /* Now we have the full path to the gromacs executable.
823 * Use it to find the library dir.
826 while(!found
&& ( (ptr
=strrchr(full_path
,DIR_SEPARATOR
)) != NULL
) ) {
828 found
=search_subdirs(full_path
,libdir
);
832 /* End of smart searching. If we didn't find it in our parent tree,
833 * or if the program name wasn't set, at least try some standard
834 * locations before giving up, in case we are running from e.g.
835 * a users home directory. This only works on unix or cygwin...
837 #if ((!defined WIN32 && !defined _WIN32 && !defined WIN64 && !defined _WIN64) || defined __CYGWIN__ || defined __CYGWIN32__)
839 found
=search_subdirs("/usr/local",libdir
);
841 found
=search_subdirs("/usr",libdir
);
843 found
=search_subdirs("/opt",libdir
);
849 char *low_gmxlibfn(const char *file
, bool bFatal
)
854 char libpath
[GMX_PATH_MAX
];
855 bool env_is_set
=FALSE
;
856 char *s
,tmppath
[GMX_PATH_MAX
];
858 /* GMXLIB can be a path now */
859 lib
=getenv("GMXLIB");
863 strncpy(libpath
,lib
,GMX_PATH_MAX
);
865 else if (!get_libdir(libpath
))
867 strncpy(libpath
,GMXLIBDIR
,GMX_PATH_MAX
);
871 if (gmx_fexist(file
))
877 strncpy(tmppath
,libpath
,GMX_PATH_MAX
);
879 while(ret
== NULL
&& (dir
=gmx_strsep(&s
, PATH_SEPARATOR
)) != NULL
)
881 sprintf(buf
,"%s%c%s",dir
,DIR_SEPARATOR
,file
);
887 if (ret
== NULL
&& bFatal
)
891 gmx_fatal(FARGS
,"Library file %s not found in current dir nor in your GMXLIB path.\n",file
);
895 gmx_fatal(FARGS
,"Library file %s not found in current dir nor in default directories.\n"
896 "(You can set the directories to search with the GMXLIB path variable)",file
);
908 FILE *low_libopen(const char *file
,bool bFatal
)
913 fn
=low_gmxlibfn(file
,bFatal
);
919 fprintf(debug
,"Opening library file %s\n",fn
);
927 char *gmxlibfn(const char *file
)
929 return low_gmxlibfn(file
,TRUE
);
932 FILE *libopen(const char *file
)
934 return low_libopen(file
,TRUE
);
937 void gmx_tmpnam(char *buf
)
941 if ((len
= strlen(buf
)) < 7)
942 gmx_fatal(FARGS
,"Buf passed to gmx_tmpnam must be at least 7 bytes long");
943 for(i
=len
-6; (i
<len
); i
++) {
946 /* mktemp is dangerous and we should use mkstemp instead, but
947 * since windows doesnt support it we have to separate the cases.
948 * 20090307: mktemp deprecated, use iso c++ _mktemp instead.
950 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
957 gmx_fatal(FARGS
,"Invalid template %s for mkstemp",buf
);
960 gmx_fatal(FARGS
,"mkstemp created existing file",buf
);
963 gmx_fatal(FARGS
,"Permission denied for opening %s",buf
);
970 /* name in Buf should now be OK */
973 int gmx_truncatefile(char *path
, gmx_off_t length
)
976 /* Microsoft visual studio does not have "truncate" */
978 LARGE_INTEGER win_length
;
980 win_length
.QuadPart
= length
;
982 fh
= CreateFile(path
,GENERIC_READ
| GENERIC_WRITE
,0,NULL
,
983 OPEN_EXISTING
,0,NULL
);
984 SetFilePointerEx(fh
,win_length
,NULL
,FILE_BEGIN
);
990 return truncate(path
,length
);
995 int gmx_file_rename(const char *oldname
, const char *newname
)
997 #if (!(defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)))
998 /* under unix, rename() is atomic (at least, it should be). */
999 return rename(oldname
, newname
);
1001 if (MoveFileEx(oldname
, newname
,
1002 MOVEFILE_REPLACE_EXISTING
|MOVEFILE_WRITE_THROUGH
))
1009 int gmx_file_copy(const char *oldname
, const char *newname
, bool copy_if_empty
)
1011 /* the full copy buffer size: */
1012 #define FILECOPY_BUFSIZE (1<<16)
1017 snew(buf
, FILECOPY_BUFSIZE
);
1019 in
=fopen(oldname
, "rb");
1023 /* If we don't copy when empty, we postpone opening the file
1024 until we're actually ready to write. */
1027 out
=fopen(newname
, "wb");
1036 nread
=fread(buf
, sizeof(char), FILECOPY_BUFSIZE
, in
);
1042 /* so this is where we open when copy_if_empty is false:
1043 here we know we read something. */
1044 out
=fopen(newname
, "wb");
1048 ret
=fwrite(buf
, sizeof(char), nread
, out
);
1068 #undef FILECOPY_BUFSIZE
1072 int gmx_fsync(FILE *fp
)
1077 /* the fahcore defines its own os-independent fsync */
1079 #else /* GMX_FAHCORE */
1083 /* get the file number */
1084 #if defined(HAVE_FILENO)
1086 #elif defined(HAVE__FILENO)
1090 /* do the actual fsync */
1093 #if (defined(HAVE_FSYNC))
1095 #elif (defined(HAVE__COMMIT))
1100 #endif /* GMX_FAHCORE */
1102 /* We check for these error codes this way because POSIX requires them
1103 to be defined, and using anything other than macros is unlikely: */
1105 /* we don't want to report an error just because fsync() caught a signal.
1106 For our purposes, we can just ignore this. */
1107 if (rc
&& errno
==EINTR
)
1111 /* we don't want to report an error just because we tried to fsync()
1112 stdout, a socket or a pipe. */
1113 if (rc
&& errno
==EINVAL
)