From 4b92ba68de4def343faf23dc1858275c4a8115fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?=
 =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= <alexey.pawlow@gmail.com>
Date: Sun, 14 Apr 2019 21:29:01 +0300
Subject: [PATCH 04/N] Add functionality for changing OS name via MSYSTEM
 environment variables.

---
 winsup/cygserver/cygserver-config   |  4 ++--
 winsup/cygwin/environ.cc            | 34 ++++++++++++++++++++++++++---
 winsup/cygwin/include/sys/utsname.h |  2 +-
 winsup/cygwin/uname.cc              | 17 +++++++++++++--
 4 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/winsup/cygserver/cygserver-config b/winsup/cygserver/cygserver-config
index abda186..1f0603f 100755
--- a/winsup/cygserver/cygserver-config
+++ b/winsup/cygserver/cygserver-config
@@ -86,7 +86,7 @@ done
 
 # Check if running on NT
 _sys="`uname`"
-_nt=`expr "${_sys}" : "CYGWIN_NT"`
+_nt=`expr "${_sys}" : "MSYS_NT"`
 
 # Check for running cygserver processes first.
 if ps -e | grep -v grep | grep -q ${service_name}
@@ -178,7 +178,7 @@ then
     echo "Do you want to install cygserver as service?"
     if request "(Say \"no\" if it's already installed as service)"
     then
-      if ! cygrunsrv -I ${service_name} -d "CYGWIN cygserver" -p /usr/sbin/cygserver
+      if ! cygrunsrv -I ${service_name} -d "MSYS cygserver" -p /usr/sbin/cygserver
       then
         echo
 	echo "Installation of cygserver as service failed.  Please check the"
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 639e693..b9f7e05 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -192,7 +192,11 @@ parse_options (const char *inbuf)
       if (export_settings)
 	{
 	  debug_printf ("%s", newbuf + 1);
+#ifdef __MSYS__
+	  setenv ("MSYS", newbuf + 1, 1);
+#else
 	  setenv ("CYGWIN", newbuf + 1, 1);
+#endif
 	}
       return;
     }
@@ -651,7 +655,7 @@ _addenv (const char *name, const char *value, int overwrite)
   win_env *spenv;
   if ((spenv = getwinenv (envhere)))
     spenv->add_cache (value);
-  if (strcmp (name, "CYGWIN") == 0)
+  if (strcmp (name, "MSYS") == 0)
     parse_options (value);
 
   return 0;
@@ -754,6 +758,9 @@ static struct renv {
 } renv_arr[] = {
 	{ NL("COMMONPROGRAMFILES=") },		// 0
 	{ NL("COMSPEC=") },
+#ifdef __MSYS__
+	{ NL("MSYSTEM=") },			// 2
+#endif /* __MSYS__ */
 	{ NL("PATH=") },			// 2
 	{ NL("PROGRAMFILES=") },
 	{ NL("SYSTEMDRIVE=") },			// 4
@@ -765,10 +772,21 @@ static struct renv {
 #define RENV_SIZE (sizeof (renv_arr) / sizeof (renv_arr[0]))
 
 /* Set of first characters of the above list of variables. */
-static const char idx_arr[] = "CPSTW";
+static const char idx_arr[] =
+#ifdef __MSYS__
+	"CMPSTW";
+#else
+	"CPSTW";
+#endif
 /* Index into renv_arr at which the variables with this specific character
    starts. */
-static const int start_at[] = { 0, 2, 4, 6, 8 };
+static const int start_at[] = {
+#ifdef __MSYS__
+				0, 2, 3, 5, 7, 9
+#else
+				0, 2, 4, 6, 8
+#endif
+								};
 
 /* Turn environment variable part of a=b string into uppercase - for some
    environment variables only. */
@@ -836,7 +854,11 @@ environ_init (char **envp, int envc)
       dumper_init ();
       if (envp_passed_in)
 	{
+#ifdef __MSYS__
+	  p = getenv ("MSYS");
+#else
 	  p = getenv ("CYGWIN");
+#endif
 	  if (p)
 	    parse_options (p);
 	}
@@ -883,8 +905,13 @@ win32env_to_cygenv (PWCHAR rawenv, bool posify)
       ucenv (newp, eq);    /* uppercase env vars which need it */
       if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
         sawTERM = 1;
+#ifdef __MSYS__
+      else if (*newp == 'M' && strncmp (newp, "MSYS=", 5) == 0)
+        parse_options (newp + 5);
+#else
       else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
         parse_options (newp + 7);
+#endif
       if (*eq && posify)
         posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
       debug_printf ("%p: %s", envp[i], envp[i]);
@@ -959,6 +986,7 @@ static NO_COPY spenv spenvs[] =
   {NL ("HOMEPATH="), false, false, &cygheap_user::env_homepath},
   {NL ("LOGONSERVER="), false, false, &cygheap_user::env_logsrv},
   {NL ("PATH="), false, true, NULL},
+  {NL ("MSYSTEM="), true, true, NULL},
   {NL ("SYSTEMDRIVE="), false, true, NULL},
   {NL ("SYSTEMROOT="), true, true, &cygheap_user::env_systemroot},
   {NL ("USERDOMAIN="), false, false, &cygheap_user::env_domain},
diff --git a/winsup/cygwin/include/sys/utsname.h b/winsup/cygwin/include/sys/utsname.h
index d6b3be9..730cb73 100644
--- a/winsup/cygwin/include/sys/utsname.h
+++ b/winsup/cygwin/include/sys/utsname.h
@@ -17,7 +17,7 @@ extern "C" {
 
 struct utsname
 {
-  char sysname[_UTSNAME_LENGTH];
+  char sysname[_UTSNAME_LENGTH + 1];
   char nodename[_UTSNAME_LENGTH];
   char release[_UTSNAME_LENGTH];
   char version[_UTSNAME_LENGTH];
diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc
index c08e30f..ed4c9c5 100644
--- a/winsup/cygwin/uname.cc
+++ b/winsup/cygwin/uname.cc
@@ -37,7 +37,12 @@ uname_x (struct utsname *name)
 
       memset (name, 0, sizeof (*name));
       /* sysname */
-      n = __small_sprintf (name->sysname, "CYGWIN_%s-%u",
+      char* msystem = getenv("MSYSTEM");
+      const char* msystem_sysname = "MSYS";
+      if (msystem != NULL && *msystem && strcmp(msystem, "MSYS") != 0)
+        msystem_sysname = (strstr(msystem, "32") != NULL) ? "MINGW32" : "MINGW64";;
+      n = __small_sprintf (name->sysname, "%s_%s-%u",
+			   msystem_sysname,
 			   wincap.osname (), wincap.build_number ());
       if (wincap.host_machine () != wincap.cygwin_machine ())
 	{
@@ -104,7 +109,7 @@ uname_x (struct utsname *name)
 /* Old entrypoint for applications up to API 334 */
 struct old_utsname
 {
-  char sysname[20];
+  char sysname[21];
   char nodename[20];
   char release[20];
   char version[20];
@@ -118,7 +123,15 @@ uname (struct utsname *in_name)
   __try
     {
       memset (name, 0, sizeof (*name));
+#ifdef __MSYS__
+      char* msystem = getenv("MSYSTEM");
+      const char* msystem_sysname = "MSYS";
+      if (msystem != NULL && *msystem && strcmp(msystem, "MSYS") != 0)
+        msystem_sysname = (strstr(msystem, "32") != NULL) ? "MINGW32" : "MINGW64";
+      __small_sprintf (name->sysname, "%s_%s", msystem_sysname, wincap.osname ());
+#else
       __small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ());
+#endif
 
       /* Computer name */
       cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1);
