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; --- 852 unchanged lines hidden (view full) --- 861 // not sure if this is totally valid, but we'll pass it through 862 // to the underlying OS 863 warn("fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd); 864 return fcntl(sim_fd, cmd); 865 } 866} 867 868SyscallReturn |
869pipeImpl(SyscallDesc *desc, int callnum, ThreadContext *tc, bool pseudo_pipe, 870 bool is_pipe2) |
871{ 872 Addr tgt_addr = 0; |
873 int flags = 0; |
874 auto p = tc->getProcessPtr(); |
875 if (!pseudo_pipe) { |
876 int index = 0; 877 tgt_addr = p->getSyscallArg(tc, index); |
878 if (is_pipe2) { 879 flags = p->getSyscallArg(tc, index); 880 } |
881 } 882 883 int sim_fds[2], tgt_fds[2]; 884 885 int pipe_retval = pipe(sim_fds); 886 if (pipe_retval == -1) 887 return -errno; 888 889 auto rend = PipeFDEntry::EndType::read; 890 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend); 891 tgt_fds[0] = p->fds->allocFD(rpfd); |
892 int sim_fd_rpfd = rpfd->getSimFD(); |
893 894 auto wend = PipeFDEntry::EndType::write; 895 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend); 896 tgt_fds[1] = p->fds->allocFD(wpfd); |
897 int sim_fd_wpfd = wpfd->getSimFD(); |
898 899 /** 900 * Now patch the read object to record the target file descriptor chosen 901 * as the write end of the pipe. 902 */ 903 rpfd->setPipeReadSource(tgt_fds[1]); 904 905 /** 906 * Alpha Linux convention for pipe() is that fd[0] is returned as 907 * the return value of the function, and fd[1] is returned in r20. 908 */ |
909 if (pseudo_pipe) { |
910 tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]); 911 return tgt_fds[0]; 912 } 913 914 /** 915 * Copy the target file descriptors into buffer space and then copy 916 * the buffer space back into the target address space. 917 */ 918 BufferArg tgt_handle(tgt_addr, sizeof(int[2])); 919 int *buf_ptr = (int*)tgt_handle.bufferPtr(); 920 buf_ptr[0] = tgt_fds[0]; 921 buf_ptr[1] = tgt_fds[1]; 922 tgt_handle.copyOut(tc->getVirtProxy()); |
923 924 // pipe2 has additional behavior if flags != 0 925 if (is_pipe2 && flags) { 926 // pipe2 only uses O_NONBLOCK, O_CLOEXEC, and (O_NONBLOCK | O_CLOEXEC) 927 // if flags set to anything else, return EINVAL 928 if ((flags != O_CLOEXEC) && (flags != O_NONBLOCK) && 929 (flags != (O_CLOEXEC | O_NONBLOCK))) { 930 return -EINVAL; 931 } 932 933 /* 934 If O_NONBLOCK is passed in as a flag to pipe2, set O_NONBLOCK file 935 status flag for two new open file descriptors. 936 */ 937 if (flags & O_NONBLOCK) { 938 /* 939 O_NONBLOCK is set when the programmer wants to avoid a separate 940 call(s) to fcntl in their code, so mirror the fcntl 941 implementation for handling file descriptors -- rely on host to 942 maintain file status flags. 943 */ 944 if (fcntl(sim_fd_rpfd, F_SETFL, O_NONBLOCK)) { 945 return -errno; 946 } 947 if (fcntl(sim_fd_wpfd, F_SETFL, O_NONBLOCK)) { 948 return -errno; 949 } 950 } 951 952 /* 953 If O_CLOEXEC is passed in as a flag to pipe2, set close-on-exec 954 (FD_CLOEXEC) file status flag for two new open file descriptors. 955 */ 956 if (flags & O_CLOEXEC) { 957 rpfd->setCOE(true); 958 wpfd->setCOE(true); 959 } 960 } 961 |
962 return 0; 963} 964 965SyscallReturn 966pipePseudoFunc(SyscallDesc *desc, int callnum, ThreadContext *tc) 967{ 968 return pipeImpl(desc, callnum, tc, true); 969} 970 971SyscallReturn 972pipeFunc(SyscallDesc *desc, int callnum, ThreadContext *tc) 973{ 974 return pipeImpl(desc, callnum, tc, false); 975} 976 977SyscallReturn |
978pipe2Func(SyscallDesc *desc, int callnum, ThreadContext *tc) 979{ 980 // call pipeImpl since the only difference between pipe and pipe2 is 981 // the flags values and what they do (at the end of pipeImpl) 982 return pipeImpl(desc, callnum, tc, false, true); 983} 984 985SyscallReturn |
986setpgidFunc(SyscallDesc *desc, int callnum, ThreadContext *tc) 987{ 988 int index = 0; 989 auto process = tc->getProcessPtr(); 990 int pid = process->getSyscallArg(tc, index); 991 int pgid = process->getSyscallArg(tc, index); 992 993 if (pgid < 0) --- 841 unchanged lines hidden --- |