0

(Disclamer: This is homework)

I am creating a shell program, lets call it fancysh. I am trying to add PATH (and other env vars) functionality to my shell, so far all is good. My naive approach was to store all these variables as static variables in fancysh.c. Now however I am trying to implement the environment variable SHLVL which holds the current "depth" of the shell. For example I can be running in the first instance of fancysh and the SHLVL should read 1, upon calling fancysh again the SHLVL should increment (and decrement when a shell is exited).

What I have tried...

fancysh.h

#ifndef FANCYSH_H
#define FANCYSH_H

extern int SHLVL;

#endif

fancysh.c

#include "fancysh.h"

int SHLVL;

int main(){

 /* some fancy code to determine if SHLVL is initalized */
 /* if not init to 0 */

 SHLVL ++;
 printf("%d\n", SHLVL);

 /* Test Code Only */
 int pid = fork();
 if(pid == 0 && SHLVL < 10)
   exec("fancysh");
 wait();
 /* Test Code Only */

 /*  shell code */
 SHLVL--;
 printf("%d\n", SHLVL);
 exit(0);
}

I used the answers here and here as part of this solution.

So how would I go about implementing the fancy code to determine if SHLVL is initialized? I had some ideas about using a combination of #ifdef and #define but I'm not 100% sure how to do this.

Community
  • 1
  • 1
Callback Kid
  • 708
  • 5
  • 22
  • Note: obfuscation is in general a very bad idea. Here you obfuscate the keyword `extern`. Why do you do that? It is extremely unlikely to change in the forseeable future. – too honest for this site Feb 04 '16 at 22:46
  • This was done so that SHLVL was only externally declared once. – Callback Kid Feb 04 '16 at 22:50
  • Multiple `extern` declarations of the same variable are not inherently problematic, neither in the same translation unit nor in different ones contributing to the same program or library. – John Bollinger Feb 04 '16 at 23:06
  • Ah, I see now. That is nonsense and very uncommon. 1st it does not matter and 2nd use standard guards for the whole header. This is the wrong place to be creative. – too honest for this site Feb 04 '16 at 23:06
  • I have updated the question. – Callback Kid Feb 04 '16 at 23:10
  • @Olaf, I wasn't trying to be creative I simply thought that [this](http://stackoverflow.com/a/1433387/3356508) answer applied to my question. – Callback Kid Feb 04 '16 at 23:14
  • If I was to provide an _answer_, I would not have posted a _comment_. Comments are not meant to provide an answer, but to add information relevant for the code or ask for clarification. Uncommon code is less readable and we might easily oversee something. That is how the human brain works (shrug:-). – too honest for this site Feb 04 '16 at 23:17

1 Answers1

0

You need to get a grasp of the fact that different shell processes are different processes. Just because one instance of the shell is started within the scope of another instance of the shell does not mean that the former automatically inherits any data from the latter.

Or not directly, anyway. Any new instance of your shell will receive an environment from the process that starts it. If that environment contains a SHLVL variable then the new shell process can of course read that value, and it may possibly present a different value of that environment variable within its own scope.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • So are you implying that instead of attempting to syncronize variables across my shell processes I should instead look into passing the env vars as command line arguments to each shell process? – Callback Kid Feb 04 '16 at 22:55
  • @CallbackKid, no one said anything about command-line arguments. I said an instance of your shell can rely on the *environment* provided to it by its parent process. It cannot in any case *share* storage for `SHLVL` among instances, because different instances can and will need to maintain different values. – John Bollinger Feb 04 '16 at 23:11