Unverified Commit e2988c5c authored by Axel Kohlmeyer's avatar Axel Kohlmeyer
Browse files

refactor sfgets() and sfread() to both allow NULL filenames and guess from...

refactor sfgets() and sfread() to both allow NULL filenames and guess from /proc if needed and possible
parent fe204908
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -606,7 +606,7 @@ void PairLJ96Cut::read_restart(FILE *fp)
  int me = comm->me;
  for (i = 1; i <= atom->ntypes; i++)
    for (j = i; j <= atom->ntypes; j++) {
      if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
      if (me == 0) utils::sfread(FLERR,&setflag[i][j],sizeof(int),1,fp,NULL,error);
      MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
      if (setflag[i][j]) {
        if (me == 0) {
+32 −17
Original line number Diff line number Diff line
@@ -107,14 +107,43 @@ int utils::cfvarg(std::string mode, const char *arg, char *&cfv_id)
  return rv;
}

/** \brief try to detect pathname from FILE pointer. Currently only supported on Linux, otherwise will report "(unknown)".
 *
 *  \param buf  storage buffer for pathname. output will be truncated if not large enough
 *  \param len  size of storage buffer. output will be truncated to this length - 1
 *  \param fp   FILE pointer structe from STDIO library for which we want to detect the name
 *  \return pointer to the storage buffer, i.e. buf
 */
static const char *guesspath(char *buf, int len, FILE *fp)
{
  memset(buf,0,len);

#if defined(__linux)
  char procpath[32];
  int fd = fileno(fp);
  snprintf(procpath,32,"/proc/self/fd/%d",fd);
  // get pathname from /proc or copy (unknown)
  if (readlink(procpath,buf,len-1) <= 0) strcpy(buf,"(unknown)");
#else
  strcpy(buf,"(unknown)");
#endif
  return buf;
}

#define MAXPATHLENBUF 1024
/* like fgets() but aborts with an error or EOF is encountered */
void utils::sfgets(const char *srcname, int srcline, char *s, int size,
                   FILE *fp, const char *filename, Error *error)
{
  char *rv = fgets(s,size,fp);
  if (rv == NULL) { // something went wrong
    char buf[MAXPATHLENBUF];
    std::string errmsg;

    // try to figure out the file name from the file pointer
    if (!filename)
      filename = guesspath(buf,MAXPATHLENBUF,fp);

    if (feof(fp)) {
      errmsg = "Unexpected end of file while reading file '";
    } else if (ferror(fp)) {
@@ -131,32 +160,18 @@ void utils::sfgets(const char *srcname, int srcline, char *s, int size,
  return;
}

#define MAXFILEBUF 1024
/* like fread() but aborts with an error or EOF is encountered */
void utils::sfread(const char *srcname, int srcline, void *s, size_t size,
                   size_t num, FILE *fp, const char *filename, Error *error)
{
  char inferred_name[MAXFILEBUF];
  size_t rv = fread(s,size,num,fp);
  if (rv != num) { // something went wrong
    char buf[MAXPATHLENBUF];
    std::string errmsg;

    // try to figure out the file name from the file pointer
    if (!filename) {
      // on Linux we can infer the name of the open file from /proc
      // otherwise we set it to "(unknown)"
#if defined(__linux)
      char procpath[32];
      int fd = fileno(fp);
      snprintf(procpath,32,"/proc/self/fd/%d",fd);
      memset(inferred_name,0,MAXFILEBUF);
      if (readlink(procpath,inferred_name,MAXFILEBUF) <= 0)
        strcpy(inferred_name,"(unknown)");
#else
      strcpy(inferred_name,"(unknown)");
#endif
      filename = inferred_name;
    }
    if (!filename)
      filename = guesspath(buf,MAXPATHLENBUF,fp);

    if (feof(fp)) {
      errmsg = "Unexpected end of file while reading file '";
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ namespace LAMMPS_NS {
     *  \param s        buffer for storing the result of fgets()
     *  \param size     size of buffer s (max number of bytes read by fgets())
     *  \param fp       file pointer used by fgets()
     *  \param filename file name associated with fp (for error message)
     *  \param filename file name associated with fp (may be NULL; then LAMMPS will try to detect)
     *  \param error    pointer to Error class instance (for abort)
     */
    void sfgets(const char *srcname, int srcline, char *s, int size,