------------------------------------------------------------ revno: 118096 committer: Jan D. branch nick: trunk timestamp: Sun 2014-10-12 10:35:50 +0200 message: Require OSX >= 10.6. Remove PowerPC unexec code. * configure.ac: Require OSX 10.6. Remove NSInteger test, use nsfont for Gnustep, macfont for OSX. * etc/NEWS: OSX required is 10.6 or newer. * src/Makefile.in: Replace nsfont.o macfont.o with ns_fontfile in comment. * src/macfont.h (MAC_FONT_FORMAT_ATTRIBUTE, MAC_FONT_FORMAT_BITMAP) (mac_font_copy_non_synthetic_table): Remove versions for OSX < 10.6 * src/nsfns.m: Always include src/macfont.h on COCOA. (ns_filename_from_panel, ns_directory_from_panel) (Fx_create_frame, Fns_popup_font_panel, ns_run_file_dialog) (Fns_read_file_name, Fns_list_services): Remove code for OSX < 10.6 * src/nsterm.m: Always include src/macfont.h on COCOA. (ns_update_auto_hide_menu_bar, ns_draw_fringe_bitmap) (ns_dumpglyphs_image, ns_check_menu_open) (applicationDidFinishLaunching) (antialiasThresholdDidChange:) (keyDown:, toggleFullScreen:, setPosition:portion:whole:): Remove checks for OSX <= 10.5/10.6. (changeFont:): Use macfont on COCOA, nsfont on GNUSTEP. (syms_of_nsterm): Call syms_of_macfont on COCOA, syms_of_nsfont on GNUSTEP. * src/macfont.m: Remove >= 1050 check. (macfont_create_family_with_symbol) (macfont_get_glyph_for_character) (mac_font_get_glyphs_for_variants) (mac_ctfont_create_available_families, syms_of_macfont): Remove code for OSX < 10.6. (mac_font_family_group, mac_font_family_compare): Remove, only used for OSX < 10.6. * src/nsimage.m (allocInitFromFile:): Remove code for OSX < 10.6. * src/nsmenu.m (NSMenuDidBeginTrackingNotification): Remove. (x_activate_menubar, trackingNotification:): Remove check for OSX >= 10.5. (menuNeedsUpdate:): Remove check for OSX < 10.5. * src/nsterm.h (MAC_OS_X_VERSION_10_4, MAC_OS_X_VERSION_10_5): Remove. (NS_HAVE_NSINTEGER): Remove block. Remove >= OSX 10.6 tests. * src/unexmacosx.c: Remove include ppc/reloc.h. (unrelocate, copy_dysymtab): Remove PPC code. (rebase_reloc_address): Remove, only used for PPC: diff: === modified file 'ChangeLog' --- ChangeLog 2014-10-12 06:09:50 +0000 +++ ChangeLog 2014-10-12 08:35:50 +0000 @@ -1,3 +1,8 @@ +2014-10-12 Jan Djärv + + * configure.ac: Require OSX 10.6. Remove NSInteger test, + use nsfont for Gnustep, macfont for OSX. + 2014-10-12 Paul Eggert Fix putenv race conditions that can crash Emacs (Bug#8705). === modified file 'configure.ac' --- configure.ac 2014-10-12 06:09:50 +0000 +++ configure.ac 2014-10-12 08:35:50 +0000 @@ -1717,12 +1717,14 @@ ns_appbindir=${ns_appdir}/Contents/MacOS ns_appresdir=${ns_appdir}/Contents/Resources ns_appsrc=Cocoa/Emacs.base + ns_fontfile=macfont.o elif test -f $GNUSTEP_CONFIG_FILE; then NS_IMPL_GNUSTEP=yes ns_appdir=`pwd`/nextstep/Emacs.app ns_appbindir=${ns_appdir} ns_appresdir=${ns_appdir}/Resources ns_appsrc=GNUstep/Emacs.base + ns_fontfile=nsfont.o dnl FIXME sourcing this several times in subshells seems inefficient. GNUSTEP_SYSTEM_HEADERS="$(. $GNUSTEP_CONFIG_FILE; echo $GNUSTEP_SYSTEM_HEADERS)" GNUSTEP_SYSTEM_LIBRARIES="$(. $GNUSTEP_CONFIG_FILE; echo $GNUSTEP_SYSTEM_LIBRARIES)" @@ -1765,48 +1767,24 @@ macfont_file="" if test "${NS_IMPL_COCOA}" = "yes"; then - AC_MSG_CHECKING([for OSX 10.4 or newer]) + AC_MSG_CHECKING([for OSX 10.6 or newer]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [ #ifdef MAC_OS_X_VERSION_MAX_ALLOWED -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 ; /* OK */ #else - error "OSX 10.4 or newer required"; + error "OSX 10.6 or newer required"; #endif #endif ])], - ns_osx_have_104=yes, - ns_osx_have_104=no) - AC_MSG_RESULT([$ns_osx_have_104]) + ns_osx_have_106=yes, + ns_osx_have_106=no) + AC_MSG_RESULT([$ns_osx_have_106]) - if test $ns_osx_have_104 = no; then - AC_MSG_ERROR([`OSX 10.4 or newer is required']); - fi - AC_MSG_CHECKING([for OSX 10.5 or newer]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], - [ -#ifdef MAC_OS_X_VERSION_MAX_ALLOWED -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 - ; /* OK */ -#else - error "OSX 10.5 not found"; -#endif -#endif - ])], - ns_osx_have_105=yes, - ns_osx_have_105=no) - AC_MSG_RESULT([$ns_osx_have_105]) - if test $ns_osx_have_105 = yes; then - macfont_file="macfont.o" - fi - fi - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], - [NSInteger i;])], - ns_have_nsinteger=yes, - ns_have_nsinteger=no) - if test $ns_have_nsinteger = yes; then - AC_DEFINE(NS_HAVE_NSINTEGER, 1, [Define to 1 if `NSInteger' is defined.]) + if test $ns_osx_have_106 = no; then + AC_MSG_ERROR([`OSX 10.6 or newer is required']); + fi fi fi @@ -1840,7 +1818,7 @@ INSTALL_ARCH_INDEP_EXTRA= fi - NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o $macfont_file" + NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o $ns_fontfile" fi CFLAGS="$tmp_CFLAGS" CPPFLAGS="$tmp_CPPFLAGS" === modified file 'etc/ChangeLog' --- etc/ChangeLog 2014-10-09 01:52:47 +0000 +++ etc/ChangeLog 2014-10-12 08:35:50 +0000 @@ -1,3 +1,7 @@ +2014-10-12 Jan Djärv + + * NEWS: OSX required is 10.6 or newer. + 2014-10-09 Leo Liu * NEWS: Mention optional arg to terpri and new cl-lib functions. === modified file 'etc/NEWS' --- etc/NEWS 2014-10-11 02:54:11 +0000 +++ etc/NEWS 2014-10-12 08:35:50 +0000 @@ -36,6 +36,9 @@ undumping code to GCC under IRIX, or by configuring --with-wide-int, or by sticking with Emacs 24.4. +** Building Emacs on OSX now requires 10.6 or newer. +That also means that PowerPC is not supported. + --- ** The configure option `--with-pkg-config-prog' has been removed. Use './configure PKG_CONFIG=/full/name/of/pkg-config' if you need to. === modified file 'src/ChangeLog' --- src/ChangeLog 2014-10-12 06:09:50 +0000 +++ src/ChangeLog 2014-10-12 08:35:50 +0000 @@ -1,3 +1,51 @@ +2014-10-12 Jan Djärv + + * unexmacosx.c: Remove include ppc/reloc.h. + (unrelocate, copy_dysymtab): Remove PPC code. + (rebase_reloc_address): Remove, only used for PPC: + + * nsterm.m: Always include macfont.h on COCOA. + (ns_update_auto_hide_menu_bar, ns_draw_fringe_bitmap) + (ns_dumpglyphs_image, ns_check_menu_open) + (applicationDidFinishLaunching) + (antialiasThresholdDidChange:) + (keyDown:, toggleFullScreen:, setPosition:portion:whole:): Remove + checks for OSX <= 10.5/10.6. + (changeFont:): Use macfont on COCOA, nsfont on GNUSTEP. + (syms_of_nsterm): Call syms_of_macfont on COCOA, syms_of_nsfont on + GNUSTEP. + + * nsterm.h (MAC_OS_X_VERSION_10_4, MAC_OS_X_VERSION_10_5): Remove. + (NS_HAVE_NSINTEGER): Remove block. + Remove >= OSX 10.6 tests. + + * nsmenu.m (NSMenuDidBeginTrackingNotification): Remove. + (x_activate_menubar, trackingNotification:): Remove check for + OSX >= 10.5. + (menuNeedsUpdate:): Remove check for OSX < 10.5. + + * nsimage.m (allocInitFromFile:): Remove code for OSX < 10.6. + + * nsfns.m: Always include macfont.h on COCOA. + (ns_filename_from_panel, ns_directory_from_panel) + (Fx_create_frame, Fns_popup_font_panel, ns_run_file_dialog) + (Fns_read_file_name, Fns_list_services): Remove code for OSX < 10.6 + + * macfont.m: Remove >= 1050 check. + (macfont_create_family_with_symbol) + (macfont_get_glyph_for_character) + (mac_font_get_glyphs_for_variants) + (mac_ctfont_create_available_families, syms_of_macfont): Remove + code for OSX < 10.6. + (mac_font_family_group, mac_font_family_compare): Remove, only used + for OSX < 10.6. + + * macfont.h (MAC_FONT_FORMAT_ATTRIBUTE, MAC_FONT_FORMAT_BITMAP) + (mac_font_copy_non_synthetic_table): Remove versions for OSX < 10.6 + + * Makefile.in: Replace nsfont.o macfont.o with ns_fontfile in + comment. + 2014-10-12 Paul Eggert Fix putenv race conditions with undefined behavior (Bug#8705). === modified file 'src/Makefile.in' --- src/Makefile.in 2014-10-07 20:17:09 +0000 +++ src/Makefile.in 2014-10-12 08:35:50 +0000 @@ -250,7 +250,7 @@ MSDOS_X_OBJ = NS_OBJ=@NS_OBJ@ -## nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macfont.o if HAVE_NS. +## nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o ns_fontfile if HAVE_NS. NS_OBJC_OBJ=@NS_OBJC_OBJ@ ## Only set if NS_IMPL_GNUSTEP. GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@ === modified file 'src/macfont.h' --- src/macfont.h 2014-07-20 13:18:47 +0000 +++ src/macfont.h 2014-10-12 08:35:50 +0000 @@ -57,11 +57,7 @@ #define MAC_FONT_CASCADE_LIST_ATTRIBUTE kCTFontCascadeListAttribute #define MAC_FONT_CHARACTER_SET_ATTRIBUTE kCTFontCharacterSetAttribute #define MAC_FONT_LANGUAGES_ATTRIBUTE kCTFontLanguagesAttribute -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 #define MAC_FONT_FORMAT_ATTRIBUTE kCTFontFormatAttribute -#else -#define MAC_FONT_FORMAT_ATTRIBUTE (CFSTR ("NSCTFontFormatAttribute")) -#endif #define MAC_FONT_SYMBOLIC_TRAIT kCTFontSymbolicTrait #define MAC_FONT_WEIGHT_TRAIT kCTFontWeightTrait #define MAC_FONT_WIDTH_TRAIT kCTFontWidthTrait @@ -79,11 +75,7 @@ }; enum { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 MAC_FONT_FORMAT_BITMAP = kCTFontFormatBitmap -#else - MAC_FONT_FORMAT_BITMAP = 5 -#endif }; enum { @@ -112,13 +104,8 @@ #define mac_font_get_underline_position CTFontGetUnderlinePosition #define mac_font_get_underline_thickness CTFontGetUnderlineThickness #define mac_font_copy_graphics_font(font) CTFontCopyGraphicsFont (font, NULL) -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 #define mac_font_copy_non_synthetic_table(font, table) \ CTFontCopyTable (font, table, kCTFontTableOptionNoOptions) -#else -#define mac_font_copy_non_synthetic_table(font, table) \ - CTFontCopyTable (font, table, kCTFontTableOptionExcludeSynthetic) -#endif #define mac_font_create_preferred_family_for_attributes \ mac_ctfont_create_preferred_family_for_attributes === modified file 'src/macfont.m' --- src/macfont.m 2014-10-05 11:34:59 +0000 +++ src/macfont.m 2014-10-12 08:35:50 +0000 @@ -36,8 +36,6 @@ #include "macfont.h" #include "macuvs.h" -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 - #include static struct font_driver macfont_driver; @@ -926,22 +924,9 @@ if (family_name == NULL) return NULL; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (CTFontManagerCompareFontFamilyNames != NULL) -#endif { family_name_comparator = CTFontManagerCompareFontFamilyNames; } -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - else /* CTFontManagerCompareFontFamilyNames == NULL */ -#endif -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 */ -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - { - family_name_comparator = mac_font_family_compare; - } -#endif if ((*family_name_comparator) (family_name, CFSTR ("LastResort"), NULL) == kCFCompareEqualTo) @@ -1331,12 +1316,8 @@ CGGlyph *glyphs; int i, len; int nrows; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 dispatch_queue_t queue; dispatch_group_t group = NULL; -#else - int nkeys; -#endif if (row != 0) { @@ -1374,14 +1355,12 @@ return glyph; } -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); group = dispatch_group_create (); dispatch_group_async (group, queue, ^{ int nkeys; uintptr_t key; -#endif nkeys = nkeys_or_perm; for (key = row * (256 / NGLYPHS_IN_VALUE); ; key++) if (CFDictionaryContainsKey (dictionary, @@ -1392,9 +1371,7 @@ if (--nkeys == 0) break; } -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 }); -#endif } len = 0; @@ -1436,13 +1413,11 @@ cache->glyph.matrix[nrows - 1] = glyphs; cache->glyph.nrows = nrows; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 if (group) { dispatch_group_wait (group, DISPATCH_TIME_FOREVER); dispatch_release (group); } -#endif } return cache->glyph.matrix[nkeys_or_perm - ROW_PERM_OFFSET][c % 256]; @@ -3165,11 +3140,9 @@ struct variation_selector_record *records = uvs->variation_selector_records; CFIndex i; UInt32 ir, nrecords; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 dispatch_queue_t queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create (); -#endif nrecords = BUINT32_VALUE (uvs->num_var_selector_records); i = 0; @@ -3193,9 +3166,7 @@ default_uvs_offset = BUINT32_VALUE (records[ir].default_uvs_offset); non_default_uvs_offset = BUINT32_VALUE (records[ir].non_default_uvs_offset); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 dispatch_group_async (group, queue, ^{ -#endif glyphs[i] = kCGFontIndexInvalid; if (default_uvs_offset) @@ -3247,18 +3218,14 @@ BUINT24_VALUE (mappings[hi - 1].unicode_value) == c) glyphs[i] = BUINT16_VALUE (mappings[hi - 1].glyph_id); } -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 }); -#endif i++; ir++; } while (i < count) glyphs[i++] = kCGFontIndexInvalid; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 dispatch_group_wait (group, DISPATCH_TIME_FOREVER); dispatch_release (group); -#endif } static int @@ -3460,10 +3427,6 @@ { CFMutableArrayRef families = NULL; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (CTFontManagerCopyAvailableFontFamilyNames != NULL) -#endif { CFArrayRef orig_families = CTFontManagerCopyAvailableFontFamilyNames (); @@ -3487,56 +3450,8 @@ CFRelease (orig_families); } } -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - else /* CTFontManagerCopyAvailableFontFamilyNames == NULL */ -#endif -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 */ -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - { - CTFontCollectionRef collection; - CFArrayRef descs = NULL; - - collection = CTFontCollectionCreateFromAvailableFonts (NULL); - if (collection) - { - descs = CTFontCollectionCreateMatchingFontDescriptors (collection); - CFRelease (collection); - } - if (descs) - { - CFIndex i, count = CFArrayGetCount (descs); - - families = CFArrayCreateMutable (NULL, count, &kCFTypeArrayCallBacks); - if (families) - for (i = 0; i < count; i++) - { - FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, i); - CFStringRef name = - mac_font_descriptor_copy_attribute (desc, - MAC_FONT_FAMILY_NAME_ATTRIBUTE); - - if (name) - { - CFIndex p, limit = CFArrayGetCount (families); - - p = CFArrayBSearchValues (families, CFRangeMake (0, limit), - (const void *) name, - mac_font_family_compare, NULL); - if (p >= limit) - CFArrayAppendValue (families, name); - else if (mac_font_family_compare - (CFArrayGetValueAtIndex (families, p), - name, NULL) != kCFCompareEqualTo) - CFArrayInsertValueAtIndex (families, p, name); - CFRelease (name); - } - } - CFRelease (descs); - } - } -#endif - - return families; + + return families; } static Boolean @@ -3855,41 +3770,6 @@ } #endif -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -static inline int -mac_font_family_group (CFStringRef family) -{ - if (CFStringHasPrefix (family, CFSTR ("#"))) - return 2; - else - { - CFRange range; - - range = CFStringFind (family, CFSTR ("Apple"), - kCFCompareCaseInsensitive | kCFCompareAnchored); - if (range.location != kCFNotFound) - return 1; - - return 0; - } -} - -static CFComparisonResult -mac_font_family_compare (const void *val1, const void *val2, void *context) -{ - CFStringRef family1 = (CFStringRef) val1, family2 = (CFStringRef) val2; - int group1, group2; - - group1 = mac_font_family_group (family1); - group2 = mac_font_family_group (family2); - if (group1 < group2) - return kCFCompareLessThan; - if (group1 > group2) - return kCFCompareGreaterThan; - return CFStringCompare (family1, family2, kCFCompareCaseInsensitive); -} -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ - static CFArrayRef mac_font_copy_default_descriptors_for_language (CFStringRef language) { @@ -4040,13 +3920,10 @@ register_font_driver (&macfont_driver, f); } -#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 - void syms_of_macfont (void) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 static struct font_driver mac_font_driver; DEFSYM (Qmac_ct, "mac-ct"); @@ -4055,5 +3932,4 @@ DEFSYM (QCdestination, ":destination"); DEFSYM (QCminspace, ":minspace"); -#endif } === modified file 'src/nsfns.m' --- src/nsfns.m 2014-09-03 15:10:29 +0000 +++ src/nsfns.m 2014-10-12 08:35:50 +0000 @@ -46,10 +46,8 @@ #ifdef NS_IMPL_COCOA #include -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 #include "macfont.h" #endif -#endif #if 0 int fns_trace_num = 1; @@ -197,7 +195,7 @@ static NSString * ns_filename_from_panel (NSSavePanel *panel) { -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA NSURL *url = [panel URL]; NSString *str = [url path]; return str; @@ -209,7 +207,7 @@ static NSString * ns_directory_from_panel (NSSavePanel *panel) { -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA NSURL *url = [panel directoryURL]; NSString *str = [url path]; return str; @@ -1197,13 +1195,10 @@ block_input (); #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - if (CTGetCoreTextVersion != NULL - && CTGetCoreTextVersion () >= kCTVersionNumber10_5) mac_register_font_driver (f); -#endif -#endif - register_font_driver (&nsfont_driver, f); +#else + register_font_driver (&nsfont_driver, f); +#endif x_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); @@ -1414,13 +1409,11 @@ id fm = [NSFontManager sharedFontManager]; struct font *font = f->output_data.ns->font; NSFont *nsfont; - if (EQ (font->driver->type, Qns)) - nsfont = ((struct nsfont_info *)font)->nsfont; +#ifdef NS_IMPL_GNUSTEP + nsfont = ((struct nsfont_info *)font)->nsfont; +#endif #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - else - nsfont = (NSFont *) macfont_get_nsctfont (font); -#endif + nsfont = (NSFont *) macfont_get_nsctfont (font); #endif [fm setSelectedFont: nsfont isMultiple: NO]; [fm orderFrontFontPanel: NSApp]; @@ -1442,8 +1435,7 @@ { id panel; BOOL ret; -#if ! defined (NS_IMPL_COCOA) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_GNUSTEP NSString *dirS, *initS; BOOL no_types; #endif @@ -1453,8 +1445,7 @@ ns_run_file_dialog (void) { if (ns_fd_data.panel == nil) return; -#if defined (NS_IMPL_COCOA) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA ns_fd_data.ret = [ns_fd_data.panel runModal]; #else if (ns_fd_data.no_types) @@ -1534,8 +1525,7 @@ block_input (); ns_fd_data.panel = panel; ns_fd_data.ret = NO; -#if defined (NS_IMPL_COCOA) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA if (! NILP (mustmatch) || ! NILP (dir_only_p)) [panel setAllowedFileTypes: nil]; if (dirS) [panel setDirectoryURL: [NSURL fileURLWithPath: dirS]]; @@ -1995,7 +1985,7 @@ doc: /* List available Nextstep services by querying NSApp. */) (void) { -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA /* You can't get services like this in 10.6+. */ return Qnil; #else === modified file 'src/nsimage.m' --- src/nsimage.m 2014-01-01 07:43:34 +0000 +++ src/nsimage.m 2014-10-12 08:35:50 +0000 @@ -188,7 +188,7 @@ image = [[EmacsImage alloc] initByReferencingFile: [NSString stringWithUTF8String: SSDATA (found)]]; -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA imgRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]]; #else imgRep = [image bestRepresentationForDevice: nil]; === modified file 'src/nsmenu.m' --- src/nsmenu.m 2014-06-30 12:38:09 +0000 +++ src/nsmenu.m 2014-10-12 08:35:50 +0000 @@ -492,11 +492,9 @@ x_activate_menubar (struct frame *f) { #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 ns_update_menubar (f, true, nil); ns_check_pending_open_menu (); #endif -#endif } @@ -542,23 +540,14 @@ } #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 -extern NSString *NSMenuDidBeginTrackingNotification; -#endif -#endif - -#ifdef NS_IMPL_COCOA -(void)trackingNotification:(NSNotification *)notification { /* Update menu in menuNeedsUpdate only while tracking menus. */ trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification ? 1 : 0); -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (! trackingMenu) ns_check_menu_open (nil); -#endif } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - (void)menuWillOpen:(NSMenu *)menu { ++trackingMenu; @@ -579,7 +568,6 @@ { --trackingMenu; } -#endif /* OSX >= 10.5 */ #endif /* NS_IMPL_COCOA */ @@ -608,8 +596,7 @@ if (trackingMenu == 0) return; /*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ -#if (! defined (NS_IMPL_COCOA) \ - || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5) +#ifdef NS_IMPL_GNUSTEP /* Don't know how to do this for anything other than OSX >= 10.5 This is wrong, as it might run Lisp code in the event loop. */ ns_update_menubar (frame, true, self); === modified file 'src/nsterm.h' --- src/nsterm.h 2014-09-24 07:17:51 +0000 +++ src/nsterm.h 2014-10-12 08:35:50 +0000 @@ -27,12 +27,6 @@ #ifdef HAVE_NS #ifdef NS_IMPL_COCOA -#ifndef MAC_OS_X_VERSION_10_4 -#define MAC_OS_X_VERSION_10_4 1040 -#endif -#ifndef MAC_OS_X_VERSION_10_5 -#define MAC_OS_X_VERSION_10_5 1050 -#endif #ifndef MAC_OS_X_VERSION_10_6 #define MAC_OS_X_VERSION_10_6 1060 #endif @@ -58,21 +52,7 @@ versions. On Cocoa >= 10.5, functions expect CGFloat*. Make compatible type. */ #ifdef NS_IMPL_COCOA - -#ifndef NS_HAVE_NSINTEGER -#if defined (__LP64__) && __LP64__ -typedef double CGFloat; -typedef long NSInteger; -typedef unsigned long NSUInteger; -#else -typedef float CGFloat; -typedef int NSInteger; -typedef unsigned int NSUInteger; -#endif /* not LP64 */ -#endif /* not NS_HAVE_NSINTEGER */ - typedef CGFloat EmacsCGFloat; - #elif GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION >= 22 typedef CGFloat EmacsCGFloat; #else @@ -139,7 +119,7 @@ @class EmacsToolbar; -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA @interface EmacsView : NSView #else @interface EmacsView : NSView @@ -217,7 +197,7 @@ ========================================================================== */ -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA @interface EmacsMenu : NSMenu #else @interface EmacsMenu : NSMenu @@ -249,7 +229,7 @@ @class EmacsImage; -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA @interface EmacsToolbar : NSToolbar #else @interface EmacsToolbar : NSToolbar @@ -305,7 +285,7 @@ - (void)timeout_handler: (NSTimer *)timedEntry; @end -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA @interface EmacsTooltip : NSObject #else @interface EmacsTooltip : NSObject === modified file 'src/nsterm.m' --- src/nsterm.m 2014-10-05 18:03:42 +0000 +++ src/nsterm.m 2014-10-12 08:35:50 +0000 @@ -65,10 +65,8 @@ #endif #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 #include "macfont.h" #endif -#endif /* call tracing */ #if 0 @@ -706,7 +704,6 @@ ns_update_auto_hide_menu_bar (void) { #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 block_input (); NSTRACE (ns_update_auto_hide_menu_bar); @@ -739,7 +736,6 @@ unblock_input (); #endif -#endif } @@ -2358,7 +2354,7 @@ [img setXBMColor: bm_color]; } -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA [img drawInRect: r fromRect: NSZeroRect operation: NSCompositeSourceOver @@ -3037,7 +3033,7 @@ /* Draw the image.. do we need to draw placeholder if img ==nil? */ if (img != nil) { -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA NSRect dr = NSMakeRect (x, y, s->slice.width, s->slice.height); NSRect ir = NSMakeRect (s->slice.x, s->slice.y, s->slice.width, s->slice.height); @@ -3450,8 +3446,7 @@ #endif /* GNUstep and OSX <= 10.4 does not have cancelTracking. */ -#if defined (NS_IMPL_COCOA) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#ifdef NS_IMPL_COCOA /* Check if menu open should be canceled or continued as normal. */ void ns_check_menu_open (NSMenu *menu) @@ -3514,7 +3509,7 @@ menu_will_open_state = MENU_OPENING; } } -#endif /* NS_IMPL_COCOA) && >= MAC_OS_X_VERSION_10_5 */ +#endif /* NS_IMPL_COCOA */ static void unwind_apploopnr (Lisp_Object not_used) @@ -4720,14 +4715,12 @@ [self antialiasThresholdDidChange:nil]; #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(antialiasThresholdDidChange:) name:NSAntialiasThresholdChangedNotification object:nil]; #endif -#endif ns_send_appdefined (-2); } @@ -4735,10 +4728,8 @@ - (void)antialiasThresholdDidChange:(NSNotification *)notification { #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 macfont_update_antialias_threshold (); #endif -#endif } @@ -5078,13 +5069,11 @@ if (!emacs_event) return; - if (EQ (font->driver->type, Qns)) - nsfont = ((struct nsfont_info *)font)->nsfont; +#ifdef NS_IMPL_GNUSTEP + nsfont = ((struct nsfont_info *)font)->nsfont; +#endif #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - else - nsfont = (NSFont *) macfont_get_nsctfont (font); -#endif + nsfont = (NSFont *) macfont_get_nsctfont (font); #endif if ((newFont = [sender convertFont: nsfont])) @@ -5136,7 +5125,7 @@ int code; unsigned fnKeysym = 0; static NSMutableArray *nsEvArray; -#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_GNUSTEP static BOOL firstTime = YES; #endif int left_is_none; @@ -5367,7 +5356,7 @@ } -#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_GNUSTEP /* if we get here we should send the key for input manager processing */ /* Disable warning, there is nothing a user can do about it anyway, and it does not seem to matter. */ @@ -6509,8 +6498,7 @@ /* Hide dock and menubar if we are on the primary screen. */ if (onFirstScreen) { -#if defined (NS_IMPL_COCOA) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA NSApplicationPresentationOptions options = NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar; @@ -6562,8 +6550,7 @@ if (onFirstScreen) { -#if defined (NS_IMPL_COCOA) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#ifdef NS_IMPL_COCOA [NSApp setPresentationOptions: NSApplicationPresentationDefault]; #else [NSMenu setMenuBarVisible:YES]; @@ -7285,7 +7272,7 @@ if (portion >= whole) { -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 +#ifdef NS_IMPL_COCOA [self setKnobProportion: 1.0]; [self setDoubleValue: 1.0]; #else @@ -7299,7 +7286,7 @@ portion = max ((float)whole*min_portion/pixel_height, portion); pos = (float)position / (whole - portion); por = (CGFloat)portion/whole; -#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 +#ifdef NS_IMPL_COCOA [self setKnobProportion: por]; [self setDoubleValue: pos]; #else @@ -7829,14 +7816,12 @@ DEFSYM (Qcocoa, "cocoa"); DEFSYM (Qgnustep, "gnustep"); - syms_of_nsfont (); #ifdef NS_IMPL_COCOA Fprovide (Qcocoa, Qnil); -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 syms_of_macfont (); -#endif #else Fprovide (Qgnustep, Qnil); + syms_of_nsfont (); #endif } === modified file 'src/unexmacosx.c' --- src/unexmacosx.c 2014-09-22 19:20:45 +0000 +++ src/unexmacosx.c 2014-10-12 08:35:50 +0000 @@ -107,9 +107,6 @@ #include #include #include -#if defined (__ppc__) -#include -#endif #ifdef HAVE_MALLOC_MALLOC_H #include #else @@ -1033,17 +1030,8 @@ name, i, reloc_info.r_type); } else - switch (sc_reloc_info->r_type) - { -#if defined (__ppc__) - case PPC_RELOC_PB_LA_PTR: - /* nothing to do for prebound lazy pointer */ - break; -#endif - default: - unexec_error ("unrelocate: %s:%d cannot handle scattered type = %d", - name, i, sc_reloc_info->r_type); - } + unexec_error ("unrelocate: %s:%d cannot handle scattered type = %d", + name, i, sc_reloc_info->r_type); } if (nrel > 0) @@ -1051,35 +1039,6 @@ unreloc_count, nrel, name); } -#if __ppc64__ -/* Rebase r_address in the relocation table. */ -static void -rebase_reloc_address (off_t reloff, int nrel, long linkedit_delta, long diff) -{ - int i; - struct relocation_info reloc_info; - struct scattered_relocation_info *sc_reloc_info - = (struct scattered_relocation_info *) &reloc_info; - - for (i = 0; i < nrel; i++, reloff += sizeof (reloc_info)) - { - if (lseek (infd, reloff - linkedit_delta, L_SET) - != reloff - linkedit_delta) - unexec_error ("rebase_reloc_table: cannot seek to reloc_info"); - if (!unexec_read (&reloc_info, sizeof (reloc_info))) - unexec_error ("rebase_reloc_table: cannot read reloc_info"); - - if (sc_reloc_info->r_scattered == 0 - && reloc_info.r_type == GENERIC_RELOC_VANILLA) - { - reloc_info.r_address -= diff; - if (!unexec_write (reloff, &reloc_info, sizeof (reloc_info))) - unexec_error ("rebase_reloc_table: cannot write reloc_info"); - } - } -} -#endif - /* Copy a LC_DYSYMTAB load command from the input file to the output file, adjusting the file offset fields. */ static void @@ -1089,28 +1048,8 @@ vm_address_t base; #ifdef _LP64 -#if __ppc64__ - { - int i; - - base = 0; - for (i = 0; i < nlc; i++) - if (lca[i]->cmd == LC_SEGMENT) - { - struct segment_command *scp = (struct segment_command *) lca[i]; - - if (scp->vmaddr + scp->vmsize > 0x100000000 - && (scp->initprot & VM_PROT_WRITE) != 0) - { - base = data_segment_scp->vmaddr; - break; - } - } - } -#else /* First writable segment address. */ base = data_segment_scp->vmaddr; -#endif #else /* First segment address in the file (unless MH_SPLIT_SEGS set). */ base = 0; @@ -1136,29 +1075,6 @@ unexec_error ("cannot write symtab command to header"); curr_header_offset += lc->cmdsize; - -#if __ppc64__ - /* Check if the relocation base needs to be changed. */ - if (base == 0) - { - vm_address_t newbase = 0; - int i; - - for (i = 0; i < num_unexec_regions; i++) - if (unexec_regions[i].range.address + unexec_regions[i].range.size - > 0x100000000) - { - newbase = data_segment_scp->vmaddr; - break; - } - - if (newbase) - { - rebase_reloc_address (dstp->locreloff, dstp->nlocrel, delta, newbase); - rebase_reloc_address (dstp->extreloff, dstp->nextrel, delta, newbase); - } - } -#endif } /* Copy a LC_TWOLEVEL_HINTS load command from the input file to the output ------------------------------------------------------------ revno: 118095 fixes bug: http://debbugs.gnu.org/8705 committer: Paul Eggert branch nick: trunk timestamp: Sat 2014-10-11 23:09:50 -0700 message: Fix putenv race conditions with undefined behavior. Do all putenv calls before Emacs creates any threads. Use a safer way to modify the TZ environment variable in the presence of multiple threads. For further thread-safety, prefer localtime_r and gmtime_r to localtime and gmtime, and prefer struct tm's tm_gmtoff (if available) to calling both localtime_r and gmtime_r. * configure.ac (LOCALTIME_CACHE): Remove. We needn't worry about SunOS 4 any more; Sun dropped support in 2003. All uses of LOCALTIME_CACHE removed. This simplifies the fix. (tzalloc): Add check for this function. * admin/merge-gnulib (GNULIB_MODULES): Add time_r, since Emacs now calls localtime_r and gmtime_r directly. * src/dbusbind.c (Fdbus__init_bus): Move xputenv call from here ... (init_dbusbind): ... to this new function. * src/emacs.c (main) [HAVE_DBUS]: Call it before creating threads. * src/xterm.c (x_term_init): Move xputenv call from here ... (init_xterm): ... to this new function. * src/emacs.c (main) [USE_GTK]: Call it before creating threads. * src/editfns.c (HAVE_TM_GMTOFF): Default to false. (dump_tz_string): New constant. (init_editfns): Use it. This centralizes the dump_tz stuff. Call set_time_zone_rule here, so that its xputenv is done before Emacs goes multithreaded. (mktime_z) [!HAVE_TZALLOC]: New function, which is typically thread-safe enough for Emacs. (format_time_string, Fdecode_time, Fcurrent_time_string) (Fcurrent_time_zone): Prefer localtime_r and gmtime_r, which are more thread-safe, to localtime and gmtime. Remove now-unnecessary calls to block_input. (tm_gmtoff): New static function. (Fdecode_time, Fcurrent_time_zone): Use it. (Fencode_time): Use mktime_z, for better thread-safety. (set_time_zone_rule): Now static. Rewrite to be mostly thread-safe, i.e., not quite thread-safe but good enough for Emacs typical usage. Do not reclaim storage that is in the environment; let it leak. Always call tzset, since localtime_r does not. * src/emacs.c (dump_tz, Fdump_emacs) [HAVE_TZSET]: Remove dump_tz stuff. This is now done in init_editfns. * src/systime.h (mktime_z, timezone_t, tzalloc, tzfree) [!HAVE_TZALLOC]: New macros and declarations, for platforms lacking tzalloc & friends. diff: === modified file 'ChangeLog' --- ChangeLog 2014-10-06 06:21:13 +0000 +++ ChangeLog 2014-10-12 06:09:50 +0000 @@ -1,3 +1,11 @@ +2014-10-12 Paul Eggert + + Fix putenv race conditions that can crash Emacs (Bug#8705). + * configure.ac (LOCALTIME_CACHE): Remove. + We needn't worry about SunOS 4 any more; Sun dropped support in 2003. + All uses of LOCALTIME_CACHE removed. This simplifies the fix. + (tzalloc): Add check for this function. + 2014-10-06 Jan Djärv * configure.ac: Add -Wno-string-plus-int for clang. === modified file 'admin/CPP-DEFINES' --- admin/CPP-DEFINES 2014-04-16 15:16:35 +0000 +++ admin/CPP-DEFINES 2014-10-12 06:09:50 +0000 @@ -368,7 +368,6 @@ INTERNAL_TERMINAL IS_ANY_SEP IS_DIRECTORY_SEP -LOCALTIME_CACHE MAIL_USE_FLOCK MAIL_USE_LOCKF MAIL_USE_POP === modified file 'admin/ChangeLog' --- admin/ChangeLog 2014-10-07 20:17:09 +0000 +++ admin/ChangeLog 2014-10-12 06:09:50 +0000 @@ -1,3 +1,9 @@ +2014-10-12 Paul Eggert + + Fix putenv race conditions with undefined behavior (Bug#8705). + * merge-gnulib (GNULIB_MODULES): Add time_r, since Emacs now + calls localtime_r and gmtime_r directly. + 2014-10-07 Glenn Morris * unidata/Makefile.in: Check for deleted uni- files. (Bug#18489) === modified file 'admin/merge-gnulib' --- admin/merge-gnulib 2014-08-30 22:59:39 +0000 +++ admin/merge-gnulib 2014-10-12 06:09:50 +0000 @@ -37,7 +37,7 @@ pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdio strftime strtoimax strtoumax symlink sys_stat - sys_time time timer-time timespec-add timespec-sub + sys_time time time_r timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings ' === modified file 'configure.ac' --- configure.ac 2014-10-06 06:21:13 +0000 +++ configure.ac 2014-10-12 06:09:50 +0000 @@ -3915,43 +3915,7 @@ AC_CHECK_HEADERS(valgrind/valgrind.h) -AC_CHECK_FUNCS_ONCE(tzset) -AC_MSG_CHECKING(whether localtime caches TZ) -AC_CACHE_VAL(emacs_cv_localtime_cache, -[if test x$ac_cv_func_tzset = xyes; then -AC_RUN_IFELSE([AC_LANG_SOURCE([[#include -char TZ_GMT0[] = "TZ=GMT0"; -char TZ_PST8[] = "TZ=PST8"; -main() -{ - time_t now = time ((time_t *) 0); - int hour_GMT0, hour_unset; - if (putenv (TZ_GMT0) != 0) - exit (1); - hour_GMT0 = localtime (&now)->tm_hour; - unsetenv("TZ"); - hour_unset = localtime (&now)->tm_hour; - if (putenv (TZ_PST8) != 0) - exit (1); - if (localtime (&now)->tm_hour == hour_GMT0) - exit (1); - unsetenv("TZ"); - if (localtime (&now)->tm_hour != hour_unset) - exit (1); - exit (0); -}]])], emacs_cv_localtime_cache=no, emacs_cv_localtime_cache=yes, -[# If we have tzset, assume the worst when cross-compiling. -emacs_cv_localtime_cache=yes]) -else - # If we lack tzset, report that localtime does not cache TZ, - # since we can't invalidate the cache if we don't have tzset. - emacs_cv_localtime_cache=no -fi])dnl -AC_MSG_RESULT($emacs_cv_localtime_cache) -if test $emacs_cv_localtime_cache = yes; then - AC_DEFINE(LOCALTIME_CACHE, 1, - [Define to 1 if localtime caches TZ.]) -fi +AC_CHECK_FUNCS_ONCE(tzalloc tzset) ok_so_far=yes AC_CHECK_FUNC(socket, , ok_so_far=no) === modified file 'src/ChangeLog' --- src/ChangeLog 2014-10-11 08:22:00 +0000 +++ src/ChangeLog 2014-10-12 06:09:50 +0000 @@ -1,3 +1,41 @@ +2014-10-12 Paul Eggert + + Fix putenv race conditions with undefined behavior (Bug#8705). + Do all putenv calls before Emacs creates any threads. + Use a safer way to modify the TZ environment variable in the + presence of multiple threads. For further thread-safety, + prefer localtime_r and gmtime_r to localtime and gmtime, + and prefer struct tm's tm_gmtoff (if available) to calling + both localtime_r and gmtime_r. + * dbusbind.c (Fdbus__init_bus): Move xputenv call from here ... + (init_dbusbind): ... to this new function. + * emacs.c (main) [HAVE_DBUS]: Call it before creating threads. + * xterm.c (x_term_init): Move xputenv call from here ... + (init_xterm): ... to this new function. + * emacs.c (main) [USE_GTK]: Call it before creating threads. + * editfns.c (HAVE_TM_GMTOFF): Default to false. + (dump_tz_string): New constant. + (init_editfns): Use it. This centralizes the dump_tz stuff. + Call set_time_zone_rule here, so that its xputenv is done + before Emacs goes multithreaded. + (mktime_z) [!HAVE_TZALLOC]: New function, which is typically + thread-safe enough for Emacs. + (format_time_string, Fdecode_time, Fcurrent_time_string) + (Fcurrent_time_zone): + Prefer localtime_r and gmtime_r, which are more thread-safe, to + localtime and gmtime. Remove now-unnecessary calls to block_input. + (tm_gmtoff): New static function. + (Fdecode_time, Fcurrent_time_zone): Use it. + (Fencode_time): Use mktime_z, for better thread-safety. + (set_time_zone_rule): Now static. Rewrite to be mostly thread-safe, + i.e., not quite thread-safe but good enough for Emacs typical usage. + Do not reclaim storage that is in the environment; let it leak. + Always call tzset, since localtime_r does not. + * emacs.c (dump_tz, Fdump_emacs) [HAVE_TZSET]: Remove dump_tz stuff. + This is now done in init_editfns. + * systime.h (mktime_z, timezone_t, tzalloc, tzfree) [!HAVE_TZALLOC]: + New macros and declarations, for platforms lacking tzalloc & friends. + 2014-10-09 Paul Eggert * lisp.h (USE_STACK_STRING): Now true only if USE_STACK CONS. === modified file 'src/dbusbind.c' --- src/dbusbind.c 2014-09-23 17:03:48 +0000 +++ src/dbusbind.c 2014-10-12 06:09:50 +0000 @@ -1054,6 +1054,7 @@ /* Unset session environment. */ #if 0 + /* This is buggy, since unsetenv is not thread-safe. */ if (XSYMBOL (QCdbus_session_bus) == data) { XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS"); @@ -1219,9 +1220,6 @@ XSETFASTINT (val, (intptr_t) connection); xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses); - /* We do not want to abort. */ - xputenv ("DBUS_FATAL_WARNINGS=0"); - /* Cleanup. */ dbus_error_free (&derror); } @@ -1738,6 +1736,13 @@ void +init_dbusbind (void) +{ + /* We do not want to abort. */ + xputenv ("DBUS_FATAL_WARNINGS=0"); +} + +void syms_of_dbusbind (void) { === modified file 'src/editfns.c' --- src/editfns.c 2014-10-01 03:28:16 +0000 +++ src/editfns.c 2014-10-12 06:09:50 +0000 @@ -64,11 +64,17 @@ extern Lisp_Object w32_get_internal_run_time (void); #endif +static void set_time_zone_rule (char const *); static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec, bool, struct tm *); +static long int tm_gmtoff (struct tm *); static int tm_diff (struct tm *, struct tm *); static void update_buffer_properties (ptrdiff_t, ptrdiff_t); +#ifndef HAVE_TM_GMTOFF +# define HAVE_TM_GMTOFF false +#endif + static Lisp_Object Qbuffer_access_fontify_functions; /* Symbol for the text property used to mark fields. */ @@ -79,15 +85,12 @@ static Lisp_Object Qboundary; -/* The startup value of the TZ environment variable so it can be - restored if the user calls set-time-zone-rule with a nil - argument. If null, the TZ environment variable was unset. */ +/* The startup value of the TZ environment variable; null if unset. */ static char const *initial_tz; -/* True if the static variable tzvalbuf (defined in - set_time_zone_rule) is part of 'environ'. */ -static bool tzvalbuf_in_environ; - +/* A valid but unlikely setting for the TZ environment variable. + It is OK (though a bit slower) if the user chooses this value. */ +static char const dump_tz_string[] = "TZ=UtC0"; void init_editfns (void) @@ -101,13 +104,38 @@ init_system_name (); #ifndef CANNOT_DUMP - /* Don't bother with this on initial start when just dumping out */ + /* When just dumping out, set the time zone to a known unlikely value + and skip the rest of this function. */ if (!initialized) - return; -#endif /* not CANNOT_DUMP */ - - initial_tz = getenv ("TZ"); - tzvalbuf_in_environ = 0; + { +# ifdef HAVE_TZSET + xputenv ((char *) dump_tz_string); + tzset (); +# endif + return; + } +#endif + + char *tz = getenv ("TZ"); + initial_tz = tz; + +#if !defined CANNOT_DUMP && defined HAVE_TZSET + /* If the execution TZ happens to be the same as the dump TZ, + change it to some other value and then change it back, + to force the underlying implementation to reload the TZ info. + This is needed on implementations that load TZ info from files, + since the TZ file contents may differ between dump and execution. */ + if (tz && strcmp (tz, &dump_tz_string[sizeof "TZ=" - 1]) == 0) + { + ++*tz; + tzset (); + --*tz; + } +#endif + + /* Call set_time_zone_rule now, so that its call to putenv is done + before multiple threads are active. */ + set_time_zone_rule (tz); pw = getpwuid (getuid ()); #ifdef MSDOS @@ -1373,6 +1401,30 @@ error ("Specified time is not representable"); } +/* A substitute for mktime_z on platforms that lack it. It's not + thread-safe, but should be good enough for Emacs in typical use. */ +#ifndef HAVE_TZALLOC +time_t +mktime_z (timezone_t tz, struct tm *tm) +{ + char *oldtz = getenv ("TZ"); + USE_SAFE_ALLOCA; + if (oldtz) + { + size_t oldtzsize = strlen (oldtz) + 1; + char *oldtzcopy = SAFE_ALLOCA (oldtzsize); + oldtz = strcpy (oldtzcopy, oldtz); + } + block_input (); + set_time_zone_rule (tz); + time_t t = mktime (tm); + set_time_zone_rule (oldtz); + unblock_input (); + SAFE_FREE (); + return t; +} +#endif + /* Return the upper part of the time T (everything but the bottom 16 bits). */ static EMACS_INT hi_time (time_t t) @@ -1768,39 +1820,28 @@ size_t len; Lisp_Object bufstring; int ns = t.tv_nsec; - struct tm *tm; USE_SAFE_ALLOCA; - while (1) + tmp = ut ? gmtime_r (&t.tv_sec, tmp) : localtime_r (&t.tv_sec, tmp); + if (! tmp) + time_overflow (); + synchronize_system_time_locale (); + + while (true) { - time_t *taddr = &t.tv_sec; - block_input (); - - synchronize_system_time_locale (); - - tm = ut ? gmtime (taddr) : localtime (taddr); - if (! tm) - { - unblock_input (); - time_overflow (); - } - *tmp = *tm; - buf[0] = '\1'; - len = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns); + len = emacs_nmemftime (buf, size, format, formatlen, tmp, ut, ns); if ((0 < len && len < size) || (len == 0 && buf[0] == '\0')) break; /* Buffer was too small, so make it bigger and try again. */ - len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tm, ut, ns); - unblock_input (); + len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tmp, ut, ns); if (STRING_BYTES_BOUND <= len) string_overflow (); size = len + 1; buf = SAFE_ALLOCA (size); } - unblock_input (); bufstring = make_unibyte_string (buf, len); SAFE_FREE (); return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0); @@ -1824,38 +1865,30 @@ (Lisp_Object specified_time) { time_t time_spec = lisp_seconds_argument (specified_time); - struct tm save_tm; - struct tm *decoded_time; - Lisp_Object list_args[9]; + struct tm local_tm, gmt_tm; - block_input (); - decoded_time = localtime (&time_spec); - if (decoded_time) - save_tm = *decoded_time; - unblock_input (); - if (! (decoded_time - && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= save_tm.tm_year - && save_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)) + if (! (localtime_r (&time_spec, &local_tm) + && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year + && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)) time_overflow (); - XSETFASTINT (list_args[0], save_tm.tm_sec); - XSETFASTINT (list_args[1], save_tm.tm_min); - XSETFASTINT (list_args[2], save_tm.tm_hour); - XSETFASTINT (list_args[3], save_tm.tm_mday); - XSETFASTINT (list_args[4], save_tm.tm_mon + 1); - /* On 64-bit machines an int is narrower than EMACS_INT, thus the - cast below avoids overflow in int arithmetics. */ - XSETINT (list_args[5], TM_YEAR_BASE + (EMACS_INT) save_tm.tm_year); - XSETFASTINT (list_args[6], save_tm.tm_wday); - list_args[7] = save_tm.tm_isdst ? Qt : Qnil; - - block_input (); - decoded_time = gmtime (&time_spec); - if (decoded_time == 0) - list_args[8] = Qnil; - else - XSETINT (list_args[8], tm_diff (&save_tm, decoded_time)); - unblock_input (); - return Flist (9, list_args); + + /* Avoid overflow when INT_MAX < EMACS_INT_MAX. */ + EMACS_INT tm_year_base = TM_YEAR_BASE; + + return Flist (9, ((Lisp_Object []) + {make_number (local_tm.tm_sec), + make_number (local_tm.tm_min), + make_number (local_tm.tm_hour), + make_number (local_tm.tm_mday), + make_number (local_tm.tm_mon + 1), + make_number (local_tm.tm_year + tm_year_base), + make_number (local_tm.tm_wday), + local_tm.tm_isdst ? Qt : Qnil, + (HAVE_TM_GMTOFF + ? make_number (tm_gmtoff (&local_tm)) + : gmtime_r (&time_spec, &gmt_tm) + ? make_number (tm_diff (&local_tm, &gmt_tm)) + : Qnil)})); } /* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that @@ -1911,18 +1944,12 @@ if (CONSP (zone)) zone = XCAR (zone); if (NILP (zone)) - { - block_input (); - value = mktime (&tm); - unblock_input (); - } + value = mktime (&tm); else { static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d"; char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)]; - char *old_tzstring; const char *tzstring; - USE_SAFE_ALLOCA; if (EQ (zone, Qt)) tzstring = "UTC0"; @@ -1939,29 +1966,13 @@ tzstring = tzbuf; } else + tzstring = 0; + + timezone_t tz = tzstring ? tzalloc (tzstring) : 0; + if (! tz) error ("Invalid time zone specification"); - - old_tzstring = getenv ("TZ"); - if (old_tzstring) - { - char *buf = SAFE_ALLOCA (strlen (old_tzstring) + 1); - old_tzstring = strcpy (buf, old_tzstring); - } - - block_input (); - - /* Set TZ before calling mktime; merely adjusting mktime's returned - value doesn't suffice, since that would mishandle leap seconds. */ - set_time_zone_rule (tzstring); - - value = mktime (&tm); - - set_time_zone_rule (old_tzstring); -#ifdef LOCALTIME_CACHE - tzset (); -#endif - unblock_input (); - SAFE_FREE (); + value = mktime_z (tz, &tm); + tzfree (tz); } if (value == (time_t) -1) @@ -1987,34 +1998,27 @@ (Lisp_Object specified_time) { time_t value = lisp_seconds_argument (specified_time); - struct tm *tm; - char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1]; - int len IF_LINT (= 0); /* Convert to a string in ctime format, except without the trailing newline, and without the 4-digit year limit. Don't use asctime or ctime, as they might dump core if the year is outside the range -999 .. 9999. */ - block_input (); - tm = localtime (&value); - if (tm) - { - static char const wday_name[][4] = - { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - static char const mon_name[][4] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - printmax_t year_base = TM_YEAR_BASE; - - len = sprintf (buf, "%s %s%3d %02d:%02d:%02d %"pMd, - wday_name[tm->tm_wday], mon_name[tm->tm_mon], tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, - tm->tm_year + year_base); - } - unblock_input (); - if (! tm) + struct tm tm; + if (! localtime_r (&value, &tm)) time_overflow (); + static char const wday_name[][4] = + { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + static char const mon_name[][4] = + { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + printmax_t year_base = TM_YEAR_BASE; + char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1]; + int len = sprintf (buf, "%s %s%3d %02d:%02d:%02d %"pMd, + wday_name[tm.tm_wday], mon_name[tm.tm_mon], tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + year_base); + return make_unibyte_string (buf, len); } @@ -2041,6 +2045,17 @@ + (a->tm_sec - b->tm_sec)); } +/* Yield A's UTC offset, or an unspecified value if unknown. */ +static long int +tm_gmtoff (struct tm *a) +{ +#if HAVE_TM_GMTOFF + return a->tm_gmtoff; +#else + return 0; +#endif +} + DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 1, 0, doc: /* Return the offset and name for the local time zone. This returns a list of the form (OFFSET NAME). @@ -2059,32 +2074,30 @@ (Lisp_Object specified_time) { struct timespec value; - int offset; - struct tm *t; - struct tm localtm; + struct tm local_tm, gmt_tm; Lisp_Object zone_offset, zone_name; zone_offset = Qnil; value = make_timespec (lisp_seconds_argument (specified_time), 0); - zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm); - block_input (); - t = gmtime (&value.tv_sec); - if (t) - offset = tm_diff (&localtm, t); - unblock_input (); + zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &local_tm); - if (t) + if (HAVE_TM_GMTOFF || gmtime_r (&value.tv_sec, &gmt_tm)) { + long int offset = (HAVE_TM_GMTOFF + ? tm_gmtoff (&local_tm) + : tm_diff (&local_tm, &gmt_tm)); zone_offset = make_number (offset); if (SCHARS (zone_name) == 0) { /* No local time zone name is available; use "+-NNNN" instead. */ - int m = offset / 60; - int am = offset < 0 ? - m : m; - char buf[sizeof "+00" + INT_STRLEN_BOUND (int)]; - zone_name = make_formatted_string (buf, "%c%02d%02d", + long int m = offset / 60; + long int am = offset < 0 ? - m : m; + long int hour = am / 60; + int min = am % 60; + char buf[sizeof "+00" + INT_STRLEN_BOUND (long int)]; + zone_name = make_formatted_string (buf, "%c%02ld%02d", (offset < 0 ? '-' : '+'), - am / 60, am % 60); + hour, min); } } @@ -2123,12 +2136,12 @@ /* Set the local time zone rule to TZSTRING. - This function is not thread-safe, partly because putenv, unsetenv - and tzset are not, and partly because of the static storage it - updates. Other threads that invoke localtime etc. may be adversely - affected while this function is executing. */ + This function is not thread-safe, in theory because putenv is not, + but mostly because of the static storage it updates. Other threads + that invoke localtime etc. may be adversely affected while this + function is executing. */ -void +static void set_time_zone_rule (const char *tzstring) { /* A buffer holding a string of the form "TZ=value", intended @@ -2137,75 +2150,47 @@ static ptrdiff_t tzvalbufsize; int tzeqlen = sizeof "TZ=" - 1; - -#ifdef LOCALTIME_CACHE - /* These two values are known to load tz files in buggy implementations, - i.e., Solaris 1 executables running under either Solaris 1 or Solaris 2. - Their values shouldn't matter in non-buggy implementations. - We don't use string literals for these strings, - since if a string in the environment is in readonly - storage, it runs afoul of bugs in SVR4 and Solaris 2.3. - See Sun bugs 1113095 and 1114114, ``Timezone routines - improperly modify environment''. */ - - static char set_time_zone_rule_tz[][sizeof "TZ=GMT+0"] - = { "TZ=GMT+0", "TZ=GMT+1" }; - - /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like - "US/Pacific" that loads a tz file, then changes to a value like - "XXX0" that does not load a tz file, and then changes back to - its original value, the last change is (incorrectly) ignored. - Also, if TZ changes twice in succession to values that do - not load a tz file, tzset can dump core (see Sun bug#1225179). - The following code works around these bugs. */ + ptrdiff_t tzstringlen = tzstring ? strlen (tzstring) : 0; + char *tzval = tzvalbuf; + bool new_tzvalbuf = tzvalbufsize <= tzeqlen + tzstringlen; + + if (new_tzvalbuf) + { + /* Do not attempt to free the old tzvalbuf, since another thread + may be using it. In practice, the first allocation is large + enough and memory does not leak. */ + tzval = xpalloc (NULL, &tzvalbufsize, + tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1); + tzvalbuf = tzval; + tzval[1] = 'Z'; + tzval[2] = '='; + } if (tzstring) { - /* Temporarily set TZ to a value that loads a tz file - and that differs from tzstring. */ - bool eq0 = strcmp (tzstring, set_time_zone_rule_tz[0] + tzeqlen) == 0; - xputenv (set_time_zone_rule_tz[eq0]); - } - else - { - /* The implied tzstring is unknown, so temporarily set TZ to - two different values that each load a tz file. */ - xputenv (set_time_zone_rule_tz[0]); - tzset (); - xputenv (set_time_zone_rule_tz[1]); - } - tzset (); - tzvalbuf_in_environ = 0; -#endif - - if (!tzstring) - { - unsetenv ("TZ"); - tzvalbuf_in_environ = 0; - } - else - { - ptrdiff_t tzstringlen = strlen (tzstring); - - if (tzvalbufsize <= tzeqlen + tzstringlen) - { - unsetenv ("TZ"); - tzvalbuf_in_environ = 0; - tzvalbuf = xpalloc (tzvalbuf, &tzvalbufsize, - tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1); - memcpy (tzvalbuf, "TZ=", tzeqlen); - } - - strcpy (tzvalbuf + tzeqlen, tzstring); - - if (!tzvalbuf_in_environ) - { - xputenv (tzvalbuf); - tzvalbuf_in_environ = 1; - } - } - -#ifdef LOCALTIME_CACHE + /* Modify TZVAL in place. Although this is dicey in a + multithreaded environment, we know of no portable alternative. + Calling putenv or setenv could crash some other thread. */ + tzval[0] = 'T'; + strcpy (tzval + tzeqlen, tzstring); + } + else + { + /* Turn 'TZ=whatever' into an empty environment variable 'tZ='. + Although this is also dicey, calling unsetenv here can crash Emacs. + See Bug#8705. */ + tzval[0] = 't'; + tzval[tzeqlen] = 0; + } + + if (new_tzvalbuf) + { + /* Although this is not thread-safe, in practice this runs only + on startup when there is only one thread. */ + xputenv (tzval); + } + +#ifdef HAVE_TZSET tzset (); #endif } === modified file 'src/emacs.c' --- src/emacs.c 2014-10-01 03:28:16 +0000 +++ src/emacs.c 2014-10-12 06:09:50 +0000 @@ -578,12 +578,6 @@ } -#ifdef HAVE_TZSET -/* A valid but unlikely value for the TZ environment value. - It is OK (though a bit slower) if the user actually chooses this value. */ -static char const dump_tz[] = "UtC0"; -#endif - /* Test whether the next argument in ARGV matches SSTR or a prefix of LSTR (at least MINLEN characters). If so, then if VALPTR is non-null (the argument is supposed to have a value) store in *VALPTR either @@ -1548,8 +1542,23 @@ init_charset (); - init_editfns (); /* init_process_emacs uses Voperating_system_release. */ - init_process_emacs (); /* init_display uses add_keyboard_wait_descriptor. */ + /* This calls putenv and so must precede init_process_emacs. Also, + it sets Voperating_system_release, which init_process_emacs uses. */ + init_editfns (); + + /* These two call putenv. */ +#ifdef HAVE_DBUS + init_dbusbind (); +#endif +#ifdef USE_GTK + init_xterm (); +#endif + + /* This can create a thread that may call getenv, so it must follow + all calls to putenv and setenv. Also, this sets up + add_keyboard_wait_descriptor, which init_display uses. */ + init_process_emacs (); + init_keyboard (); /* This too must precede init_sys_modes. */ if (!noninteractive) init_display (); /* Determine terminal type. Calls init_sys_modes. */ @@ -1586,26 +1595,6 @@ build_string ("loadup.el")); } - if (initialized) - { -#ifdef HAVE_TZSET - { - /* If the execution TZ happens to be the same as the dump TZ, - change it to some other value and then change it back, - to force the underlying implementation to reload the TZ info. - This is needed on implementations that load TZ info from files, - since the TZ file contents may differ between dump and execution. */ - char *tz = getenv ("TZ"); - if (tz && !strcmp (tz, dump_tz)) - { - ++*tz; - tzset (); - --*tz; - } - } -#endif - } - /* Set up for profiling. This is known to work on FreeBSD, GNU/Linux and MinGW. It might work on some other systems too. Give it a try and tell us if it works on your system. To compile @@ -1630,15 +1619,6 @@ initialized = 1; -#ifdef LOCALTIME_CACHE - /* Some versions of localtime have a bug. They cache the value of the time - zone rather than looking it up every time. Since localtime() is - called to bolt the undumping time into the undumped emacs, this - results in localtime ignoring the TZ environment variable. - This flushes the new TZ value into localtime. */ - tzset (); -#endif /* defined (LOCALTIME_CACHE) */ - /* Enter editor command loop. This never returns. */ Frecursive_edit (); /* NOTREACHED */ @@ -2119,14 +2099,6 @@ tem = Vpurify_flag; Vpurify_flag = Qnil; -#ifdef HAVE_TZSET - set_time_zone_rule (dump_tz); -#ifndef LOCALTIME_CACHE - /* Force a tz reload, since set_time_zone_rule doesn't. */ - tzset (); -#endif -#endif - fflush (stdout); /* Tell malloc where start of impure now is. */ /* Also arrange for warnings when nearly out of space. */ === modified file 'src/lisp.h' --- src/lisp.h 2014-10-09 06:54:10 +0000 +++ src/lisp.h 2014-10-12 06:09:50 +0000 @@ -3990,7 +3990,6 @@ ptrdiff_t, bool); extern void init_editfns (void); extern void syms_of_editfns (void); -extern void set_time_zone_rule (const char *); /* Defined in buffer.c. */ extern bool mouse_face_overlay_overlaps (Lisp_Object); @@ -4398,6 +4397,7 @@ extern void syms_of_xselect (void); /* Defined in xterm.c. */ +extern void init_xterm (void); extern void syms_of_xterm (void); #endif /* HAVE_X_WINDOWS */ @@ -4419,6 +4419,7 @@ #ifdef HAVE_DBUS /* Defined in dbusbind.c. */ +void init_dbusbind (void); void syms_of_dbusbind (void); #endif === modified file 'src/systime.h' --- src/systime.h 2014-09-24 20:30:28 +0000 +++ src/systime.h 2014-10-12 06:09:50 +0000 @@ -93,6 +93,22 @@ extern struct timespec lisp_time_argument (Lisp_Object); #endif +#ifndef HAVE_TZALLOC +# undef mktime_z +# undef timezone_t +# undef tzalloc +# undef tzfree +# define mktime_z emacs_mktime_z +# define timezone_t emacs_timezone_t +# define tzalloc emacs_tzalloc +# define tzfree emacs_tzfree +typedef char const *timezone_t; +INLINE timezone_t tzalloc (char const *name) { return name; } +INLINE void tzfree (timezone_t tz) { } +/* Defined in editfns.c. */ +extern time_t mktime_z (timezone_t, struct tm *); +#endif + INLINE_HEADER_END #endif /* EMACS_SYSTIME_H */ === modified file 'src/xterm.c' --- src/xterm.c 2014-10-03 02:20:52 +0000 +++ src/xterm.c 2014-10-12 06:09:50 +0000 @@ -10717,10 +10717,6 @@ XSetLocaleModifiers (""); - /* Emacs can only handle core input events, so make sure - Gtk doesn't use Xinput or Xinput2 extensions. */ - xputenv ("GDK_CORE_DEVICE_EVENTS=1"); - /* Work around GLib bug that outputs a faulty warning. See https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL @@ -11470,6 +11466,15 @@ XSetIOErrorHandler (x_io_error_quitter); } +#ifdef USE_GTK +void +init_xterm (void) +{ + /* Emacs can handle only core input events, so make sure + Gtk doesn't use Xinput or Xinput2 extensions. */ + xputenv ("GDK_CORE_DEVICE_EVENTS=1"); +} +#endif void syms_of_xterm (void) ------------------------------------------------------------ revno: 118094 committer: Jan D. branch nick: trunk timestamp: Sat 2014-10-11 22:00:59 +0200 message: Fix ns-use-fullscreen-animation again... add boolean. * cus-start.el (all): Add missing ns and boolean to ns-use-fullscreen-animation. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-10-11 19:58:02 +0000 +++ lisp/ChangeLog 2014-10-11 20:00:59 +0000 @@ -1,6 +1,7 @@ 2014-10-11 Jan Djärv - * cus-start.el (all): Add missing ns to ns-use-fullscreen-animation. + * cus-start.el (all): Add missing ns and boolean to + ns-use-fullscreen-animation. 2014-10-11 Leo Liu === modified file 'lisp/cus-start.el' --- lisp/cus-start.el 2014-10-11 19:58:02 +0000 +++ lisp/cus-start.el 2014-10-11 20:00:59 +0000 @@ -404,7 +404,7 @@ (ns-antialias-text ns boolean "23.1") (ns-auto-hide-menu-bar ns boolean "24.1") (ns-use-native-fullscreen ns boolean "24.4") - (ns-use-fullscreen-animation ns "25.1") + (ns-use-fullscreen-animation ns boolean "25.1") (ns-use-srgb-colorspace ns boolean "24.4") ;; process.c (delete-exited-processes processes-basics boolean) ------------------------------------------------------------ revno: 118093 committer: Jan D. branch nick: trunk timestamp: Sat 2014-10-11 21:58:02 +0200 message: * cus-start.el (all): Add missing ns to ns-use-fullscreen-animation. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-10-11 14:11:03 +0000 +++ lisp/ChangeLog 2014-10-11 19:58:02 +0000 @@ -1,3 +1,7 @@ +2014-10-11 Jan Djärv + + * cus-start.el (all): Add missing ns to ns-use-fullscreen-animation. + 2014-10-11 Leo Liu * progmodes/cfengine.el (cfengine3-defuns, cfengine3-vartypes): === modified file 'lisp/cus-start.el' --- lisp/cus-start.el 2014-10-11 08:28:11 +0000 +++ lisp/cus-start.el 2014-10-11 19:58:02 +0000 @@ -404,7 +404,7 @@ (ns-antialias-text ns boolean "23.1") (ns-auto-hide-menu-bar ns boolean "24.1") (ns-use-native-fullscreen ns boolean "24.4") - (ns-use-fullscreen-animation "25.1") + (ns-use-fullscreen-animation ns "25.1") (ns-use-srgb-colorspace ns boolean "24.4") ;; process.c (delete-exited-processes processes-basics boolean) ------------------------------------------------------------ revno: 118092 committer: Leo Liu branch nick: trunk timestamp: Sat 2014-10-11 22:27:47 +0800 message: Fix last change diff: === modified file 'lisp/progmodes/cfengine.el' --- lisp/progmodes/cfengine.el 2014-10-11 14:11:03 +0000 +++ lisp/progmodes/cfengine.el 2014-10-11 14:27:47 +0000 @@ -1302,8 +1302,8 @@ "A function for `imenu-create-index-function'." (goto-char (point-min)) (let ((re (concat "^\\s-*" cfengine3-defuns-regex - "\\s-*\\(\\(?:\\w\\|\\s_\\)+\\)" ;type - "\\s-*\\(\\(?:\\w\\|\\s_\\)+\\)" ;id + "\\s-+\\(\\(?:\\w\\|\\s_\\)+\\)" ;type + "\\s-+\\(\\(?:\\w\\|\\s_\\)+\\)" ;id )) (defuns ())) (while (re-search-forward re nil t) ------------------------------------------------------------ revno: 118091 committer: Leo Liu branch nick: trunk timestamp: Sat 2014-10-11 22:11:03 +0800 message: * progmodes/cfengine.el (cfengine3-defuns, cfengine3-vartypes): Use strings. (cfengine3-create-imenu-index): New function. (cfengine3-mode): Use it for `imenu-create-index-function'. (cfengine-auto-mode): Improve and prefer cfengine3-mode when buffer is empty. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-10-11 08:28:11 +0000 +++ lisp/ChangeLog 2014-10-11 14:11:03 +0000 @@ -1,3 +1,12 @@ +2014-10-11 Leo Liu + + * progmodes/cfengine.el (cfengine3-defuns, cfengine3-vartypes): + Use strings. + (cfengine3-create-imenu-index): New function. + (cfengine3-mode): Use it for `imenu-create-index-function'. + (cfengine-auto-mode): Improve and prefer cfengine3-mode when + buffer is empty. + 2014-10-11 Jan Djärv * cus-start.el (all): Add ns-use-fullscreen-animation. === modified file 'lisp/progmodes/cfengine.el' --- lisp/progmodes/cfengine.el 2014-10-08 15:34:58 +0000 +++ lisp/progmodes/cfengine.el 2014-10-11 14:11:03 +0000 @@ -27,9 +27,6 @@ ;; Provides support for editing GNU Cfengine files, including ;; font-locking, Imenu and indentation, but with no special keybindings. -;; The CFEngine 3.x support doesn't have Imenu support but patches are -;; welcome. - ;; By default, CFEngine 3.x syntax is used. ;; You can set it up so either `cfengine2-mode' (2.x and earlier) or @@ -56,7 +53,6 @@ ;;; Code: (autoload 'json-read "json") -(autoload 'regexp-opt "regexp-opt") (defgroup cfengine () "Editing CFEngine files." @@ -815,24 +811,18 @@ "List of the action keywords supported by Cfengine. This includes those for cfservd as well as cfagent.") - (defconst cfengine3-defuns - (mapcar - 'symbol-name - '(bundle body)) + (defconst cfengine3-defuns '("bundle" "body") "List of the CFEngine 3.x defun headings.") - (defconst cfengine3-defuns-regex - (regexp-opt cfengine3-defuns t) + (defconst cfengine3-defuns-regex (regexp-opt cfengine3-defuns t) "Regex to match the CFEngine 3.x defuns.") (defconst cfengine3-class-selector-regex "\\([[:alnum:]_().&|!:]+\\)::") (defconst cfengine3-category-regex "\\([[:alnum:]_]+\\):") - (defconst cfengine3-vartypes - (mapcar - 'symbol-name - '(string int real slist ilist rlist irange rrange counter data)) + (defconst cfengine3-vartypes '("string" "int" "real" "slist" "ilist" "rlist" + "irange" "rrange" "counter" "data") "List of the CFEngine 3.x variable types.")) (defvar cfengine2-font-lock-keywords @@ -1308,6 +1298,20 @@ ("=>" . ?⇒) ("::" . ?∷))) +(defun cfengine3-create-imenu-index () + "A function for `imenu-create-index-function'." + (goto-char (point-min)) + (let ((re (concat "^\\s-*" cfengine3-defuns-regex + "\\s-*\\(\\(?:\\w\\|\\s_\\)+\\)" ;type + "\\s-*\\(\\(?:\\w\\|\\s_\\)+\\)" ;id + )) + (defuns ())) + (while (re-search-forward re nil t) + (push (cons (mapconcat #'match-string '(1 2 3) ".") + (copy-marker (match-beginning 3))) + defuns)) + (nreverse defuns))) + ;;;###autoload (define-derived-mode cfengine3-mode prog-mode "CFE3" "Major mode for editing CFEngine3 input. @@ -1334,17 +1338,16 @@ (when buffer-file-name (shell-quote-argument buffer-file-name))))) - (set (make-local-variable 'eldoc-documentation-function) - #'cfengine3-documentation-function) + (setq-local eldoc-documentation-function #'cfengine3-documentation-function) (add-hook 'completion-at-point-functions #'cfengine3-completion-function nil t) ;; Use defuns as the essential syntax block. - (set (make-local-variable 'beginning-of-defun-function) - #'cfengine3-beginning-of-defun) - (set (make-local-variable 'end-of-defun-function) - #'cfengine3-end-of-defun)) + (setq-local beginning-of-defun-function #'cfengine3-beginning-of-defun) + (setq-local end-of-defun-function #'cfengine3-end-of-defun) + + (setq-local imenu-create-index-function #'cfengine3-create-imenu-index)) ;;;###autoload (define-derived-mode cfengine2-mode prog-mode "CFE2" @@ -1378,15 +1381,18 @@ ;;;###autoload (defun cfengine-auto-mode () - "Choose between `cfengine2-mode' and `cfengine3-mode' depending -on the buffer contents" - (let ((v3 nil)) - (save-restriction - (goto-char (point-min)) - (while (not (or (eobp) v3)) - (setq v3 (looking-at (concat cfengine3-defuns-regex "\\_>"))) - (forward-line))) - (if v3 (cfengine3-mode) (cfengine2-mode)))) + "Choose `cfengine2-mode' or `cfengine3-mode' by buffer contents." + (interactive) + (if (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (forward-comment (point-max)) + (or (eobp) + (re-search-forward + (concat "^\\s-*" cfengine3-defuns-regex "\\_>") nil t)))) + (cfengine3-mode) + (cfengine2-mode))) (defalias 'cfengine-mode 'cfengine3-mode) ------------------------------------------------------------ revno: 118090 committer: Jan D. branch nick: trunk timestamp: Sat 2014-10-11 10:28:11 +0200 message: * cus-start.el (all): Add ns-use-fullscreen-animation. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-10-11 02:54:11 +0000 +++ lisp/ChangeLog 2014-10-11 08:28:11 +0000 @@ -1,3 +1,7 @@ +2014-10-11 Jan Djärv + + * cus-start.el (all): Add ns-use-fullscreen-animation. + 2014-10-11 Glenn Morris * calendar/diary-lib.el (diary-display-function): === modified file 'lisp/cus-start.el' --- lisp/cus-start.el 2014-06-02 00:18:22 +0000 +++ lisp/cus-start.el 2014-10-11 08:28:11 +0000 @@ -404,7 +404,8 @@ (ns-antialias-text ns boolean "23.1") (ns-auto-hide-menu-bar ns boolean "24.1") (ns-use-native-fullscreen ns boolean "24.4") - (ns-use-srgb-colorspace ns boolean "24.4") + (ns-use-fullscreen-animation "25.1") + (ns-use-srgb-colorspace ns boolean "24.4") ;; process.c (delete-exited-processes processes-basics boolean) ;; syntax.c ------------------------------------------------------------ revno: 118089 committer: Jan D. branch nick: trunk timestamp: Sat 2014-10-11 10:22:00 +0200 message: Fix mailaddress. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-10-09 06:54:10 +0000 +++ src/ChangeLog 2014-10-11 08:22:00 +0000 @@ -1099,7 +1099,7 @@ * Makefile.in (EMACS_HEAPSIZE): Remove, no longer used. (Bug#18416) -2014-09-04 Jan D +2014-09-04 Jan D * xterm.c (x_term_init): Don't call x_session_initialize if running as a daemon (Bug#18375). ------------------------------------------------------------ revno: 118088 committer: Glenn Morris branch nick: trunk timestamp: Fri 2014-10-10 19:54:11 -0700 message: Drop support for deprecated (since 23.1) forms of diary-display-function * lisp/calendar/diary-lib.el (diary-display-function): Drop support for deprecated nil and list forms. (diary-list-entries): Update for the above. * lisp/calendar/cal-x.el (calendar-dedicate-diary): Simplify accordingly. diff: === modified file 'etc/NEWS' --- etc/NEWS 2014-10-10 03:24:41 +0000 +++ etc/NEWS 2014-10-11 02:54:11 +0000 @@ -169,6 +169,8 @@ **** Variables `european-calendar-style', `diary-face', `hebrew-holidays-{1,4}'. +**** The nil and list forms of `diary-display-function'. + ** New ERT function `ert-summarize-tests-batch-and-exit'. --- === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-10-10 12:39:49 +0000 +++ lisp/ChangeLog 2014-10-11 02:54:11 +0000 @@ -1,3 +1,10 @@ +2014-10-11 Glenn Morris + + * calendar/diary-lib.el (diary-display-function): + Drop support for deprecated nil and list forms. + (diary-list-entries): Update for the above. + * calendar/cal-x.el (calendar-dedicate-diary): Simplify accordingly. + 2014-10-10 Leo Liu * window.el (temp-buffer-window-show): Make BUFFER a required arg. === modified file 'lisp/calendar/cal-x.el' --- lisp/calendar/cal-x.el 2014-10-08 18:30:45 +0000 +++ lisp/calendar/cal-x.el 2014-10-11 02:54:11 +0000 @@ -93,9 +93,7 @@ "Display and dedicate the window associated with the diary buffer." (set-window-dedicated-p (display-buffer - (if (if (listp diary-display-function) - (memq 'diary-fancy-display diary-display-function) - (eq diary-display-function 'diary-fancy-display)) + (if (eq diary-display-function 'diary-fancy-display) (progn ;; If there are no diary entries, there won't be a buffer ;; to dedicate, so make a basic one. === modified file 'lisp/calendar/diary-lib.el' --- lisp/calendar/diary-lib.el 2014-10-06 02:02:04 +0000 +++ lisp/calendar/diary-lib.el 2014-10-11 02:54:11 +0000 @@ -159,11 +159,6 @@ "Function used to display the diary. The two standard options are `diary-fancy-display' and `diary-simple-display'. -For historical reasons, `nil' is the same as `diary-simple-display' -\(so you must use `ignore' for no display). Also for historical -reasons, this variable can be a list of functions to run. These -uses are not recommended and may be removed at some point. - When this function is called, the variable `diary-entries-list' is a list, in order by date, of all relevant diary entries in the form of ((MONTH DAY YEAR) STRING), where string is the diary @@ -172,9 +167,8 @@ holidays), or hard copy output." :type '(choice (const diary-fancy-display :tag "Fancy display") (const diary-simple-display :tag "Basic display") - (const ignore :tag "No display") - (const nil :tag "Obsolete way to choose basic display") - (hook :tag "Obsolete form with list of display functions")) + (const :tag "No display" ignore) + (function :tag "User-specified function")) :initialize 'custom-initialize-default :set 'diary-set-maybe-redraw :version "23.2" ; simple->fancy @@ -867,12 +861,7 @@ 'display-buffer-in-previous-window (copy-sequence (car display-buffer-fallback-action)))))) - (if (and diary-display-function - (listp diary-display-function)) - ;; Backwards compatibility. - (run-hooks 'diary-display-function) - (funcall (or diary-display-function - 'diary-simple-display))))) + (funcall diary-display-function))) (run-hooks 'diary-hook))))) (and temp-buff (buffer-name temp-buff) (kill-buffer temp-buff))) (or d-incp (message "Preparing diary...done")) ------------------------------------------------------------ revno: 118087 committer: Glenn Morris branch nick: trunk timestamp: Fri 2014-10-10 12:53:19 -0400 message: * lisp/erc/erc.el: Fix paren typo in previous. diff: === modified file 'lisp/erc/erc.el' --- lisp/erc/erc.el 2014-10-10 13:16:12 +0000 +++ lisp/erc/erc.el 2014-10-10 16:53:19 +0000 @@ -2060,7 +2060,7 @@ (unless (markerp erc-last-saved-position) (setq erc-last-saved-position (make-marker)) (move-marker erc-last-saved-position - (1- (marker-position erc-insert-marker))))) + (1- (marker-position erc-insert-marker)))))) ;; interactive startup ------------------------------------------------------------ revno: 118086 fixes bug: http://debbugs.gnu.org/16145 author: Ivan Shmakov committer: Kelvin White branch nick: trunk timestamp: Fri 2014-10-10 09:16:12 -0400 message: Only initialize erc-last-saved-position if not already a marker. diff: === modified file 'lisp/erc/ChangeLog' --- lisp/erc/ChangeLog 2014-10-04 03:04:51 +0000 +++ lisp/erc/ChangeLog 2014-10-10 13:16:12 +0000 @@ -1,3 +1,8 @@ +2014-10-10 Kelvin White + + * erc.el (erc-initialize-log-marker): Only initialize + erc-last-saved-position if not already a marker. + 2014-10-04 Stefan Monnier * erc.el (erc-channel-receive-names): Silence compiler warning. === modified file 'lisp/erc/erc.el' --- lisp/erc/erc.el 2014-10-04 03:04:51 +0000 +++ lisp/erc/erc.el 2014-10-10 13:16:12 +0000 @@ -2057,9 +2057,10 @@ "Initialize the `erc-last-saved-position' marker to a sensible position. BUFFER is the current buffer." (with-current-buffer buffer - (setq erc-last-saved-position (make-marker)) - (move-marker erc-last-saved-position - (1- (marker-position erc-insert-marker))))) + (unless (markerp erc-last-saved-position) + (setq erc-last-saved-position (make-marker)) + (move-marker erc-last-saved-position + (1- (marker-position erc-insert-marker))))) ;; interactive startup ------------------------------------------------------------ revno: 118085 fixes bug: http://debbugs.gnu.org/18656 committer: Leo Liu branch nick: trunk timestamp: Fri 2014-10-10 20:39:49 +0800 message: * lisp/window.el (temp-buffer-window-show): Make BUFFER a required arg. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-10-10 03:28:24 +0000 +++ lisp/ChangeLog 2014-10-10 12:39:49 +0000 @@ -1,3 +1,8 @@ +2014-10-10 Leo Liu + + * window.el (temp-buffer-window-show): Make BUFFER a required arg. + (Bug#18656) + 2014-10-10 Stefan Monnier * select.el (gui-selection-exists-p-alist): New method. === modified file 'lisp/window.el' --- lisp/window.el 2014-10-04 08:20:24 +0000 +++ lisp/window.el 2014-10-10 12:39:49 +0000 @@ -108,7 +108,7 @@ ;; Return the buffer. buffer))) -(defun temp-buffer-window-show (&optional buffer action) +(defun temp-buffer-window-show (buffer &optional action) "Show temporary buffer BUFFER in a window. Return the window showing BUFFER. Pass ACTION as action argument to `display-buffer'." ------------------------------------------------------------ revno: 118084 committer: Thien-Thi Nguyen branch nick: trunk timestamp: Fri 2014-10-10 09:54:08 +0200 message: [maint] Start Emacs versioning doc; nfc. * admin/versioning: New file. diff: === added file 'admin/versioning' --- admin/versioning 1970-01-01 00:00:00 +0000 +++ admin/versioning 2014-10-10 07:54:08 +0000 @@ -0,0 +1,49 @@ +GNU EMACS VERSIONING -*- org -*- + +The version number scheme of Emacs, including how to determine when to +bump various components of the version number, has evolved over the +years. This file defines the current method, explains why it was +chosen, and lightly documents the previous schemes. It was prompted +by http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00872.html. + +Releated info: +- [[file:FOR-RELEASE][FOR-RELEASE]] +- [[file:make-tarball.txt][make-tarball.txt]] + +* what: MAJOR.MINOR + +This has always been the case (see [[was]], below). MINOR is 1 or more, +usually, the exception being for pretest releases, where there is +an additional trailing ".ALPHA" (e.g., 24.3.95 prior to 24.4). + +To determine any release's version, we follow this algorithm: + +- If MAJOR-CHANGES, increment MAJOR and set MINOR to 1. +- Otherwise, increment MINOR. + +where MAJOR-CHANGES is defined roughly as the union of: + +- dropped support for IMPORTANT + - platforms (almost never happens) + - Emacs Lisp features + - non-programming features/packages +- IMPORTANT additions and changes + - Emacs Lisp features + - non-programming features/packages + +and IMPORTANT is defined through discussion on the [[http://mail.gnu.org/archive/html/emacs-devel/][emacs-devel]] +mailing list and/or private arm-twisting (although this latter +method is somewhat discouraged :-D). + +* why + +People expect bumps in MINOR for "minor" changes. This typically +includes bugfixes, doc improvements, or fully-backward-compatible +additions and changes, only. + +Anything else is actually IMPORTANT, to the user. [Actually, who +really knows what the user thinks? I certainly don't. --ttn] + +* was + +TODO (be sure to include "ad-hoc" :-D)