|
@@ -54,15 +54,47 @@ static HashTable<RefPtr<GUI::Window>> file_operation_windows;
|
|
|
|
|
|
static void run_file_operation([[maybe_unused]] FileOperation operation, const String& source, const String& destination, GUI::Window* parent_window)
|
|
|
{
|
|
|
- // FIXME: Don't use popen() like this, very string injection friendly..
|
|
|
- FILE* helper_pipe = popen(String::formatted("/bin/FileOperation Copy {} {}", source, LexicalPath(destination).dirname()).characters(), "r");
|
|
|
- VERIFY(helper_pipe);
|
|
|
+ int pipe_fds[2];
|
|
|
+ if (pipe(pipe_fds) < 0) {
|
|
|
+ perror("pipe");
|
|
|
+ VERIFY_NOT_REACHED();
|
|
|
+ }
|
|
|
+
|
|
|
+ pid_t child_pid = fork();
|
|
|
+ if (child_pid < 0) {
|
|
|
+ perror("fork");
|
|
|
+ VERIFY_NOT_REACHED();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!child_pid) {
|
|
|
+ if (close(pipe_fds[0]) < 0) {
|
|
|
+ perror("close");
|
|
|
+ _exit(1);
|
|
|
+ }
|
|
|
+ if (dup2(pipe_fds[1], STDOUT_FILENO) < 0) {
|
|
|
+ perror("dup2");
|
|
|
+ _exit(1);
|
|
|
+ }
|
|
|
+ if (execlp("/bin/FileOperation", "/bin/FileOperation", "Copy", source.characters(), LexicalPath(destination).dirname().characters(), nullptr) < 0) {
|
|
|
+ perror("execlp");
|
|
|
+ _exit(1);
|
|
|
+ }
|
|
|
+ VERIFY_NOT_REACHED();
|
|
|
+ } else {
|
|
|
+ if (close(pipe_fds[1]) < 0) {
|
|
|
+ perror("close");
|
|
|
+ _exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
auto window = GUI::Window::construct();
|
|
|
file_operation_windows.set(window);
|
|
|
|
|
|
+ auto pipe_input_file = Core::File::construct();
|
|
|
+ pipe_input_file->open(pipe_fds[0], Core::IODevice::ReadOnly, Core::File::ShouldCloseFileDescriptor::Yes);
|
|
|
+
|
|
|
window->set_title("Copying Files...");
|
|
|
- window->set_main_widget<FileOperationProgressWidget>(helper_pipe);
|
|
|
+ window->set_main_widget<FileOperationProgressWidget>(pipe_input_file);
|
|
|
window->resize(320, 200);
|
|
|
if (parent_window)
|
|
|
window->center_within(*parent_window);
|