aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-08-20 09:23:48 +0300
committerSergey Poznyakoff <gray@gnu.org>2016-08-20 09:23:48 +0300
commitcee62ab20bf767c3a07562ad30c67126ea3bab32 (patch)
treef432c01460d9d820cf92de7a55b17109715cf12d
parent6dd16ac66166ef62fcfc499c184a1b86ca82b227 (diff)
downloadpies-cee62ab20bf767c3a07562ad30c67126ea3bab32.tar.gz
pies-cee62ab20bf767c3a07562ad30c67126ea3bab32.tar.bz2
Fix environment modification code
Port fixes from GNU rush
-rw-r--r--src/progman.c82
1 files changed, 57 insertions, 25 deletions
diff --git a/src/progman.c b/src/progman.c
index fdb829a..43aff48 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -659,22 +659,44 @@ add_env (const char *name, const char *value)
659 659
660static char * 660/* Find variable NAME in environment ENV.
661find_env (const char *name, int val) 661 On success, store the index of the ENV slot in *IDX,
662 the offset of the value (position right past '=') in *VALOFF, and
663 return 0 (IDX and/or VALOFF can be NULL, if that info is not needed).
664 Return -1 if NAME was not found. */
665static int
666find_env_pos (char **env, char *name, size_t *idx, size_t *valoff)
662{ 667{
663 if (environ) 668 size_t nlen = strcspn (name, "+=");
664 { 669 size_t i;
665 int nlen = strcspn (name, "+=");
666 int i;
667 670
668 for (i = 0; environ[i]; i++) 671 for (i = 0; env[i]; i++)
672 {
673 size_t elen = strcspn (env[i], "=");
674 if (elen == nlen && memcmp (name, env[i], nlen) == 0)
669 { 675 {
670 size_t elen = strcspn (environ[i], "="); 676 if (idx)
671 if (elen == nlen && memcmp (name, environ[i], nlen) == 0) 677 *idx = i;
672 return val ? environ[i] + elen + 1 : environ[i]; 678 if (valoff)
679 *valoff = elen + 1;
680 return 0;
673 } 681 }
674 } 682 }
675 return NULL; 683 return -1;
684}
685
686/* Find variable NAME in environment ENV.
687 On success, return pointer to the variable assignment (if VAL is 0),
688 or to the value (if VAL is 1).
689 Return NULL if NAME is not present in ENV. */
690static char *
691find_env_ptr (char **env, char *name, int val)
692{
693 size_t i, j;
694 if (find_env_pos (env, name, &i, &j))
695 return NULL;
696 return val ? env[i] + j : env[i];
676} 697}
677 698
699/* Return 1 if ENV contains a matching unset statement for variable NAME. */
678static int 700static int
679locate_unset (char **env, const char *name) 701var_is_unset (char **env, const char *name)
680{ 702{
@@ -710,3 +732,3 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b)
710 strcpy (res + namelen + 1, a); 732 strcpy (res + namelen + 1, a);
711 strcat (res, b); 733 strcat (res + namelen + 1, b);
712 } 734 }
@@ -739,3 +761,3 @@ environ_setup (char **hint)
739 char **new_env; 761 char **new_env;
740 size_t count, i, n; 762 size_t count, i, j, n;
741 763
@@ -768,3 +790,3 @@ environ_setup (char **hint)
768 { 790 {
769 if (!locate_unset (hint, old_env[i])) 791 if (!var_is_unset (hint, old_env[i]))
770 new_env[n++] = old_env[i]; 792 new_env[n++] = old_env[i];
@@ -781,2 +803,8 @@ environ_setup (char **hint)
781 } 803 }
804
805 /* Find the slot for the variable. Use next available
806 slot if there's no such variable in new_env */
807 if (find_env_pos (new_env, hint[i], &j, NULL))
808 j = n;
809
782 if ((p = strchr (hint[i], '='))) 810 if ((p = strchr (hint[i], '=')))
@@ -786,16 +814,20 @@ environ_setup (char **hint)
786 if (p[-1] == '+') 814 if (p[-1] == '+')
787 new_env[n++] = env_concat (hint[i], p - hint[i] - 1, 815 new_env[j] = env_concat (hint[i], p - hint[i] - 1,
788 find_env(hint[i], 1), p + 1); 816 find_env_ptr (environ, hint[i], 1),
817 p + 1);
789 else if (p[1] == '+') 818 else if (p[1] == '+')
790 new_env[n++] = env_concat (hint[i], p - hint[i], 819 new_env[j] = env_concat (hint[i], p - hint[i],
791 p + 2, find_env(hint[i], 1)); 820 p + 2,
821 find_env_ptr (environ, hint[i], 1));
792 else 822 else
793 new_env[n++] = hint[i]; 823 new_env[j] = hint[i];
794 } 824 }
825 else if ((p = find_env_ptr (environ, hint[i], 0)))
826 new_env[j] = p;
795 else 827 else
796 { 828 continue;
797 p = find_env (hint[i], 0); 829
798 if (p) 830 /* Adjust environment size */
799 new_env[n++] = p; 831 if (j == n)
800 } 832 ++n;
801 } 833 }

Return to:

Send suggestions and report system problems to the System administrator.