Removed submodules
This commit is contained in:
+118
@@ -0,0 +1,118 @@
|
||||
#include <fcntl.h>
|
||||
#include <spawn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pipe.h"
|
||||
|
||||
/* Creates a child process. If this fails, close the pipe and return -1.
|
||||
If the child is created, use it to run the executable program on the
|
||||
filename passed. Send the result back through the pipe. The parent process
|
||||
should just return the child's PID. Sample call:
|
||||
|
||||
int fd[2];
|
||||
pipe (fd);
|
||||
pid_t child_pid = create_child (exec, fd, "foo.txt");
|
||||
*/
|
||||
pid_t
|
||||
create_child (char *const exec, int *pipe, char *const filename)
|
||||
{
|
||||
char *args[3] = { exec, filename, NULL };
|
||||
pid_t pid = fork ();
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
close (pipe[0]);
|
||||
dup2 (pipe[1], STDOUT_FILENO);
|
||||
close (pipe[1]);
|
||||
execvp (exec, args);
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
close (pipe[1]);
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* Runs the executable program on the input filename. Start by creating a
|
||||
pipe and calling create_child() to create the child process. If that
|
||||
fails, return NULL. Otherwise, implement the parent here so that it
|
||||
reads the result of the process from the pipe and returns the result
|
||||
without a newline. The returned string must be a dynamically allocated
|
||||
copy; you can use the constant BUFFER_LENGTH for its size. Be sure to
|
||||
close the ends of the pipe at appropriate times. Sample call:
|
||||
|
||||
char *sum = get_result ("cksum", "data/f1.txt");
|
||||
// sum is "3015617425 6 data/f1.txt" [without the newline]
|
||||
*/
|
||||
char *
|
||||
get_result (char *const exec, char *const filename)
|
||||
{
|
||||
int fd[2];
|
||||
if (pipe (fd) == -1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pid_t pid = create_child (exec, fd, filename);
|
||||
|
||||
char *buffer = calloc (BUFFER_LENGTH, sizeof (char));
|
||||
ssize_t n = read (fd[0], buffer, BUFFER_LENGTH);
|
||||
buffer[n - 1] = '\0';
|
||||
|
||||
close (fd[0]);
|
||||
waitpid (pid, NULL, 0);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Re-implementation of the create_child() in pipe.c. Instead of
|
||||
using the calls to pipe/fork/dup2/exec, combine the latter three
|
||||
into a call to posix_spawn(). Sample call:
|
||||
|
||||
char *sum = spawn_result ("cksum", "data/f1.txt");
|
||||
// sum is "3015617425 6 data/f1.txt\n" [with the newline]
|
||||
*/
|
||||
char *
|
||||
spawn_result (char *const exec, char *const filename)
|
||||
{
|
||||
// Instead of using fork() and exec(), use the posix_spawn functions.
|
||||
// Note that you will need to create a pipe, initialize a
|
||||
// posix_spawn_file_actions_t instance, and add close and dup2 actions
|
||||
// to it so that the child process writes its STDOUT to the pipe.
|
||||
// After spawning the new process, make sure to call
|
||||
// posix_spawn_file_actions_destroy() on the actions to prevent
|
||||
// memory leaks. To avoid looking up the executable in the $PATH,
|
||||
// you can use posix_spawnp().
|
||||
|
||||
// Parent code: read the value back from the pipe into a dynamically
|
||||
// allocated buffer. Wait for the child to exit, then return the
|
||||
// buffer. Make sure to close the ends of the pipe in appropriate
|
||||
// places.
|
||||
int fd[2];
|
||||
pipe (fd);
|
||||
|
||||
posix_spawn_file_actions_t actions;
|
||||
posix_spawn_file_actions_init (&actions);
|
||||
posix_spawn_file_actions_addclose (&actions, fd[0]);
|
||||
posix_spawn_file_actions_adddup2 (&actions, fd[1], STDOUT_FILENO);
|
||||
posix_spawn_file_actions_addclose (&actions, fd[1]);
|
||||
|
||||
pid_t pid = -1;
|
||||
char *args[3] = { exec, filename, NULL };
|
||||
|
||||
posix_spawnp (&pid, exec, &actions, NULL, args, NULL);
|
||||
posix_spawn_file_actions_destroy (&actions);
|
||||
close (fd[1]);
|
||||
|
||||
char *buffer = calloc (BUFFER_LENGTH, sizeof (char));
|
||||
ssize_t n = read (fd[0], buffer, BUFFER_LENGTH);
|
||||
buffer[n - 1] = '\0';
|
||||
|
||||
close (fd[0]);
|
||||
waitpid (pid, NULL, 0);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
Reference in New Issue
Block a user