Skip to content

Commit

Permalink
Add stats-uniq command (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruilopesm committed May 10, 2023
1 parent 76fe66a commit a40a9f5
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 5 deletions.
4 changes: 4 additions & 0 deletions include/requests.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,8 @@ int stats_time_request(PIDS_ARR *pids_arr);

int stats_command_request(PIDS_ARR_WITH_PROGRAM *pids_arr_with_program);

int stats_uniq_request(PIDS_ARR *pids_arr);

int is_program_in_array(char **array, int size, char *program_name);

#endif // REQUESTS_H
2 changes: 2 additions & 0 deletions include/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ int execute_stats_command(
int monitor_fd, PIDS_ARR_WITH_PROGRAM *pids_arr_with_program
);

int execute_stats_uniq(int monitor_fd, PIDS_ARR *pids_arr);

#endif // TRACER_H
5 changes: 3 additions & 2 deletions include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ typedef enum request_type {
STATUS,
STATS_TIME,
STATS_COMMAND,
STATS_UNIQ,
UPDATE,
ERROR,
DONE,
Expand All @@ -35,7 +36,7 @@ typedef struct header {
typedef struct pids_arr {
int pids[32];
int n_pids;
int child_pid;
pid_t child_pid;
} PIDS_ARR;

typedef struct pids_arr_with_program {
Expand All @@ -49,7 +50,7 @@ PROGRAM_INFO *create_program_info(

HEADER *create_header(REQUEST_TYPE type, size_t size);

PIDS_ARR *create_pids_arr(int pids[32], int n_pids, int child_pid);
PIDS_ARR *create_pids_arr(int pids[32], int n_pids, pid_t child_pid);

PIDS_ARR_WITH_PROGRAM *create_pids_arr_with_program(
PIDS_ARR pids_arr, char *program
Expand Down
114 changes: 114 additions & 0 deletions src/requests.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@ int deal_with_request(
stats_command_request(pids_arr_with_program);
exit(EXIT_SUCCESS);
}
} else if (type == STATS_UNIQ) {
PIDS_ARR *pids_arr = (PIDS_ARR *)data;
printf(
"Stats uniq request with %d pids (%d)\n", pids_arr->n_pids,
pids_arr->child_pid
);
pid_t pid = fork();
if (pid == 0) {
stats_uniq_request(pids_arr);
exit(EXIT_SUCCESS);
}
} else {
printf("Invalid request type received (%d)\n", type);
exit(EXIT_FAILURE);
Expand Down Expand Up @@ -282,6 +293,10 @@ int stats_time_request(PIDS_ARR *pids_arr) {
open_fifo(&fd, fifo_name, O_WRONLY);
write_to_fd(fd, &total_time, sizeof(double), STATS_TIME);

// Clean resources
free(fifo_name);
close(fd);

return 0;
}

Expand Down Expand Up @@ -360,5 +375,104 @@ int stats_command_request(PIDS_ARR_WITH_PROGRAM *pids_arr_with_program) {
open_fifo(&fd, fifo_name, O_WRONLY);
write_to_fd(fd, &total_execs, sizeof(int), STATS_COMMAND);

// Clean resources
close(fd);
free(fifo_name);

exit(EXIT_SUCCESS);
}

int stats_uniq_request(PIDS_ARR *pids_arr) {
int n_pids = pids_arr->n_pids;

int num_forks, files_per_fork;
divide_files_per_fork(n_pids, &num_forks, &files_per_fork);

// pipe from childs to communicate with parent
int pipe_fd[2];
pipe(pipe_fd);

char **programs_holder = malloc(sizeof(char *) * n_pids);
int programs_holder_size = 0;

// Create and use num_forks forks to search for the files
for (int i = 0; i < num_forks; i++) {
pid_t pid = fork();
if (pid == 0) {
close(pipe_fd[0]); // Close stdin on child

// Each fork will search for files_per_fork files
for (int j = 0; j < files_per_fork; j++) {
int index = i * files_per_fork + j;
if (index >= n_pids) {
break;
}

char *pid_str = malloc(sizeof(char) * 64);
// NOLINTBEGIN
sprintf(pid_str, "%s/%d", folder, pids_arr->pids[index]);
// NOLINTEND

int fd = open_file_by_path(pid_str, O_RDONLY, 0644);
if (fd == -1) {
continue;
}

char *program_name = retrieve_program_name_from_file(fd);
simple_write_to_fd(pipe_fd[1], program_name, 256);

// Clean resources
free(pid_str);
close(fd);
}

exit(EXIT_SUCCESS);
}
}

close(pipe_fd[1]); // Close stdout on parent

// Hold programs only if they are "uniq"
char *program_name = malloc(sizeof(char) * 256);
while (read(pipe_fd[0], program_name, 256) != 0) {
if (!is_program_in_array(
programs_holder, programs_holder_size, program_name
)) {
programs_holder[programs_holder_size] = strdup(program_name);
programs_holder_size++;
}
}

char *fifo_name = malloc(sizeof(char) * 64);
sprintf(fifo_name, "tmp/%d.fifo", pids_arr->child_pid); // NOLINT

int fd;
open_fifo(&fd, fifo_name, O_WRONLY);

for (int i = 0; i < programs_holder_size; i++) {
write_to_fd(fd, programs_holder[i], 256, STATS_COMMAND);
}

// Send DONE to inform client that all requests were sent
write_to_fd(fd, NULL, 0, DONE);

// Clean resources
close(fd);
free(program_name);
free(fifo_name);
free(programs_holder);

exit(EXIT_SUCCESS);
}

int is_program_in_array(
char **programs_holder, int programs_holder_size, char *program_name
) {
for (int i = 0; i < programs_holder_size; i++) {
if (!strcmp(programs_holder[i], program_name)) {
return 1;
}
}

return 0;
}
45 changes: 43 additions & 2 deletions src/tracer.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ int main(int argc, char **argv) {
perror("execute_stats_command");
exit(EXIT_FAILURE);
}
} else if (!strcmp(option, "stats-uniq")) {
int n_pids = argc - 2;
if (n_pids == 0) {
printf("Usage: %s stats-uniq <PID-123> <PID-456> ...\n", argv[0]);
exit(EXIT_FAILURE);
}

char **pids = argv + 2;
int *parsed_pids = parse_pids(pids, n_pids);
PIDS_ARR *pids_arr = create_pids_arr(parsed_pids, n_pids, getpid());

if (execute_stats_uniq(monitor_fd, pids_arr) == -1) {
perror("execute_stats_uniq");
exit(EXIT_FAILURE);
}
} else {
printf("Invalid option\n");
exit(EXIT_FAILURE);
Expand All @@ -114,7 +129,7 @@ int execute_program(char *full_program, char **parsed_program, int monitor_fd) {
struct timeval start_time, final_time;
gettimeofday(&start_time, NULL);

int child_pid = fork();
pid_t child_pid = fork();
if (child_pid == 0) {
// Child
PROGRAM_INFO *execute_info =
Expand Down Expand Up @@ -213,7 +228,7 @@ int execute_pipeline(
int original_stdin = dup(STDIN_FILENO);
int original_stdout = dup(STDOUT_FILENO);

int child_pid = fork();
pid_t child_pid = fork();
if (child_pid == 0) {
// Child
PROGRAM_INFO *info = create_program_info(pid, pipeline, start_time);
Expand Down Expand Up @@ -360,5 +375,31 @@ int execute_stats_command(
"%s was executed %d times\n", pids_arr_with_program->program, *answer_data
);

// Clean resources
free(answer_data);
free(fifo_name);

exit(EXIT_SUCCESS);
}

int execute_stats_uniq(int monitor_fd, PIDS_ARR *pids_arr) {
write_to_fd(monitor_fd, pids_arr, sizeof(PIDS_ARR), STATS_UNIQ);

char *fifo_name = create_fifo(pids_arr->child_pid);
int pid_fd;
open_fifo(&pid_fd, fifo_name, O_RDONLY);

REQUEST_TYPE type;
char *program_name = read_from_fd(pid_fd, &type);
while (type != DONE) {
printf("%s\n", program_name);
free(program_name);
program_name = read_from_fd(pid_fd, &type);
}

// Clean resources
free(program_name);
free(fifo_name);

exit(EXIT_SUCCESS);
}
2 changes: 1 addition & 1 deletion src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ HEADER *create_header(REQUEST_TYPE type, size_t size) {
return header;
}

PIDS_ARR *create_pids_arr(int pids[32], int n_pids, int child_pid) {
PIDS_ARR *create_pids_arr(int pids[32], int n_pids, pid_t child_pid) {
PIDS_ARR *pids_arr = malloc(sizeof(PIDS_ARR));

pids_arr->n_pids = n_pids;
Expand Down

0 comments on commit a40a9f5

Please sign in to comment.