/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include // needed for _POSIX_MONOTONIC_CLOCK #include #include "Util.h" #include "LibCMocks.h" #undef USING_DUMA using namespace std; // ***************************************************************************** // gethostbyname struct hostent* gethostbyname(const char *name) { if(!Mock_gethostbyname::mock_) return LIBC_SYMBOLS.gethostbyname(name); return Mock_gethostbyname::mock_->call(name); } Mock_gethostbyname* Mock_gethostbyname::mock_=0; Mock_gethostbyname::~Mock_gethostbyname(){ mock_=0; for(unsigned int i=0;icall(p1,p2); } #endif void* Mock_calloc::call(size_t p1, size_t p2){ #ifndef USING_DUMA if(counter++ ==callsBeforeFailure){ counter=0; errno=errnoOnFailure; return 0; } return CALL_REAL(calloc,(p1,p2)); #else return 0; #endif } Mock_calloc* Mock_calloc::mock_=0; // ***************************************************************************** // realloc #ifndef USING_DUMA DECLARE_WRAPPER(void*,realloc,(void* p, size_t s)){ if(!Mock_realloc::mock_) return LIBC_SYMBOLS.realloc(p,s); return Mock_realloc::mock_->call(p,s); } #endif Mock_realloc* Mock_realloc::mock_=0; void* Mock_realloc::call(void* p, size_t s){ if(counter++ ==callsBeforeFailure){ counter=0; errno=errnoOnFailure; return 0; } return LIBC_SYMBOLS.realloc(p,s); } // ***************************************************************************** // random RANDOM_RET_TYPE random(){ if(!Mock_random::mock_) return LIBC_SYMBOLS.random(); return Mock_random::mock_->call(); } void srandom(unsigned long seed){ if (!Mock_random::mock_) LIBC_SYMBOLS.srandom(seed); else Mock_random::mock_->setSeed(seed); } Mock_random* Mock_random::mock_=0; int Mock_random::call(){ assert("Must specify one or more random integers"&&(randomReturns.size()!=0)); return randomReturns[currentIdx++ % randomReturns.size()]; } // ***************************************************************************** // free #ifndef USING_DUMA DECLARE_WRAPPER(void,free,(void* p)){ if(Mock_free_noop::mock_ && !Mock_free_noop::mock_->nested) Mock_free_noop::mock_->call(p); else CALL_REAL(free,(p)); } #endif void Mock_free_noop::call(void* p){ // on cygwin libc++ is linked statically // push_back() may call free(), hence the nesting guards synchronized(mx); nested++; callCounter++; requested.push_back(p); nested--; } void Mock_free_noop::freeRequested(){ #ifndef USING_DUMA synchronized(mx); for(unsigned i=0; icallSocket(domain,type,protocol); } int close(int fd){ if (!Mock_socket::mock_) return LIBC_SYMBOLS.close(fd); return Mock_socket::mock_->callClose(fd); } int getsockopt(int s,int level,int optname,void *optval,socklen_t *optlen){ if (!Mock_socket::mock_) return LIBC_SYMBOLS.getsockopt(s,level,optname,optval,optlen); return Mock_socket::mock_->callGet(s,level,optname,optval,optlen); } int setsockopt(int s,int level,int optname,const void *optval,socklen_t optlen){ if (!Mock_socket::mock_) return LIBC_SYMBOLS.setsockopt(s,level,optname,optval,optlen); return Mock_socket::mock_->callSet(s,level,optname,optval,optlen); } int connect(int s,const struct sockaddr *addr,socklen_t len){ #ifdef AF_UNIX /* don't mock UNIX domain sockets */ if (!Mock_socket::mock_ || addr->sa_family == AF_UNIX) #else if (!Mock_socket::mock_) #endif return LIBC_SYMBOLS.connect(s,addr,len); return Mock_socket::mock_->callConnect(s,addr,len); } ssize_t send(int s,const void *buf,size_t len,int flags){ if (!Mock_socket::mock_) return LIBC_SYMBOLS.send(s,buf,len,flags); return Mock_socket::mock_->callSend(s,buf,len,flags); } ssize_t recv(int s,void *buf,size_t len,int flags){ if (!Mock_socket::mock_) return LIBC_SYMBOLS.recv(s,buf,len,flags); return Mock_socket::mock_->callRecv(s,buf,len,flags); } Mock_socket* Mock_socket::mock_=0; // ***************************************************************************** // fcntl extern "C" int fcntl(int fd,int cmd,...){ va_list va; va_start(va,cmd); void* arg = va_arg(va, void *); va_end (va); if (!Mock_fcntl::mock_) return LIBC_SYMBOLS.fcntl(fd,cmd,arg); return Mock_fcntl::mock_->call(fd,cmd,arg); } Mock_fcntl* Mock_fcntl::mock_=0; // ***************************************************************************** // select int select(int nfds,fd_set *rfds,fd_set *wfds,fd_set *efds,struct timeval *timeout){ if (!Mock_select::mock_) return LIBC_SYMBOLS.select(nfds,rfds,wfds,efds,timeout); return Mock_select::mock_->call(nfds,rfds,wfds,efds,timeout); } Mock_select* Mock_select::mock_=0; // ***************************************************************************** // poll Mock_poll* Mock_poll::mock_=0; int poll(struct pollfd *fds, POLL_NFDS_TYPE nfds, int timeout){ if (!Mock_poll::mock_) return LIBC_SYMBOLS.poll(fds,nfds,timeout); return Mock_poll::mock_->call(fds,nfds,timeout); } /* * Recent gcc with -O2 and glibc FORTIFY feature may cause our poll * mock to be ignored. */ #if __USE_FORTIFY_LEVEL > 0 int __poll_chk (struct pollfd *__fds, nfds_t __nfds, int __timeout, __SIZE_TYPE__ __fdslen) { return poll(__fds, __nfds, __timeout); } #endif // ***************************************************************************** // gettimeofday int gettimeofday(struct timeval *tp, GETTIMEOFDAY_ARG2_TYPE tzp){ if (!Mock_gettimeofday::mock_) return LIBC_SYMBOLS.gettimeofday(tp,tzp); return Mock_gettimeofday::mock_->call(tp,tzp); } Mock_gettimeofday* Mock_gettimeofday::mock_=0; // ***************************************************************************** #ifdef _POSIX_MONOTONIC_CLOCK // clock_gettime int clock_gettime(clockid_t id, struct timespec *tp) { if (!Mock_gettimeofday::mock_) return LIBC_SYMBOLS.clock_gettime(id,tp); struct timeval tv = { 0 }; int res = Mock_gettimeofday::mock_->call(&tv, NULL); tp->tv_sec = tv.tv_sec; tp->tv_nsec = tv.tv_usec * 1000; return res; } #endif