Help with this Code.

Hi,
 i found this code and i want to understand what he do, so if you can explain to me i will be very appreciated.
I know what he do but i want to comprehend every line of code and if there are other ways to achieve the some result.
The code use fork() and exec() functions what are they?
So if you can comment the code and explain i will be grateful.

Regards.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
 
 
main()
{
    char cmd[80]=" ";
    char *args[20];
 
    for (;;)
	{
           printf(">> ");
	   //scanf("%s", &cmd);
 
       	   if (gets(cmd) == NULL) 
	    {
              printf("\n");
              exit(1);
            }
        passagem(cmd, args);
        executar(args);
    	}
 
}
passagem(cmd, args)
char *cmd;
char **args;
{
    while (*cmd != NULL) 
	{
          while ((*cmd == ' ') || (*cmd == '\t'))
            *cmd++ = NULL;
            *args++ = cmd;
 
          while ((*cmd != NULL) && (*cmd != ' ') && (*cmd != '\t'))
            cmd++;
        }
 
    *args = NULL;
}
 
executar(cmd)
char **cmd;
{
 	int pid, status;
	pid= fork();
 
	 if (pid < 0) 
	  {
            execvp(*cmd,cmd);
            perror("Erro na funcao fork()");
            exit(1);
          }
 
	 if (pid == 0) 
          {
            execvp(*cmd,cmd);
            printf("Erro: Comando nao executado...\n");
            exit(1);
          }
while (wait(&status) != pid)
;
}

Open in new window

LVL 12
David Paris VicenteSystems and Comunications Administrator Asked:
Who is Participating?
 
xtravaganConnect With a Mentor Commented:
Easiest way to comprehend each line is to use a debugger. Sadly (in my opnion) this is unix code and gettings a visual gdb to work for you can be a challenge depending on your environment, eclipse or the one built into KDE might help you. For Windows simply use Visual Studio express, which is free.

With the debugger you can step each line and see exactly what it does and what happens to the CPU when it does it.

Good luck.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
 
 
main()
{
    char cmd[80]=" ";
    char *args[20];
 
    for (;;) // loops forever
	{
           printf(">> ");
	   //scanf("%s", &cmd);
 
      if (gets(cmd) == NULL)  // Get something from the stdin, bad security wise, buffer overrun problem
	    {
              printf("\n");
              exit(1);
      }
      passagem(cmd, args);
      executar(args);
  }
 
}
 
// simply a routine to plug the input liine into an array
passagem(cmd, args)
char *cmd;  // old way of specifying arguments to a function, same as passagem(char* cmd, char **args)
char **args;
{
    while (*cmd != NULL) 
	{
          while ((*cmd == ' ') || (*cmd == '\t'))
            *cmd++ = NULL;
            *args++ = cmd;
 
          while ((*cmd != NULL) && (*cmd != ' ') && (*cmd != '\t'))
            cmd++;
        }
 
    *args = NULL;
}
 
executar(cmd)
char **cmd;
{
 	int pid, status;
	pid= fork(); // For, duplicates the current running process, with its entire heap/stack state, that is a complete copy
	             // see, man fork, 0 is returned for the child and the pid of the child is returned to the parent, you will now have 2 processes
 
	 if (pid < 0) // Failed to fork
	  {
            execvp(*cmd,cmd);
            perror("Erro na funcao fork()");
            exit(1);
          }
 
	 if (pid == 0) 
          {
            execvp(*cmd,cmd); // child running here, execvp will replace the current process with whatever binary image *cmd points to. That is it will now start execute that binary from main
            printf("Erro: Comando nao executado...\n"); // Weird, cannot get to here unless execvp isn't working, remeber we are now in the new binary image, supposedly executing from its main
            exit(1);
          }
while (wait(&status) != pid)  // waits for the child to exit, don't know why fork is used if this is all it does..
;
}

Open in new window

0
 
mrjoltcolaConnect With a Mentor Commented:
>>The code use fork() and exec() functions what are they?

fork() creates a child process that begins executing at the exact same line of code, but the fork() functions returns different values so the parent can tell itself from the child. It is used to spawn off "worker" processes, etc.

exec() is used to execute another program from disk. The program will replace the calling process, but will maintain the input and output handles, etc.

The whole program appears to be a typical UNIX command shell homework project, it reads in a full string with gets() and then parses the string into separate arguments, and runs the command portion with the arguments as array elements in the execvp() call. execvp() is simply a variant of exec()

The fork + exec is done to execute the command, while retaining the actual command shell that is reading the input from the user.

Good luck.
0
 
David Paris VicenteSystems and Comunications  Administrator Author Commented:
Thank you for the explanations.
xtravagan>> For Windows simply use Visual Studio express.
I try to use the gdb to debug the code but it´s dificult to compreehend the gdb.
So I try to use the Visual studio but i get some errors when i compile the code.
"Error 1 fatal error C1083: Cannot open include file: 'unistd.h': "
Do you know how to resolve this?
0
 
mrjoltcolaCommented:
The code is for UNIX. You can compile it on Windows if you install one of the POSIX packages (mingw, cygwin or interix) but otherwise, its still a UNIX program. Any use of fork() on Windows is just emulation.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.