From e0fdb6943066032db294720915c3bd644bf2bcd1 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 4 Aug 2013 09:56:56 -0700 Subject: Fix some minor races in hosts lacking mkostemp. Gnulib's emulation of mkostemp doesn't have races that Emacs's does. * configure.ac (mkostemp): Remove check for this function; gnulib does the check now. (mkstemp): Remove check for this no-longer-used function. * lib/mkostemp.c, lib/secure_getenv.c, lib/tempname.c, lib/tempname.h: * m4/mkostemp.m4, m4/secure_getenv.m4, m4/tempname.m4: New files, copied from Gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * admin/merge-gnulib (GNULIB_MODULES): Add mkostemp. * lib-src/movemail.c (main): * lib-src/update-game-score.c (write_scores): Use mkostemp (which now works on all platforms, due to changes in the portability layer) rather than mktemp (which has a race) or mkstemp (which we no longer bother with). * src/callproc.c (create_temp_file): * src/filelock.c (create_lock_file): Assume mkostemp, since it's now provided by Gnulib. Fixes: debbugs:15015 --- lib-src/ChangeLog | 9 +++++++++ lib-src/movemail.c | 17 +++-------------- lib-src/update-game-score.c | 12 ++++++------ 3 files changed, 18 insertions(+), 20 deletions(-) (limited to 'lib-src') diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index f41c23df5d2..2cfe46f5352 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,12 @@ +2013-08-04 Paul Eggert + + Fix some minor races in hosts lacking mkostemp (Bug#15015). + * movemail.c (main): + * update-game-score.c (write_scores): + Use mkostemp (which now works on all platforms, due to changes + in the portability layer) rather than mktemp (which has a race) + or mkstemp (which we no longer bother with). + 2013-07-10 Paul Eggert Port to C89. diff --git a/lib-src/movemail.c b/lib-src/movemail.c index 81ac8aa187c..9434782cb17 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -304,24 +304,13 @@ main (int argc, char **argv) memcpy (tempname, inname, inname_dirlen); strcpy (tempname + inname_dirlen, "EXXXXXX"); -#ifdef HAVE_MKSTEMP - desc = mkstemp (tempname); -#else - mktemp (tempname); - if (!*tempname) - desc = -1; - else - { - unlink (tempname); - desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0600); - } -#endif + desc = mkostemp (tempname, 0); if (desc < 0) { - int mkstemp_errno = errno; + int mkostemp_errno = errno; error ("error while creating what would become the lock file", 0, 0); - errno = mkstemp_errno; + errno = mkostemp_errno; pfatal_with_name (tempname); } close (desc); diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index ec8b4317770..1699e305c8d 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c @@ -383,6 +383,7 @@ sort_scores (struct score_entry *scores, int count, int reverse) static int write_scores (const char *filename, const struct score_entry *scores, int count) { + int fd; FILE *f; int i; char *tempfile = malloc (strlen (filename) + strlen (".tempXXXXXX") + 1); @@ -390,12 +391,11 @@ write_scores (const char *filename, const struct score_entry *scores, int count) return -1; strcpy (tempfile, filename); strcat (tempfile, ".tempXXXXXX"); -#ifdef HAVE_MKSTEMP - if (mkstemp (tempfile) < 0 -#else - if (mktemp (tempfile) != tempfile -#endif - || !(f = fopen (tempfile, "w"))) + fd = mkostemp (tempfile, 0); + if (fd < 0) + return -1; + f = fdopen (fd, "w"); + if (! f) return -1; for (i = 0; i < count; i++) if (fprintf (f, "%ld %s %s\n", scores[i].score, scores[i].username, -- cgit v1.2.1 From e443729d658ee2b9e0f55bbbb90241819bf516a6 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 4 Aug 2013 20:52:25 +0300 Subject: MS-Windows followup to last commit. lib-src/ntlib.h: Include fcntl.h. (mkostemp): Declare prototype. (mktemp): Don't redefine. lib-src/ntlib.c (mkostemp): New function. Fixes: debbugs:15015 --- lib-src/ChangeLog | 8 ++++++++ lib-src/ntlib.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib-src/ntlib.h | 4 ++-- 3 files changed, 65 insertions(+), 2 deletions(-) (limited to 'lib-src') diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 2cfe46f5352..ace62d9d8f7 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,11 @@ +2013-08-04 Eli Zaretskii + + * ntlib.h: Include fcntl.h. + (mkostemp): Declare prototype. + (mktemp): Don't redefine. + + * ntlib.c (mkostemp): New function. (Bug#15015) + 2013-08-04 Paul Eggert Fix some minor races in hosts lacking mkostemp (Bug#15015). diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index 41b4e3a0cbc..0d0642d1bf2 100644 --- a/lib-src/ntlib.c +++ b/lib-src/ntlib.c @@ -422,3 +422,58 @@ lstat (const char * path, struct stat * buf) { return stat (path, buf); } + +/* Implementation of mkostemp for MS-Windows, to avoid race conditions + when using mktemp. + + Standard algorithm for generating a temporary file name seems to be + use pid or tid with a letter on the front (in place of the 6 X's) + and cycle through the letters to find a unique name. We extend + that to allow any reasonable character as the first of the 6 X's, + so that the number of simultaneously used temporary files will be + greater. */ + +int +mkostemp (char * template, int flags) +{ + char * p; + int i, fd = -1; + unsigned uid = GetCurrentThreadId (); + int save_errno = errno; + static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; + + errno = EINVAL; + if (template == NULL) + return -1; + + p = template + strlen (template); + i = 5; + /* replace up to the last 5 X's with uid in decimal */ + while (--p >= template && p[0] == 'X' && --i >= 0) + { + p[0] = '0' + uid % 10; + uid /= 10; + } + + if (i < 0 && p[0] == 'X') + { + i = 0; + do + { + p[0] = first_char[i]; + if ((fd = open (template, + flags | _O_CREAT | _O_EXCL | _O_RDWR, + S_IRUSR | S_IWUSR)) >= 0 + || errno != EEXIST) + { + if (fd >= 0) + errno = save_errno; + return fd; + } + } + while (++i < sizeof (first_char)); + } + + /* Template is badly formed or else we can't generate a unique name. */ + return -1; +} diff --git a/lib-src/ntlib.h b/lib-src/ntlib.h index 3e48d2997e0..c30958365ca 100644 --- a/lib-src/ntlib.h +++ b/lib-src/ntlib.h @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see . */ /* Include these headers now so we don't have to worry about include order dependencies in common source files. */ #include +#include #include #include @@ -41,6 +42,7 @@ int setuid (unsigned uid); int setregid (unsigned rgid, unsigned gid); char * getpass (const char * prompt); int fchown (int fd, unsigned uid, unsigned gid); +int mkostemp (char * template, int flags); /* redirect or undo interceptions created by config.h */ #undef access @@ -61,8 +63,6 @@ int fchown (int fd, unsigned uid, unsigned gid); #undef fopen #undef mkdir #define mkdir _mkdir -#undef mktemp -#define mktemp _mktemp #undef open #define open _open #undef pipe -- cgit v1.2.1 From 98a428c15ad48f8579b00b68aae6a89b34238b12 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 5 Aug 2013 20:09:28 +0300 Subject: Fix bugs in update-game-score, on MS-Windows and elsewhere. lib-src/update-game-score.c (read_score): Try reading a character before probing the stream for EOF. Initialize score->score to zero, before reading and accumulating the score. (read_scores): Fix logic that determines which value to return. Close the input stream when finished reading the scores (avoids failures in overwriting the file with a new one on MS-Windows, since a file that is open cannot be deleted). lib-src/ntlib.h (rename): Don't undefine. lib-src/ntlib.c (sys_rename): New function, needed for update-game-score. --- lib-src/ChangeLog | 15 +++++++++++++++ lib-src/ntlib.c | 28 +++++++++++++++++++++------- lib-src/ntlib.h | 1 - lib-src/update-game-score.c | 44 ++++++++++++++++++++++++-------------------- 4 files changed, 60 insertions(+), 28 deletions(-) (limited to 'lib-src') diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index ace62d9d8f7..0336eae0981 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,18 @@ +2013-08-05 Eli Zaretskii + + * update-game-score.c (read_score): Try reading a character before + probing the stream for EOF. Initialize score->score to zero, + before reading and accumulating the score. + (read_scores): Fix logic that determines which value to return. + Close the input stream when finished reading the scores (avoids + failures in overwriting the file with a new one on MS-Windows, + since a file that is open cannot be deleted). + + * ntlib.h (rename): Don't undefine. + + * ntlib.c (sys_rename): New function, needed for + update-game-score. + 2013-08-04 Eli Zaretskii * ntlib.h: Include fcntl.h. diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index 0d0642d1bf2..ab7d8b590df 100644 --- a/lib-src/ntlib.c +++ b/lib-src/ntlib.c @@ -424,14 +424,14 @@ lstat (const char * path, struct stat * buf) } /* Implementation of mkostemp for MS-Windows, to avoid race conditions - when using mktemp. + when using mktemp. Copied from w32.c. - Standard algorithm for generating a temporary file name seems to be - use pid or tid with a letter on the front (in place of the 6 X's) - and cycle through the letters to find a unique name. We extend - that to allow any reasonable character as the first of the 6 X's, - so that the number of simultaneously used temporary files will be - greater. */ + This is used only in update-game-score.c. It is overkill for that + use case, since update-game-score renames the temporary file into + the game score file, which isn't atomic on MS-Windows anyway, when + the game score already existed before running the program, which it + almost always does. But using a simpler implementation just to + make a point is uneconomical... */ int mkostemp (char * template, int flags) @@ -477,3 +477,17 @@ mkostemp (char * template, int flags) /* Template is badly formed or else we can't generate a unique name. */ return -1; } + +/* On Windows, you cannot rename into an existing file. */ +int +sys_rename (const char *from, const char *to) +{ + int retval = rename (from, to); + + if (retval < 0 && errno == EEXIST) + { + if (unlink (to) == 0) + retval = rename (from, to); + } + return retval; +} diff --git a/lib-src/ntlib.h b/lib-src/ntlib.h index c30958365ca..ab5f5ea3b89 100644 --- a/lib-src/ntlib.h +++ b/lib-src/ntlib.h @@ -69,7 +69,6 @@ int mkostemp (char * template, int flags); #define pipe _pipe #undef read #define read _read -#undef rename #undef rmdir #define rmdir _rmdir #undef unlink diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index 1699e305c8d..92c1663f658 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c @@ -228,10 +228,11 @@ static int read_score (FILE *f, struct score_entry *score) { int c; + if ((c = getc (f)) != EOF) + ungetc (c, f); if (feof (f)) return 1; - while ((c = getc (f)) != EOF - && isdigit (c)) + for (score->score = 0; (c = getc (f)) != EOF && isdigit (c); ) { score->score *= 10; score->score += (c-48); @@ -311,34 +312,38 @@ read_score (FILE *f, struct score_entry *score) static int read_scores (const char *filename, struct score_entry **scores, int *count) { - int readval, scorecount, cursize; + int readval = -1, scorecount, cursize; struct score_entry *ret; FILE *f = fopen (filename, "r"); + int retval = -1; if (!f) return -1; scorecount = 0; cursize = 16; ret = (struct score_entry *) malloc (sizeof (struct score_entry) * cursize); - if (!ret) - return -1; - while ((readval = read_score (f, &ret[scorecount])) == 0) + if (ret) { - /* We encountered an error. */ - if (readval < 0) - return -1; - scorecount++; - if (scorecount >= cursize) + while ((readval = read_score (f, &ret[scorecount])) == 0) { - cursize *= 2; - ret = (struct score_entry *) - realloc (ret, (sizeof (struct score_entry) * cursize)); - if (!ret) - return -1; + scorecount++; + if (scorecount >= cursize) + { + cursize *= 2; + ret = (struct score_entry *) + realloc (ret, (sizeof (struct score_entry) * cursize)); + if (!ret) + break; + } } } - *count = scorecount; - *scores = ret; - return 0; + if (readval > 0) + { + *count = scorecount; + *scores = ret; + retval = 0; + } + fclose (f); + return retval; } static int @@ -461,5 +466,4 @@ unlock_file (const char *filename, void *state) return ret; } - /* update-game-score.c ends here */ -- cgit v1.2.1 From dc6c0edad789a8aab129ae12b8f064d0e912cca7 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 5 Aug 2013 14:05:46 -0400 Subject: Revert introduction of isearch-filter-predicates. Rely on add-function instead. * lisp/loadup.el: Preload nadvice. * lisp/isearch.el (isearch-filter-predicates): Rename it back to isearch-filter-predicate. (isearch-message-prefix): Use advice-function-mapc and advice properties to get the isearch-message-prefix. (isearch-search, isearch-lazy-highlight-search): Revert to funcall instead of run-hook-with-args-until-failure. (isearch-filter-visible): Not obsolete any more. * lisp/replace.el (perform-replace): Revert to funcall instead of run-hook-with-args-until-failure. * lisp/wdired.el (wdired-change-to-wdired-mode): Use add-function. * lisp/dired-aux.el (dired-isearch-filenames-mode): Rename from dired-isearch-filenames-toggle; make it into a proper minor mode. Use add/remove-function. (dired-isearch-filenames-setup, dired-isearch-filenames-end): Call the minor-mode rather than add/remove-hook. (dired-isearch-filter-filenames): Remove isearch-message-prefix property. * lisp/info.el (Info--search-loop): New function, extracted from Info-search. Funcall isearch-filter-predicate instead of run-hook-with-args-until-failure isearch-filter-predicates. (Info-search): Use it. (Info-mode): Use isearch-filter-predicate instead of isearch-filter-predicates. * src/lisp.mk (lisp): Add nadvice.elc. * lib-src/makefile.w32-in (lisp2): Add nadvice.elc. Fixes: debbugs:14714 --- lib-src/ChangeLog | 4 ++++ lib-src/makefile.w32-in | 1 + 2 files changed, 5 insertions(+) (limited to 'lib-src') diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 0336eae0981..da97246ef64 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,7 @@ +2013-08-05 Stefan Monnier + + * makefile.w32-in (lisp2): Add nadvice.elc. + 2013-08-05 Eli Zaretskii * update-game-score.c (read_score): Try reading a character before diff --git a/lib-src/makefile.w32-in b/lib-src/makefile.w32-in index 9656a3badec..dee80c4b560 100644 --- a/lib-src/makefile.w32-in +++ b/lib-src/makefile.w32-in @@ -251,6 +251,7 @@ lisp2 = \ $(lispsource)register.elc \ $(lispsource)replace.elc \ $(lispsource)simple.elc \ + $(lispsource)emacs-lisp/nadvice.elc \ $(lispsource)minibuffer.elc \ $(lispsource)startup.elc \ $(lispsource)subr.elc \ -- cgit v1.2.1 From d4166523bc8c4565cde24fcda56d3d5cdabb70ce Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 10 Aug 2013 10:43:41 +0300 Subject: Provide a Windows manifest for update-game-score.exe. lib-src/update-game-score.exe.manifest: New file. lib-src/Makefile.in (UPDATE_MANIFEST): New variable. (SCRIPTS): Add $(UPDATE_MANIFEST). configure.ac: Define and substitute UPDATE_MANIFEST. --- lib-src/ChangeLog | 7 +++++++ lib-src/Makefile.in | 3 ++- lib-src/update-game-score.exe.manifest | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 lib-src/update-game-score.exe.manifest (limited to 'lib-src') diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index da97246ef64..53d66ba1e37 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,10 @@ +2013-08-10 Eli Zaretskii + + * update-game-score.exe.manifest: New file. + + * Makefile.in (UPDATE_MANIFEST): New variable. + (SCRIPTS): Add $(UPDATE_MANIFEST). + 2013-08-05 Stefan Monnier * makefile.w32-in (lisp2): Add nadvice.elc. diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 8285910cdbf..fe1900a2a40 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -40,6 +40,7 @@ C_SWITCH_MACHINE=@C_SWITCH_MACHINE@ PROFILING_CFLAGS = @PROFILING_CFLAGS@ WARN_CFLAGS = @WARN_CFLAGS@ WERROR_CFLAGS = @WERROR_CFLAGS@ +UPDATE_MANIFEST = @UPDATE_MANIFEST@ # Program name transformation. TRANSFORM = @program_transform_name@ @@ -132,7 +133,7 @@ DONT_INSTALL= test-distrib${EXEEXT} make-docfile${EXEEXT} # Like UTILITIES, but they're not system-dependent, and should not be # deleted by the distclean target. -SCRIPTS= rcs2log +SCRIPTS= rcs2log $(UPDATE_MANIFEST) # All files that are created by the linker, i.e., whose names end in ${EXEEXT}. EXE_FILES = ${INSTALLABLES} ${UTILITIES} ${DONT_INSTALL} diff --git a/lib-src/update-game-score.exe.manifest b/lib-src/update-game-score.exe.manifest new file mode 100644 index 00000000000..1db836bec6b --- /dev/null +++ b/lib-src/update-game-score.exe.manifest @@ -0,0 +1,10 @@ + + + + + + + + + + -- cgit v1.2.1 From 43aac990c339c0fc3304aa476ebc8ea8467f107e Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 27 Aug 2013 11:47:55 -0700 Subject: Simplify EMACS_TIME-related code. This portability layer is no longer needed, since Emacs has been using struct timespec as a portability layer for some time. Merge from gnulib, incorporating: 2013-08-27 timespec: new convenience constants and function * src/atimer.h, src/buffer.h, src/dispextern.h, src/xgselect.h: Include rather than "systime.h"; that's all that's needed now. * src/dispnew.c: Include rather than "systime.h"; that's all that's needed now. * src/systime.h (EMACS_TIME): Remove. All uses changed to struct timespec. (EMACS_TIME_RESOLUTION): Remove. All uses changed to TIMESPEC_RESOLUTION. (LOG10_EMACS_TIME_RESOLUTION): Remove. All uses changed to LOG10_TIMESPEC_RESOLUTION. (EMACS_SECS, emacs_secs_addr): Remove. All uses changed to tv_sec. (EMACS_NSECS): Remove. All uses changed to tv_nsec. (make_emacs_time): Remove. All used changed to make_timespec. (invalid_timespec): Rename from invalid_emacs_time. All uses changed. (current_timespec): Rename from current_emacs_time. All uses changed. (add_emacs_time): Remove. All uses changed to timespec_add. (sub_emacs_time): Remove. All uses change dot timespec_sub. (EMACS_TIME_SIGN): Remove. All uses changed to timespec_sign. (timespec_valid_p): Rename from EMACS_TIME_VALID_P. All uses changed. (EMACS_TIME_FROM_DOUBLE): Remove. All uses changed to dtotimespec. (EMACS_TIME_TO_DOUBLE): Remove. All uses changed to timespectod. (current_timespec): Rename from current_emacs_time. All uses changed. (EMACS_TIME_EQ, EMACS_TIME_LT, EMACS_TIME_LE): Remove. All uses changed to timespec_cmp. * src/xgselect.c: Include , since our .h files don't. --- lib-src/profile.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib-src') diff --git a/lib-src/profile.c b/lib-src/profile.c index ab17b52ca28..bddfea76334 100644 --- a/lib-src/profile.c +++ b/lib-src/profile.c @@ -39,17 +39,17 @@ along with GNU Emacs. If not, see . */ #include #include -static EMACS_TIME TV1; +static struct timespec TV1; static int watch_not_started = 1; /* flag */ static char time_string[INT_STRLEN_BOUND (uintmax_t) + sizeof "." - + LOG10_EMACS_TIME_RESOLUTION]; + + LOG10_TIMESPEC_RESOLUTION]; /* Reset the stopwatch to zero. */ static void reset_watch (void) { - TV1 = current_emacs_time (); + TV1 = current_timespec (); watch_not_started = 0; } @@ -60,12 +60,12 @@ reset_watch (void) static char * get_time (void) { - EMACS_TIME TV2 = sub_emacs_time (current_emacs_time (), TV1); - uintmax_t s = EMACS_SECS (TV2); - int ns = EMACS_NSECS (TV2); + struct timespec TV2 = timespec_sub (current_timespec (), TV1); + uintmax_t s = TV2.tv_sec; + int ns = TV2.tv_nsec; if (watch_not_started) exit (EXIT_FAILURE); /* call reset_watch first ! */ - sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_EMACS_TIME_RESOLUTION, ns); + sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_TIMESPEC_RESOLUTION, ns); return time_string; } -- cgit v1.2.1 From 50b13cdedb19f4bdd6737e8d2cdb4daa4e886c92 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 27 Aug 2013 23:01:52 -0700 Subject: * Makefile.in (SHELL): Now @SHELL@, not /bin/sh, for portability to hosts where /bin/sh has problems. --- lib-src/ChangeLog | 5 +++++ lib-src/Makefile.in | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'lib-src') diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 53d66ba1e37..d2e9dd18177 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,8 @@ +2013-08-28 Paul Eggert + + * Makefile.in (SHELL): Now @SHELL@, not /bin/sh, + for portability to hosts where /bin/sh has problems. + 2013-08-10 Eli Zaretskii * update-game-score.exe.manifest: New file. diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index fe1900a2a40..994eb2bb266 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -18,10 +18,7 @@ # You should have received a copy of the GNU General Public License # along with GNU Emacs. If not, see . - -# Avoid trouble on systems where the `SHELL' variable might be -# inherited from the environment. -SHELL = /bin/sh +SHELL = @SHELL@ # Following ../lisp/Makefile.in. EMACS = ../src/emacs -- cgit v1.2.1