Visualizzazione dei risultati da 1 a 6 su 6

Discussione: C --- Shell in Linux

  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    353

    C --- Shell in Linux

    BUona domenica a tutti,sono un nuovo iscritto e mi trovo subito a dover fare una domanda
    codice:
    #include "smallsh.h"
    
    
    
    static char inpbuf[MAXBUF], tokbuf[2*MAXBUF],
    	    *ptr, *tok;
    
    
    
    static char special[]=
    	{' ', '\t', '&', ';', '\n', '\0'};
    
    int userin(char *p)		{
      int c, count;
    
      ptr = inpbuf;
      tok = tokbuf;
    
       printf("%s ",p);
    
      count=0;
    
      while(1) {
    
        if ((c = getchar()) == EOF)
          return(EOF);
    
        if (count < MAXBUF)
          inpbuf[count++] = c;
    
         if (c == '\n' && count < MAXBUF) {
          inpbuf[count] = '\0';
          return(count);
        }
    
          if (c == '\n') {	
          printf("riga in input troppo lunga\n");
          count = 0;
          printf("%s ",p);
        }
      }
    }
    
    int gettok(char **outptr)	{
      int type;
    
        *outptr = tok;
    
     
    
      while (*ptr == ' ' || *ptr == '\t') ptr++;
    
    
    
      *tok++ = *ptr;
    
      
      switch(*ptr++){
    
        case '\n':
          type = EOL; break;
        case '&':
          type = AMPERSAND; break;
        case ';':
          type = SEMICOLON; break;
        default:
          type = ARG;
               while(inarg(*ptr))
    	*tok++ = *ptr++;
      }
    
    
    
      *tok++ = '\0';
      return(type);
    
    }
    
    int inarg(char c)	{
       char *wrk;
    
       for (wrk = special; *wrk != '\0'; wrk++)
           if (c == *wrk) return(0);
    
       return(1);
    }
    .....e.....
    codice:
    #include "smallsh.h"
    #include <sys/types.h>
    #include <stdlib.h>
    char *prompt = "Comando";
    
    int procline(void) 	
    {
      char *arg[MAXARG+1];	
      int toktype;  	
      int narg;		
      int type;			
      narg=0;
    
      while (1) {	
    	
    
        switch (toktype = gettok(&arg[narg])) {
    	
      
          case ARG:
    		
            if (narg < MAXARG)
    	  narg++;
    	  break;
    
          case EOL:
          case SEMICOLON:
          case AMPERSAND:
            type = (toktype == AMPERSAND) ? BACKGROUND : FOREGROUND;
          
            if (narg != 0) {
    	  arg[narg] = NULL;
    	  runcommand(arg,type);
            }
          
    
            if (toktype == EOL) return;
          
    
            narg = 0;
            break;
        }
      }
    }
    in questo codice devo evitare che un segnale termini tutto,deve terminare solo il figlio e rendere attiva la possibilità di usare & per il background
    Mi potete dare consigli?Come faccio a disattivare nel primo caso l' "uscita"?

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326

    Re: C --- Shell in Linux

    Originariamente inviato da CodiceProg
    in questo codice devo evitare che un segnale termini tutto,deve terminare solo il figlio e rendere attiva la possibilità di usare & per il background
    Entrambe le cose credo siano risolvibili ricorrendo a wait() o waitpid().
    every day above ground is a good one

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    353
    grazie,sono però esordiente in queste cose,puoi essere più preciso?

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Ora come ora non posso leggermi tutto il codice per darti consigli "mirati", tra l'altro non so cosa contenga l'header file smallsh.h, ma di sicuro per realizzare una mini shell su Linux non puoi non conoscere funzioni dell'API Unix come execve() (e simili), fork(), wait() (e simili) e altro. Sbalgio o nel tuo codice non c'è traccia di tutto questo? Insomma, come stai tentando di procedere?

    In ogni caso quello che una shell molto elementare dovrebbe fare sarebbe avere un processo principale che mostri a video il prompt e, per ogni comando generato, dovrebbe aprire un nuovo processo che esegua quel comando. Ora ci sono due scenari possibili: se il processo padre non attende la fine del processo figlio, in pratica il processo figlio sta già lavorando in background, questo perché il padre ti mostrerà subito il prompt di nuovo; se invece il padre si blocca in attesa della terminazione del figlio con una waitpid(), allora il comando avviato lavorerà in foreground e bloccherà la shell, quindi il prompt ti verrà mostrato di nuovo una volta conclusa l'esecuzione del comando.

    L'altra domanda forse non l'ho capita: vuoi avere la possibilità di terminare l'esecuzione del comando da tastiera senza chiudere anche il programma principale (cioè la shell) ? Se è così, ancora una volta devi ricorrere all'API di Unix per la gestione dei processi, ma se non hai mai studiato nulla di tutto questo penso ti sarà difficile...
    every day above ground is a good one

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    353
    codice:
    void runcommand(char **cline,int where)
    {
      pid_t pid;
      int exitstat,ret;
      
      pid = fork();
      if (pid == (pid_t) -1) {
         perror("smallsh: fork fallita");
         return;
      }
      
    
      if (pid == (pid_t) 0) { 	
    
     
       
        
        execvp(*cline,cline);
        perror(*cline);
       
        exit(1);
        
        
    
      
      }
    
    
    
      ret = wait(&exitstat);
    
      if (ret == -1) perror("wait");
    }
    
    int main()
    {
    
    
    
    signal(SIGINT,SIG_DFL)
    
      while(userin(prompt) != EOF)
        procline();
    }
    ho provato così,ma non funziona

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    353
    noto solo adesso che mi sono dimenticato di includere il codice come tale,e mi scuso
    Ho fatto questa correzione,va bene?

    codice:
    int runcommand(char **cline, int where){
        pid_t pid;
        int status;
    
        switch(pid=fork()){
        case -1:
            perror("smallsh");
            return (-1);
        case 0:
           if(where == BACKGROUND)
            {
             signal(SIGINT, SIG_IGN);
             signal(SIGQUIT, SIG_IGN);
            }
            else
            {
            signal(SIGINT, SIG_DFL);
            signal(SIGQUIT,SIG_DFL);
            }
            execvp(*cline,cline);
            perror(*cline);
            exit(1);
        default:
            signal(SIGINT, SIG_IGN);
            signal(SIGQUIT, SIG_DFL);
    
          }
    
        if(where == BACKGROUND){
            printf("[Process id %d]\n",pid);
            return (0);
        }
    
      
        if (waitpid(pid,&status,0) == -1)
            return (-1);
        else
            return (status);
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.