refactor sfgets() and sfread() to both allow NULL filenames and guess from /proc if needed and possible
This commit is contained in:
@ -606,7 +606,7 @@ void PairLJ96Cut::read_restart(FILE *fp)
|
|||||||
int me = comm->me;
|
int me = comm->me;
|
||||||
for (i = 1; i <= atom->ntypes; i++)
|
for (i = 1; i <= atom->ntypes; i++)
|
||||||
for (j = i; j <= atom->ntypes; j++) {
|
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);
|
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
|
||||||
if (setflag[i][j]) {
|
if (setflag[i][j]) {
|
||||||
if (me == 0) {
|
if (me == 0) {
|
||||||
|
|||||||
@ -107,14 +107,43 @@ int utils::cfvarg(std::string mode, const char *arg, char *&cfv_id)
|
|||||||
return rv;
|
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 */
|
/* like fgets() but aborts with an error or EOF is encountered */
|
||||||
void utils::sfgets(const char *srcname, int srcline, char *s, int size,
|
void utils::sfgets(const char *srcname, int srcline, char *s, int size,
|
||||||
FILE *fp, const char *filename, Error *error)
|
FILE *fp, const char *filename, Error *error)
|
||||||
{
|
{
|
||||||
char *rv = fgets(s,size,fp);
|
char *rv = fgets(s,size,fp);
|
||||||
if (rv == NULL) { // something went wrong
|
if (rv == NULL) { // something went wrong
|
||||||
|
char buf[MAXPATHLENBUF];
|
||||||
std::string errmsg;
|
std::string errmsg;
|
||||||
|
|
||||||
|
// try to figure out the file name from the file pointer
|
||||||
|
if (!filename)
|
||||||
|
filename = guesspath(buf,MAXPATHLENBUF,fp);
|
||||||
|
|
||||||
if (feof(fp)) {
|
if (feof(fp)) {
|
||||||
errmsg = "Unexpected end of file while reading file '";
|
errmsg = "Unexpected end of file while reading file '";
|
||||||
} else if (ferror(fp)) {
|
} else if (ferror(fp)) {
|
||||||
@ -131,32 +160,18 @@ void utils::sfgets(const char *srcname, int srcline, char *s, int size,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAXFILEBUF 1024
|
|
||||||
/* like fread() but aborts with an error or EOF is encountered */
|
/* like fread() but aborts with an error or EOF is encountered */
|
||||||
void utils::sfread(const char *srcname, int srcline, void *s, size_t size,
|
void utils::sfread(const char *srcname, int srcline, void *s, size_t size,
|
||||||
size_t num, FILE *fp, const char *filename, Error *error)
|
size_t num, FILE *fp, const char *filename, Error *error)
|
||||||
{
|
{
|
||||||
char inferred_name[MAXFILEBUF];
|
|
||||||
size_t rv = fread(s,size,num,fp);
|
size_t rv = fread(s,size,num,fp);
|
||||||
if (rv != num) { // something went wrong
|
if (rv != num) { // something went wrong
|
||||||
|
char buf[MAXPATHLENBUF];
|
||||||
std::string errmsg;
|
std::string errmsg;
|
||||||
|
|
||||||
// try to figure out the file name from the file pointer
|
// try to figure out the file name from the file pointer
|
||||||
if (!filename) {
|
if (!filename)
|
||||||
// on Linux we can infer the name of the open file from /proc
|
filename = guesspath(buf,MAXPATHLENBUF,fp);
|
||||||
// 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 (feof(fp)) {
|
if (feof(fp)) {
|
||||||
errmsg = "Unexpected end of file while reading file '";
|
errmsg = "Unexpected end of file while reading file '";
|
||||||
|
|||||||
@ -63,7 +63,7 @@ namespace LAMMPS_NS {
|
|||||||
* \param s buffer for storing the result of fgets()
|
* \param s buffer for storing the result of fgets()
|
||||||
* \param size size of buffer s (max number of bytes read by fgets())
|
* \param size size of buffer s (max number of bytes read by fgets())
|
||||||
* \param fp file pointer used 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)
|
* \param error pointer to Error class instance (for abort)
|
||||||
*/
|
*/
|
||||||
void sfgets(const char *srcname, int srcline, char *s, int size,
|
void sfgets(const char *srcname, int srcline, char *s, int size,
|
||||||
|
|||||||
Reference in New Issue
Block a user