Now on revision 113987. ------------------------------------------------------------ revno: 113987 committer: Paul Eggert branch nick: trunk timestamp: Fri 2013-08-23 19:23:34 -0700 message: System-dependent integer overflow fixes. * process.c (Fset_process_window_size): Signal an error if the window size is outside the range supported by the lower level. * sysdep.c (set_window_size): Return negative on error, nonnegative on success, rather than -1, 0, 1 on not in system, failure, success. This is simpler. Caller changed. (serial_configure): Remove unnecessary initialization of local. (procfs_get_total_memory) [GNU_LINUX]: Don't assume system memory size fits in unsigned long; this isn't true on some 32-bit hosts. Avoid buffer overrun if some future version of /proc/meminfo has a variable name longer than 20 bytes. (system_process_attributes) [__FreeBSD__]: Don't assume hw.availpages fits in 'int'. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-23 17:57:07 +0000 +++ src/ChangeLog 2013-08-24 02:23:34 +0000 @@ -1,3 +1,19 @@ +2013-08-24 Paul Eggert + + System-dependent integer overflow fixes. + * process.c (Fset_process_window_size): Signal an error if + the window size is outside the range supported by the lower level. + * sysdep.c (set_window_size): Return negative on error, + nonnegative on success, rather than -1, 0, 1 on not in system, + failure, success. This is simpler. Caller changed. + (serial_configure): Remove unnecessary initialization of local. + (procfs_get_total_memory) [GNU_LINUX]: Don't assume system memory + size fits in unsigned long; this isn't true on some 32-bit hosts. + Avoid buffer overrun if some future version of /proc/meminfo has a + variable name longer than 20 bytes. + (system_process_attributes) [__FreeBSD__]: + Don't assume hw.availpages fits in 'int'. + 2013-08-23 Paul Eggert Don't let very long directory names overrun the stack. === modified file 'src/process.c' --- src/process.c 2013-08-23 17:57:07 +0000 +++ src/process.c 2013-08-24 02:23:34 +0000 @@ -1140,15 +1140,18 @@ DEFUN ("set-process-window-size", Fset_process_window_size, Sset_process_window_size, 3, 3, 0, doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */) - (register Lisp_Object process, Lisp_Object height, Lisp_Object width) + (Lisp_Object process, Lisp_Object height, Lisp_Object width) { CHECK_PROCESS (process); - CHECK_RANGED_INTEGER (height, 0, INT_MAX); - CHECK_RANGED_INTEGER (width, 0, INT_MAX); + + /* All known platforms store window sizes as 'unsigned short'. */ + CHECK_RANGED_INTEGER (height, 0, USHRT_MAX); + CHECK_RANGED_INTEGER (width, 0, USHRT_MAX); if (XPROCESS (process)->infd < 0 - || set_window_size (XPROCESS (process)->infd, - XINT (height), XINT (width)) <= 0) + || (set_window_size (XPROCESS (process)->infd, + XINT (height), XINT (width)) + < 0)) return Qnil; else return Qt; === modified file 'src/sysdep.c' --- src/sysdep.c 2013-08-23 17:57:07 +0000 +++ src/sysdep.c 2013-08-24 02:23:34 +0000 @@ -1170,7 +1170,8 @@ } /* Set the logical window size associated with descriptor FD - to HEIGHT and WIDTH. This is used mainly with ptys. */ + to HEIGHT and WIDTH. This is used mainly with ptys. + Return a negative value on failure. */ int set_window_size (int fd, int height, int width) @@ -1182,10 +1183,7 @@ size.ws_row = height; size.ws_col = width; - if (ioctl (fd, TIOCSWINSZ, &size) == -1) - return 0; /* error */ - else - return 1; + return ioctl (fd, TIOCSWINSZ, &size); #else #ifdef TIOCSSIZE @@ -1195,10 +1193,7 @@ size.ts_lines = height; size.ts_cols = width; - if (ioctl (fd, TIOCGSIZE, &size) == -1) - return 0; - else - return 1; + return ioctl (fd, TIOCGSIZE, &size); #else return -1; #endif /* not SunOS-style */ @@ -2459,7 +2454,7 @@ Lisp_Object childp2 = Qnil; Lisp_Object tem = Qnil; struct termios attr; - int err = -1; + int err; char summary[4] = "???"; /* This usually becomes "8N1". */ childp2 = Fcopy_sequence (p->childp); @@ -2826,29 +2821,41 @@ return build_string (name); } -static unsigned long +static uintmax_t procfs_get_total_memory (void) { FILE *fmem; - unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ + uintmax_t retval = 2 * 1024 * 1024; /* default: 2 GiB */ + int c; block_input (); fmem = emacs_fopen ("/proc/meminfo", "r"); if (fmem) { - unsigned long entry_value; - char entry_name[20]; /* the longest I saw is 13+1 */ - - while (!feof (fmem) && !ferror (fmem)) - { - if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2 - && strcmp (entry_name, "MemTotal:") == 0) - { - retval = entry_value; - break; - } - } + uintmax_t entry_value; + bool done; + + do + switch (fscanf (fmem, "MemTotal: %"SCNuMAX, &entry_value)) + { + case 1: + retval = entry_value; + done = 1; + break; + + case 0: + while ((c = getc (fmem)) != EOF && c != '\n') + continue; + done = c == EOF; + break; + + default: + done = 1; + break; + } + while (!done); + fclose (fmem); } unblock_input (); @@ -3249,7 +3256,7 @@ { int proc_id; int pagesize = getpagesize (); - int npages; + unsigned long npages; int fscale; struct passwd *pw; struct group *gr; ------------------------------------------------------------ revno: 113986 committer: Glenn Morris branch nick: trunk timestamp: Fri 2013-08-23 14:58:41 -0400 message: * lisp/files.el (auto-mode-alist): Use sh-mode for .bash_history. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-23 17:34:09 +0000 +++ lisp/ChangeLog 2013-08-23 18:58:41 +0000 @@ -1,5 +1,7 @@ 2013-08-23 Glenn Morris + * files.el (auto-mode-alist): Use sh-mode for .bash_history. + * files.el (interpreter-mode-alist): Use tcl-mode for expect scripts. * files.el (create-file-buffer): If the result would begin with === modified file 'lisp/files.el' --- lisp/files.el 2013-08-23 17:34:09 +0000 +++ lisp/files.el 2013-08-23 18:58:41 +0000 @@ -2275,8 +2275,8 @@ ("\\.scm\\.[0-9]*\\'" . scheme-mode) ("\\.[ck]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode) ("\\.bash\\'" . sh-mode) - ("\\(/\\|\\`\\)\\.\\(bash_profile\\|z?login\\|bash_login\\|z?logout\\)\\'" . sh-mode) - ("\\(/\\|\\`\\)\\.\\(bash_logout\\|shrc\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode) + ("\\(/\\|\\`\\)\\.\\(bash_\\(profile\\|history\\|log\\(in\\|out\\)\\)\\|z?log\\(in\\|out\\)\\)\\'" . sh-mode) + ("\\(/\\|\\`\\)\\.\\(shrc\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode) ("\\(/\\|\\`\\)\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode) ("\\.m?spec\\'" . sh-mode) ("\\.m[mes]\\'" . nroff-mode) ------------------------------------------------------------ revno: 113985 committer: Paul Eggert branch nick: trunk timestamp: Fri 2013-08-23 10:57:07 -0700 message: Don't let very long directory names overrun the stack. Fix some related minor problems involving "//", vfork. * callproc.c (encode_current_directory): New function. (call_process): Don't append "/"; not needed. * fileio.c (file_name_as_directory_slop): New constant. (file_name_as_directory): Allow SRC to be longer than SRCLEN; this can save the caller having to alloca. (Ffile_name_as_directory, Fdirectory_file_name, Fexpand_file_name): Use SAFE_ALLOCA, not alloca. (directory_file_name, Fexpand_file_name): Leave leading "//" alone, since it can be special even on POSIX platforms. * callproc.c (call_process): * process.c (Fformat_network_address): * sysdep.c (sys_subshell): Use encode_current_directory rather than rolling our own. (create_process): No need to encode directory; caller does that now. * process.h (encode_current_directory): New decl. * sysdep.c (sys_subshell): Work even if vfork trashes saved_handlers. Rework to avoid 'goto xyzzy;'. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-23 14:25:39 +0000 +++ src/ChangeLog 2013-08-23 17:57:07 +0000 @@ -1,3 +1,25 @@ +2013-08-23 Paul Eggert + + Don't let very long directory names overrun the stack. + Fix some related minor problems involving "//", vfork. + * callproc.c (encode_current_directory): New function. + (call_process): Don't append "/"; not needed. + * fileio.c (file_name_as_directory_slop): New constant. + (file_name_as_directory): Allow SRC to be longer than SRCLEN; + this can save the caller having to alloca. + (Ffile_name_as_directory, Fdirectory_file_name, Fexpand_file_name): + Use SAFE_ALLOCA, not alloca. + (directory_file_name, Fexpand_file_name): Leave leading "//" + alone, since it can be special even on POSIX platforms. + * callproc.c (call_process): + * process.c (Fformat_network_address): + * sysdep.c (sys_subshell): + Use encode_current_directory rather than rolling our own. + (create_process): No need to encode directory; caller does that now. + * process.h (encode_current_directory): New decl. + * sysdep.c (sys_subshell): Work even if vfork trashes saved_handlers. + Rework to avoid 'goto xyzzy;'. + 2013-08-23 Eli Zaretskii * xdisp.c (handle_face_prop): If the default face was remapped use === modified file 'src/callproc.c' --- src/callproc.c 2013-08-21 21:27:30 +0000 +++ src/callproc.c 2013-08-23 17:57:07 +0000 @@ -123,6 +123,37 @@ pthread_sigmask (SIG_SETMASK, &empty_mask, 0); } +/* Return the current buffer's working directory, or the home + directory if it's unreachable, as a string suitable for a system call. + Signal an error if the result would not be an accessible directory. */ + +Lisp_Object +encode_current_directory (void) +{ + Lisp_Object dir; + struct gcpro gcpro1; + + dir = BVAR (current_buffer, directory); + GCPRO1 (dir); + + dir = Funhandled_file_name_directory (dir); + + /* If the file name handler says that dir is unreachable, use + a sensible default. */ + if (NILP (dir)) + dir = build_string ("~"); + + dir = expand_and_dir_to_file (dir, Qnil); + + if (STRING_MULTIBYTE (dir)) + dir = ENCODE_FILE (dir); + if (! file_accessible_directory_p (SSDATA (dir))) + report_file_error ("Setting current directory", + BVAR (current_buffer, directory)); + + RETURN_UNGCPRO (dir); +} + /* If P is reapable, record it as a deleted process and kill it. Do this in a critical section. Unless PID is wedged it will be reaped on receipt of the first SIGCHLD after the critical section. */ @@ -408,24 +439,10 @@ { struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; - current_dir = BVAR (current_buffer, directory); + current_dir = encode_current_directory (); GCPRO4 (buffer, current_dir, error_file, output_file); - current_dir = Funhandled_file_name_directory (current_dir); - if (NILP (current_dir)) - /* If the file name handler says that current_dir is unreachable, use - a sensible default. */ - current_dir = build_string ("~/"); - current_dir = expand_and_dir_to_file (current_dir, Qnil); - current_dir = Ffile_name_as_directory (current_dir); - - if (NILP (Ffile_accessible_directory_p (current_dir))) - report_file_error ("Setting current directory", - BVAR (current_buffer, directory)); - - if (STRING_MULTIBYTE (current_dir)) - current_dir = ENCODE_FILE (current_dir); if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) error_file = ENCODE_FILE (error_file); if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) @@ -1176,23 +1193,21 @@ static variables as if the superior had done alloca and will be cleaned up in the usual way. */ { - register char *temp; - size_t i; /* size_t, because ptrdiff_t might overflow here! */ + char *temp; + ptrdiff_t i; i = SBYTES (current_dir); #ifdef MSDOS /* MSDOS must have all environment variables malloc'ed, because low-level libc functions that launch subsidiary processes rely on that. */ - pwd_var = xmalloc (i + 6); + pwd_var = xmalloc (i + 5); #else - pwd_var = alloca (i + 6); + pwd_var = alloca (i + 5); #endif temp = pwd_var + 4; memcpy (pwd_var, "PWD=", 4); - memcpy (temp, SDATA (current_dir), i); - if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP; - temp[i] = 0; + strcpy (temp, SSDATA (current_dir)); #ifndef DOS_NT /* We can't signal an Elisp error here; we're in a vfork. Since === modified file 'src/fileio.c' --- src/fileio.c 2013-08-14 16:36:16 +0000 +++ src/fileio.c 2013-08-23 17:57:07 +0000 @@ -504,6 +504,10 @@ return Ffile_name_directory (filename); } +/* Maximum number of bytes that DST will be longer than SRC + in file_name_as_directory. This occurs when SRCLEN == 0. */ +enum { file_name_as_directory_slop = 2 }; + /* Convert from file name SRC of length SRCLEN to directory name in DST. MULTIBYTE non-zero means the file name in SRC is a multibyte string. On UNIX, just make sure there is a terminating /. Return @@ -521,14 +525,10 @@ return 2; } - strcpy (dst, src); - + memcpy (dst, src, srclen); if (!IS_DIRECTORY_SEP (dst[srclen - 1])) - { - dst[srclen] = DIRECTORY_SEP; - dst[srclen + 1] = '\0'; - srclen++; - } + dst[srclen++] = DIRECTORY_SEP; + dst[srclen] = 0; #ifdef DOS_NT dostounix_filename (dst, multibyte); #endif @@ -547,7 +547,8 @@ { char *buf; ptrdiff_t length; - Lisp_Object handler; + Lisp_Object handler, val; + USE_SAFE_ALLOCA; CHECK_STRING (file); if (NILP (file)) @@ -569,10 +570,12 @@ if (!NILP (Vw32_downcase_file_names)) file = Fdowncase (file); #endif - buf = alloca (SBYTES (file) + 10); + buf = SAFE_ALLOCA (SBYTES (file) + file_name_as_directory_slop + 1); length = file_name_as_directory (buf, SSDATA (file), SBYTES (file), STRING_MULTIBYTE (file)); - return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); + val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); + SAFE_FREE (); + return val; } /* Convert from directory name SRC of length SRCLEN to file name in @@ -584,18 +587,17 @@ directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte) { /* Process as Unix format: just remove any final slash. - But leave "/" unchanged; do not change it to "". */ - strcpy (dst, src); - if (srclen > 1 - && IS_DIRECTORY_SEP (dst[srclen - 1]) + But leave "/" and "//" unchanged. */ + while (srclen > 1 #ifdef DOS_NT - && !IS_ANY_SEP (dst[srclen - 2]) + && !IS_ANY_SEP (src[srclen - 2]) #endif - ) - { - dst[srclen - 1] = 0; - srclen--; - } + && IS_DIRECTORY_SEP (src[srclen - 1]) + && ! (srclen == 2 && IS_DIRECTORY_SEP (src[0]))) + srclen--; + + memcpy (dst, src, srclen); + dst[srclen] = 0; #ifdef DOS_NT dostounix_filename (dst, multibyte); #endif @@ -613,7 +615,8 @@ { char *buf; ptrdiff_t length; - Lisp_Object handler; + Lisp_Object handler, val; + USE_SAFE_ALLOCA; CHECK_STRING (directory); @@ -636,10 +639,12 @@ if (!NILP (Vw32_downcase_file_names)) directory = Fdowncase (directory); #endif - buf = alloca (SBYTES (directory) + 20); + buf = SAFE_ALLOCA (SBYTES (directory) + 1); length = directory_file_name (buf, SSDATA (directory), SBYTES (directory), STRING_MULTIBYTE (directory)); - return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); + val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); + SAFE_FREE (); + return val; } static const char make_temp_name_tbl[64] = @@ -837,6 +842,7 @@ Lisp_Object handler, result, handled_name; bool multibyte; Lisp_Object hdir; + USE_SAFE_ALLOCA; CHECK_STRING (name); @@ -1011,11 +1017,11 @@ || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0)))) lose = 1; - /* We want to replace multiple `/' in a row with a single - slash. */ - else if (p > nm - && IS_DIRECTORY_SEP (p[0]) - && IS_DIRECTORY_SEP (p[1])) + /* Replace multiple slashes with a single one, except + leave leading "//" alone. */ + else if (IS_DIRECTORY_SEP (p[0]) + && IS_DIRECTORY_SEP (p[1]) + && (p != nm || IS_DIRECTORY_SEP (p[2]))) lose = 1; p++; } @@ -1098,10 +1104,11 @@ else /* ~user/filename */ { char *o, *p; - for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)); p++); - o = alloca (p - nm + 1); + for (p = nm; *p && !IS_DIRECTORY_SEP (*p); p++) + continue; + o = SAFE_ALLOCA (p - nm + 1); memcpy (o, nm, p - nm); - o [p - nm] = 0; + o[p - nm] = 0; block_input (); pw = getpwnam (o + 1); @@ -1217,7 +1224,8 @@ if (!IS_DIRECTORY_SEP (nm[0])) { ptrdiff_t newlen = strlen (newdir); - char *tmp = alloca (newlen + strlen (nm) + 2); + char *tmp = alloca (newlen + file_name_as_directory_slop + + strlen (nm) + 1); file_name_as_directory (tmp, newdir, newlen, multibyte); strcat (tmp, nm); nm = tmp; @@ -1271,31 +1279,18 @@ if (newdir) { - /* Get rid of any slash at the end of newdir, unless newdir is - just / or // (an incomplete UNC name). */ + /* Ignore any slash at the end of newdir, unless newdir is + just "/" or "//". */ length = strlen (newdir); - tlen = length + 1; - if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) -#ifdef WINDOWSNT - && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) -#endif - ) - { - char *temp = alloca (length); - memcpy (temp, newdir, length - 1); - temp[length - 1] = 0; - length--; - newdir = temp; - } + while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) + && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) + length--; } else - { - length = 0; - tlen = 0; - } + length = 0; /* Now concatenate the directory and name to new space in the stack frame. */ - tlen += strlen (nm) + 1; + tlen = length + file_name_as_directory_slop + strlen (nm) + 1; #ifdef DOS_NT /* Reserve space for drive specifier and escape prefix, since either or both may need to be inserted. (The Microsoft x86 compiler @@ -1303,7 +1298,7 @@ target = alloca (tlen + 4); target += 4; #else /* not DOS_NT */ - target = alloca (tlen); + target = SAFE_ALLOCA (tlen); #endif /* not DOS_NT */ *target = 0; @@ -1320,7 +1315,10 @@ if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0]) && newdir[1] == '\0')) #endif - strcpy (target, newdir); + { + memcpy (target, newdir, length); + target[length] = 0; + } } else file_name_as_directory (target, newdir, length, multibyte); @@ -1380,8 +1378,9 @@ ++o; p += 3; } - else if (p > target && IS_DIRECTORY_SEP (p[1])) - /* Collapse multiple `/' in a row. */ + else if (IS_DIRECTORY_SEP (p[1]) + && (p != target || IS_DIRECTORY_SEP (p[2]))) + /* Collapse multiple "/", except leave leading "//" alone. */ p++; else { @@ -1429,11 +1428,12 @@ { handled_name = call3 (handler, Qexpand_file_name, result, default_directory); - if (STRINGP (handled_name)) - return handled_name; - error ("Invalid handler in `file-name-handler-alist'"); + if (! STRINGP (handled_name)) + error ("Invalid handler in `file-name-handler-alist'"); + result = handled_name; } + SAFE_FREE (); return result; } === modified file 'src/process.c' --- src/process.c 2013-08-22 18:29:51 +0000 +++ src/process.c 2013-08-23 17:57:07 +0000 @@ -1408,22 +1408,9 @@ function. The argument list is protected by the caller, so all we really have to worry about is buffer. */ { - struct gcpro gcpro1, gcpro2; - - current_dir = BVAR (current_buffer, directory); - - GCPRO2 (buffer, current_dir); - - current_dir = Funhandled_file_name_directory (current_dir); - if (NILP (current_dir)) - /* If the file name handler says that current_dir is unreachable, use - a sensible default. */ - current_dir = build_string ("~/"); - current_dir = expand_and_dir_to_file (current_dir, Qnil); - if (NILP (Ffile_accessible_directory_p (current_dir))) - report_file_error ("Setting current directory", - BVAR (current_buffer, directory)); - + struct gcpro gcpro1; + GCPRO1 (buffer); + current_dir = encode_current_directory (); UNGCPRO; } @@ -1670,7 +1657,6 @@ bool pty_flag = 0; char pty_name[PTY_NAME_SIZE]; Lisp_Object lisp_pty_name = Qnil; - Lisp_Object encoded_current_dir; inchannel = outchannel = -1; @@ -1735,15 +1721,13 @@ /* This may signal an error. */ setup_process_coding_systems (process); - encoded_current_dir = ENCODE_FILE (current_dir); - block_input (); block_child_signal (); #ifndef WINDOWSNT /* vfork, and prevent local vars from being clobbered by the vfork. */ { - Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; + Lisp_Object volatile current_dir_volatile = current_dir; Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; char **volatile new_argv_volatile = new_argv; int volatile forkin_volatile = forkin; @@ -1752,7 +1736,7 @@ pid = vfork (); - encoded_current_dir = encoded_current_dir_volatile; + current_dir = current_dir_volatile; lisp_pty_name = lisp_pty_name_volatile; new_argv = new_argv_volatile; forkin = forkin_volatile; @@ -1864,11 +1848,9 @@ if (pty_flag) child_setup_tty (xforkout); #ifdef WINDOWSNT - pid = child_setup (xforkin, xforkout, xforkout, - new_argv, 1, encoded_current_dir); + pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); #else /* not WINDOWSNT */ - child_setup (xforkin, xforkout, xforkout, - new_argv, 1, encoded_current_dir); + child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); #endif /* not WINDOWSNT */ } === modified file 'src/process.h' --- src/process.h 2013-08-12 07:12:07 +0000 +++ src/process.h 2013-08-23 17:57:07 +0000 @@ -218,6 +218,7 @@ extern void block_child_signal (void); extern void unblock_child_signal (void); +extern Lisp_Object encode_current_directory (void); extern void record_kill_process (struct Lisp_Process *, Lisp_Object); /* Defined in sysdep.c. */ === modified file 'src/sysdep.c' --- src/sysdep.c 2013-08-22 18:29:51 +0000 +++ src/sysdep.c 2013-08-23 17:57:07 +0000 @@ -471,10 +471,20 @@ pid_t pid; int status; struct save_signal saved_handlers[5]; - Lisp_Object dir; - unsigned char *volatile str_volatile = 0; - unsigned char *str; - int len; + char *str = SSDATA (encode_current_directory ()); + +#ifdef DOS_NT + pid = 0; +#else + { + char *volatile str_volatile = str; + pid = vfork (); + str = str_volatile; + } +#endif + + if (pid < 0) + error ("Can't spawn subshell"); saved_handlers[0].code = SIGINT; saved_handlers[1].code = SIGQUIT; @@ -486,31 +496,8 @@ saved_handlers[3].code = 0; #endif - /* Mentioning current_buffer->buffer would mean including buffer.h, - which somehow wedges the hp compiler. So instead... */ - - dir = intern ("default-directory"); - if (NILP (Fboundp (dir))) - goto xyzzy; - dir = Fsymbol_value (dir); - if (!STRINGP (dir)) - goto xyzzy; - - dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil); - str_volatile = str = alloca (SCHARS (dir) + 2); - len = SCHARS (dir); - memcpy (str, SDATA (dir), len); - if (str[len - 1] != '/') str[len++] = '/'; - str[len] = 0; - xyzzy: - #ifdef DOS_NT - pid = 0; save_signal_handlers (saved_handlers); -#else - pid = vfork (); - if (pid == -1) - error ("Can't spawn subshell"); #endif if (pid == 0) @@ -528,11 +515,10 @@ sh = "sh"; /* Use our buffer's default directory for the subshell. */ - str = str_volatile; - if (str && chdir ((char *) str) != 0) + if (chdir (str) != 0) { #ifndef DOS_NT - emacs_perror ((char *) str); + emacs_perror (str); _exit (EXIT_CANCELED); #endif } @@ -546,8 +532,6 @@ if (epwd) { strcpy (old_pwd, epwd); - if (str[len - 1] == '/') - str[len - 1] = '\0'; setenv ("PWD", str, 1); } st = system (sh); ------------------------------------------------------------ revno: 113984 committer: Glenn Morris branch nick: trunk timestamp: Fri 2013-08-23 13:34:09 -0400 message: * lisp/files.el (create-file-buffer): Rework previous change. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-23 17:09:09 +0000 +++ lisp/ChangeLog 2013-08-23 17:34:09 +0000 @@ -2,8 +2,8 @@ * files.el (interpreter-mode-alist): Use tcl-mode for expect scripts. - * files.el (create-file-buffer): Handle the vital case of a file - whose basename is all spaces. (Bug#15162) + * files.el (create-file-buffer): If the result would begin with + spaces, prepend a "|" instead of removing them. (Bug#15162) 2013-08-23 Stefan Monnier === modified file 'lisp/files.el' --- lisp/files.el 2013-08-23 17:09:09 +0000 +++ lisp/files.el 2013-08-23 17:34:09 +0000 @@ -1603,17 +1603,16 @@ "Create a suitably named buffer for visiting FILENAME, and return it. FILENAME (sans directory) is used unchanged if that name is free; otherwise a string <2> or <3> or ... is appended to get an unused name. -Spaces at the start of FILENAME (sans directory) are removed." - ;; ^ Because buffers whose name begins with a space are treated as - ;; internal Emacs buffers. + +Emacs treats buffers whose names begin with a space as internal buffers. +To avoid confusion when visiting a file whose name begins with a space, +this function prepends a \"|\" to the final result if necessary." (let ((lastname (file-name-nondirectory filename))) (if (string= lastname "") (setq lastname filename)) - (save-match-data - (if (string-match "\\` +\\(.*\\)" lastname) - (if (zerop (length (setq lastname (match-string 1 lastname)))) - (setq lastname "SPC")))) ; bug#15162 - (generate-new-buffer lastname))) + (generate-new-buffer (if (string-match-p "\\` " lastname) + (concat "|" lastname) + lastname)))) (defun generate-new-buffer (name) "Create and return a buffer with a name based on NAME. ------------------------------------------------------------ revno: 113983 committer: Glenn Morris branch nick: trunk timestamp: Fri 2013-08-23 13:09:09 -0400 message: * lisp/files.el (interpreter-mode-alist): Use tcl-mode for expect scripts. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-23 17:08:19 +0000 +++ lisp/ChangeLog 2013-08-23 17:09:09 +0000 @@ -1,5 +1,7 @@ 2013-08-23 Glenn Morris + * files.el (interpreter-mode-alist): Use tcl-mode for expect scripts. + * files.el (create-file-buffer): Handle the vital case of a file whose basename is all spaces. (Bug#15162) === modified file 'lisp/files.el' --- lisp/files.el 2013-08-23 17:08:19 +0000 +++ lisp/files.el 2013-08-23 17:09:09 +0000 @@ -2455,6 +2455,7 @@ ("wishx" . tcl-mode) ("tcl" . tcl-mode) ("tclsh" . tcl-mode) + ("expect" . tcl-mode) ("scm" . scheme-mode) ("ash" . sh-mode) ("bash" . sh-mode) ------------------------------------------------------------ revno: 113982 fixes bug: http://debbugs.gnu.org/15162 committer: Glenn Morris branch nick: trunk timestamp: Fri 2013-08-23 13:08:19 -0400 message: * files.el (create-file-buffer): Handle a file whose basename is all spaces. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-23 15:31:45 +0000 +++ lisp/ChangeLog 2013-08-23 17:08:19 +0000 @@ -1,3 +1,8 @@ +2013-08-23 Glenn Morris + + * files.el (create-file-buffer): Handle the vital case of a file + whose basename is all spaces. (Bug#15162) + 2013-08-23 Stefan Monnier * textmodes/fill.el (fill-match-adaptive-prefix): Don't throw away === modified file 'lisp/files.el' --- lisp/files.el 2013-08-06 16:33:14 +0000 +++ lisp/files.el 2013-08-23 17:08:19 +0000 @@ -1604,12 +1604,16 @@ FILENAME (sans directory) is used unchanged if that name is free; otherwise a string <2> or <3> or ... is appended to get an unused name. Spaces at the start of FILENAME (sans directory) are removed." + ;; ^ Because buffers whose name begins with a space are treated as + ;; internal Emacs buffers. (let ((lastname (file-name-nondirectory filename))) (if (string= lastname "") (setq lastname filename)) (save-match-data - (string-match "^ *\\(.*\\)" lastname) - (generate-new-buffer (match-string 1 lastname))))) + (if (string-match "\\` +\\(.*\\)" lastname) + (if (zerop (length (setq lastname (match-string 1 lastname)))) + (setq lastname "SPC")))) ; bug#15162 + (generate-new-buffer lastname))) (defun generate-new-buffer (name) "Create and return a buffer with a name based on NAME. ------------------------------------------------------------ revno: 113981 fixes bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15155 committer: Stefan Monnier branch nick: trunk timestamp: Fri 2013-08-23 11:31:45 -0400 message: * lisp/textmodes/fill.el (fill-match-adaptive-prefix): Don't throw away text-properties. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-23 15:21:19 +0000 +++ lisp/ChangeLog 2013-08-23 15:31:45 +0000 @@ -1,5 +1,8 @@ 2013-08-23 Stefan Monnier + * textmodes/fill.el (fill-match-adaptive-prefix): Don't throw away + text-properties (bug#15155). + * calc/calc-keypd.el (calc-keypad-execute): `x-flush-mouse-queue' doesn't exist any more. (calc-keypad-redraw): Remove unused var `pad'. === modified file 'lisp/textmodes/fill.el' --- lisp/textmodes/fill.el 2013-01-02 16:13:04 +0000 +++ lisp/textmodes/fill.el 2013-08-23 15:31:45 +0000 @@ -220,7 +220,7 @@ (let ((str (or (and adaptive-fill-function (funcall adaptive-fill-function)) (and adaptive-fill-regexp (looking-at adaptive-fill-regexp) - (match-string-no-properties 0))))) + (match-string 0))))) (if (>= (+ (current-left-margin) (length str)) (current-fill-column)) ;; Death to insanely long prefixes. nil ------------------------------------------------------------ revno: 113980 committer: Stefan Monnier branch nick: trunk timestamp: Fri 2013-08-23 11:21:19 -0400 message: * lisp/calc/calc-keypd.el (calc-keypad-execute): `x-flush-mouse-queue' doesn't exist any more. (calc-keypad-redraw): Remove unused var `pad'. (calc-keypad-press): Remove unused var `menu'. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-23 06:52:19 +0000 +++ lisp/ChangeLog 2013-08-23 15:21:19 +0000 @@ -1,7 +1,14 @@ +2013-08-23 Stefan Monnier + + * calc/calc-keypd.el (calc-keypad-execute): `x-flush-mouse-queue' doesn't + exist any more. + (calc-keypad-redraw): Remove unused var `pad'. + (calc-keypad-press): Remove unused var `menu'. + 2013-08-23 Martin Rudalics - * window.el (display-buffer-pop-up-frame): Call - pop-up-frame-function with BUFFER current so `make-frame' will + * window.el (display-buffer-pop-up-frame): + Call pop-up-frame-function with BUFFER current so `make-frame' will use it as the new frame's buffer (Bug#15133). 2013-08-22 Stefan Monnier === modified file 'lisp/calc/calc-keypd.el' --- lisp/calc/calc-keypd.el 2013-01-01 09:11:05 +0000 +++ lisp/calc/calc-keypd.el 2013-08-23 15:21:19 +0000 @@ -349,8 +349,7 @@ (if (> (length (car key)) cwid) (substring (car key) 0 cwid) (car key)))) - (wid (length name)) - (pad (- cwid (/ wid 2)))) + (wid (length name))) (insert (make-string (/ (- cwid wid) 2) 32) name (make-string (/ (- cwid wid -1) 2) 32) @@ -399,7 +398,6 @@ inv calc-inverse-flag) calc-hyperbolic-flag)) (invhyp t) - (menu (symbol-value (nth calc-keypad-menu calc-keypad-menus))) (input calc-keypad-input) (iexpon (and input (or (string-match "\\*[0-9]+\\.\\^" input) @@ -535,19 +533,22 @@ (defun calc-keypad-left-click (event) "Handle a left-button mouse click in Calc Keypad window." + ;; FIXME: Why not use "@e" instead to select the buffer? (interactive "e") (with-current-buffer calc-keypad-buffer (goto-char (posn-point (event-start event))) (calc-keypad-press))) -(defun calc-keypad-right-click (event) +(defun calc-keypad-right-click (_event) "Handle a right-button mouse click in Calc Keypad window." + ;; FIXME: Why not use "@e" instead to select the buffer? (interactive "e") (with-current-buffer calc-keypad-buffer (calc-keypad-menu))) -(defun calc-keypad-middle-click (event) +(defun calc-keypad-middle-click (_event) "Handle a middle-button mouse click in Calc Keypad window." + ;; FIXME: Why not use "@e" instead to select the buffer? (interactive "e") (with-current-buffer calc-keypad-buffer (calc-keypad-menu-back))) @@ -588,7 +589,6 @@ (defun calc-keypad-execute () (interactive) (let* ((prompt "Calc keystrokes: ") - (flush 'x-flush-mouse-queue) (prefix nil) keys cmd) (save-excursion @@ -605,10 +605,9 @@ (progn (setq last-command-event (aref keys (1- (length keys)))) (command-execute cmd) - (setq flush 'not-any-more - prefix t + (setq prefix t prompt (concat prompt (key-description keys) " "))) - (eq cmd flush))))) ; skip mouse-up event + nil)))) ; skip mouse-up event (message "") (if (commandp cmd) (command-execute cmd) ------------------------------------------------------------ revno: 113979 fixes bug: http://debbugs.gnu.org/15155 committer: Eli Zaretskii branch nick: trunk timestamp: Fri 2013-08-23 17:25:39 +0300 message: Fix bug #15155 with ignoring face remapping for strings from prefix properties. src/xdisp.c (handle_face_prop): If the default face was remapped use the remapped face for strings from prefix properties. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-23 04:03:25 +0000 +++ src/ChangeLog 2013-08-23 14:25:39 +0000 @@ -1,3 +1,8 @@ +2013-08-23 Eli Zaretskii + + * xdisp.c (handle_face_prop): If the default face was remapped use + the remapped face for strings from prefix properties. (Bug#15155) + 2013-08-23 Dmitry Antipov Minor cleanup for redisplay interface and few related functions. === modified file 'src/xdisp.c' --- src/xdisp.c 2013-08-23 04:03:25 +0000 +++ src/xdisp.c 2013-08-23 14:25:39 +0000 @@ -3912,10 +3912,14 @@ /* For strings from a `display' property, use the face at IT's current buffer position as the base face to merge with, so that overlay strings appear in the same face as - surrounding text, unless they specify their own - faces. */ + surrounding text, unless they specify their own faces. + For strings from wrap-prefix and line-prefix properties, + use the default face, possibly remapped via + Vface_remapping_alist. */ base_face_id = it->string_from_prefix_prop_p - ? DEFAULT_FACE_ID + ? (!NILP (Vface_remapping_alist) + ? lookup_basic_face (it->f, DEFAULT_FACE_ID) + : DEFAULT_FACE_ID) : underlying_face_id (it); } ------------------------------------------------------------ revno: 113978 committer: Glenn Morris branch nick: trunk timestamp: Fri 2013-08-23 06:17:44 -0400 message: Auto-commit of generated files. diff: === modified file 'autogen/configure' --- autogen/configure 2013-08-21 10:17:37 +0000 +++ autogen/configure 2013-08-23 10:17:44 +0000 @@ -3486,16 +3486,37 @@ -emacs_config_options="$@" -## Add some environment variables, if they were passed via the environment -## rather than on the command-line. -for var in CFLAGS CPPFLAGS LDFLAGS; do - case "$emacs_config_options" in - *$var=*) continue ;; - esac - eval val="\$${var}" - test x"$val" = x && continue - emacs_config_options="${emacs_config_options}${emacs_config_options:+ }$var=\"$val\"" +emacs_config_options= +optsep= +for opt in ${1+"$@"} CFLAGS CPPFLAGS LDFLAGS; do + case $opt in + -n | --no-create | --no-recursion) + continue ;; + CFLAGS | CPPFLAGS | LDFLAGS) + eval 'test "${'$opt'+set}" = set' || continue + case " $*" in + *" $opt="*) continue ;; + esac + eval opt=$opt=\$$opt ;; + esac + + emacs_shell_specials=$IFS\''"#$&()*;<>?[\\`{|~' + case $opt in + *["$emacs_shell_specials"]*) + case $opt in + *\'*) + emacs_quote_apostrophes="s/'/'\\\\''/g" + opt=`$as_echo "$opt" | sed "$emacs_quote_apostrophes"` ;; + esac + opt="'$opt'" + case $opt in + *['"\\']*) + emacs_quote_for_c='s/["\\]/\\&/g; $!s/$/\\n\\/' + opt=`$as_echo "$opt" | sed "$emacs_quote_for_c"` ;; + esac ;; + esac + as_fn_append emacs_config_options "$optsep$opt" + optsep=' ' done ac_config_headers="$ac_config_headers src/config.h:src/config.in" @@ -17173,7 +17194,6 @@ #define EMACS_CONFIGURATION "${canonical}" _ACEOF -emacs_config_options=`echo "$emacs_config_options " | sed -e 's/--no-create //' -e 's/--no-recursion //' -e 's/ *$//' -e "s/\"/'/g" -e 's/\\\\/\\\\\\\\/g'` cat >>confdefs.h <<_ACEOF #define EMACS_CONFIG_OPTIONS "${emacs_config_options}" ------------------------------------------------------------ revno: 113977 committer: martin rudalics branch nick: trunk timestamp: Fri 2013-08-23 08:52:19 +0200 message: In display-buffer-pop-up-frame make BUFFER current (Bug#15133). * window.el (display-buffer-pop-up-frame): Call pop-up-frame-function with BUFFER current so `make-frame' will use it as the new frame's buffer (Bug#15133). diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-22 01:09:08 +0000 +++ lisp/ChangeLog 2013-08-23 06:52:19 +0000 @@ -1,3 +1,9 @@ +2013-08-23 Martin Rudalics + + * window.el (display-buffer-pop-up-frame): Call + pop-up-frame-function with BUFFER current so `make-frame' will + use it as the new frame's buffer (Bug#15133). + 2013-08-22 Stefan Monnier * calendar/timeclock.el: Minor cleanups. === modified file 'lisp/window.el' --- lisp/window.el 2013-08-16 09:44:32 +0000 +++ lisp/window.el 2013-08-23 06:52:19 +0000 @@ -5642,7 +5642,10 @@ (fun pop-up-frame-function) frame window) (when (and fun - (setq frame (funcall fun)) + ;; Make BUFFER current so `make-frame' will use it as the + ;; new frame's buffer (Bug#15133). + (with-current-buffer buffer + (setq frame (funcall fun))) (setq window (frame-selected-window frame))) (prog1 (window--display-buffer buffer window 'frame alist display-buffer-mark-dedicated)