NAMD
common.C
Go to the documentation of this file.
1 
7 /*
8  global functions as declared in common.h
9 */
10 
11 #if !defined(WIN32) || defined(__CYGWIN__)
12 #include <unistd.h>
13 #endif
14 #include <errno.h>
15 #include <string.h>
16 #include <fcntl.h>
17 #include <sys/stat.h>
18 #include <ctype.h>
19 
20 #include "common.h"
21 #include "InfoStream.h"
22 
23 #include "charm++.h"
24 
25 #ifdef WIN32
26 #include <io.h>
27 #define access(PATH,MODE) _access(PATH,00)
28 #define NOCOMPRESSED
29 #endif
30 
31 #ifdef USESTDIOSTUBS
32 
33 // On the ASCI-Red, these functions have prototypes that don't match
34 // the standard, so I'll override them
35 
36 int write(int fd, const void* buf, int count)
37 {
38  return write(fd,(void*)buf,(size_t)count);
39 }
40 
41 int stat(const char* fn, struct stat* buf)
42 {
43  return stat((char*)fn, buf);
44 }
45 
46 #endif
47 
48 
49 // make a duplicate of a string
50 char *NAMD_stringdup(const char *s) {
51  char *rs;
52 
53  if(!s)
54  return NULL;
55 
56  rs = new char[strlen(s) + 1];
57  strcpy(rs,s);
58 
59  return rs;
60 }
61 
62 
63 // signal all nodes, it's time to quit
64 void NAMD_quit(const char *err_msg)
65 {
66  if ( ! err_msg ) err_msg = "(unknown error)";
67  CkPrintf("EXITING: %s\n", err_msg);
68  fflush(stdout);
69  char repstr[24] = "";
70  if (CmiNumPartitions() > 1) {
71  sprintf(repstr,"REPLICA %d ", CmiMyPartition());
72  }
73  CkError("%sEXITING: %s\n", repstr, err_msg);
74 #if CHARM_VERSION < 61000
75  CkExit();
76 #else
77  CkExit(0);
78 #endif
79 }
80 
81 
82 // signal all nodes, it's time to quit
83 void NAMD_die(const char *err_msg)
84 {
85  if ( ! err_msg ) err_msg = "(unknown error)";
86  CkPrintf("FATAL ERROR: %s\n", err_msg);
87  fflush(stdout);
88  char repstr[24] = "";
89  if (CmiNumPartitions() > 1) {
90  sprintf(repstr,"REPLICA %d ", CmiMyPartition());
91  }
92  CkError("%sFATAL ERROR: %s\n", repstr, err_msg);
93 #if CHARM_VERSION < 61000
94  CkExit();
95 #else
96  CkExit(1);
97 #endif
98 }
99 
100 
101 // signal all nodes, it's time to quit
102 void NAMD_err(const char *err_msg)
103 {
104  if ( ! err_msg ) err_msg = "(unknown error)";
105  const char *sys_err_msg = strerror(errno);
106  if ( ! sys_err_msg ) sys_err_msg = "(unknown error)";
107  CkPrintf("FATAL ERROR: %s: %s\n", err_msg, sys_err_msg);
108  fflush(stdout);
109  char repstr[24] = "";
110  if (CmiNumPartitions() > 1) {
111  sprintf(repstr,"REPLICA %d ", CmiMyPartition());
112  }
113  CkError("%sFATAL ERROR: %s: %s\n", repstr, err_msg, sys_err_msg);
114 #if CHARM_VERSION < 61000
115  CkExit();
116 #else
117  CkExit(1);
118 #endif
119 }
120 
121 
122 // signal all nodes, it's time to quit and it's our own damn fault
123 void NAMD_bug(const char *err_msg)
124 {
125  if ( ! err_msg ) err_msg = "(unknown error)";
126  const char *bug_msg =
127  "FATAL ERROR: See http://www.ks.uiuc.edu/Research/namd/bugreport.html";
128  CkPrintf("FATAL ERROR: %s\n%s\n",err_msg, bug_msg);
129  fflush(stdout);
130  char repstr[24] = "";
131  if (CmiNumPartitions() > 1) {
132  sprintf(repstr,"REPLICA %d ", CmiMyPartition());
133  }
134  CkError("%sFATAL ERROR: %s\n%s\n", repstr, err_msg, bug_msg);
135 #if CHARM_VERSION < 61000
136  CkExit();
137 #else
138  CkExit(2);
139 #endif
140 }
141 
142 
143 int NAMD_file_exists(const char *filename) {
144  int rval;
145  do {
146  rval = access(filename, F_OK);
147  } while ( rval != 0 && errno == EINTR );
148  if ( rval != 0 && errno != ENOENT ) {
149  const char *sys_err_msg = strerror(errno);
150  if ( ! sys_err_msg ) sys_err_msg = "(unknown error)";
151  iout << iERROR << "Error on checking file "
152  << filename << ": " << sys_err_msg << "\n" << endi;
153  fflush(stdout);
154  }
155  return ! rval;
156 }
157 
158 // move filename to filename.BAK
159 void NAMD_backup_file(const char *filename, const char *extension)
160 {
161  if (NAMD_file_exists(filename)) {
162  if ( ! extension ) extension = ".BAK";
163  char *backup = new char[strlen(filename)+strlen(extension)+1];
164  strcpy(backup, filename);
165  strcat(backup, extension);
166 #if defined(WIN32) && !defined(__CYGWIN__)
167  if ( remove(backup) ) if ( errno != ENOENT ) {
168  char *sys_err_msg = strerror(errno);
169  if ( ! sys_err_msg ) sys_err_msg = "(unknown error)";
170  iout << iERROR << "Error on removing file "
171  << backup << ": " << sys_err_msg << "\n" << endi;
172  fflush(stdout);
173  }
174 #endif
175  while ( rename(filename,backup) )
176  {
177  if ( errno == EINTR ) continue;
178  const char *sys_err_msg = strerror(errno);
179  if ( ! sys_err_msg ) sys_err_msg = "(unknown error)";
180  iout << iERROR << "Error on renaming file " << filename
181  << " to " << backup << ": " << sys_err_msg << "\n" << endi;
182  fflush(stdout);
183  if ( errno == EXDEV ) continue;
184  break;
185  // char errmsg[256];
186  // sprintf(errmsg, "Error on renaming file %s to %s",filename,backup);
187  // NAMD_err(errmsg);
188  }
189  delete [] backup;
190  }
191 }
192 
193 // same as open, only does error checking internally
194 int NAMD_open_text(const char *fname, int append) {
195  int fd;
196 
197  // open the file and die if the open fails
198 #ifdef WIN32
199  while ( (fd = _open(fname, O_WRONLY|(append?O_APPEND:O_EXCL)|O_CREAT|O_TEXT,_S_IREAD|_S_IWRITE)) < 0) {
200 #else
201 #ifdef NAMD_NO_O_EXCL
202  while ( (fd = open(fname, O_WRONLY|(append?O_APPEND:O_TRUNC)|O_CREAT,
203 #else
204  while ( (fd = open(fname, O_WRONLY|(append?O_APPEND:O_EXCL)|O_CREAT,
205 #endif
206  S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
207 #endif
208  if ( errno != EINTR ) {
209  char errmsg[1024];
210  sprintf(errmsg, "Unable to open text file %s", fname);
211  NAMD_err(errmsg);
212  }
213  }
214 
215  return fd;
216 }
217 
218 // same as write, only does error checking internally
219 void NAMD_write(int fd, const char *buf, size_t count, const char *fname) {
220  while ( count ) {
221 #if defined(WIN32) && !defined(__CYGWIN__)
222  long retval = _write(fd,buf,count);
223 #else
224  ssize_t retval = write(fd,buf,count);
225 #endif
226  if ( retval < 0 && errno == EINTR ) retval = 0;
227  if ( retval < 0 ) {
228  char errmsg[1024];
229  sprintf(errmsg, "Error on writing to file %s", fname);
230  NAMD_err(errmsg);
231  }
232  if ( retval > count ) NAMD_bug("extra bytes written in NAMD_write()");
233  buf += retval;
234  count -= retval;
235  }
236 }
237 
238 // same as close, only does error checking internally
239 void NAMD_close(int fd, const char *fname) {
240 #ifdef WIN32
241  while ( _close(fd) ) {
242 #else
243  while ( close(fd) ) {
244 #endif
245  if ( errno != EINTR ) {
246  char errmsg[1024];
247  sprintf(errmsg, "Error on closing file %s", fname);
248  NAMD_err(errmsg);
249  }
250  }
251 }
252 
253 
254 /***************************************************************************
255  Fopen(char *Filename, char *mode): similar to fopen(filename,mode) except
256  it checks for compressed file names too.
257  For example: Fopen("config");
258  This will first look for the filename "config" (and return "r" file handle
259  if it is found).
260  Then it will look for "config.Z" (and run "zcat config.Z", returning
261  a file handle to the uncompressed data if found).
262  Then it will look for "config.gz" (and run "gzip -d -c config.gz", returning
263  a file handle to the uncompressed data if found).
264  ***************************************************************************/
265 FILE *Fopen (const char *filename, const char *mode)
266 {
267  struct stat buf;
268  // check if basic filename exists (and not a directory)
269 
270 #if defined(NOCOMPRESSED)
271  if (!stat(filename,&buf))
272  {
273  FILE *rval;
274  while ( ! (rval = fopen(filename,mode)) ) {
275  if ( errno != EINTR ) break;
276  }
277  return(rval);
278  }
279 #else
280  if (!stat(filename,&buf))
281  {
282  if (!S_ISDIR(buf.st_mode)) {
283  FILE *rval;
284  while ( ! (rval = fopen(filename,mode)) ) {
285  if ( errno != EINTR ) break;
286  }
287  return(rval);
288  }
289  }
290  // check for a compressed file
291  char *realfilename;
292  char *command;
293  FILE *fout;
294  command = (char *)malloc(strlen(filename)+25);
295  // check for .Z (unix compress)
296  sprintf(command,"zcat %s.Z",filename);
297  realfilename = command+5;
298  iout << "Command = " << command << "\n" << endi;
299  iout << "Filename.Z = " << realfilename << "\n" << endi;
300  if (!stat(realfilename,&buf))
301  {
302  if (!S_ISDIR(buf.st_mode))
303  {
304  fout = popen(command,mode);
305  // on HP-UX, the first character(s) out of pipe may be
306  // garbage! (Argh!)
307  int C;
308  do
309  {
310  C = fgetc(fout);
311  // iout << "C is " << C << "\n" << endi;
312  if (isalnum(C) || isspace(C))
313  {
314  ungetc(C,fout);
315  C = -1; // outta loop
316  }
317  } while(C != -1);
318  free(command);
319  return(fout);
320  }
321  }
322  // check for .gz (gzip)
323  sprintf(command,"gzip -d -c %s.gz",filename);
324  realfilename = command+11;
325  iout << "Command = " << command << "\n" << endi;
326  iout << "Filename.gz = " << realfilename << "\n" << endi;
327  if (!stat(realfilename,&buf))
328  {
329  if (!S_ISDIR(buf.st_mode))
330  {
331  fout = popen(command,mode);
332  // on HP-UX, the first character(s) out of pipe may be
333  // garbage! (Argh!)
334  int C;
335  do
336  {
337  C = fgetc(fout);
338  // iout << "C is " << C << "\n" << endi;
339  if (isalnum(C) || isspace(C))
340  {
341  ungetc(C,fout);
342  C = -1; // outta loop
343  }
344  } while(C != -1);
345  free(command);
346  return(fout);
347  }
348  }
349  free(command);
350 #endif /* !defined(NOCOMPRESSED) */
351 
352  return(NULL);
353 } /* Fopen() */
354 
355 /***************************************************************************
356  Fclose(FILE *fout): similar to fclose(fout) except it first checks if the
357  file handle fout is a named pipe.
358  ***************************************************************************/
359 int Fclose (FILE *fout)
360 {
361  int rc = -1;
362 #if !defined(NOCOMPRESSED)
363  rc = pclose(fout);
364 #endif
365  if (rc == -1) // stream not associated with a popen()
366  {
367  rc = fclose(fout);
368  }
369  return rc;
370 } /* Fclose() */
371 
372 
void NAMD_err(const char *err_msg)
Definition: common.C:102
int NAMD_open_text(const char *fname, int append)
Definition: common.C:194
void NAMD_quit(const char *err_msg)
Definition: common.C:64
int NAMD_file_exists(const char *filename)
Definition: common.C:143
#define NAMD_write
Definition: dcdlib.C:24
#define NAMD_close
Definition: Output.C:52
#define iout
Definition: InfoStream.h:87
char * NAMD_stringdup(const char *s)
Definition: common.C:50
void NAMD_bug(const char *err_msg)
Definition: common.C:123
FILE * Fopen(const char *filename, const char *mode)
Definition: common.C:265
void NAMD_die(const char *err_msg)
Definition: common.C:83
void NAMD_backup_file(const char *filename, const char *extension)
Definition: common.C:159
int Fclose(FILE *fout)
Definition: common.C:359
std::ostream & iERROR(std::ostream &s)
Definition: InfoStream.C:109
infostream & endi(infostream &s)
Definition: InfoStream.C:38