M file-browser/include/file_execute.h => file-browser/include/file_execute.h +24 -12
@@ 1,47 1,59 @@
-#include <unistd.h>
+#ifndef __FILE_EXECUTE_H__
+#define __FILE_EXECUTE_H__
+
#include <stdbool.h>
+#include <unistd.h>
+
+#define WRITE_END 1
+#define READ_END 0
/**
* @brief This structure holds information about executing subprocess
- *
+ *
*/
typedef struct {
- pid_t pid;/**< PID of the running process */
- int output_signal;/**< Exit code of the process*/
- bool exited;/**< Whether the process has ended */
+ pid_t pid; /**< PID of the running process */
+ int output_signal; /**< Exit code of the process*/
+ bool exited; /**< Whether the process has ended */
+
+ int stderr_pipe[2];
} executing_file_t;
/**
* @brief This structure holds error or executing subprocess
- *
+ *
*/
typedef struct {
- bool error; /**< in case there was an error, this is true*/
+ bool error; /**< in case there was an error, this is true*/
executing_file_t file; /**< executing file if error is false*/
} executing_file_error_t;
/**
* @brief Start executing given file
- *
+ *
* @param path path to the executable
* @param args arguments to start the executable with
* @return executing_file_error_t with either error or process information set
*/
executing_file_error_t executing_file_execute(char *path, char *args);
+void executing_file_destroy(executing_file_t *file);
+
/**
* @brief Wait for the process to exit
- *
- * @param file
+ *
+ * @param file
* @return int exit code
*/
int executing_file_wait(executing_file_t *file);
/**
* @brief Check whether the process has ended and return immediatelly
- *
- * @param file
+ *
+ * @param file
* @return true when the process has ended
* @return false when the process is still running
*/
bool executing_file_has_ended(executing_file_t *file);
+
+#endif // __FILE_EXECUTE_H__
M file-browser/include/file_open.h => file-browser/include/file_open.h +19 -1
@@ 5,7 5,25 @@
#include "file_access.h"
#include "options.h"
-file_operation_error_t file_open(file_t *file, exec_options_t *options,
+typedef enum {
+ OPENED_NONE,
+ OPENED_MIME,
+ OPENED_EXEC,
+ OPENED_TEXT,
+} opened_type_t;
+
+typedef struct {
+ opened_type_t type;
+
+ bool executed;
+ bool ended_with_error;
+
+ file_operation_error_t error;
+
+ executing_file_t executing_file;
+} opened_file_state_t;
+
+opened_file_state_t file_open(file_t *file, exec_options_t *options,
fileaccess_state_t state);
#endif // __FILE_OPEN_H__
M file-browser/src/file_execute.c => file-browser/src/file_execute.c +31 -1
@@ 1,4 1,5 @@
#include "file_execute.h"
+#include "file_access.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
@@ 8,19 9,44 @@
executing_file_error_t executing_file_execute(char *path, char *args) {
executing_file_error_t ret;
+ executing_file_t file;
+
+ if (pipe(file.stderr_pipe) == -1) {
+ ret.error = file_operation_error_from_errno(errno);
+ return ret;
+ }
+
pid_t pid = fork();
if (pid == -1) {
+ close(file.stderr_pipe[0]);
+ close(file.stderr_pipe[1]);
+
ret.error = true;
return ret;
}
- if (pid == 0) {
+ if (pid == 0) { // child process
+ close(file.stderr_pipe[READ_END]);
+
+ if(dup2(file.stderr_pipe[WRITE_END], STDERR_FILENO) == -1) {
+ perror("There was an error during dup2");
+ exit(errno);
+ }
+
execl(path, path, args, (char*)NULL);
+
+ // Is reached only in case of an error
+ fprintf(stderr, "Could not execute file: %s\r\n",
+ fileaccess_get_error_text(file_operation_error_from_errno(errno)));
exit(errno);
}
+ // parent process
+ close(file.stderr_pipe[WRITE_END]);
+
ret.error = false;
+ ret.file = file;
ret.file.pid = pid;
ret.file.output_signal = 0;
ret.file.exited = false;
@@ 49,3 75,7 @@ bool executing_file_has_ended(executing_file_t *file) {
return false;
}
+
+void executing_file_destroy(executing_file_t *file) {
+ close(file->stderr_pipe[READ_END]);
+}