PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 'cp -dp' in C++



Der Untergeher
25-09-2006, 23:52
Hallo zusammen,

ich versuche mit einem C++ Proramm Dateien zu kopieren. Und zwar genau so wie 'cp -dp Datei1 Datei2' es machen würde. Einfach per
system("cp -dp Datei1 Datei2"); die Kopie zu erstellen bietet sich nicht an, da ich über die Dateinamen keine Kontrolle habe und sie vom Command Interpreter (hier: bash) interpretiert werden würden. Ich hab also zwei Möglichkeiten:
1. Die Dateinnamen so escapen, dass die shell nichts anrichten kann und einen Befehl (statt 'cp') verwenden, der damit umgehen kann. Kennt da jemand eine Möglichkeit?
2. Eine Bibliothek verwenden, die eine Funktion anbietet die sich wie 'cp -dp' benimmt. Ich war schon versucht einfach nen wrapper um die 'main' von cp aus den coreutils zu schreiben ... Aber das Problem muss doch schonmal jemand gehabt (und gelöst) haben. Kennt da jemand ne Lösung?

Lieben Gruß & vielen Dank
Daniel

peschmae
26-09-2006, 15:55
Ich würde wennschon nicht system() verwenden sondern exec() und damit direkt cp aufrufen - d.h. da läuft dann keine Shell und du kannst auch ganz genau angeben was cp als erstes, zweites und n-tes Argument erhält.

Die noch schlauere (wenn auch etwas Programmieraufwändigere) Lösung ist natürlich das ganze selber mit Streams zu kopieren - eine unnötige Abhängigkeit weniger, portablerer Code und du startest erst noch jedes Mal keinen zusätzlichen Prozess (was immer recht Ressourcen benötigt).

Die Boost Filesystem Library (http://www.boost.org/libs/filesystem/doc/) währe wohl auch eine gute Lösung, wenn du nicht schon sonst ein C++-Framework wie Qt oder so verwendest.

MfG Peschmä

Der Untergeher
26-09-2006, 17:05
Ups, auf die fork+exec Möglichkeit hätt ich auch selbst kommen können :o .
Das ist dann schon mal eine Möglichkeit.
Die POSIX C API oder die C++ Standardbibliothek möchte ich zum kopieren nach Möglichkeit nicht direkt bemühen - das Land der Schmerzen.
Eleganter wär's natürlich mit einer Bibliothek. Boost hab ich mir schon angeschaut, das bietet zumindest schon mal 'copy_file' an, was so circa 'cp -p' entspricht. Bei Qt hab ich auch reingeschaut, aber nichts passendes gefunden.

Viel Dank
Daniel

PS: Wenn noch jemand Ideen für Bibliotheken hat gerne raus damit - zumal ich inzwischen einen Ersatz für "cp -dpR" brauche.

peschmae
26-09-2006, 17:10
Nur zu Qt: QFile hat durchaus eine copy() Funktion. Aber das würde ich natürlich nur benutzen wenn du Qt auch sonst in deinem Programm verwendest, sonst eher boost.

MfG Peschmä

Der Untergeher
26-09-2006, 23:28
So, die unelegante Lösung funktioniert ...
Wenn man das waitpid rausnimmt laufen die cp's asynchron


void fork_exec_cp_r( string cp_from, string cp_to )
{
pid_t pid;
switch( pid=fork() ) {
case -1:
cerr << "Fehler bei fork()" << endl;
exit(1);
break;
case 0:
execl("/bin/cp", "cp", "--no-dereference", "--preserve=mode,timestamps", "-r", cp_from.c_str(), cp_to.c_str(), NULL );
cerr << "Fehler bei execl" << endl;
exit(1);
break;
default:
waitpid(pid,NULL,0);
break;
}
}


edit: der Aufruf von cp sieht besser so aus:


execl("/bin/cp", "cp", "--no-dereference", "--preserve=mode,timestamps", "-r", "--", cp_from.c_str(), cp_to.c_str(), NULL );

Dann klappts auch mit Dateinamen wie "--link" (werden nicht mehr als Option interpretiert)