'cp -dpR' in C++
-
Hallo zusammen,
ich versuche mit einem C++ Proramm Dateien zu kopieren. Und zwar genau so wie 'cp -dpR Datei1 Datei2' es machen würde. Einfach per
system("cp -dpR 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?
oder besser noch:
2. Eine Bibliothek verwenden, die eine Funktion anbietet die sich wie 'cp -dpR' 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 elegant gelöst) haben.
Die Recherche hier im Forum hat mich schon hierhin geführt. Die POSIX C API würde ich nur ungern bemühen - das ist das Land der Schmerzen. Am Ende des Artikels wird auf Boost verwiesen, das bietet zumindest schonmal 'copy_file' an, was so circa 'cp -p' entspricht. Das ebenfalls zitierte More scheint ein "ruhendes" Projekt zu sein - dagegen würde ich ungern linken.
Kennt jemand ne elegante Lösung?Lieben Gruß & vielen Dank
Daniel
-
statt system könntest du exec nehmen
eine lib dafür kenne ich auch nicht.
-
Auf die fork+exec Möglichkeit hat mich in einem anderen Forum auch schon einer gebracht - das hat dann auch den zusätzlichen Charme, dass die io-Last in nem anderen Prozess liegt. Eleganter wär's natürlich mit einer Bibliothek.
Vielen Dank
Daniel
-
So, die unelegante Lösung funktioniert ...
Wenn man das waitpid rausnimmt laufen die cp's asynchronvoid 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; } }
-
Ein kleines Problem hat deine Funktion noch, falls die Dateien spezielle Namen haben:
// Beispiel fork_exec_cp_r("-p", "--link")
-
Ja stimmt. In meinem Fall werden allerdings immer absolute Dateiname übergeben ( "/home/d..." ), so dass das Problem nicht auftritt. Weiss jemand wie man das Problem prinzipell umgeht ?(in der bash läuft sowas ja so: rm -- -rf (zum löschen der Datei "-rf"))
-
Argh, hab gerade nen Knoten im Gehirn:
execl("/bin/cp", "cp", "--no-dereference", "--preserve=mode,timestamps", "-r", "--", cp_from.c_str(), cp_to.c_str(), NULL );
sollte es tun.
-
ansonsten, falls cp das -- jetzt nicht kennen würde, müsste man nur schauen ob das erste zeichen ein / ist (absoluter pfad) und ansonsten einfach $PWD davor setzen um daraus einen Absoluten zu machen.