Skip to content
Snippets Groups Projects
Commit 4e291984 authored by Sébastien Gendre's avatar Sébastien Gendre
Browse files

Jobs: Add management of stdout redirection to file

parent df2cd86a
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,56 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
/* Search file redirection argument ('>') in argv */
int job_write_redirection_position_in_argv(int argc, char *argv[]) {
// Check each argument in the argv
for (int i = 0; i < argc; ++i) {
if (strcmp(argv[i], ">") == 0) {
// If ">" found, return its position
return i;
}
}
return -1;
}
/* See if argv has an redirection symbole '>' and return its position */
char* job_write_redirection_path_in_argv(int argc, char *argv[]) {
int redirect_pos = job_write_redirection_position_in_argv(argc, argv);
if (redirect_pos == -1) {
return NULL;
} else {
return argv[redirect_pos + 1];
}
}
/* Clean arguments after stdout redirection */
int job_clean_argv_after_redirection_char(int *argc, char **argv) {
int redirect_arg_pos = job_write_redirection_position_in_argv(*argc, argv);
// If the redirection char argument position are beyound argv length, return error
// code
if (redirect_arg_pos >= *argc) {
return -1;
}
/* // Free all arguments after the redirection argument position */
/* for (int i = redirect_arg_pos; i < *argc; ++i) { */
/* free(argv[i]); */
/* } */
// Place a NULL at the redirection argument position
argv[redirect_arg_pos] = NULL;
// Define the new argc value
*argc = redirect_arg_pos;
// Reduce argv length
argv = realloc(argv, (*argc+1)*sizeof(char*));
return 0;
}
// Execute a given command as job
......@@ -13,6 +63,9 @@ int job_exec_command(int argc, char *argv[]) {
pid_t pid;
int child_process_status;
int exec_status;
char *redirection_path = NULL;
int redirection_file;
int stdout_new_desc = -1;
pid = fork();
......@@ -20,6 +73,21 @@ int job_exec_command(int argc, char *argv[]) {
// In case of fork error
} else if (pid == 0) {
// I'm the child process
// Check if the redirection of stdout to file is requested by user
redirection_path = job_write_redirection_path_in_argv(argc, argv);
if (redirection_path) {
// If yes, open the file path
redirection_file = open(redirection_path, O_WRONLY | O_CREAT, 0640);
// Replace stdout file descriptor by a copy of the file
// descriptor of the openned file
stdout_new_desc = dup2(redirection_file, STDOUT_FILENO);
if (stdout_new_desc == -1) {
perror("Cannot redirect stdout");
} else {
// Remove all arguments after the '>'
job_clean_argv_after_redirection_char(&argc, argv);
}
}
// Exec the command found in PATH env by using execvpe()
exec_status = execvpe(argv[0], argv, NULL);
if (exec_status == -1) {
......@@ -44,3 +112,4 @@ int job_exec_command(int argc, char *argv[]) {
}
}
}
......@@ -11,7 +11,8 @@
/* Execute a given command as job
*
* Parameters:
* - cmd: The command to execute
* - argc: The command arguments counter
* - argv: The command arguments
*
* Return:
* - The command return code (0 is success)
......@@ -19,4 +20,41 @@
*/
int job_exec_command(int argc, char *argv[]);
/* Search file redirection argument ('>') in argv
*
* Parameters:
* - argc: The command arguments counter
* - argv: The command arguments
*
* Return:
* The position of '>' argument in the argv, -1 if not found
*/
int job_write_redirection_position_in_argv(int argc, char *argv[]);
/* Get file path where user ask to redirect stdout, if defined by the
* user with a '>'
*
* Parameters:
* - argc: The command arguments counter
* - argv: The command arguments
*
* Return:
* The file path where user ask to redirect stdout
* If not defined, return NULL
*/
char* job_write_redirection_path_in_argv(int argc, char *argv[]);
/* Clean arguments after stdout redirection
*
* Parameters:
* - argc: The command arguments counter
* - argv: The command arguments
*
* Return:
* 0 if success, -1 if error
*/
int job_clean_argv_after_redirection_char(int *argc, char **argv);
#endif /* JOBS_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment