why are all environment-variables (null)

84 views Asked by At

i have a problem where i must concatenate variable on even positions, to the previous odd positioned variables, so to the one above the even.

ps forgot to mention that par mean even in romanian and impar means odd

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
  extern char **environ;
  char **env=environ;

  printf("Environment initial\n");
  for(int i=0;env[i]!=NULL;i++)
  {
    printf("%s\n",env[i]);
  }

  for(int i=2;env[i]!=NULL;i++)
  {
    if(i%2==0)
    {
      char *sir_par=env[i];
      char *sir_imp=env[i-1];
      char *var_par=getenv(sir_par);
      if(var_par==NULL)
      {
        fprintf(stderr,"%s\n","Eroare la obtinerea variabilei de pe pozitie para\n");
        exit(1);
      }
      char *var_imp=getenv(sir_imp);
      if(var_imp==NULL)
      {
        fprintf(stderr,"%s\n","Eroare la obtinerea variabilei de pe pozitie impara\n");
        exit(1);
      }
      char *var_nou;
      var_nou=malloc(strlen(var_imp)+strlen(var_par)+1);
      if(var_nou==NULL)
      {
        perror("Eroare la alocarea memoriei\n");
        exit(1);
      }
      strcpy(var_nou,var_imp);
      strcat(var_nou,var_par);
      if(setenv(sir_imp,var_nou,1)==-1)
      {
        perror("Eroare la modificarea variabilei de environment de pe pozitie impara\n");
        exit(1);
      }
      free(var_nou);
    }
  }

  printf("Environment dupa prelucrare\n");
  for(int i=0;env[i]!=NULL;i++)
  {
    printf("%s\n",env[i]);
  }

  return 0;
}

i did this and got segmentation fault, then tested the getenvs and setenv and got error at the first getenv so i did this

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
  extern char **environ;
  char **env=environ;


  printf("Environment initial\n");
  for(int i=0;env[i]!=NULL;i++)
  {
    printf("Environment: %s\n",env[i]);
    if(i%2==0){
    char *par=getenv(env[i]);
    printf("\n\n Variabila:\n%s\n\n",par);
  }
  }


  return 0;
}

and it prints the environment correctly but every time it reaches even position it prints (null)

i don't have to use getenv and setenv, but it would be way faster than manual string manipulation, as in looping through the environment and manually getting the values after the '=' charater.

1

There are 1 answers

0
Luis Colorado On

In the fragment of code:

  printf("Environment initial\n");
  for(int i=0;env[i]!=NULL;i++)
  {
    printf("Environment: %s\n",env[i]);
    if(i%2==0){
    char *par=getenv(env[i]);
    printf("\n\n Variabila:\n%s\n\n",par);
  }

you try to use getenv() with the full string in env[i] (which is the variable name, concatenated with the '=' character and the environment variable value) This will make the function to fail (as you are not using the variable name, but both things, and no variable name can have a '=' in it's name) so it always return NULL, which is why you print all variables in the environment like this.

An example will illustrate your mistake:

If you have PATH=/bin:/usr/bin:/usr/local/bin as an environ string, the following are true:

  • getenv("PATH") will return the correct value "/bin:/usr/bin:/usr/local/bin"
  • but getenv("PATH=/bin:/usr/bin:/usr/local/bin") will return NULL, as no variable named that way exists in the environment.

You are following the second option. If you read the manpage of getenv(3), you will see that if you ask for a nonexistent variable the function returns NULL.

BTW, your problem is not properly explained in the question, as you say:

i must concatenate variable on even positions, to the previous odd positioned variables

but in this case the first position is 0 (which is even) and so, should we append this value to position -1? it is not clear what to do in the beginning. Probably you mean in positions with odd index (these have odd index, but are even positions indeed) But it is not clear, as you start at index 2, and also, you check for even indices, so please clarify in your question. It is understood that, if you are talking about array positions, the first will be odd (and you will have to add the second position ---even--- to the first, but odd positions have even indices and even positions have odd indices, remember) What should happen to the even positioned environment variables? just nothing. Also, how the output must be formatted. That is not clear too.

IMHO, if you have to catenate the even positioned values to the odd positioned environment variables you don't actually need to do any concatenation in the program, it suffices you to print the odd positioned variables in full, and print after that the value of the even positioned variable, making the concatenation to happen actually in the output:

#include <stdio.h>
#include <string.h>

int main()
{
    int i;
    extern char **environ;
    for (i = 0; environ[i]; i++) {
        if (i % 2 == 0) { /* odd position, even index */
            printf("%s", environ[i]); /* print the variable */
            if (environ[i + 1]) { /* if next position exists */
                /* search for the position of the '=' char */
                char *val = strchr(environ[i + 1], '=');
                if (val) {
                    /* print the value of the even positioned
                     * value at val + 1 */
                    printf("%s", val + 1); /* print the next value */
                }
            }
            printf("\n"); /* end the line */
        }
    } /* for */
    return 0;
} /* main */

if you want to separate the two parts (with something like ">>><<<" to mark the place at which the values are catenated, just change

                    printf("%s", val + 1); /* print the next value */

by

                    printf(">>><<<%s", val + 1); /* print the next value */

and you will have something like:

SHELL=/usr/local/bin/bash>>><<<18874380
CVSROOT=/home/cvsroot>>><<</usr/lib/pkgconfig
XTERM_VERSION=XTerm(384)>>><<</usr/local/bin/bash
EDITOR=vi>>><<</home/lcu
MAKEOBJDIRPREFIX=/home/lcu/obj>>><<<lcu
MANPATH=/home/lcu/man:>>><<<Europe/Helsinki
WINDOWPATH=9>>><<<.:/home/lcu
HOME=/home/lcu>>><<<es_ES.UTF-8
XTERM_LOCALE=es_ES.UTF-8>>><<<xterm
USER=lcu>>><<<:0
FORTUNE_PATH=/home/lcu/.fortune:/usr/share/games/fortune:/usr/local/share/games/fortune>>><<<1
PAGER=less -r>>><<<UTF-8
LD_LIBRARY_PATH=/home/lcu/lib:>>><<</home/lcu/bin:/home/lcu/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
BLOCKSIZE=K>>><<</var/mail/lcu
_=./pru1660

(see that, as the number of variables was odd, the last variable has not ben catenated the next one)