[C++] łącza nienazwane problem z zadaniem


(rafalski) #1

Witam!

Mam następujęce zadanie z systemów operacyjnych i stanąłem w miejscu:

Napisać program my_shell. Ma on umożliwić użytkownikowi uruchamianie programów, udostępniając mu wiersz poleceń oraz obsługiwać jeden operator potoku | i jeden operator przekierowania: > (dla ułatwienia zakładamy, że operator przekierowania może dotyczyć tylko ostatniego polecenia). Ponadto powinien potrafić obsługiwać skrytpy, czyli polecenie cat script_file | ./my_shell powinno spowodować wykonanie skryptu script_file przez program my_shell. Dodać do programu my_shell możliwość uruchamiania procesów (a właściwie zadań) w tle (& na końcu linii.

Jak na razie napisałem następujecy kod:

#include 

#include 

#include 

# define buf_size 256



int main(int argc, char *argv[])

{

  int pid;

  int p[2];

  int pol1[2];

  int pol2[2];

  char status[buf_size];


if(pipe(p)==0){

            pid=fork();

            if (pid>0){

                printf("Wykonuje się proces macierzysty\n");

                wait(&status);

            }

            else{

                printf("Wykonuje się proces potomny\n");                

                p[1]=open(pol2[0],O_WRONLY|O_CREAT|O_APPEND, 0666);

                  dup2(p[1],1);


                  close(p[1]);

                execvp(pol1[0],pol1);


            }

        }

}

Z góry dziękuje za podpowiedź.


(Marcin 110) #2

Zajrzyj tutaj: http://www.mimuw.edu.pl/~mengel/SO/PUBLIC-SO/

W szczególności katalogi fork (simple_shell.c) i pipe. To powinno wystarczyć.

BTW: tytuł jest trochę mylący :expressionless:


(mati75) #3

Mała propozycja popraw w temacie, bo to nie bash tylko c++.


(rafalski) #4

Znalazłem pod tamtym adresem mini shella, ale wciąż mam problem w dopisaniu do niego obsługi operatora potoku i przekierowania. Czy ktoś mógłby pomóc?

#include 

#include 

#include 

#include 

#include 

#include 

#include "err.h"


/* parse - dzieli polecenie z buf na pojedyncze slowa i umieszcza je w args */

void parse (char buf[], char *args[])

{

  int i = 0, j = 0;


  while (buf[i] != '\0') {


     /* omija biale znaki */

    for (; buf[i] == ' ' || buf[i] == '\t'; buf[i++] = '\0');


     /* zapamietuje argument */

    args[j] = buf + i;

    j++;


     /* omija argument */

    for (; buf[i] != '\0' && buf[i] != ' ' && buf[i] != '\t'; i++);

  } 


  args[j] = 0;

} /* parse */


/* execute - tworzy proces potomny, ktory wykonuje polecenie */

void execute(char *args[])

{

  int pid;


  switch(pid = fork()) {

    case -1: /* blad */

      syserr("Error in fork\n");


    case 0: /* proces potomny */

      execvp(args[0], args);

      syserr("Error in execlp %s\n", args[0]);


    default: /* proces macierzysty */

      while (wait(0) != pid);  

  }

} /* execute */


int main()

{

  char buf[1024], *args[64];


  for (;;) {


     /* prosi o polecenia i wczytuje je na buf */

    printf("Polecenie: ");


    if (fgets(buf, sizeof(buf), stdin) == 0) {

      printf("\n");

      return 0;

    }


    if (strlen(buf) == 0) 

      continue;

     /* wstawia znak konca napisu (zamiast znaku nowego wiersza) */

    buf[strlen(buf) - 1] = '\0';


     /* analizuje polecenie ... */    

    parse(buf, args);


     /* ... i je wykonuje */

    execute(args);

  } 

} /* main */

(Marcin 110) #5

Mam kilka uwag:

-