all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#21687: Proposed patch to nt/runemacs.c: a way to augment environment variables prior to starting Em
@ 2015-10-15  1:59 Evgeny Roubinchtein
  2015-10-15 15:30 ` Eli Zaretskii
  0 siblings, 1 reply; 3+ messages in thread
From: Evgeny Roubinchtein @ 2015-10-15  1:59 UTC (permalink / raw)
  To: 21687

[-- Attachment #1: Type: text/plain, Size: 1167 bytes --]

Dear Emacs developers,

Would you consider applying the attached patch to nt/runemacs.c?

My "use case" is that I compiled 64-bit Emacs under Windows following
instructions at
http://sourceforge.net/p/emacsbinw64/wiki/Build%20guideline%20for%20MSYS2-MinGW-w64%20system/,
but I want to avoid copying libraries from ${msys2_root}/mingw64/bin
to the Emacs installation directory, and I also don't want to add
${msys2_root}/mingw64/bin to the PATH for my user account (let alone
system-wide).  The attached patch gives me a way to augment system
environment variables before runemacs starts the actual emacs
executable.

With this patch applied, I can set the environment variable EMACS_ENV
to ">PATH>${msys2_root}/mingw64/bin", and have that directory appended
to the PATH but only in the environment of the runemacs process.  That
environment is inherited by the emacs process, so I can allow Emacs to
find the libraries it needs in order to run without copying them to
the Emacs installation directory and without altering the PATH for my
user account.

Please let me know if it would be possible to get this patch applied
to the Emacs sources.

Thank you in advance!

[-- Attachment #2: 0001-Allow-the-environment-of-the-runemacs-process-to-be-.patch --]
[-- Type: application/octet-stream, Size: 3481 bytes --]

From ae638dc1f3d49523552901f4e56eda785d3e286d Mon Sep 17 00:00:00 2001
From: Evgeny Roubinchtein <zhenya1007@gmail.com>
Date: Thu, 15 Oct 2015 02:51:20 +0100
Subject: [PATCH] Allow the environment of the runemacs process to be
 augmented.

The user may augment the environment of the runemacs process (and the
emacs process started by runemacs) by setting the "EMACS_ENV"
environment variable.
---
 nt/runemacs.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 100 insertions(+), 1 deletion(-)

diff --git a/nt/runemacs.c b/nt/runemacs.c
index 86644b4..26fbd67 100644
--- a/nt/runemacs.c
+++ b/nt/runemacs.c
@@ -46,6 +46,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 static void set_user_model_id (void);
 static int ensure_unicows_dll (void);
+static void expand_emacs_env (void);
 
 int WINAPI
 WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
@@ -166,6 +167,8 @@ WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
       SetEnvironmentVariable ("emacs_dir", modname);
     }
 
+  expand_emacs_env ();
+
   memset (&start, 0, sizeof (start));
   start.cb = sizeof (start);
   start.dwFlags = STARTF_USESHOWWINDOW | STARTF_USECOUNTCHARS;
@@ -257,7 +260,7 @@ ensure_unicows_dll (void)
 	    {
 	      case IDOK:
 	      default:
-	        return 0;
+		return 0;
 	    }
 	}
       FreeLibrary (h);
@@ -265,3 +268,99 @@ ensure_unicows_dll (void)
     }
   return 1;
 }
+
+static int
+get_env_var(char const *const name, char **buf)
+{
+  int len;
+  len = GetEnvironmentVariable(name, NULL, 0);
+  if (0 == len)
+    return 0;
+  *buf = malloc(len);
+  if (!*buf)
+    return 0;
+  if (!GetEnvironmentVariable (name, *buf, len))
+    return 0;
+  return 1;
+}
+
+/* BNF grammar:
+   emacs_env_string = 'EMACS_ENV=' {prepend_clause|append_clause|overwrite_clause} '\0'
+   prepend_clause = '<' name '<' value
+   append_clause = '>' name '>' value
+   overwrite_clause = '*' name '*'
+   , where name is valid environment variable name.
+*/
+static void
+expand_emacs_env()
+{
+  char *buf;
+  char *b;
+  char *e;
+
+  if (!get_env_var ("EMACS_ENV", &buf))
+    goto free_buf;
+
+  b = e = buf;
+  while (NULL != (b = strpbrk (b, ">*<")))
+    {
+      char *ee;
+      char *val = NULL;
+      char *nval = NULL;
+      char sep[2] = {'\0', '\0'};
+
+      sep[0] = *b;
+      ++b;
+      e = strpbrk(b, sep);
+      if (NULL == e)
+	goto free_buf;
+      else
+	*e = '\0';
+      ee = strpbrk(e+1, sep);
+      if (NULL != ee)
+	*ee = '\0';
+      switch (sep[0])
+	{
+	case '>': /*append*/
+	  if (!get_env_var (b, &val))
+	    goto cleanup;
+	  nval = malloc (strlen(val) + strlen(e+1) + 1);
+	  strcpy(nval, val);
+	  strcat(nval, e+1);
+	  if (!SetEnvironmentVariable (b, nval))
+	    goto cleanup;
+	  break;
+	case '<': /*prepend*/
+	  if (!get_env_var (b, &val))
+	    goto cleanup;
+	  nval = malloc (strlen(val) + strlen(e+1) + 1);
+	  strcpy(nval, e+1);
+	  strcat(nval, val);
+	  if (!SetEnvironmentVariable (b, nval))
+	    goto cleanup;
+	  break;
+	case '*': /*overwrite*/
+	  if (!SetEnvironmentVariable (b, e+1))
+	    goto cleanup;
+	  break;
+	default:
+	  goto cleanup;
+	}
+    cleanup:
+      if (NULL != val)
+	free (val);
+      if (NULL != nval)
+	free (nval);
+      *e = sep[0];
+      if (NULL != ee)
+	{
+	  b = ee + 1;
+	  *ee = sep[0];
+	}
+      else
+	b = e + 1;
+    }
+ free_buf:
+  if (NULL != buf)
+    free (buf);
+}
-- 
2.6.1.windows.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* bug#21687: Proposed patch to nt/runemacs.c: a way to augment environment variables prior to starting Em
  2015-10-15  1:59 bug#21687: Proposed patch to nt/runemacs.c: a way to augment environment variables prior to starting Em Evgeny Roubinchtein
@ 2015-10-15 15:30 ` Eli Zaretskii
  2016-02-23  8:37   ` Lars Ingebrigtsen
  0 siblings, 1 reply; 3+ messages in thread
From: Eli Zaretskii @ 2015-10-15 15:30 UTC (permalink / raw)
  To: Evgeny Roubinchtein; +Cc: 21687

> Date: Wed, 14 Oct 2015 18:59:26 -0700
> From: Evgeny Roubinchtein <zhenya1007@gmail.com>
> 
> My "use case" is that I compiled 64-bit Emacs under Windows following
> instructions at
> http://sourceforge.net/p/emacsbinw64/wiki/Build%20guideline%20for%20MSYS2-MinGW-w64%20system/,
> but I want to avoid copying libraries from ${msys2_root}/mingw64/bin
> to the Emacs installation directory, and I also don't want to add
> ${msys2_root}/mingw64/bin to the PATH for my user account (let alone
> system-wide).

Can you explain why you don't want to do any of these 2 things?  I'm
not sure I understand the use case.  Doing one or the other is the
standard way of installing programs and their dependency libraries,
and the former of the 2 is the platform recommended method, so it
sounds strange that you don't want that.

> The attached patch gives me a way to augment system environment
> variables before runemacs starts the actual emacs executable.

> With this patch applied, I can set the environment variable EMACS_ENV
> to ">PATH>${msys2_root}/mingw64/bin", and have that directory appended
> to the PATH but only in the environment of the runemacs process.  That
> environment is inherited by the emacs process, so I can allow Emacs to
> find the libraries it needs in order to run without copying them to
> the Emacs installation directory and without altering the PATH for my
> user account.

Thanks, but I think this solution will do more harm than help, even
for you.  Setting PATH of the Emacs process affects much more than
just the places where Emacs looks for DLLs.  It also affects where it
will look for programs it invokes, such as Grep and Diff, that have
nothing to do with optional libraries.

Moreover, from the user perspective, runemacs.exe and emacs.exe are
the same program, so having each one run with a different value of
PATH will confuse and might even annoy.

If you want to affect just the place where the DLLs are loaded from,
you can instead redefine dynamic-library-alist (see w32-win.el for its
default value) in your init files to include full absolute file names
of each DLL; then Emacs will load only that DLL from its specified
directory.  I think this will solve your use case without affecting
others.  This solution can be used with the current Emacs code.

If your use case is important enough, we could consider adding a
facility that would allow the user to customize the directory or
directories where Emacs looks for DLLs, using methods that don't
affect PATH (e.g., the SetDllDirectory opr SetDefaultDllDirectories
APIs).  That'd be somewhat hairy, because we'd need to hook those into
Posix-style environment variables like LD_LIBRARY_PATH, but it will be
still cleaner than your suggestion.  So please describe your use case
in more detail for us to understand whether it needs any changes in
existing code.

Thanks.





^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#21687: Proposed patch to nt/runemacs.c: a way to augment environment variables prior to starting Em
  2015-10-15 15:30 ` Eli Zaretskii
@ 2016-02-23  8:37   ` Lars Ingebrigtsen
  0 siblings, 0 replies; 3+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-23  8:37 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 21687, Evgeny Roubinchtein

Eli Zaretskii <eliz@gnu.org> writes:

> So please describe your use case in more detail for us to understand
> whether it needs any changes in existing code.

More information was requested, but no response was given within a few
months, so I'm closing this bug report.  If the problem still exists,
please reopen this bug report.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-02-23  8:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-15  1:59 bug#21687: Proposed patch to nt/runemacs.c: a way to augment environment variables prior to starting Em Evgeny Roubinchtein
2015-10-15 15:30 ` Eli Zaretskii
2016-02-23  8:37   ` Lars Ingebrigtsen

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.