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
This commit is contained in:
parent
c56efa4074
commit
5745a7df2b
16 changed files with 661 additions and 125 deletions
|
@ -1,3 +1,10 @@
|
|||
2012-12-08 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Use putenv+unsetenv instead of modifying environ directly (Bug#13070).
|
||||
* 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.
|
||||
|
||||
2012-12-08 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* lib/makefile.w32-in ($(BLD)/sig2str.$(O)): New dependency.
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
2012-12-08 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Use putenv+unsetenv instead of modifying environ directly (Bug#13070).
|
||||
* merge-gnulib (GNULIB_MODULES): Add putenv, unsetenv.
|
||||
|
||||
Simplify get_lim_data.
|
||||
* CPP-DEFINES (ULIMIT_BREAK_VALUE): Remove.
|
||||
|
||||
|
|
|
@ -31,10 +31,10 @@ GNULIB_MODULES='
|
|||
dtoastr dtotimespec dup2 environ execinfo faccessat
|
||||
fcntl-h filemode getloadavg getopt-gnu gettime gettimeofday
|
||||
ignore-value intprops largefile lstat
|
||||
manywarnings mktime pselect pthread_sigmask readlink
|
||||
manywarnings mktime pselect pthread_sigmask putenv readlink
|
||||
sig2str socklen stat-time stdalign stdarg stdbool stdio
|
||||
strftime strtoimax strtoumax symlink sys_stat
|
||||
sys_time time timer-time timespec-add timespec-sub utimens
|
||||
sys_time time timer-time timespec-add timespec-sub unsetenv utimens
|
||||
warnings
|
||||
'
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
# the same distribution terms as the rest of that program.
|
||||
#
|
||||
# Generated by gnulib-tool.
|
||||
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=at-internal --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=openat-die --avoid=openat-h --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl-h filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings
|
||||
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=at-internal --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=openat-die --avoid=openat-h --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl-h filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask putenv readlink sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings
|
||||
|
||||
|
||||
MOSTLYCLEANFILES += core *.stackdump
|
||||
|
@ -439,6 +439,15 @@ EXTRA_libgnu_a_SOURCES += pthread_sigmask.c
|
|||
|
||||
## end gnulib module pthread_sigmask
|
||||
|
||||
## begin gnulib module putenv
|
||||
|
||||
|
||||
EXTRA_DIST += putenv.c
|
||||
|
||||
EXTRA_libgnu_a_SOURCES += putenv.c
|
||||
|
||||
## end gnulib module putenv
|
||||
|
||||
## begin gnulib module readlink
|
||||
|
||||
|
||||
|
@ -1409,6 +1418,15 @@ EXTRA_DIST += unistd.in.h
|
|||
|
||||
## end gnulib module unistd
|
||||
|
||||
## begin gnulib module unsetenv
|
||||
|
||||
|
||||
EXTRA_DIST += unsetenv.c
|
||||
|
||||
EXTRA_libgnu_a_SOURCES += unsetenv.c
|
||||
|
||||
## end gnulib module unsetenv
|
||||
|
||||
## begin gnulib module utimens
|
||||
|
||||
libgnu_a_SOURCES += utimens.c
|
||||
|
|
134
lib/putenv.c
Normal file
134
lib/putenv.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2012 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3 of the License, or any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* Include errno.h *after* sys/types.h to work around header problems
|
||||
on AIX 3.2.5. */
|
||||
#include <errno.h>
|
||||
#ifndef __set_errno
|
||||
# define __set_errno(ev) ((errno) = (ev))
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if _LIBC
|
||||
# if HAVE_GNU_LD
|
||||
# define environ __environ
|
||||
# else
|
||||
extern char **environ;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if _LIBC
|
||||
/* This lock protects against simultaneous modifications of 'environ'. */
|
||||
# include <bits/libc-lock.h>
|
||||
__libc_lock_define_initialized (static, envlock)
|
||||
# define LOCK __libc_lock_lock (envlock)
|
||||
# define UNLOCK __libc_lock_unlock (envlock)
|
||||
#else
|
||||
# define LOCK
|
||||
# define UNLOCK
|
||||
#endif
|
||||
|
||||
static int
|
||||
_unsetenv (const char *name)
|
||||
{
|
||||
size_t len;
|
||||
char **ep;
|
||||
|
||||
if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen (name);
|
||||
|
||||
LOCK;
|
||||
|
||||
ep = environ;
|
||||
while (*ep != NULL)
|
||||
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
{
|
||||
/* Found it. Remove this pointer by moving later ones back. */
|
||||
char **dp = ep;
|
||||
|
||||
do
|
||||
dp[0] = dp[1];
|
||||
while (*dp++);
|
||||
/* Continue the loop in case NAME appears again. */
|
||||
}
|
||||
else
|
||||
++ep;
|
||||
|
||||
UNLOCK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Put STRING, which is of the form "NAME=VALUE", in the environment.
|
||||
If STRING contains no '=', then remove STRING from the environment. */
|
||||
int
|
||||
putenv (char *string)
|
||||
{
|
||||
const char *const name_end = strchr (string, '=');
|
||||
register size_t size;
|
||||
register char **ep;
|
||||
|
||||
if (name_end == NULL)
|
||||
{
|
||||
/* Remove the variable from the environment. */
|
||||
return _unsetenv (string);
|
||||
}
|
||||
|
||||
size = 0;
|
||||
for (ep = environ; *ep != NULL; ++ep)
|
||||
if (!strncmp (*ep, string, name_end - string) &&
|
||||
(*ep)[name_end - string] == '=')
|
||||
break;
|
||||
else
|
||||
++size;
|
||||
|
||||
if (*ep == NULL)
|
||||
{
|
||||
static char **last_environ = NULL;
|
||||
char **new_environ = (char **) malloc ((size + 2) * sizeof (char *));
|
||||
if (new_environ == NULL)
|
||||
return -1;
|
||||
(void) memcpy ((void *) new_environ, (void *) environ,
|
||||
size * sizeof (char *));
|
||||
new_environ[size] = (char *) string;
|
||||
new_environ[size + 1] = NULL;
|
||||
free (last_environ);
|
||||
last_environ = new_environ;
|
||||
environ = new_environ;
|
||||
}
|
||||
else
|
||||
*ep = string;
|
||||
|
||||
return 0;
|
||||
}
|
127
lib/unsetenv.c
Normal file
127
lib/unsetenv.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* Copyright (C) 1992, 1995-2002, 2005-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
|
||||
optimizes away the name == NULL test below. */
|
||||
#define _GL_ARG_NONNULL(params)
|
||||
|
||||
/* Specification. */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <errno.h>
|
||||
#if !_LIBC
|
||||
# define __set_errno(ev) ((errno) = (ev))
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !_LIBC
|
||||
# define __environ environ
|
||||
#endif
|
||||
|
||||
#if _LIBC
|
||||
/* This lock protects against simultaneous modifications of 'environ'. */
|
||||
# include <bits/libc-lock.h>
|
||||
__libc_lock_define_initialized (static, envlock)
|
||||
# define LOCK __libc_lock_lock (envlock)
|
||||
# define UNLOCK __libc_lock_unlock (envlock)
|
||||
#else
|
||||
# define LOCK
|
||||
# define UNLOCK
|
||||
#endif
|
||||
|
||||
/* In the GNU C library we must keep the namespace clean. */
|
||||
#ifdef _LIBC
|
||||
# define unsetenv __unsetenv
|
||||
#endif
|
||||
|
||||
#if _LIBC || !HAVE_UNSETENV
|
||||
|
||||
int
|
||||
unsetenv (const char *name)
|
||||
{
|
||||
size_t len;
|
||||
char **ep;
|
||||
|
||||
if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen (name);
|
||||
|
||||
LOCK;
|
||||
|
||||
ep = __environ;
|
||||
while (*ep != NULL)
|
||||
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
{
|
||||
/* Found it. Remove this pointer by moving later ones back. */
|
||||
char **dp = ep;
|
||||
|
||||
do
|
||||
dp[0] = dp[1];
|
||||
while (*dp++);
|
||||
/* Continue the loop in case NAME appears again. */
|
||||
}
|
||||
else
|
||||
++ep;
|
||||
|
||||
UNLOCK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
# undef unsetenv
|
||||
weak_alias (__unsetenv, unsetenv)
|
||||
#endif
|
||||
|
||||
#else /* HAVE_UNSETENV */
|
||||
|
||||
# undef unsetenv
|
||||
# if !HAVE_DECL_UNSETENV
|
||||
# if VOID_UNSETENV
|
||||
extern void unsetenv (const char *);
|
||||
# else
|
||||
extern int unsetenv (const char *);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Call the underlying unsetenv, in case there is hidden bookkeeping
|
||||
that needs updating beyond just modifying environ. */
|
||||
int
|
||||
rpl_unsetenv (const char *name)
|
||||
{
|
||||
int result = 0;
|
||||
if (!name || !*name || strchr (name, '='))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
while (getenv (name))
|
||||
# if !VOID_UNSETENV
|
||||
result =
|
||||
# endif
|
||||
unsetenv (name);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* HAVE_UNSETENV */
|
|
@ -85,6 +85,7 @@ AC_DEFUN([gl_EARLY],
|
|||
# Code from module pathmax:
|
||||
# Code from module pselect:
|
||||
# Code from module pthread_sigmask:
|
||||
# Code from module putenv:
|
||||
# Code from module readlink:
|
||||
# Code from module root-uid:
|
||||
# Code from module sig2str:
|
||||
|
@ -126,6 +127,7 @@ AC_DEFUN([gl_EARLY],
|
|||
# Code from module timespec-sub:
|
||||
# Code from module u64:
|
||||
# Code from module unistd:
|
||||
# Code from module unsetenv:
|
||||
# Code from module utimens:
|
||||
# Code from module verify:
|
||||
# Code from module warnings:
|
||||
|
@ -240,6 +242,11 @@ AC_DEFUN([gl_INIT],
|
|||
gl_PREREQ_PTHREAD_SIGMASK
|
||||
fi
|
||||
gl_SIGNAL_MODULE_INDICATOR([pthread_sigmask])
|
||||
gl_FUNC_PUTENV
|
||||
if test $REPLACE_PUTENV = 1; then
|
||||
AC_LIBOBJ([putenv])
|
||||
fi
|
||||
gl_STDLIB_MODULE_INDICATOR([putenv])
|
||||
gl_FUNC_READLINK
|
||||
if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
|
||||
AC_LIBOBJ([readlink])
|
||||
|
@ -297,6 +304,12 @@ AC_DEFUN([gl_INIT],
|
|||
gl_TIMER_TIME
|
||||
gl_TIMESPEC
|
||||
gl_UNISTD_H
|
||||
gl_FUNC_UNSETENV
|
||||
if test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1; then
|
||||
AC_LIBOBJ([unsetenv])
|
||||
gl_PREREQ_UNSETENV
|
||||
fi
|
||||
gl_STDLIB_MODULE_INDICATOR([unsetenv])
|
||||
gl_UTIMENS
|
||||
gl_gnulib_enabled_dosname=false
|
||||
gl_gnulib_enabled_euidaccess=false
|
||||
|
@ -679,6 +692,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/pathmax.h
|
||||
lib/pselect.c
|
||||
lib/pthread_sigmask.c
|
||||
lib/putenv.c
|
||||
lib/readlink.c
|
||||
lib/root-uid.h
|
||||
lib/sha1.c
|
||||
|
@ -723,6 +737,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/u64.h
|
||||
lib/unistd.c
|
||||
lib/unistd.in.h
|
||||
lib/unsetenv.c
|
||||
lib/utimens.c
|
||||
lib/utimens.h
|
||||
lib/verify.h
|
||||
|
@ -764,7 +779,9 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
m4/pathmax.m4
|
||||
m4/pselect.m4
|
||||
m4/pthread_sigmask.m4
|
||||
m4/putenv.m4
|
||||
m4/readlink.m4
|
||||
m4/setenv.m4
|
||||
m4/sha1.m4
|
||||
m4/sha256.m4
|
||||
m4/sha512.m4
|
||||
|
|
50
m4/putenv.m4
Normal file
50
m4/putenv.m4
Normal file
|
@ -0,0 +1,50 @@
|
|||
# putenv.m4 serial 19
|
||||
dnl Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl From Jim Meyering.
|
||||
dnl
|
||||
dnl Check whether putenv ("FOO") removes FOO from the environment.
|
||||
dnl The putenv in libc on at least SunOS 4.1.4 does *not* do that.
|
||||
|
||||
AC_DEFUN([gl_FUNC_PUTENV],
|
||||
[
|
||||
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
AC_CACHE_CHECK([for putenv compatible with GNU and SVID],
|
||||
[gl_cv_func_svid_putenv],
|
||||
[AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],[[
|
||||
/* Put it in env. */
|
||||
if (putenv ("CONFTEST_putenv=val"))
|
||||
return 1;
|
||||
|
||||
/* Try to remove it. */
|
||||
if (putenv ("CONFTEST_putenv"))
|
||||
return 2;
|
||||
|
||||
/* Make sure it was deleted. */
|
||||
if (getenv ("CONFTEST_putenv") != 0)
|
||||
return 3;
|
||||
|
||||
return 0;
|
||||
]])],
|
||||
gl_cv_func_svid_putenv=yes,
|
||||
gl_cv_func_svid_putenv=no,
|
||||
dnl When crosscompiling, assume putenv is broken.
|
||||
[case "$host_os" in
|
||||
# Guess yes on glibc systems.
|
||||
*-gnu*) gl_cv_func_svid_putenv="guessing yes" ;;
|
||||
# If we don't know, assume the worst.
|
||||
*) gl_cv_func_svid_putenv="guessing no" ;;
|
||||
esac
|
||||
])
|
||||
])
|
||||
case "$gl_cv_func_svid_putenv" in
|
||||
*yes) ;;
|
||||
*)
|
||||
REPLACE_PUTENV=1
|
||||
;;
|
||||
esac
|
||||
])
|
160
m4/setenv.m4
Normal file
160
m4/setenv.m4
Normal file
|
@ -0,0 +1,160 @@
|
|||
# setenv.m4 serial 26
|
||||
dnl Copyright (C) 2001-2004, 2006-2012 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_FUNC_SETENV],
|
||||
[
|
||||
AC_REQUIRE([gl_FUNC_SETENV_SEPARATE])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
if test $ac_cv_func_setenv = no; then
|
||||
HAVE_SETENV=0
|
||||
else
|
||||
AC_CACHE_CHECK([whether setenv validates arguments],
|
||||
[gl_cv_func_setenv_works],
|
||||
[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
]], [[
|
||||
int result = 0;
|
||||
{
|
||||
if (setenv ("", "", 0) != -1)
|
||||
result |= 1;
|
||||
else if (errno != EINVAL)
|
||||
result |= 2;
|
||||
}
|
||||
{
|
||||
if (setenv ("a", "=", 1) != 0)
|
||||
result |= 4;
|
||||
else if (strcmp (getenv ("a"), "=") != 0)
|
||||
result |= 8;
|
||||
}
|
||||
return result;
|
||||
]])],
|
||||
[gl_cv_func_setenv_works=yes], [gl_cv_func_setenv_works=no],
|
||||
[case "$host_os" in
|
||||
# Guess yes on glibc systems.
|
||||
*-gnu*) gl_cv_func_setenv_works="guessing yes" ;;
|
||||
# If we don't know, assume the worst.
|
||||
*) gl_cv_func_setenv_works="guessing no" ;;
|
||||
esac
|
||||
])])
|
||||
case "$gl_cv_func_setenv_works" in
|
||||
*yes) ;;
|
||||
*)
|
||||
REPLACE_SETENV=1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
|
||||
# Like gl_FUNC_SETENV, except prepare for separate compilation
|
||||
# (no REPLACE_SETENV, no AC_LIBOBJ).
|
||||
AC_DEFUN([gl_FUNC_SETENV_SEPARATE],
|
||||
[
|
||||
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
|
||||
AC_CHECK_DECLS_ONCE([setenv])
|
||||
if test $ac_cv_have_decl_setenv = no; then
|
||||
HAVE_DECL_SETENV=0
|
||||
fi
|
||||
AC_CHECK_FUNCS_ONCE([setenv])
|
||||
gl_PREREQ_SETENV
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_FUNC_UNSETENV],
|
||||
[
|
||||
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
AC_CHECK_DECLS_ONCE([unsetenv])
|
||||
if test $ac_cv_have_decl_unsetenv = no; then
|
||||
HAVE_DECL_UNSETENV=0
|
||||
fi
|
||||
AC_CHECK_FUNCS([unsetenv])
|
||||
if test $ac_cv_func_unsetenv = no; then
|
||||
HAVE_UNSETENV=0
|
||||
else
|
||||
HAVE_UNSETENV=1
|
||||
dnl Some BSDs return void, failing to do error checking.
|
||||
AC_CACHE_CHECK([for unsetenv() return type], [gt_cv_func_unsetenv_ret],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[
|
||||
#undef _BSD
|
||||
#define _BSD 1 /* unhide unsetenv declaration in OSF/1 5.1 <stdlib.h> */
|
||||
#include <stdlib.h>
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
int unsetenv (const char *name);
|
||||
]],
|
||||
[[]])],
|
||||
[gt_cv_func_unsetenv_ret='int'],
|
||||
[gt_cv_func_unsetenv_ret='void'])])
|
||||
if test $gt_cv_func_unsetenv_ret = 'void'; then
|
||||
AC_DEFINE([VOID_UNSETENV], [1], [Define to 1 if unsetenv returns void
|
||||
instead of int.])
|
||||
REPLACE_UNSETENV=1
|
||||
fi
|
||||
|
||||
dnl Solaris 10 unsetenv does not remove all copies of a name.
|
||||
dnl Haiku alpha 2 unsetenv gets confused by assignment to environ.
|
||||
dnl OpenBSD 4.7 unsetenv("") does not fail.
|
||||
AC_CACHE_CHECK([whether unsetenv obeys POSIX],
|
||||
[gl_cv_func_unsetenv_works],
|
||||
[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
extern char **environ;
|
||||
]], [[
|
||||
char entry1[] = "a=1";
|
||||
char entry2[] = "b=2";
|
||||
char *env[] = { entry1, entry2, NULL };
|
||||
if (putenv ((char *) "a=1")) return 1;
|
||||
if (putenv (entry2)) return 2;
|
||||
entry2[0] = 'a';
|
||||
unsetenv ("a");
|
||||
if (getenv ("a")) return 3;
|
||||
if (!unsetenv ("") || errno != EINVAL) return 4;
|
||||
entry2[0] = 'b';
|
||||
environ = env;
|
||||
if (!getenv ("a")) return 5;
|
||||
entry2[0] = 'a';
|
||||
unsetenv ("a");
|
||||
if (getenv ("a")) return 6;
|
||||
]])],
|
||||
[gl_cv_func_unsetenv_works=yes], [gl_cv_func_unsetenv_works=no],
|
||||
[case "$host_os" in
|
||||
# Guess yes on glibc systems.
|
||||
*-gnu*) gl_cv_func_unsetenv_works="guessing yes" ;;
|
||||
# If we don't know, assume the worst.
|
||||
*) gl_cv_func_unsetenv_works="guessing no" ;;
|
||||
esac
|
||||
])])
|
||||
case "$gl_cv_func_unsetenv_works" in
|
||||
*yes) ;;
|
||||
*)
|
||||
REPLACE_UNSETENV=1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
|
||||
# Prerequisites of lib/setenv.c.
|
||||
AC_DEFUN([gl_PREREQ_SETENV],
|
||||
[
|
||||
AC_REQUIRE([AC_FUNC_ALLOCA])
|
||||
AC_REQUIRE([gl_ENVIRON])
|
||||
AC_CHECK_HEADERS_ONCE([unistd.h])
|
||||
AC_CHECK_HEADERS([search.h])
|
||||
AC_CHECK_FUNCS([tsearch])
|
||||
])
|
||||
|
||||
# Prerequisites of lib/unsetenv.c.
|
||||
AC_DEFUN([gl_PREREQ_UNSETENV],
|
||||
[
|
||||
AC_REQUIRE([gl_ENVIRON])
|
||||
AC_CHECK_HEADERS_ONCE([unistd.h])
|
||||
])
|
|
@ -1,3 +1,29 @@
|
|||
2012-12-08 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Use putenv+unsetenv instead of modifying environ directly (Bug#13070).
|
||||
* alloc.c (xputenv): New function.
|
||||
* dbusbind.c (Fdbus_init_bus):
|
||||
* emacs.c (main):
|
||||
* xterm.c (x_term_init):
|
||||
Use xputenv instead of setenv or putenv, to detect memory exhaustion.
|
||||
* 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.
|
||||
* emacs.c (dump_tz) [HAVE_TZSET]: Now const.
|
||||
* lisp.h (xputenv): New decl.
|
||||
|
||||
2012-12-08 Fabrice Popineau <fabrice.popineau@gmail.com>
|
||||
|
||||
* w32fns.c (emacs_abort): Don't do arithmetics on void pointers.
|
||||
|
|
|
@ -820,6 +820,15 @@ xstrdup (const char *s)
|
|||
return p;
|
||||
}
|
||||
|
||||
/* Like putenv, but (1) use the equivalent of xmalloc and (2) the
|
||||
argument is a const pointer. */
|
||||
|
||||
void
|
||||
xputenv (char const *string)
|
||||
{
|
||||
if (putenv ((char *) string) != 0)
|
||||
memory_full (0);
|
||||
}
|
||||
|
||||
/* Unwind for SAFE_ALLOCA */
|
||||
|
||||
|
|
|
@ -1203,7 +1203,7 @@ this connection to those buses. */)
|
|||
xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses);
|
||||
|
||||
/* We do not want to abort. */
|
||||
putenv ((char *) "DBUS_FATAL_WARNINGS=0");
|
||||
xputenv ("DBUS_FATAL_WARNINGS=0");
|
||||
|
||||
/* Cleanup. */
|
||||
dbus_error_free (&derror);
|
||||
|
|
212
src/editfns.c
212
src/editfns.c
|
@ -78,6 +78,15 @@ Lisp_Object Qfield;
|
|||
|
||||
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. */
|
||||
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;
|
||||
|
||||
|
||||
void
|
||||
init_editfns (void)
|
||||
|
@ -96,6 +105,9 @@ init_editfns (void)
|
|||
return;
|
||||
#endif /* not CANNOT_DUMP */
|
||||
|
||||
initial_tz = getenv ("TZ");
|
||||
tzvalbuf_in_environ = 0;
|
||||
|
||||
pw = getpwuid (getuid ());
|
||||
#ifdef MSDOS
|
||||
/* 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) */)
|
|||
}
|
||||
else
|
||||
{
|
||||
char tzbuf[100];
|
||||
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;
|
||||
char **oldenv = environ, **newenv;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
if (EQ (zone, Qt))
|
||||
tzstring = "UTC0";
|
||||
|
@ -1914,13 +1928,20 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
|
|||
EMACS_INT zone_hr = abszone / (60*60);
|
||||
int zone_min = (abszone/60) % 60;
|
||||
int zone_sec = abszone % 60;
|
||||
sprintf (tzbuf, "XXX%s%"pI"d:%02d:%02d", "-" + (XINT (zone) < 0),
|
||||
sprintf (tzbuf, tzbuf_format, "-" + (XINT (zone) < 0),
|
||||
zone_hr, zone_min, zone_sec);
|
||||
tzstring = tzbuf;
|
||||
}
|
||||
else
|
||||
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
|
||||
|
@ -1929,15 +1950,12 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
|
|||
|
||||
value = mktime (&tm);
|
||||
|
||||
/* Restore TZ to previous value. */
|
||||
newenv = environ;
|
||||
environ = oldenv;
|
||||
set_time_zone_rule (old_tzstring);
|
||||
#ifdef LOCALTIME_CACHE
|
||||
tzset ();
|
||||
#endif
|
||||
unblock_input ();
|
||||
|
||||
xfree (newenv);
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
if (value == (time_t) -1)
|
||||
|
@ -2067,16 +2085,6 @@ the data it can't find. */)
|
|||
return list2 (zone_offset, zone_name);
|
||||
}
|
||||
|
||||
/* This holds the value of `environ' produced by the previous
|
||||
call to Fset_time_zone_rule, or 0 if Fset_time_zone_rule
|
||||
has never been called. */
|
||||
static char **environbuf;
|
||||
|
||||
/* This holds 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. */
|
||||
static char *initial_tz;
|
||||
|
||||
DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
|
||||
doc: /* Set the local time zone using TZ, a string specifying a time zone rule.
|
||||
If TZ is nil, use implementation-defined default time zone information.
|
||||
|
@ -2089,18 +2097,10 @@ only the former. */)
|
|||
(Lisp_Object tz)
|
||||
{
|
||||
const char *tzstring;
|
||||
char **old_environbuf;
|
||||
|
||||
if (! (NILP (tz) || EQ (tz, Qt)))
|
||||
CHECK_STRING (tz);
|
||||
|
||||
block_input ();
|
||||
|
||||
/* When called for the first time, save the original TZ. */
|
||||
old_environbuf = environbuf;
|
||||
if (!old_environbuf)
|
||||
initial_tz = (char *) getenv ("TZ");
|
||||
|
||||
if (NILP (tz))
|
||||
tzstring = initial_tz;
|
||||
else if (EQ (tz, Qt))
|
||||
|
@ -2108,106 +2108,97 @@ only the former. */)
|
|||
else
|
||||
tzstring = SSDATA (tz);
|
||||
|
||||
block_input ();
|
||||
set_time_zone_rule (tzstring);
|
||||
environbuf = environ;
|
||||
|
||||
unblock_input ();
|
||||
|
||||
xfree (old_environbuf);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
#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_tz1[] = "TZ=GMT+0";
|
||||
static char set_time_zone_rule_tz2[] = "TZ=GMT+1";
|
||||
|
||||
#endif
|
||||
|
||||
/* Set the local time zone rule to TZSTRING.
|
||||
This allocates memory into `environ', which it is the caller's
|
||||
responsibility to free. */
|
||||
|
||||
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. */
|
||||
|
||||
void
|
||||
set_time_zone_rule (const char *tzstring)
|
||||
{
|
||||
ptrdiff_t envptrs;
|
||||
char **from, **to, **newenv;
|
||||
/* A buffer holding a string of the form "TZ=value", intended
|
||||
to be part of the environment. */
|
||||
static char *tzvalbuf;
|
||||
static ptrdiff_t tzvalbufsize;
|
||||
|
||||
/* Make the ENVIRON vector longer with room for TZSTRING. */
|
||||
for (from = environ; *from; from++)
|
||||
continue;
|
||||
envptrs = from - environ + 2;
|
||||
newenv = to = xmalloc (envptrs * sizeof *newenv
|
||||
+ (tzstring ? strlen (tzstring) + 4 : 0));
|
||||
|
||||
/* Add TZSTRING to the end of environ, as a value for TZ. */
|
||||
if (tzstring)
|
||||
{
|
||||
char *t = (char *) (to + envptrs);
|
||||
strcpy (t, "TZ=");
|
||||
strcat (t, tzstring);
|
||||
*to++ = t;
|
||||
}
|
||||
|
||||
/* Copy the old environ vector elements into NEWENV,
|
||||
but don't copy the TZ variable.
|
||||
So we have only one definition of TZ, which came from TZSTRING. */
|
||||
for (from = environ; *from; from++)
|
||||
if (strncmp (*from, "TZ=", 3) != 0)
|
||||
*to++ = *from;
|
||||
*to = 0;
|
||||
|
||||
environ = newenv;
|
||||
|
||||
/* If we do have a TZSTRING, NEWENV points to the vector slot where
|
||||
the TZ variable is stored. If we do not have a TZSTRING,
|
||||
TO points to the vector slot which has the terminating null. */
|
||||
int tzeqlen = sizeof "TZ=" - 1;
|
||||
|
||||
#ifdef LOCALTIME_CACHE
|
||||
{
|
||||
/* 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. */
|
||||
/* 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''. */
|
||||
|
||||
if (tzstring)
|
||||
{
|
||||
/* Temporarily set TZ to a value that loads a tz file
|
||||
and that differs from tzstring. */
|
||||
char *tz = *newenv;
|
||||
*newenv = (strcmp (tzstring, set_time_zone_rule_tz1 + 3) == 0
|
||||
? set_time_zone_rule_tz2 : set_time_zone_rule_tz1);
|
||||
tzset ();
|
||||
*newenv = tz;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The implied tzstring is unknown, so temporarily set TZ to
|
||||
two different values that each load a tz file. */
|
||||
*to = set_time_zone_rule_tz1;
|
||||
to[1] = 0;
|
||||
tzset ();
|
||||
*to = set_time_zone_rule_tz2;
|
||||
tzset ();
|
||||
*to = 0;
|
||||
}
|
||||
static char set_time_zone_rule_tz[][sizeof "TZ=GMT+0"]
|
||||
= { "TZ=GMT+0", "TZ=GMT+1" };
|
||||
|
||||
/* Now TZ has the desired value, and tzset can be invoked safely. */
|
||||
}
|
||||
/* 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. */
|
||||
|
||||
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 ();
|
||||
#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
|
||||
tzset ();
|
||||
#endif
|
||||
}
|
||||
|
@ -4800,9 +4791,6 @@ Transposing beyond buffer boundaries is an error. */)
|
|||
void
|
||||
syms_of_editfns (void)
|
||||
{
|
||||
environbuf = 0;
|
||||
initial_tz = 0;
|
||||
|
||||
DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions");
|
||||
|
||||
DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion,
|
||||
|
|
|
@ -535,7 +535,7 @@ DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
|
|||
#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 dump_tz[] = "UtC0";
|
||||
static char const dump_tz[] = "UtC0";
|
||||
#endif
|
||||
|
||||
#ifndef ORDINARY_LINK
|
||||
|
@ -717,7 +717,7 @@ main (int argc, char **argv)
|
|||
|
||||
#ifdef G_SLICE_ALWAYS_MALLOC
|
||||
/* This is used by the Cygwin build. */
|
||||
setenv ("G_SLICE", "always-malloc", 1);
|
||||
xputenv ("G_SLICE=always-malloc");
|
||||
#endif
|
||||
|
||||
#ifdef GNU_LINUX
|
||||
|
@ -803,9 +803,8 @@ main (int argc, char **argv)
|
|||
#ifdef HAVE_PERSONALITY_LINUX32
|
||||
if (dumping && ! getenv ("EMACS_HEAP_EXEC"))
|
||||
{
|
||||
static char heapexec[] = "EMACS_HEAP_EXEC=true";
|
||||
/* Set this so we only do this once. */
|
||||
putenv (heapexec);
|
||||
xputenv ("EMACS_HEAP_EXEC=true");
|
||||
|
||||
/* A flag to turn off address randomization which is introduced
|
||||
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
|
|||
don't pollute Vglobal_environment. */
|
||||
/* Setting LANG here will defeat the startup locale processing... */
|
||||
#ifdef AIX
|
||||
putenv ("LANG=C");
|
||||
xputenv ("LANG=C");
|
||||
#endif
|
||||
|
||||
init_buffer (); /* Init default directory of main buffer. */
|
||||
|
|
|
@ -3594,6 +3594,7 @@ extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t);
|
|||
extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
|
||||
|
||||
extern char *xstrdup (const char *);
|
||||
extern void xputenv (const char *);
|
||||
|
||||
extern char *egetenv (const char *);
|
||||
|
||||
|
|
|
@ -9908,10 +9908,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
|
|||
|
||||
/* Emacs can only handle core input events, so make sure
|
||||
Gtk doesn't use Xinput or Xinput2 extensions. */
|
||||
{
|
||||
static char fix_events[] = "GDK_CORE_DEVICE_EVENTS=1";
|
||||
putenv (fix_events);
|
||||
}
|
||||
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. */
|
||||
|
|
Loading…
Add table
Reference in a new issue