PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Variablen Inhalt zuweisen - NICHT nur die Pointer - Adresse!!! PROBLEM



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

ContainerDriver
22-05-2008, 16:27
Hallo,

soweit ich das sehe zeigen sowohl cmd_in[0] als auch cmd_out[0] auf strcpy_search_parameter; Änderst du den Inhalt von strcpy_search_parameter änderst du auch indirekt cmd_in[0] und cmd_out[0].
Eine Lösungsmöglichkeit wäre, aus cmd_in[0] und cmd_out[0] Arrays zu machen und den Inhalt von strcpy_search_parameter reinzukopieren, oder du holst dir für strcpy_search_parameter in jedem Schleifendurchlauf neuen Speicher (mit malloc()) und zeigst dann auf diesen Speicher (free() dann später aber nicht vergessen).

Gruß, Florian

Chito
22-05-2008, 17:29
WOW .... ich haette nicht gedacht das mir jmd so schnell hilft! :)

Vielen Dank! So wie du sah ich das Problem auch. Nur fand ich halt keine Lösung dafür.

Ich werde mal versuchen deinen Lösungsvorschlag umzusetzen ;)

danke

Chito
22-05-2008, 17:46
Ich habe deinen rat umgesetzt, aber es hat sich am ergebnis nichts getan.

beide variablen haben immer noch den gleichen letzten wert.

hier mal mein codeauszug:




if((strchr (strcpy_search_parameter, ' ')) == 0) // kein weiteres Leerzeichen gefunden << command_1; bei Eingabe: ls und cd
{

if (command_1 = (char *) malloc(sizeof(char)) != NULL)
{
command_1 = strcpy_search_parameter;
}
else
{
printf("Nicht genügend Arbeitsspeicher vorhanden!");
}


//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;
//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]);
free(command_1); // <- free()
}
if ( index == 1 )
{ DEBUGOUT("\n1.2 Ich bin INDEX 1 !!!!!!!!!!!!!!!!!!!! \n");
cmd_out[0] = 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]);
free(command_1); // <- free()
}
DEBUGOUT("\n\nERROR Zeile 409: cmd_in[0] : %s\n", cmd_in[0]);
DEBUGOUT("ERROR Zeile 410: cmd_out[0] : %s\n", cmd_out[0]);

}



Was zum geier mache ich falsch. ich weiß auch nicht wo ich mir diesbezüglich rat holen könnte. - bzw. wie ich bei google nach diesem problem suchen könnte.


Bitte schau dir den code doch noch einmal an.


danke :)


EDIT: Konnte mein Problem soeben selber lösen. Vielen Dank für deine Hilfe!

ContainerDriver
22-05-2008, 18:25
EDIT: Konnte mein Problem soeben selber lösen. Vielen Dank für deine Hilfe!

Wäre jetzt noch schön, wenn du deine Lösungsidee posten würdest! :)

Chito
22-05-2008, 18:41
Gerne!

Dieser Auszug des Codes ist die Wurzel der Problemlösung:



if((strchr (strcpy_search_parameter, ' ')) == 0) // kein weiteres Leerzeichen gefunden << command_1; bei Eingabe: ls und cd
{
command_1 = strcpy_search_parameter;

//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");
// Inhalt kopieren
strcpy(cmd_in_0,command_1);
//
cmd_in[0] = cmd_in_0;
//
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]);

}
if ( index == 1 )
{ DEBUGOUT("\n1.2 Ich bin INDEX 1 !!!!!!!!!!!!!!!!!!!! \n");
// Inhalt kopieren
strcpy(cmd_out_0,command_1);
//
cmd_out[0] = cmd_out_0;
//
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]);

}


DEBUGOUT("\n\nERROR Zeile 422: cmd_in[0] : %s\n", cmd_in[0]);
DEBUGOUT("ERROR Zeile 423: cmd_out[0] : %s\n", cmd_out[0]);

}

Für die Zwischenspeicherung der Werte deklarierte ich vorher zwei char-arrays, so wie du meintest. :)