aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2012-12-08 09:19:51 -0800
committerPaul Eggert2012-12-08 09:19:51 -0800
commit5745a7df2b4abe06d032820f6ec7ddbac9ad5028 (patch)
tree5deecfc1b7b7c789abf9df72c177380d2cbef905 /src
parentc56efa40745336c8067f047fe8f736821ddb3791 (diff)
downloademacs-5745a7df2b4abe06d032820f6ec7ddbac9ad5028.tar.gz
emacs-5745a7df2b4abe06d032820f6ec7ddbac9ad5028.zip
Use putenv+unsetenv instead of modifying environ directly.
* admin/merge-gnulib (GNULIB_MODULES): Add putenv, unsetenv. * lib/putenv.c, lib/unsetenv.c, m4/putenv.m4, m4/setenv.m4: New files, copied automatically from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * src/alloc.c (xputenv): New function. * src/dbusbind.c (Fdbus_init_bus): * src/emacs.c (main): * src/xterm.c (x_term_init): Use xputenv instead of setenv or putenv, to detect memory exhaustion. * src/editfns.c (initial_tz): Move static var decl up. (tzvalbuf_in_environ): New static var. (init_editfns): Initialize these two static vars. (Fencode_time): Don't assume arbitrary limit on EMACS_INT width. Save old TZ value on stack, if it's small. (Fencode_time, set_time_zone_rule): Don't modify 'environ' directly; instead, use xputenv+unsetenv to set and restore TZ. (environbuf): Remove static var. All uses removed. (Fset_time_zone_rule): Do not save TZ and environ; no longer needed here. (set_time_zone_rule_tz1, set_time_zone_rule_tz2) [LOCALTIME_CACHE]: Move to inside set_time_zone_rule; they don't need file scope any more. (set_time_zone_rule): Maintain the TZ=value string separately. (syms_of_editfns): Don't initialize initial_tz; init_editfns now does it. * src/emacs.c (dump_tz) [HAVE_TZSET]: Now const. * src/lisp.h (xputenv): New decl. Fixes: debbugs:13070
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog26
-rw-r--r--src/alloc.c9
-rw-r--r--src/dbusbind.c2
-rw-r--r--src/editfns.c204
-rw-r--r--src/emacs.c9
-rw-r--r--src/lisp.h1
-rw-r--r--src/xterm.c5
7 files changed, 138 insertions, 118 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 54985d33b59..0be3eee6726 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,29 @@
12012-12-08 Paul Eggert <eggert@cs.ucla.edu>
2
3 Use putenv+unsetenv instead of modifying environ directly (Bug#13070).
4 * alloc.c (xputenv): New function.
5 * dbusbind.c (Fdbus_init_bus):
6 * emacs.c (main):
7 * xterm.c (x_term_init):
8 Use xputenv instead of setenv or putenv, to detect memory exhaustion.
9 * editfns.c (initial_tz): Move static var decl up.
10 (tzvalbuf_in_environ): New static var.
11 (init_editfns): Initialize these two static vars.
12 (Fencode_time): Don't assume arbitrary limit on EMACS_INT width.
13 Save old TZ value on stack, if it's small.
14 (Fencode_time, set_time_zone_rule): Don't modify 'environ' directly;
15 instead, use xputenv+unsetenv to set and restore TZ.
16 (environbuf): Remove static var. All uses removed.
17 (Fset_time_zone_rule): Do not save TZ and environ;
18 no longer needed here.
19 (set_time_zone_rule_tz1, set_time_zone_rule_tz2) [LOCALTIME_CACHE]:
20 Move to inside set_time_zone_rule; they don't need file scope any more.
21 (set_time_zone_rule): Maintain the TZ=value string separately.
22 (syms_of_editfns): Don't initialize initial_tz;
23 init_editfns now does it.
24 * emacs.c (dump_tz) [HAVE_TZSET]: Now const.
25 * lisp.h (xputenv): New decl.
26
12012-12-08 Fabrice Popineau <fabrice.popineau@gmail.com> 272012-12-08 Fabrice Popineau <fabrice.popineau@gmail.com>
2 28
3 * w32fns.c (emacs_abort): Don't do arithmetics on void pointers. 29 * w32fns.c (emacs_abort): Don't do arithmetics on void pointers.
diff --git a/src/alloc.c b/src/alloc.c
index 0f105f87207..5a3ba465d81 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -820,6 +820,15 @@ xstrdup (const char *s)
820 return p; 820 return p;
821} 821}
822 822
823/* Like putenv, but (1) use the equivalent of xmalloc and (2) the
824 argument is a const pointer. */
825
826void
827xputenv (char const *string)
828{
829 if (putenv ((char *) string) != 0)
830 memory_full (0);
831}
823 832
824/* Unwind for SAFE_ALLOCA */ 833/* Unwind for SAFE_ALLOCA */
825 834
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 80086946fc4..da8bbb1e5d7 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -1203,7 +1203,7 @@ this connection to those buses. */)
1203 xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses); 1203 xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses);
1204 1204
1205 /* We do not want to abort. */ 1205 /* We do not want to abort. */
1206 putenv ((char *) "DBUS_FATAL_WARNINGS=0"); 1206 xputenv ("DBUS_FATAL_WARNINGS=0");
1207 1207
1208 /* Cleanup. */ 1208 /* Cleanup. */
1209 dbus_error_free (&derror); 1209 dbus_error_free (&derror);
diff --git a/src/editfns.c b/src/editfns.c
index ffb9a38909b..7d179c8566a 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -78,6 +78,15 @@ Lisp_Object Qfield;
78 78
79static Lisp_Object Qboundary; 79static Lisp_Object Qboundary;
80 80
81/* The startup value of the TZ environment variable so it can be
82 restored if the user calls set-time-zone-rule with a nil
83 argument. If null, the TZ environment variable was unset. */
84static char const *initial_tz;
85
86/* True if the static variable tzvalbuf (defined in
87 set_time_zone_rule) is part of 'environ'. */
88static bool tzvalbuf_in_environ;
89
81 90
82void 91void
83init_editfns (void) 92init_editfns (void)
@@ -96,6 +105,9 @@ init_editfns (void)
96 return; 105 return;
97#endif /* not CANNOT_DUMP */ 106#endif /* not CANNOT_DUMP */
98 107
108 initial_tz = getenv ("TZ");
109 tzvalbuf_in_environ = 0;
110
99 pw = getpwuid (getuid ()); 111 pw = getpwuid (getuid ());
100#ifdef MSDOS 112#ifdef MSDOS
101 /* We let the real user name default to "root" because that's quite 113 /* We let the real user name default to "root" because that's quite
@@ -1900,9 +1912,11 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1900 } 1912 }
1901 else 1913 else
1902 { 1914 {
1903 char tzbuf[100]; 1915 static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d";
1916 char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)];
1917 char *old_tzstring;
1904 const char *tzstring; 1918 const char *tzstring;
1905 char **oldenv = environ, **newenv; 1919 USE_SAFE_ALLOCA;
1906 1920
1907 if (EQ (zone, Qt)) 1921 if (EQ (zone, Qt))
1908 tzstring = "UTC0"; 1922 tzstring = "UTC0";
@@ -1914,13 +1928,20 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1914 EMACS_INT zone_hr = abszone / (60*60); 1928 EMACS_INT zone_hr = abszone / (60*60);
1915 int zone_min = (abszone/60) % 60; 1929 int zone_min = (abszone/60) % 60;
1916 int zone_sec = abszone % 60; 1930 int zone_sec = abszone % 60;
1917 sprintf (tzbuf, "XXX%s%"pI"d:%02d:%02d", "-" + (XINT (zone) < 0), 1931 sprintf (tzbuf, tzbuf_format, "-" + (XINT (zone) < 0),
1918 zone_hr, zone_min, zone_sec); 1932 zone_hr, zone_min, zone_sec);
1919 tzstring = tzbuf; 1933 tzstring = tzbuf;
1920 } 1934 }
1921 else 1935 else
1922 error ("Invalid time zone specification"); 1936 error ("Invalid time zone specification");
1923 1937
1938 old_tzstring = getenv ("TZ");
1939 if (old_tzstring)
1940 {
1941 char *buf = SAFE_ALLOCA (strlen (old_tzstring) + 1);
1942 old_tzstring = strcpy (buf, old_tzstring);
1943 }
1944
1924 block_input (); 1945 block_input ();
1925 1946
1926 /* Set TZ before calling mktime; merely adjusting mktime's returned 1947 /* Set TZ before calling mktime; merely adjusting mktime's returned
@@ -1929,15 +1950,12 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1929 1950
1930 value = mktime (&tm); 1951 value = mktime (&tm);
1931 1952
1932 /* Restore TZ to previous value. */ 1953 set_time_zone_rule (old_tzstring);
1933 newenv = environ;
1934 environ = oldenv;
1935#ifdef LOCALTIME_CACHE 1954#ifdef LOCALTIME_CACHE
1936 tzset (); 1955 tzset ();
1937#endif 1956#endif
1938 unblock_input (); 1957 unblock_input ();
1939 1958 SAFE_FREE ();
1940 xfree (newenv);
1941 } 1959 }
1942 1960
1943 if (value == (time_t) -1) 1961 if (value == (time_t) -1)
@@ -2067,16 +2085,6 @@ the data it can't find. */)
2067 return list2 (zone_offset, zone_name); 2085 return list2 (zone_offset, zone_name);
2068} 2086}
2069 2087
2070/* This holds the value of `environ' produced by the previous
2071 call to Fset_time_zone_rule, or 0 if Fset_time_zone_rule
2072 has never been called. */
2073static char **environbuf;
2074
2075/* This holds the startup value of the TZ environment variable so it
2076 can be restored if the user calls set-time-zone-rule with a nil
2077 argument. */
2078static char *initial_tz;
2079
2080DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, 2088DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
2081 doc: /* Set the local time zone using TZ, a string specifying a time zone rule. 2089 doc: /* Set the local time zone using TZ, a string specifying a time zone rule.
2082If TZ is nil, use implementation-defined default time zone information. 2090If TZ is nil, use implementation-defined default time zone information.
@@ -2089,18 +2097,10 @@ only the former. */)
2089 (Lisp_Object tz) 2097 (Lisp_Object tz)
2090{ 2098{
2091 const char *tzstring; 2099 const char *tzstring;
2092 char **old_environbuf;
2093 2100
2094 if (! (NILP (tz) || EQ (tz, Qt))) 2101 if (! (NILP (tz) || EQ (tz, Qt)))
2095 CHECK_STRING (tz); 2102 CHECK_STRING (tz);
2096 2103
2097 block_input ();
2098
2099 /* When called for the first time, save the original TZ. */
2100 old_environbuf = environbuf;
2101 if (!old_environbuf)
2102 initial_tz = (char *) getenv ("TZ");
2103
2104 if (NILP (tz)) 2104 if (NILP (tz))
2105 tzstring = initial_tz; 2105 tzstring = initial_tz;
2106 else if (EQ (tz, Qt)) 2106 else if (EQ (tz, Qt))
@@ -2108,106 +2108,97 @@ only the former. */)
2108 else 2108 else
2109 tzstring = SSDATA (tz); 2109 tzstring = SSDATA (tz);
2110 2110
2111 block_input ();
2111 set_time_zone_rule (tzstring); 2112 set_time_zone_rule (tzstring);
2112 environbuf = environ;
2113
2114 unblock_input (); 2113 unblock_input ();
2115 2114
2116 xfree (old_environbuf);
2117 return Qnil; 2115 return Qnil;
2118} 2116}
2119 2117
2120#ifdef LOCALTIME_CACHE
2121
2122/* These two values are known to load tz files in buggy implementations,
2123 i.e. Solaris 1 executables running under either Solaris 1 or Solaris 2.
2124 Their values shouldn't matter in non-buggy implementations.
2125 We don't use string literals for these strings,
2126 since if a string in the environment is in readonly
2127 storage, it runs afoul of bugs in SVR4 and Solaris 2.3.
2128 See Sun bugs 1113095 and 1114114, ``Timezone routines
2129 improperly modify environment''. */
2130
2131static char set_time_zone_rule_tz1[] = "TZ=GMT+0";
2132static char set_time_zone_rule_tz2[] = "TZ=GMT+1";
2133
2134#endif
2135
2136/* Set the local time zone rule to TZSTRING. 2118/* Set the local time zone rule to TZSTRING.
2137 This allocates memory into `environ', which it is the caller's 2119
2138 responsibility to free. */ 2120 This function is not thread-safe, partly because putenv, unsetenv
2121 and tzset are not, and partly because of the static storage it
2122 updates. Other threads that invoke localtime etc. may be adversely
2123 affected while this function is executing. */
2139 2124
2140void 2125void
2141set_time_zone_rule (const char *tzstring) 2126set_time_zone_rule (const char *tzstring)
2142{ 2127{
2143 ptrdiff_t envptrs; 2128 /* A buffer holding a string of the form "TZ=value", intended
2144 char **from, **to, **newenv; 2129 to be part of the environment. */
2130 static char *tzvalbuf;
2131 static ptrdiff_t tzvalbufsize;
2145 2132
2146 /* Make the ENVIRON vector longer with room for TZSTRING. */ 2133 int tzeqlen = sizeof "TZ=" - 1;
2147 for (from = environ; *from; from++) 2134
2148 continue; 2135#ifdef LOCALTIME_CACHE
2149 envptrs = from - environ + 2; 2136 /* These two values are known to load tz files in buggy implementations,
2150 newenv = to = xmalloc (envptrs * sizeof *newenv 2137 i.e., Solaris 1 executables running under either Solaris 1 or Solaris 2.
2151 + (tzstring ? strlen (tzstring) + 4 : 0)); 2138 Their values shouldn't matter in non-buggy implementations.
2139 We don't use string literals for these strings,
2140 since if a string in the environment is in readonly
2141 storage, it runs afoul of bugs in SVR4 and Solaris 2.3.
2142 See Sun bugs 1113095 and 1114114, ``Timezone routines
2143 improperly modify environment''. */
2144
2145 static char set_time_zone_rule_tz[][sizeof "TZ=GMT+0"]
2146 = { "TZ=GMT+0", "TZ=GMT+1" };
2147
2148 /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like
2149 "US/Pacific" that loads a tz file, then changes to a value like
2150 "XXX0" that does not load a tz file, and then changes back to
2151 its original value, the last change is (incorrectly) ignored.
2152 Also, if TZ changes twice in succession to values that do
2153 not load a tz file, tzset can dump core (see Sun bug#1225179).
2154 The following code works around these bugs. */
2152 2155
2153 /* Add TZSTRING to the end of environ, as a value for TZ. */
2154 if (tzstring) 2156 if (tzstring)
2155 { 2157 {
2156 char *t = (char *) (to + envptrs); 2158 /* Temporarily set TZ to a value that loads a tz file
2157 strcpy (t, "TZ="); 2159 and that differs from tzstring. */
2158 strcat (t, tzstring); 2160 bool eq0 = strcmp (tzstring, set_time_zone_rule_tz[0] + tzeqlen) == 0;
2159 *to++ = t; 2161 xputenv (set_time_zone_rule_tz[eq0]);
2160 } 2162 }
2163 else
2164 {
2165 /* The implied tzstring is unknown, so temporarily set TZ to
2166 two different values that each load a tz file. */
2167 xputenv (set_time_zone_rule_tz[0]);
2168 tzset ();
2169 xputenv (set_time_zone_rule_tz[1]);
2170 }
2171 tzset ();
2172#endif
2161 2173
2162 /* Copy the old environ vector elements into NEWENV, 2174 if (!tzstring)
2163 but don't copy the TZ variable. 2175 {
2164 So we have only one definition of TZ, which came from TZSTRING. */ 2176 unsetenv ("TZ");
2165 for (from = environ; *from; from++) 2177 tzvalbuf_in_environ = 0;
2166 if (strncmp (*from, "TZ=", 3) != 0) 2178 }
2167 *to++ = *from; 2179 else
2168 *to = 0; 2180 {
2169 2181 ptrdiff_t tzstringlen = strlen (tzstring);
2170 environ = newenv;
2171 2182
2172 /* If we do have a TZSTRING, NEWENV points to the vector slot where 2183 if (tzvalbufsize <= tzeqlen + tzstringlen)
2173 the TZ variable is stored. If we do not have a TZSTRING, 2184 {
2174 TO points to the vector slot which has the terminating null. */ 2185 unsetenv ("TZ");
2186 tzvalbuf_in_environ = 0;
2187 tzvalbuf = xpalloc (tzvalbuf, &tzvalbufsize,
2188 tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1);
2189 memcpy (tzvalbuf, "TZ=", tzeqlen);
2190 }
2175 2191
2176#ifdef LOCALTIME_CACHE 2192 strcpy (tzvalbuf + tzeqlen, tzstring);
2177 {
2178 /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like
2179 "US/Pacific" that loads a tz file, then changes to a value like
2180 "XXX0" that does not load a tz file, and then changes back to
2181 its original value, the last change is (incorrectly) ignored.
2182 Also, if TZ changes twice in succession to values that do
2183 not load a tz file, tzset can dump core (see Sun bug#1225179).
2184 The following code works around these bugs. */
2185
2186 if (tzstring)
2187 {
2188 /* Temporarily set TZ to a value that loads a tz file
2189 and that differs from tzstring. */
2190 char *tz = *newenv;
2191 *newenv = (strcmp (tzstring, set_time_zone_rule_tz1 + 3) == 0
2192 ? set_time_zone_rule_tz2 : set_time_zone_rule_tz1);
2193 tzset ();
2194 *newenv = tz;
2195 }
2196 else
2197 {
2198 /* The implied tzstring is unknown, so temporarily set TZ to
2199 two different values that each load a tz file. */
2200 *to = set_time_zone_rule_tz1;
2201 to[1] = 0;
2202 tzset ();
2203 *to = set_time_zone_rule_tz2;
2204 tzset ();
2205 *to = 0;
2206 }
2207 2193
2208 /* Now TZ has the desired value, and tzset can be invoked safely. */ 2194 if (!tzvalbuf_in_environ)
2209 } 2195 {
2196 xputenv (tzvalbuf);
2197 tzvalbuf_in_environ = 1;
2198 }
2199 }
2210 2200
2201#ifdef LOCALTIME_CACHE
2211 tzset (); 2202 tzset ();
2212#endif 2203#endif
2213} 2204}
@@ -4800,9 +4791,6 @@ Transposing beyond buffer boundaries is an error. */)
4800void 4791void
4801syms_of_editfns (void) 4792syms_of_editfns (void)
4802{ 4793{
4803 environbuf = 0;
4804 initial_tz = 0;
4805
4806 DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); 4794 DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions");
4807 4795
4808 DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, 4796 DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion,
diff --git a/src/emacs.c b/src/emacs.c
index b2b193e3a4f..fbaf0355000 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -535,7 +535,7 @@ DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
535#ifdef HAVE_TZSET 535#ifdef HAVE_TZSET
536/* A valid but unlikely value for the TZ environment value. 536/* A valid but unlikely value for the TZ environment value.
537 It is OK (though a bit slower) if the user actually chooses this value. */ 537 It is OK (though a bit slower) if the user actually chooses this value. */
538static char dump_tz[] = "UtC0"; 538static char const dump_tz[] = "UtC0";
539#endif 539#endif
540 540
541#ifndef ORDINARY_LINK 541#ifndef ORDINARY_LINK
@@ -717,7 +717,7 @@ main (int argc, char **argv)
717 717
718#ifdef G_SLICE_ALWAYS_MALLOC 718#ifdef G_SLICE_ALWAYS_MALLOC
719 /* This is used by the Cygwin build. */ 719 /* This is used by the Cygwin build. */
720 setenv ("G_SLICE", "always-malloc", 1); 720 xputenv ("G_SLICE=always-malloc");
721#endif 721#endif
722 722
723#ifdef GNU_LINUX 723#ifdef GNU_LINUX
@@ -803,9 +803,8 @@ main (int argc, char **argv)
803#ifdef HAVE_PERSONALITY_LINUX32 803#ifdef HAVE_PERSONALITY_LINUX32
804 if (dumping && ! getenv ("EMACS_HEAP_EXEC")) 804 if (dumping && ! getenv ("EMACS_HEAP_EXEC"))
805 { 805 {
806 static char heapexec[] = "EMACS_HEAP_EXEC=true";
807 /* Set this so we only do this once. */ 806 /* Set this so we only do this once. */
808 putenv (heapexec); 807 xputenv ("EMACS_HEAP_EXEC=true");
809 808
810 /* A flag to turn off address randomization which is introduced 809 /* A flag to turn off address randomization which is introduced
811 in linux kernel shipped with fedora core 4 */ 810 in linux kernel shipped with fedora core 4 */
@@ -1309,7 +1308,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1309 don't pollute Vglobal_environment. */ 1308 don't pollute Vglobal_environment. */
1310 /* Setting LANG here will defeat the startup locale processing... */ 1309 /* Setting LANG here will defeat the startup locale processing... */
1311#ifdef AIX 1310#ifdef AIX
1312 putenv ("LANG=C"); 1311 xputenv ("LANG=C");
1313#endif 1312#endif
1314 1313
1315 init_buffer (); /* Init default directory of main buffer. */ 1314 init_buffer (); /* Init default directory of main buffer. */
diff --git a/src/lisp.h b/src/lisp.h
index 172a32e92a9..91fc3dfa1c6 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3594,6 +3594,7 @@ extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t);
3594extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); 3594extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
3595 3595
3596extern char *xstrdup (const char *); 3596extern char *xstrdup (const char *);
3597extern void xputenv (const char *);
3597 3598
3598extern char *egetenv (const char *); 3599extern char *egetenv (const char *);
3599 3600
diff --git a/src/xterm.c b/src/xterm.c
index 8acd1d7843e..e9e99574663 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9908,10 +9908,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9908 9908
9909 /* Emacs can only handle core input events, so make sure 9909 /* Emacs can only handle core input events, so make sure
9910 Gtk doesn't use Xinput or Xinput2 extensions. */ 9910 Gtk doesn't use Xinput or Xinput2 extensions. */
9911 { 9911 xputenv ("GDK_CORE_DEVICE_EVENTS=1");
9912 static char fix_events[] = "GDK_CORE_DEVICE_EVENTS=1";
9913 putenv (fix_events);
9914 }
9915 9912
9916 /* Work around GLib bug that outputs a faulty warning. See 9913 /* Work around GLib bug that outputs a faulty warning. See
9917 https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ 9914 https://bugzilla.gnome.org/show_bug.cgi?id=563627. */