Chito
22-05-2008, 14:31
Hallo,
ich programmiere gerade eine eigene Shell und möchte eine Eingabe mit einer PIPE vornehmen. Zum Beispiel:
ls | more
Das funktioniert so weit ganz gut.
Es gibt nur ein kleines Problem.
Zunächst analysiere ich den Eingabestrom. Ist darin ein PIPE '|' vorhanden, dann selectiere ich aus dem Eingabestrom das 'more' und das 'ls'.
Folglich wird dann meine Schleife 2 mal ducrhlaufen - für cmd_in und cmd_out ... die beiden Variablen brauche ich zum pipen. ( pipe(); execvp(cmd_in[0],cmd_in); und execvp(cmd_out[0], cmd_out); )
bei den einzelnen durchläufen via Pointer wird auch jeweils der richtige wert - 'ls' und 'more' in das pointer char - array geschrieben.
Nach den beiden ducrhläufen aber erhalte ich aber:
cmd_in: ls
cmd_out: ls
... obwohl ich pro durchlauf erst cmd_in: more und dann für cmd_out: ls zuwies.
Ich weiß das ich hier beim 2. Durchlauf die Adresse des Zeigers auf cmd_in ändere, und somit dann auch da ls wie bei cmd_out steht.
Wie bekomme ich in C sowas wie eine Tiefenkopie wie bei C++ hin?
Hier mein Code-Auszug:
char* eingabe[MAXLINE];
char strcpy_search_pipe [MAXLINE],
memcpy_search_pipe [MAXLINE],
strcpy_search_parameter [MAXLINE], // <- more und ls ausgelesen
strcpy_search_command_2 [MAXLINE],
strcpy_search_command_3 [MAXLINE],
memcpy_search_OUTPUT [MAXLINE],
query_search_pipe [MAXLINE],
memcpy_search_command_3 [MAXLINE],
memcpy_search_command_2 [MAXLINE],
memcpy_search_command_1 [MAXLINE],
memcpy_search_command_0 [MAXLINE],
//command_1 [MAXLINE],
*tmp_chdir,
*search_parameter,
*search_command_0,
*search_command_1,
*search_command_2,
*search_command_3,
*parameter,
*command_0,
*command_1, // <- more bzw. ls an zeiger übergeben
*command_2,
*command_3,
//
*search_INPUT,
*search_OUTPUT;
char* ptr;
char *cmd [6],
*cmd_in [6], // <- 1. Durchlauf 'more' von *command_1
*cmd_out[6]; // <- 2. Durchlauf 'ls' von *command_1
char* cmd_input_output[6];
int size_eingabe_command_2 = 0,
size_cut_command_3 = 0,
size_cut_command_2 = 0,
size_cut_command_1 = 0,
size_cut_command_0 = 0,
size_parameter = 0,
size_command_0 = 0,
size_command_1 = 0,
size_command_2 = 0,
size_command_3 = 0,
//
size_cut_search_OUTPUT = 0;
int fd[2], // filedeskriptor PIPE
err,
ERROR = -1;
printf("\nShell-Eingabe ( [command] [parameter] ) > ");
/* Eingabe */
fgets(eingabe, MAXLINE, stdin);
printf("#########################################\n\n");
/* Zeilenumbruch wird eliminiert */
if( (ptr = (char *) strchr(eingabe, '\n')) != NULL)
{
*ptr = '\0'; // '\n' durch '\0' ersetzen
}
/* Eingabe wird umkopiert kopiert */
strcpy (strcpy_search_pipe, eingabe);
strcpy (memcpy_search_pipe, eingabe);
strcpy (query_search_pipe, eingabe);
//
// Nach der PIPE wird gesucht:
if((strchr (strcpy_search_pipe, '|')) != 0) //wenn eine PIPE gefunden
{
DEBUGOUT("PIPE gefunden!!!\n\n");
DEBUGOUT("Eingabestrom!!!\n\n");
search_INPUT = strchr (memcpy_search_pipe, '|');
*search_INPUT++ = '\0';
*search_INPUT++ = '\0';
DEBUGOUT("search_INPUT : %s | size : %i\n\n", search_INPUT, strlen(search_INPUT));
DEBUGOUT("Ausgabestrom!!!\n\n");
size_cut_search_OUTPUT = (strlen(memcpy_search_pipe) - ((strlen(search_INPUT))-3)); // (-3) '_|_' werden abgezogen!
DEBUGOUT("size_cut_search_OUTPUT : %i \n\n", size_cut_search_OUTPUT);
memcpy(memcpy_search_OUTPUT, query_search_pipe, (size_cut_search_OUTPUT));
DEBUGOUT("memcpy_search_OUTPUT : %s | SIZE : %i \n\n", memcpy_search_OUTPUT, strlen(memcpy_search_OUTPUT));
search_OUTPUT = memcpy_search_OUTPUT;
DEBUGOUT("search_OUTPUT : %s | size : %i\n\n", search_OUTPUT, strlen(search_OUTPUT));
cmd_input_output[0] = search_INPUT;
cmd_input_output[1] = search_OUTPUT;
DEBUGOUT("cmd_input_output : %s \n", cmd_input_output[0]);
for ( int index = 0 ; index <= 1 ; index++ )
{
DEBUGOUT("\nindex : %i ################################################## #################\n", index);
DEBUGOUT("$$$$$$$$$\n\n");
//
// Eingabe Shell-Befehle
strcpy (strcpy_search_parameter, cmd_input_output[index]);
strcpy (strcpy_search_command_2, cmd_input_output[index]);
DEBUGOUT("strcpy_search_parameter : %s | size : %i\n\n", strcpy_search_parameter, strlen(strcpy_search_parameter));
DEBUGOUT("strcpy_search_command_2 : %s | size : %i\n\n\n", strcpy_search_command_2, strlen(strcpy_search_command_2));
DEBUGOUT("strcpy_search_parameter : %s | size : %i\n", strcpy_search_parameter, strlen(strcpy_search_parameter));
/* parameter wird herausgeschnitten */
if((strchr (strcpy_search_parameter, '$')) == 0) // kein weiteres Leerzeichen gefunden << command_1
{
search_parameter = "$PWD";
size_parameter = strlen(search_parameter);
DEBUGOUT("search_parameter : %s | size : %i\n", search_parameter, size_parameter);
//
if((strchr (strcpy_search_parameter, ' ')) == 0) // kein weiteres Leerzeichen gefunden << command_1; bei Eingabe: ls und cd
{
command_1 = strcpy_search_parameter;
DEBUGOUT("command_1 READY : %s | size : %i\n", command_1, strlen(command_1));
//
*search_parameter++ = '\0';
DEBUGOUT("parameter READY : %s | size : %i\n", search_parameter, strlen(search_parameter));
//
//
if ( index == 0 )
{ DEBUGOUT("\n1.1 Ich bin INDEX 0 !!!!!!!!!!!!!!!!!!!! \n");
//strcpy(to,tmp);
cmd_in[0] = command_1; // <- uebergabe ueber command_1
//strcpy(cmd_in[0],command_1);
//
if((strcmp(cmd_in[0],"cd"))==0) //Eingabe: cd
{ // Shell-EINGABE: 'cd'
cmd_in[1]=getenv("HOME");
cmd_in[2]=(char *)NULL;
}
else
{
cmd_in[1]=(char *)NULL;
}
DEBUGOUT("\n\nIN IN IN");
DEBUGOUT("\n\ncmd_in[0] : %s\n", cmd_in[0]); // <-- AUSGABE: 'more'
}
if ( index == 1 )
{ DEBUGOUT("\n1.2 Ich bin INDEX 1 !!!!!!!!!!!!!!!!!!!! \n");
cmd_out[0] = command_1; // <- uebergabe ueber command_1
//cmd_out[0]="more";
//
if((strcmp(cmd_out[0],"cd"))==0) //Eingabe: cd
{ // Shell-EINGABE: 'cd'
cmd_out[1]=getenv("HOME");
cmd_out[2]=(char *)NULL;
}
else
{
cmd_out[1]=(char *)NULL;
}
DEBUGOUT("\n\nOUT OUT OUT");
DEBUGOUT("\n\ncmd_out[0] : %s\n", cmd_out[0]); // <- AUSGABE: 'ls'
}
DEBUGOUT("\n\nERROR Zeile 409: cmd_in[0] : %s\n", cmd_in[0]); // <- an dem Punkt AUSGABE: 'ls'
DEBUGOUT("ERROR Zeile 410: cmd_out[0] : %s\n", cmd_out[0]); // <- an dem Punkt AUSGABE: 'ls'
Bitte schaut doch über den Code
ich programmiere gerade eine eigene Shell und möchte eine Eingabe mit einer PIPE vornehmen. Zum Beispiel:
ls | more
Das funktioniert so weit ganz gut.
Es gibt nur ein kleines Problem.
Zunächst analysiere ich den Eingabestrom. Ist darin ein PIPE '|' vorhanden, dann selectiere ich aus dem Eingabestrom das 'more' und das 'ls'.
Folglich wird dann meine Schleife 2 mal ducrhlaufen - für cmd_in und cmd_out ... die beiden Variablen brauche ich zum pipen. ( pipe(); execvp(cmd_in[0],cmd_in); und execvp(cmd_out[0], cmd_out); )
bei den einzelnen durchläufen via Pointer wird auch jeweils der richtige wert - 'ls' und 'more' in das pointer char - array geschrieben.
Nach den beiden ducrhläufen aber erhalte ich aber:
cmd_in: ls
cmd_out: ls
... obwohl ich pro durchlauf erst cmd_in: more und dann für cmd_out: ls zuwies.
Ich weiß das ich hier beim 2. Durchlauf die Adresse des Zeigers auf cmd_in ändere, und somit dann auch da ls wie bei cmd_out steht.
Wie bekomme ich in C sowas wie eine Tiefenkopie wie bei C++ hin?
Hier mein Code-Auszug:
char* eingabe[MAXLINE];
char strcpy_search_pipe [MAXLINE],
memcpy_search_pipe [MAXLINE],
strcpy_search_parameter [MAXLINE], // <- more und ls ausgelesen
strcpy_search_command_2 [MAXLINE],
strcpy_search_command_3 [MAXLINE],
memcpy_search_OUTPUT [MAXLINE],
query_search_pipe [MAXLINE],
memcpy_search_command_3 [MAXLINE],
memcpy_search_command_2 [MAXLINE],
memcpy_search_command_1 [MAXLINE],
memcpy_search_command_0 [MAXLINE],
//command_1 [MAXLINE],
*tmp_chdir,
*search_parameter,
*search_command_0,
*search_command_1,
*search_command_2,
*search_command_3,
*parameter,
*command_0,
*command_1, // <- more bzw. ls an zeiger übergeben
*command_2,
*command_3,
//
*search_INPUT,
*search_OUTPUT;
char* ptr;
char *cmd [6],
*cmd_in [6], // <- 1. Durchlauf 'more' von *command_1
*cmd_out[6]; // <- 2. Durchlauf 'ls' von *command_1
char* cmd_input_output[6];
int size_eingabe_command_2 = 0,
size_cut_command_3 = 0,
size_cut_command_2 = 0,
size_cut_command_1 = 0,
size_cut_command_0 = 0,
size_parameter = 0,
size_command_0 = 0,
size_command_1 = 0,
size_command_2 = 0,
size_command_3 = 0,
//
size_cut_search_OUTPUT = 0;
int fd[2], // filedeskriptor PIPE
err,
ERROR = -1;
printf("\nShell-Eingabe ( [command] [parameter] ) > ");
/* Eingabe */
fgets(eingabe, MAXLINE, stdin);
printf("#########################################\n\n");
/* Zeilenumbruch wird eliminiert */
if( (ptr = (char *) strchr(eingabe, '\n')) != NULL)
{
*ptr = '\0'; // '\n' durch '\0' ersetzen
}
/* Eingabe wird umkopiert kopiert */
strcpy (strcpy_search_pipe, eingabe);
strcpy (memcpy_search_pipe, eingabe);
strcpy (query_search_pipe, eingabe);
//
// Nach der PIPE wird gesucht:
if((strchr (strcpy_search_pipe, '|')) != 0) //wenn eine PIPE gefunden
{
DEBUGOUT("PIPE gefunden!!!\n\n");
DEBUGOUT("Eingabestrom!!!\n\n");
search_INPUT = strchr (memcpy_search_pipe, '|');
*search_INPUT++ = '\0';
*search_INPUT++ = '\0';
DEBUGOUT("search_INPUT : %s | size : %i\n\n", search_INPUT, strlen(search_INPUT));
DEBUGOUT("Ausgabestrom!!!\n\n");
size_cut_search_OUTPUT = (strlen(memcpy_search_pipe) - ((strlen(search_INPUT))-3)); // (-3) '_|_' werden abgezogen!
DEBUGOUT("size_cut_search_OUTPUT : %i \n\n", size_cut_search_OUTPUT);
memcpy(memcpy_search_OUTPUT, query_search_pipe, (size_cut_search_OUTPUT));
DEBUGOUT("memcpy_search_OUTPUT : %s | SIZE : %i \n\n", memcpy_search_OUTPUT, strlen(memcpy_search_OUTPUT));
search_OUTPUT = memcpy_search_OUTPUT;
DEBUGOUT("search_OUTPUT : %s | size : %i\n\n", search_OUTPUT, strlen(search_OUTPUT));
cmd_input_output[0] = search_INPUT;
cmd_input_output[1] = search_OUTPUT;
DEBUGOUT("cmd_input_output : %s \n", cmd_input_output[0]);
for ( int index = 0 ; index <= 1 ; index++ )
{
DEBUGOUT("\nindex : %i ################################################## #################\n", index);
DEBUGOUT("$$$$$$$$$\n\n");
//
// Eingabe Shell-Befehle
strcpy (strcpy_search_parameter, cmd_input_output[index]);
strcpy (strcpy_search_command_2, cmd_input_output[index]);
DEBUGOUT("strcpy_search_parameter : %s | size : %i\n\n", strcpy_search_parameter, strlen(strcpy_search_parameter));
DEBUGOUT("strcpy_search_command_2 : %s | size : %i\n\n\n", strcpy_search_command_2, strlen(strcpy_search_command_2));
DEBUGOUT("strcpy_search_parameter : %s | size : %i\n", strcpy_search_parameter, strlen(strcpy_search_parameter));
/* parameter wird herausgeschnitten */
if((strchr (strcpy_search_parameter, '$')) == 0) // kein weiteres Leerzeichen gefunden << command_1
{
search_parameter = "$PWD";
size_parameter = strlen(search_parameter);
DEBUGOUT("search_parameter : %s | size : %i\n", search_parameter, size_parameter);
//
if((strchr (strcpy_search_parameter, ' ')) == 0) // kein weiteres Leerzeichen gefunden << command_1; bei Eingabe: ls und cd
{
command_1 = strcpy_search_parameter;
DEBUGOUT("command_1 READY : %s | size : %i\n", command_1, strlen(command_1));
//
*search_parameter++ = '\0';
DEBUGOUT("parameter READY : %s | size : %i\n", search_parameter, strlen(search_parameter));
//
//
if ( index == 0 )
{ DEBUGOUT("\n1.1 Ich bin INDEX 0 !!!!!!!!!!!!!!!!!!!! \n");
//strcpy(to,tmp);
cmd_in[0] = command_1; // <- uebergabe ueber command_1
//strcpy(cmd_in[0],command_1);
//
if((strcmp(cmd_in[0],"cd"))==0) //Eingabe: cd
{ // Shell-EINGABE: 'cd'
cmd_in[1]=getenv("HOME");
cmd_in[2]=(char *)NULL;
}
else
{
cmd_in[1]=(char *)NULL;
}
DEBUGOUT("\n\nIN IN IN");
DEBUGOUT("\n\ncmd_in[0] : %s\n", cmd_in[0]); // <-- AUSGABE: 'more'
}
if ( index == 1 )
{ DEBUGOUT("\n1.2 Ich bin INDEX 1 !!!!!!!!!!!!!!!!!!!! \n");
cmd_out[0] = command_1; // <- uebergabe ueber command_1
//cmd_out[0]="more";
//
if((strcmp(cmd_out[0],"cd"))==0) //Eingabe: cd
{ // Shell-EINGABE: 'cd'
cmd_out[1]=getenv("HOME");
cmd_out[2]=(char *)NULL;
}
else
{
cmd_out[1]=(char *)NULL;
}
DEBUGOUT("\n\nOUT OUT OUT");
DEBUGOUT("\n\ncmd_out[0] : %s\n", cmd_out[0]); // <- AUSGABE: 'ls'
}
DEBUGOUT("\n\nERROR Zeile 409: cmd_in[0] : %s\n", cmd_in[0]); // <- an dem Punkt AUSGABE: 'ls'
DEBUGOUT("ERROR Zeile 410: cmd_out[0] : %s\n", cmd_out[0]); // <- an dem Punkt AUSGABE: 'ls'
Bitte schaut doch über den Code