syscall_emul.cc (14124:9742fcde81e1) | syscall_emul.cc (14129:7a41ca7e465c) |
---|---|
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 | 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 pseudoPipe) | 869pipeImpl(SyscallDesc *desc, int callnum, ThreadContext *tc, bool pseudo_pipe, 870 bool is_pipe2) |
870{ 871 Addr tgt_addr = 0; | 871{ 872 Addr tgt_addr = 0; |
873 int flags = 0; |
|
872 auto p = tc->getProcessPtr(); | 874 auto p = tc->getProcessPtr(); |
873 if (!pseudoPipe) { | 875 if (!pseudo_pipe) { |
874 int index = 0; 875 tgt_addr = p->getSyscallArg(tc, index); | 876 int index = 0; 877 tgt_addr = p->getSyscallArg(tc, index); |
878 if (is_pipe2) { 879 flags = p->getSyscallArg(tc, index); 880 } |
|
876 } 877 878 int sim_fds[2], tgt_fds[2]; 879 880 int pipe_retval = pipe(sim_fds); 881 if (pipe_retval == -1) 882 return -errno; 883 884 auto rend = PipeFDEntry::EndType::read; 885 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend); 886 tgt_fds[0] = p->fds->allocFD(rpfd); | 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(); |
|
887 888 auto wend = PipeFDEntry::EndType::write; 889 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend); 890 tgt_fds[1] = p->fds->allocFD(wpfd); | 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(); |
|
891 892 /** 893 * Now patch the read object to record the target file descriptor chosen 894 * as the write end of the pipe. 895 */ 896 rpfd->setPipeReadSource(tgt_fds[1]); 897 898 /** 899 * Alpha Linux convention for pipe() is that fd[0] is returned as 900 * the return value of the function, and fd[1] is returned in r20. 901 */ | 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 */ |
902 if (pseudoPipe) { | 909 if (pseudo_pipe) { |
903 tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]); 904 return tgt_fds[0]; 905 } 906 907 /** 908 * Copy the target file descriptors into buffer space and then copy 909 * the buffer space back into the target address space. 910 */ 911 BufferArg tgt_handle(tgt_addr, sizeof(int[2])); 912 int *buf_ptr = (int*)tgt_handle.bufferPtr(); 913 buf_ptr[0] = tgt_fds[0]; 914 buf_ptr[1] = tgt_fds[1]; 915 tgt_handle.copyOut(tc->getVirtProxy()); | 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 |
|
916 return 0; 917} 918 919SyscallReturn 920pipePseudoFunc(SyscallDesc *desc, int callnum, ThreadContext *tc) 921{ 922 return pipeImpl(desc, callnum, tc, true); 923} 924 925SyscallReturn 926pipeFunc(SyscallDesc *desc, int callnum, ThreadContext *tc) 927{ 928 return pipeImpl(desc, callnum, tc, false); 929} 930 931SyscallReturn | 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 |
|
932setpgidFunc(SyscallDesc *desc, int callnum, ThreadContext *tc) 933{ 934 int index = 0; 935 auto process = tc->getProcessPtr(); 936 int pid = process->getSyscallArg(tc, index); 937 int pgid = process->getSyscallArg(tc, index); 938 939 if (pgid < 0) --- 841 unchanged lines hidden --- | 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 --- |