2

I'm following along with this lab from a Udemy course on computer security which primarily uses C (I think) scripts for demonstrations. After trying to run the following program on my own computer (in both an Ubuntu and MacOS environment), I get so many errors that it seems as if the compiler doesn't even know what language it's reading.

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

extern char **environ;

void printenv()
{
  int i = 0;
  while (environ[i] != NULL) {
    printf("%s\n", environ[i]);
    i++;
  }
}

void main()
{
  pid_t childPid;
  switch(childPid = fork()) {
    case 0: /* child process */
      printenv();
      exit(0);
    default: /* parent process */
      //printenv();
      exit(0);
  }
}

The errors:

line 4: extern: command not found
line 5: syntax error near unexpected token '('
line 5: 'void printenv()'

Does anyone know what's going on? I'm unfamiliar with C (mostly work in Javascript and Python), but it seems like everything is pretty standard syntax and shouldn't be erroring.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • 7
    It sounds like you may be trying to execute the C source code when you need to compile it first. Did you compile it? – Retired Ninja Jun 18 '20 at 21:00
  • 4
    " run the following program" How exactly? If you give details then we can on the one hand tell whether Retired Ninja might guess correctly and otherwise find whatever other problem you might be having. C programmers expect you to answer something like `gcc mycodefile.c` and then `a`. If you do something like `call mycodefile.c` (sorry, windows affliction here) then it is along Retired Ninjas guess. (And you would not be the first to have that misunderstanding, don't worry.) – Yunnosch Jun 18 '20 at 21:08
  • 2
    Side note: [`main` should return an `int`](https://stackoverflow.com/a/207992/4581301) – user4581301 Jun 18 '20 at 21:14
  • regarding: `default: /* parent process */ //printenv(); exit(0);` the parent MUST wait for the child to exit. Otherwise, effectively, the chlld becomes a zombie. (note in modern linux OS, it is actually attached, as a child, to the `init` process. Suggest `#include ` and in the parent, before the call to `exit()` `wait( childPid );` – user3629249 Jun 19 '20 at 06:25

1 Answers1

0

the following proposed code:

  1. cleanly compiles
  2. performs the desired functionality
  3. does not try to produce a zombie

Note: I compiled this, on linux with:

gcc   -O1  -ggdb -Wall -Wextra -Wconversion -pedantic   -c "untitled2.c"  -I. 

Note: I linked it with:

gcc   -ggdb -Wall -o "untitled2" "untitled2.o"

However, fork() can fail, in which case it returns -1, so the code should have a

case -1:
    perror( "fork failed" );
    break;

and now, the proposed code:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

extern char **environ;

void printenv()
{
  int i = 0;
  while (environ[i] != NULL) {
    printf("%s\n", environ[i]);
    i++;
  }
}

int main( void )
{
  pid_t childPid;

  switch(childPid = fork()) 
  {
    case 0: /* child process */
      printenv();
      exit(0);

    default: /* parent process */
      //printenv();
      waitpid( childPid, NULL, 0);
      exit(0);
  }
}
user3629249
  • 16,402
  • 1
  • 16
  • 17