Deleted Added
sdiff udiff text old ( 11907:48a3d32da9d8 ) new ( 11908:2fd0307d03e9 )
full compact
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 612 unchanged lines hidden (view full) ---

621 uid_t hostOwner = owner;
622 uint32_t group = p->getSyscallArg(tc, index);
623 gid_t hostGroup = group;
624
625 int result = fchown(sim_fd, hostOwner, hostGroup);
626 return (result == -1) ? -errno : result;
627}
628
629/**
630 * FIXME: The file description is not shared among file descriptors created
631 * with dup. Really, it's difficult to maintain fields like file offset or
632 * flags since an update to such a field won't be reflected in the metadata
633 * for the fd entries that we maintain for checkpoint restoration.
634 */
635SyscallReturn
636dupFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
637{
638 int index = 0;
639 int tgt_fd = p->getSyscallArg(tc, index);
640
641 auto old_hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
642 if (!old_hbfdp)
643 return -EBADF;
644 int sim_fd = old_hbfdp->getSimFD();
645
646 int result = dup(sim_fd);
647 if (result == -1)
648 return -errno;
649
650 auto new_hbfdp = std::dynamic_pointer_cast<HBFDEntry>(old_hbfdp->clone());
651 new_hbfdp->setSimFD(result);
652 new_hbfdp->setCOE(false);
653 return p->fds->allocFD(new_hbfdp);
654}
655
656SyscallReturn
657dup2Func(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
658{
659 int index = 0;
660
661 int old_tgt_fd = p->getSyscallArg(tc, index);
662 auto old_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[old_tgt_fd]);
663 if (!old_hbp)
664 return -EBADF;
665 int old_sim_fd = old_hbp->getSimFD();
666
667 /**
668 * We need a valid host file descriptor number to be able to pass into
669 * the second parameter for dup2 (newfd), but we don't know what the
670 * viable numbers are; we execute the open call to retrieve one.
671 */
672 int res_fd = dup2(old_sim_fd, open("/dev/null", O_RDONLY));
673 if (res_fd == -1)
674 return -errno;
675
676 int new_tgt_fd = p->getSyscallArg(tc, index);
677 auto new_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[new_tgt_fd]);
678 if (new_hbp)
679 p->fds->closeFDEntry(new_tgt_fd);
680 new_hbp = std::dynamic_pointer_cast<HBFDEntry>(old_hbp->clone());
681 new_hbp->setSimFD(res_fd);
682 new_hbp->setCOE(false);
683
684 return p->fds->allocFD(new_hbp);
685}
686
687SyscallReturn
688fcntlFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
689{
690 int arg;
691 int index = 0;
692 int tgt_fd = p->getSyscallArg(tc, index);

--- 62 unchanged lines hidden (view full) ---

755 // not sure if this is totally valid, but we'll pass it through
756 // to the underlying OS
757 warn("fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd);
758 return fcntl(sim_fd, cmd);
759 }
760}
761
762SyscallReturn
763pipeImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc,
764 bool pseudoPipe)
765{
766 Addr tgt_addr = 0;
767 if (!pseudoPipe) {
768 int index = 0;
769 tgt_addr = p->getSyscallArg(tc, index);
770 }
771
772 int sim_fds[2], tgt_fds[2];
773
774 int pipe_retval = pipe(sim_fds);
775 if (pipe_retval == -1)
776 return -errno;
777
778 auto rend = PipeFDEntry::EndType::read;
779 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
780 tgt_fds[0] = p->fds->allocFD(rpfd);
781
782 auto wend = PipeFDEntry::EndType::write;
783 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
784 tgt_fds[1] = p->fds->allocFD(wpfd);
785
786 /**
787 * Now patch the read object to record the target file descriptor chosen
788 * as the write end of the pipe.
789 */
790 rpfd->setPipeReadSource(tgt_fds[1]);
791
792 /**
793 * Alpha Linux convention for pipe() is that fd[0] is returned as
794 * the return value of the function, and fd[1] is returned in r20.
795 */
796 if (pseudoPipe) {
797 tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]);
798 return tgt_fds[0];
799 }
800
801 /**
802 * Copy the target file descriptors into buffer space and then copy
803 * the buffer space back into the target address space.
804 */
805 BufferArg tgt_handle(tgt_addr, sizeof(int[2]));
806 int *buf_ptr = (int*)tgt_handle.bufferPtr();
807 buf_ptr[0] = tgt_fds[0];
808 buf_ptr[1] = tgt_fds[1];
809 tgt_handle.copyOut(tc->getMemProxy());
810 return 0;
811}
812
813SyscallReturn
814pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process,
815 ThreadContext *tc)
816{
817 return pipeImpl(desc, callnum, process, tc, true);
818}
819
820SyscallReturn
821pipeFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
822{
823 return pipeImpl(desc, callnum, process, tc, false);
824}
825
826SyscallReturn
827setpgidFunc(SyscallDesc *desc, int callnum, Process *process,
828 ThreadContext *tc)
829{
830 int index = 0;
831 int pid = process->getSyscallArg(tc, index);
832 int pgid = process->getSyscallArg(tc, index);
833
834 if (pgid < 0)

--- 169 unchanged lines hidden ---