From 9242810cd3bb14056dde937fc9ad39fc49261dfd Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 10 Jul 2014 16:33:35 +0400 Subject: [PATCH] * configure.ac: Check whether sys/sysinfo.h provides Linux 'sysinfo' function and 'struct sysinfo' type. * src/alloc.c (Fmemory_info): New function. * lisp/files.el (warn-maybe-out-of-memory): New function. (find-file-noselect): Use it. --- ChangeLog | 5 +++++ configure.ac | 16 ++++++++++++++++ lisp/ChangeLog | 5 +++++ lisp/files.el | 19 ++++++++++++++++++- src/ChangeLog | 2 ++ src/alloc.c | 33 ++++++++++++++++++++++++++++++++- 6 files changed, 78 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8226a138d06..f763607537f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2014-07-10 Dmitry Antipov + + * configure.ac: Check whether sys/sysinfo.h provides + Linux 'sysinfo' function and 'struct sysinfo' type. + 2014-06-28 Glenn Morris * configure.ac (lwlib_deps_frag, oldxmenu_deps_frag): New output files. diff --git a/configure.ac b/configure.ac index 04c75e30df8..fc7a87a075a 100644 --- a/configure.ac +++ b/configure.ac @@ -1510,6 +1510,7 @@ fi dnl checks for header files AC_CHECK_HEADERS_ONCE( sys/systeminfo.h + sys/sysinfo.h coff.h pty.h sys/resource.h sys/utsname.h pwd.h utmp.h util.h) @@ -1525,6 +1526,21 @@ if test $emacs_cv_personality_linux32 = yes; then [Define to 1 if personality LINUX32 can be set.]) fi +if test "$ac_cv_header_sys_sysinfo_h" = yes; then + AC_MSG_CHECKING([if Linux sysinfo may be used]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[struct sysinfo si; sysinfo (&si)]])], + emacs_cv_linux_sysinfo=yes, emacs_cv_linux_sysinfo=no) + AC_MSG_RESULT($emacs_cv_linux_sysinfo) + if test $emacs_cv_linux_sysinfo = yes; then + AC_DEFINE([HAVE_LINUX_SYSINFO], 1, [Define to 1 if you have Linux sysinfo function.]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[struct sysinfo si; return si.mem_unit]])], + AC_DEFINE(LINUX_SYSINFO_UNIT, 1, + [Define to 1 if Linux sysinfo sizes are in multiples of mem_unit bytes.])) + fi +fi + dnl On Solaris 8 there's a compilation warning for term.h because dnl it doesn't define `bool'. AC_CHECK_HEADERS(term.h, , , -) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d14a3a8584b..ffb1eee945e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2014-07-10 Dmitry Antipov + + * files.el (warn-maybe-out-of-memory): New function. + (find-file-noselect): Use it. + 2014-07-09 Sam Steingold * progmodes/cperl-mode.el (cperl-block-p): Treat the perl keyword diff --git a/lisp/files.el b/lisp/files.el index 27d3ec7464e..63bdf636b63 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1796,6 +1796,22 @@ OP-TYPE specifies the file operation being performed (for message to user)." (file-size-human-readable size) op-type)))) (error "Aborted"))) +(defun warn-maybe-out-of-memory (size) + "Warn if an attempt to open file of SIZE bytes may run out of memory." + (let ((meminfo (memory-info))) + (when (consp meminfo) + (let ((total-free-memory (+ (nth 1 meminfo) (nth 3 meminfo)))) + (when (and (not (zerop size)) + (> (/ size 1024) total-free-memory)) + (warn + "You are trying to open file which size (%s) +exceeds an amount of available free memory (%s). If that +fails, try to open it with `find-file-literally' (but note +that some characters may be displayed incorrectly)." + (file-size-human-readable size) + (file-size-human-readable + (* (float total-free-memory) 1024)))))))) + (defun find-file-noselect (filename &optional nowarn rawfile wildcards) "Read file FILENAME into a buffer and return the buffer. If a buffer exists visiting FILENAME, return that one, but @@ -1848,7 +1864,8 @@ the various files." (setq buf other)))) ;; Check to see if the file looks uncommonly large. (when (not (or buf nowarn)) - (abort-if-file-too-large (nth 7 attributes) "open" filename)) + (abort-if-file-too-large (nth 7 attributes) "open" filename) + (warn-maybe-out-of-memory (nth 7 attributes))) (if buf ;; We are using an existing buffer. (let (nonexistent) diff --git a/src/ChangeLog b/src/ChangeLog index 541697c5567..87a8f1c7814 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -9,6 +9,8 @@ (decode_coding_big5, decode_coding_charset, decode_coding) (encode_coding): Adjust users. + * alloc.c (Fmemory_info): New function. + 2014-07-09 Paul Eggert * syntax.c (back_comment): Use more-natural location for label. diff --git a/src/alloc.c b/src/alloc.c index 6eb2e756ed1..c535e836397 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -49,6 +49,10 @@ along with GNU Emacs. If not, see . */ #include #include /* For backtrace. */ +#ifdef HAVE_LINUX_SYSINFO +#include +#endif + #if (defined ENABLE_CHECKING \ && defined HAVE_VALGRIND_VALGRIND_H \ && !defined USE_VALGRIND) @@ -6865,7 +6869,33 @@ gc_sweep (void) check_string_bytes (!noninteractive); } - +DEFUN ("memory-info", Fmemory_info, Smemory_info, 0, 0, 0, + doc: /* Return a list of (TOTAL-RAM FREE-RAM TOTAL-SWAP FREE-SWAP). +All values are in Kbytes. If there is no swap space, last two +values are zero. If the system is not supported, return nil. */) + (void) +{ +#ifdef HAVE_LINUX_SYSINFO + struct sysinfo si; + uintmax_t units; + + if (sysinfo (&si)) + emacs_abort (); +#ifdef LINUX_SYSINFO_UNIT + units = si.mem_unit; +#else + units = 1; +#endif + return list4i ((uintmax_t) si.totalram * units / 1024, + (uintmax_t) si.freeram * units / 1024, + (uintmax_t) si.totalswap * units / 1024, + (uintmax_t) si.freeswap * units / 1024); +#else /* not HAVE_LINUX_SYSINFO */ + /* FIXME: add more systems. */ + return Qnil; +#endif /* HAVE_LINUX_SYSINFO */ +} + /* Debugging aids. */ DEFUN ("memory-limit", Fmemory_limit, Smemory_limit, 0, 0, 0, @@ -7204,6 +7234,7 @@ The time is in seconds as a floating point value. */); defsubr (&Spurecopy); defsubr (&Sgarbage_collect); defsubr (&Smemory_limit); + defsubr (&Smemory_info); defsubr (&Smemory_use_counts); defsubr (&Ssuspicious_object); -- 2.39.2