869c869,870
< pipeImpl(SyscallDesc *desc, int callnum, ThreadContext *tc, bool pseudoPipe)
---
> pipeImpl(SyscallDesc *desc, int callnum, ThreadContext *tc, bool pseudo_pipe,
> bool is_pipe2)
871a873
> int flags = 0;
873c875
< if (!pseudoPipe) {
---
> if (!pseudo_pipe) {
875a878,880
> if (is_pipe2) {
> flags = p->getSyscallArg(tc, index);
> }
886a892
> int sim_fd_rpfd = rpfd->getSimFD();
890a897
> int sim_fd_wpfd = wpfd->getSimFD();
902c909
< if (pseudoPipe) {
---
> if (pseudo_pipe) {
915a923,961
>
> // pipe2 has additional behavior if flags != 0
> if (is_pipe2 && flags) {
> // pipe2 only uses O_NONBLOCK, O_CLOEXEC, and (O_NONBLOCK | O_CLOEXEC)
> // if flags set to anything else, return EINVAL
> if ((flags != O_CLOEXEC) && (flags != O_NONBLOCK) &&
> (flags != (O_CLOEXEC | O_NONBLOCK))) {
> return -EINVAL;
> }
>
> /*
> If O_NONBLOCK is passed in as a flag to pipe2, set O_NONBLOCK file
> status flag for two new open file descriptors.
> */
> if (flags & O_NONBLOCK) {
> /*
> O_NONBLOCK is set when the programmer wants to avoid a separate
> call(s) to fcntl in their code, so mirror the fcntl
> implementation for handling file descriptors -- rely on host to
> maintain file status flags.
> */
> if (fcntl(sim_fd_rpfd, F_SETFL, O_NONBLOCK)) {
> return -errno;
> }
> if (fcntl(sim_fd_wpfd, F_SETFL, O_NONBLOCK)) {
> return -errno;
> }
> }
>
> /*
> If O_CLOEXEC is passed in as a flag to pipe2, set close-on-exec
> (FD_CLOEXEC) file status flag for two new open file descriptors.
> */
> if (flags & O_CLOEXEC) {
> rpfd->setCOE(true);
> wpfd->setCOE(true);
> }
> }
>
931a978,985
> pipe2Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
> {
> // call pipeImpl since the only difference between pipe and pipe2 is
> // the flags values and what they do (at the end of pipeImpl)
> return pipeImpl(desc, callnum, tc, false, true);
> }
>
> SyscallReturn