Welcome, guest! Login / Register - Why register?
Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)

Paste

Pasted as C by P3 ( 15 years ago )
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(void)
{
 pid_t pid;     // PID des Kindes speichern
 int status;
 char eingabe[1000];  // Stringbuffer fuer eingelesenen Befehl
 char *args[512];  // Buffer fuer die Argumente (max. 512)
       
 char *file_in = NULL; // Dateiname fuer Ein- bzw. Ausgabedatei
 char *file_out = NULL;
 int append = 0;   // anhängen oder nicht
 int in = -1;      // File Handle
 int out = -1;

 int n, pos, pos2;

 while(1)
 {
  printf("Shelln");
  printf("> ");

     // scanf liest immer nur bis zum naechsten Whitespace, deshalb fgets verwenden
  //scanf("%s",eingabe);
  fgets(eingabe, 1000, stdin);              // Befehl von Kommandozeile einlesen
  eingabe[strlen(eingabe)-1] = '�';        // Eingabe mit � abschließen,da
                                                  // fgets des n auch mit einliest

  if (strcmp(eingabe,"exit")==0)
   break;         //exit beendet die shell


  // Argumente parsen:

  n = 0;
  pos = 0;

  do
  {
   for (; isspace(eingabe[pos]); pos++ ); // Leerzeichen ignorieren

   if (eingabe[pos] == '"')
   {
    // String komplett einlesen als einen Parameter , ohne "
    for (pos2 = pos + 1; eingabe[pos2] != '�' && eingabe[pos2] != '"'; pos2++ );
    if (eingabe[pos2] != '"') // Stringende erwartet
    {
     fprintf (stderr, "Stringende wurde nicht gefunden!n");
     exit(-1);
    }

    eingabe[pos2] = '�'; // strdup liest bis �
    args[n++] = strdup(eingabe + (pos+1)); // Zeigerarithmetik, eingabe[0] erstes Zeichen + pos+1 ist also Stringanfang nach "
    pos = pos2 + 1; // nach String weitermachen
   }

   else if (eingabe[pos] == '>') // Ausgabe in Datei
   {
    if (eingabe[++pos] == '>') // Anhängen
     append = 1;
    else pos--;     // Damit kein Zeichen verloren geht

    for (pos++; isspace(eingabe[pos]); pos++ ); // Leerzeichen ignorieren

    // Dateinamen einlesen, bis Leerzeichen, Dateinamen als String angegeben werden nicht unterstützt!
    for(pos2 = pos + 1; !isspace(eingabe[pos2]) && eingabe[pos2] != '�'; pos2++ );

    eingabe[pos2] = '�'; // fuer strdup
    file_out = strdup(eingabe + pos);
    pos = pos2 + 1; // nach Leerzeichen weitermachen
   }

   else if (eingabe[pos] == '<') // Einlesen aus Datei
   {
    for (pos++; isspace(eingabe[pos]); pos++ ); // Leerzeichen ignorieren

    // Dateinamen einlesen, bis Leerzeichen, Dateinamen als String angegeben werden nicht unterstützt!
    for(pos2 = pos + 1; !isspace(eingabe[pos2]) && eingabe[pos2] != '�'; pos2++ );

    eingabe[pos2] = '�'; // fuer strdup
    file_in = strdup(eingabe + pos);
    pos = pos2 + 1; // nach Leerzeichen weitermachen
   }

   else
   {
    // naechsten Parameter einlesen, bis Leerzeichen, Parameter muss ja mindestens 1 Zeichen lang sein, deshalb pos + 1
    for(pos2 = pos + 1; !isspace(eingabe[pos2]) && eingabe[pos2] != '�'; pos2++ );

    eingabe[pos2] = '�'; // fuer strdup
    args[n++] = strdup(eingabe + pos);
    pos = pos2 + 1; // nach Leerzeichen weitermachen
   }
  }
  while (eingabe[pos] != '�');  // bis Stringende


  args[n] = NULL;  // letzter Wert im Parameterarray muss NULL sein!

  char *cmd=strdup(args[0]);  // Erster Parameter ist Befehlsname



  pid=fork();  // Prozess kopieren

  if (pid<0) // Fehler bei Prozesserzeugung
  {
   fprintf(stderr, "Prozess konnte nicht erstellt werden!n");
   exit(-1);
  }

  if (pid==0) //im Kindprozess Befehl ausführen
  {
   if (file_in)
   {
    in = open(file_in, O_RDONLY); // Datei für Lesezugriff öffnen
    if (in < 0)            // Bei Fehler ist der File Descriptor < 0
   }

    
   if (file_out)
   {
    
    if (out < 0)
    {
     fprintf(stderr, "Fehler beim Dateizugriff!n");
     exit(-1); //manuell terminieren
    }

   }

   //execvp(char *file, *char arg[]);
   //exec mit Übernahme einer Argumentliste als Vector wie bei main. Das letzte Element des Parameterarrays arg muss NULL sein.

   status = execvp(cmd, args); // Befehl ausfuehren

            // execvp beendet Unterprozess, ausser es tritt ein Fehler auf
   fprintf(stderr, "Fehler bei execvp(): %dn", status);
   exit(-1); //manuell terminieren
  }

  else
  {
   waitpid (pid, &status;, 0); //Eöternprozess wartet, bis Kind fertig
   printf ("Unterprozess beendet mit Status: %dn", status);

   // Speicher wieder freigeben, der von den Argumenten belegt wurde (strdup())
   n=0;
   while (args[n] != NULL)
    free(args[n++]);
   // File Handles wieder schließen und Speicher freigeben
   if (in >= 0)
    close(in);
   if (out >= 0)
    close(out);
   free(file_in);
   free(file_out);
   // Dateinamen und append wieder zurücksetzen
   file_in = file_out = NULL;
   in = out = -1;
   append = 0;
  }
 }
 return 0;
}

 

Revise this Paste

Parent: 32741
Your Name: Code Language: