[cs631apue] "HW" 2 grades sent

Jan Schaumann jschauma at stevens.edu
Fri Oct 25 22:33:29 EDT 2019


All,

I've just sent out grades for the in-class "homework".

Please note that the assignment gave you the basic
outline of your code and logic:

- create two pipes, one for stdout, one for stderr
  of the command to execute
- ignore SIGINT, SIGQUIT; block SIGCHLD
- fork(2) a new process
- dup2(2) the respective file descriptors onto the
  write-ends of the pipes
- exec(3) the command in question
- read(2) from the read-ends of the pipes
- append output to the respective buffer, careful to
  not overflow them
- wait(3) for the process to terminate

Deviation from this logic is bound to lead to failure.

The assignment also told you to look at the source
code for system(3) in
/usr/src/lib/libc/stdlib/system.c, from which you
could take code.  That code is about 90% of what you
need.

Here's an abbreviated implementation; you'd have to
sprinkle the signal logic from system.c, and there are
a few aspects that can be improved, but to illustrate
the basic functionality and logic:

---
int command(const char *cmd, char *out, int outlen, char *err, int errlen) {

	int opipe[2], epipe[2];
	pid_t pid;

	if (pipe(opipe) < 0) {
		perror("pipe error");
		return -1;
	}

	if (pipe(epipe) < 0) {
		perror("pipe error");
		return -1;
	}

        if ((pid = fork()) < 0) {
                perror("fork error");
		return -1;
        } else if (pid == 0) {
		close(opipe[0]);
		close(epipe[0]);
		if (dup2(opipe[1], STDOUT_FILENO) < 0) {
			perror("dup2 stdout");
			return -1;
		}
		if (dup2(epipe[1], STDERR_FILENO) < 0) {
			perror("dup2 stdout");
			return -1;
		}
		execlp("/bin/sh", "runcommand", "-c", cmd, (char *) 0);
		return -1;
	} else {
		size_t n;
		char buf[BUFSIZ];
		int total = 0;
		int i;
		close(opipe[1]);
		close(epipe[1]);
		if ((pid = wait(&i)) < 0) {
			perror("wait");
			return -1;
		}
		while ((n = read(epipe[0], buf, BUFSIZ)) > 0) {
			total += n;
			if (total <= errlen) {
				strlcat(err, buf, errlen);
			}
		}
		while ((n = read(opipe[0], buf, BUFSIZ)) > 0) {
			total += n;
			if (total <= outlen) {
				strlcat(out, buf, outlen);
			}
			bzero(buf, BUFSIZ);
		}
	}
	return 0;
}
---

-Jan


More information about the cs631apue mailing list