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