common.C

Go to the documentation of this file.
00001 
00007 /*
00008    global functions as declared in common.h
00009 */
00010 
00011 #if !defined(WIN32) || defined(__CYGWIN__)
00012 #include <unistd.h>
00013 #endif
00014 #include <errno.h>
00015 #include <string.h>
00016 #include <fcntl.h>
00017 #include <sys/stat.h>
00018 #include <ctype.h>
00019 
00020 #include "common.h"
00021 #include "InfoStream.h"
00022 
00023 #include "charm++.h"
00024 
00025 #ifdef WIN32
00026 #include <io.h>
00027 #define access(PATH,MODE) _access(PATH,00)
00028 #define NOCOMPRESSED
00029 #endif
00030 
00031 #ifdef USESTDIOSTUBS
00032 
00033 // On the ASCI-Red, these functions have prototypes that don't match
00034 // the standard, so I'll override them
00035 
00036 int write(int fd, const void* buf, int count) 
00037 { 
00038   return write(fd,(void*)buf,(size_t)count);
00039 }
00040 
00041 int stat(const char* fn, struct stat* buf)
00042 {
00043   return stat((char*)fn, buf);
00044 }
00045 
00046 #endif
00047 
00048 
00049 // make a duplicate of a string
00050 char *NAMD_stringdup(const char *s) {
00051   char *rs;
00052 
00053   if(!s)
00054     return NULL;
00055 
00056   rs = new char[strlen(s) + 1];
00057   strcpy(rs,s);
00058 
00059   return rs;
00060 }
00061 
00062 
00063 // signal all nodes, it's time to quit
00064 void NAMD_quit(const char *err_msg)
00065 
00066 {
00067    if ( ! err_msg ) err_msg = "(unknown error)";
00068    char *new_err_msg = new char[strlen(err_msg) + 40];
00069    sprintf(new_err_msg,"EXITING: %s\n",err_msg);
00070    CkPrintf(new_err_msg);
00071    fflush(stdout);
00072    if ( CmiNumPartitions() > 1 ) {
00073      sprintf(new_err_msg,"REPLICA %d EXITING: %s\n", CmiMyPartition(), err_msg);
00074    }
00075    CmiAbort(new_err_msg);
00076    delete [] new_err_msg;
00077 }
00078 
00079  
00080 // signal all nodes, it's time to quit
00081 void NAMD_die(const char *err_msg)
00082 
00083 {
00084    if ( ! err_msg ) err_msg = "(unknown error)";
00085    char *new_err_msg = new char[strlen(err_msg) + 40];
00086    sprintf(new_err_msg,"FATAL ERROR: %s\n",err_msg);
00087    CkPrintf(new_err_msg);
00088    fflush(stdout);
00089    if ( CmiNumPartitions() > 1 ) {
00090      sprintf(new_err_msg,"REPLICA %d FATAL ERROR: %s\n", CmiMyPartition(), err_msg);
00091    }
00092    CmiAbort(new_err_msg);
00093    delete [] new_err_msg;
00094 }
00095 
00096 
00097 // signal all nodes, it's time to quit
00098 void NAMD_err(const char *err_msg)
00099 
00100 {
00101    if ( ! err_msg ) err_msg = "(unknown error)";
00102    char *sys_err_msg = strerror(errno);
00103    if ( ! sys_err_msg ) sys_err_msg = "(unknown error)";
00104    char *new_err_msg = new char[strlen(err_msg) + 40 + strlen(sys_err_msg)];
00105    sprintf(new_err_msg,"FATAL ERROR: %s: %s\n",err_msg, sys_err_msg);
00106    CkPrintf(new_err_msg);
00107    fflush(stdout);
00108    if ( CmiNumPartitions() > 1 ) {
00109      sprintf(new_err_msg,"REPLICA %d FATAL ERROR: %s: %s\n", CmiMyPartition(), err_msg, sys_err_msg);
00110    }
00111    CmiAbort(new_err_msg);
00112    delete [] new_err_msg;
00113 }
00114 
00115 
00116 // signal all nodes, it's time to quit and it's our own damn fault
00117 void NAMD_bug(const char *err_msg)
00118 
00119 {
00120    if ( ! err_msg ) err_msg = "(unknown error)";
00121    const char *bug_msg = 
00122      "FATAL ERROR: See http://www.ks.uiuc.edu/Research/namd/bugreport.html";
00123    char *new_err_msg = new char[strlen(err_msg) + 40 + strlen(bug_msg)];
00124    sprintf(new_err_msg,"FATAL ERROR: %s\n%s\n",err_msg,bug_msg);
00125    CkPrintf(new_err_msg);
00126    fflush(stdout);
00127    if ( CmiNumPartitions() > 1 ) {
00128      sprintf(new_err_msg,"REPLICA %d FATAL ERROR: %s\n%s\n", CmiMyPartition(), err_msg,bug_msg);
00129    }
00130    CmiAbort(new_err_msg);
00131    delete [] new_err_msg;
00132 }
00133 
00134 int NAMD_file_exists(const char *filename) {
00135   int rval;
00136   do {
00137     rval = access(filename, F_OK);
00138   } while ( rval != 0 && errno == EINTR );
00139   if ( rval != 0 && errno != ENOENT ) {
00140     char *sys_err_msg = strerror(errno);
00141     if ( ! sys_err_msg ) sys_err_msg = "(unknown error)";
00142     iout << iERROR << "Error on checking file "
00143       << filename << ": " << sys_err_msg << "\n" << endi;
00144     fflush(stdout);
00145   }
00146   return ! rval;
00147 }
00148 
00149 // move filename to filename.BAK
00150 void NAMD_backup_file(const char *filename, const char *extension)
00151 {
00152   if (NAMD_file_exists(filename)) {
00153     if ( ! extension ) extension = ".BAK";
00154     char *backup = new char[strlen(filename)+strlen(extension)+1];
00155     strcpy(backup, filename);
00156     strcat(backup, extension);
00157 #if defined(WIN32) && !defined(__CYGWIN__)
00158     if ( remove(backup) ) if ( errno != ENOENT ) {
00159       char *sys_err_msg = strerror(errno);
00160       if ( ! sys_err_msg ) sys_err_msg = "(unknown error)";
00161       iout << iERROR << "Error on removing file "
00162         << backup << ": " << sys_err_msg << "\n" << endi;
00163       fflush(stdout);
00164     }
00165 #endif
00166     while ( rename(filename,backup) )
00167     {
00168       if ( errno == EINTR ) continue;
00169       char *sys_err_msg = strerror(errno);
00170       if ( ! sys_err_msg ) sys_err_msg = "(unknown error)";
00171       iout << iERROR << "Error on renaming file " << filename
00172         << " to " << backup << ": " << sys_err_msg << "\n" << endi;
00173       fflush(stdout);
00174       if ( errno == EXDEV ) continue;
00175       break;
00176       // char errmsg[256];
00177       // sprintf(errmsg, "Error on renaming file %s to %s",filename,backup);
00178       // NAMD_err(errmsg);
00179     }
00180     delete [] backup;
00181   }
00182 }
00183 
00184 // same as open, only does error checking internally
00185 int NAMD_open_text(const char *fname, int append) {
00186   int fd;
00187 
00188   //  open the file and die if the open fails
00189 #ifdef WIN32
00190   while ( (fd = _open(fname, O_WRONLY|(append?O_APPEND:O_EXCL)|O_CREAT|O_TEXT,_S_IREAD|_S_IWRITE)) < 0) {
00191 #else
00192 #ifdef NAMD_NO_O_EXCL
00193   while ( (fd = open(fname, O_WRONLY|(append?O_APPEND:O_TRUNC)|O_CREAT,
00194 #else
00195   while ( (fd = open(fname, O_WRONLY|(append?O_APPEND:O_EXCL)|O_CREAT,
00196 #endif
00197                            S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
00198 #endif
00199     if ( errno != EINTR ) {
00200       char errmsg[1024];
00201       sprintf(errmsg, "Unable to open text file %s", fname);
00202       NAMD_err(errmsg);
00203     }
00204   }
00205 
00206   return fd;
00207 }
00208 
00209 // same as write, only does error checking internally
00210 void NAMD_write(int fd, const char *buf, size_t count, const char *fname) {
00211   while ( count ) {
00212 #if defined(WIN32) && !defined(__CYGWIN__)
00213     long retval = _write(fd,buf,count);
00214 #else
00215     ssize_t retval = write(fd,buf,count);
00216 #endif
00217     if ( retval < 0 && errno == EINTR ) retval = 0;
00218     if ( retval < 0 ) {
00219       char errmsg[1024];
00220       sprintf(errmsg, "Error on writing to file %s", fname);
00221       NAMD_err(errmsg);
00222     }
00223     if ( retval > count ) NAMD_bug("extra bytes written in NAMD_write()");
00224     buf += retval;
00225     count -= retval;
00226   }
00227 }
00228 
00229 // same as close, only does error checking internally
00230 void NAMD_close(int fd, const char *fname) {
00231 #ifdef WIN32
00232   while ( _close(fd) ) {
00233 #else
00234   while ( close(fd) ) {
00235 #endif
00236     if ( errno != EINTR ) {
00237       char errmsg[1024];
00238       sprintf(errmsg, "Error on closing file %s", fname);
00239       NAMD_err(errmsg);
00240     }
00241   }
00242 }
00243 
00244 
00245 /***************************************************************************
00246  Fopen(char *Filename, char *mode):  similar to fopen(filename,mode) except
00247  it checks for compressed file names too.
00248  For example:  Fopen("config");
00249    This will first look for the filename "config" (and return "r" file handle
00250    if it is found).
00251    Then it will look for "config.Z" (and run "zcat config.Z", returning
00252    a file handle to the uncompressed data if found).
00253    Then it will look for "config.gz" (and run "gzip -d -c config.gz", returning
00254    a file handle to the uncompressed data if found).
00255  ***************************************************************************/
00256 FILE *Fopen     (const char *filename, const char *mode)
00257 {
00258   struct stat buf;
00259   // check if basic filename exists (and not a directory)
00260 
00261 #if defined(NOCOMPRESSED)
00262   if (!stat(filename,&buf))
00263     {
00264       FILE *rval;
00265       while ( ! (rval = fopen(filename,mode)) ) {
00266         if ( errno != EINTR ) break;
00267       }
00268       return(rval);
00269     }
00270 #else
00271   if (!stat(filename,&buf))
00272     {
00273       if (!S_ISDIR(buf.st_mode)) {
00274         FILE *rval;
00275         while ( ! (rval = fopen(filename,mode)) ) {
00276           if ( errno != EINTR ) break;
00277         }
00278         return(rval);
00279       }
00280     }
00281   // check for a compressed file
00282   char *realfilename;
00283   char *command;
00284   FILE *fout;
00285   command = (char *)malloc(strlen(filename)+25);
00286   // check for .Z (unix compress)
00287   sprintf(command,"zcat %s.Z",filename);
00288   realfilename = command+5;
00289   iout << "Command = " << command << "\n" << endi;
00290   iout << "Filename.Z = " << realfilename << "\n" << endi;
00291   if (!stat(realfilename,&buf))
00292         {
00293         if (!S_ISDIR(buf.st_mode))
00294                 {
00295                 fout = popen(command,mode);
00296                 // on HP-UX, the first character(s) out of pipe may be
00297                 // garbage!  (Argh!)
00298                 int C;
00299                 do
00300                   {
00301                   C = fgetc(fout);
00302                   // iout << "C is " << C << "\n" << endi;
00303                   if (isalnum(C) || isspace(C))
00304                         {
00305                         ungetc(C,fout);
00306                         C = -1; // outta loop
00307                         }
00308                   } while(C != -1);
00309                 free(command);
00310                 return(fout);
00311                 }
00312         }
00313   // check for .gz (gzip)
00314   sprintf(command,"gzip -d -c %s.gz",filename);
00315   realfilename = command+11;
00316   iout << "Command = " << command << "\n" << endi;
00317   iout << "Filename.gz = " << realfilename << "\n" << endi;
00318   if (!stat(realfilename,&buf))
00319         {
00320         if (!S_ISDIR(buf.st_mode))
00321                 {
00322                 fout = popen(command,mode);
00323                 // on HP-UX, the first character(s) out of pipe may be
00324                 // garbage!  (Argh!)
00325                 int C;
00326                 do
00327                   {
00328                   C = fgetc(fout);
00329                   // iout << "C is " << C << "\n" << endi;
00330                   if (isalnum(C) || isspace(C))
00331                         {
00332                         ungetc(C,fout);
00333                         C = -1; // outta loop
00334                         }
00335                   } while(C != -1);
00336                 free(command);
00337                 return(fout);
00338                 }
00339         }
00340   free(command);
00341 #endif /* !defined(NOCOMPRESSED) */
00342 
00343   return(NULL);
00344 } /* Fopen() */
00345 
00346 /***************************************************************************
00347  Fclose(FILE *fout):  similar to fclose(fout) except it first checks if the
00348  file handle fout is a named pipe.
00349  ***************************************************************************/
00350 int     Fclose  (FILE *fout)
00351 {
00352   int rc = -1;
00353 #if !defined(NOCOMPRESSED)
00354   rc = pclose(fout);
00355 #endif
00356   if (rc == -1) // stream not associated with a popen()
00357     {
00358     rc = fclose(fout);
00359     }
00360   return rc;
00361 } /* Fclose() */
00362 
00363 

Generated on Tue Sep 19 01:17:10 2017 for NAMD by  doxygen 1.4.7