lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Current code of the function, last lines:
...
  readstatus = ferror(lf.f);
  if (filename) fclose(lf.f);  /* close file (even in case of errors) */
  if (readstatus) {
    lua_settop(L, fnameindex);  /* ignore results from 'lua_load' */
    return errfile(L, "read", fnameindex);
  }
  lua_remove(L, fnameindex);
  return status;
}


On some OS fclose could change errno. See for example
http://man7.org/linux/man-pages/man3/fclose.3.html
       The fclose() function may also fail and set errno for any of the
       errors specified for the routines close(2), write(2), or fflush(3).


A little improvement to preserve the OS error:
...
  readstatus = ferror(lf.f);
  if (readstatus)
    readstatus_errno = errno;
  if (filename)
    fclose(lf.f);  /* close file (could change errno) */
  if (readstatus) {
    lua_settop(L, fnameindex);  /* ignore results from 'lua_load' */
    return errfile_custom(L, "read", strerror(readstatus_errno), fnameindex);
  }
  lua_remove(L, fnameindex);
  return status;
}


See the attached file, I modified two functions and add a new one.

Best regards, Massimo

static int errfile_custom (lua_State *L, const char *what, const char *serr, int fnameindex) {
  const char *filename = lua_tostring(L, fnameindex) + 1;
  lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
  lua_remove(L, fnameindex);
  return LUA_ERRFILE;
}

static int errfile_errno (lua_State *L, const char *what, int fnameindex) {
  return errfile_custom(L, what, strerror(errno), fnameindex);
}


LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
                                             const char *mode) {
  LoadF lf;
  int status, readstatus, readstatus_errno;
  int c;
  int fnameindex = lua_gettop(L) + 1;  /* index of filename on the stack */
  if (filename == NULL) {
    lua_pushliteral(L, "=stdin");
    lf.f = stdin;
  }
  else {
    lua_pushfstring(L, "@%s", filename);
    lf.f = fopen(filename, "r");
    if (lf.f == NULL) return errfile_errno(L, "open", fnameindex);
  }
  if (skipcomment(&lf, &c))  /* read initial portion */
    lf.buff[lf.n++] = '\n';  /* add line to correct line numbers */
  if (c == LUA_SIGNATURE[0] && filename) {  /* binary file? */
    lf.f = freopen(filename, "rb", lf.f);  /* reopen in binary mode */
    if (lf.f == NULL) return errfile_errno(L, "reopen", fnameindex);
    skipcomment(&lf, &c);  /* re-read initial portion */
  }
  if (c != EOF)
    lf.buff[lf.n++] = c;  /* 'c' is the first character of the stream */
  status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);

  readstatus = ferror(lf.f);
  if (readstatus)
    readstatus_errno = errno;

  if (filename)
    fclose(lf.f);  /* close file (could change errno) */

  if (readstatus) {
    lua_settop(L, fnameindex);  /* ignore results from 'lua_load' */
    return errfile_custom(L, "read", strerror(readstatus_errno), fnameindex);
  }
  lua_remove(L, fnameindex);
  return status;
}
_______________________________________________
lua-l mailing list -- lua-l@lists.lua.org
To unsubscribe send an email to lua-l-leave@lists.lua.org