123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- /**
- * 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 <cstdlib>
- #include <cstdarg>
- #include <iostream>
- #include <unistd.h> // needed for _POSIX_MONOTONIC_CLOCK
- #include <stdarg.h>
- #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;i<gethostbynameReturns.size();i++)
- delete gethostbynameReturns[i];
- }
- Mock_gethostbyname::HostEntry& Mock_gethostbyname::addHostEntry(
- const char* hostName, short addrtype) {
- gethostbynameReturns.push_back(new HostEntry(hostName, addrtype));
- return *gethostbynameReturns.back();
- }
- hostent* Mock_gethostbyname::call(const char* name) {
- assert("Must add one or more mock hostent entries first"&&
- (gethostbynameReturns.size()!=0));
- return gethostbynameReturns[current++ % gethostbynameReturns.size()];
- }
- static char** appendString(char **list,const char* str,int len=0){
- const int SIZE_INCREMENT=16;
- if(list==0)
- list=(char**)LIBC_SYMBOLS.calloc(SIZE_INCREMENT,sizeof(char*));
- // find the first available slot
- int count=0;
- for(char** ptr=list; *ptr!=0; ptr++,count++);
- if(((count+1)%SIZE_INCREMENT)==0){
- list=(char**)LIBC_SYMBOLS.realloc(list,(count+1+SIZE_INCREMENT)*sizeof(char*));
- memset(list+count+1,0,SIZE_INCREMENT*sizeof(char*));
- }
- if(len==0){
- len=strlen(str)+1;
- }
- char* ptr=(char*)malloc(len);
- memcpy(ptr,str,len);
- list[count]=ptr;
- return list;
- }
- static void freeList(char **list){
- if(list==0) return;
- for(char** ptr=list; *ptr!=0; ptr++)
- LIBC_SYMBOLS.free((void*)*ptr);
- LIBC_SYMBOLS.free((void*)list);
- }
- Mock_gethostbyname::HostEntry::HostEntry(const char* hostName, short addrtype) {
- h_name=strdup(hostName);
- h_addrtype=addrtype;
- if(addrtype==AF_INET)
- h_length=4;
- else{
- #ifdef AF_INET6
- h_length=6; // TODO: not really sure, verify!
- #else
- assert("AF_INET6 not supported yet"&&false);
- #endif
- }
- h_aliases=h_addr_list=0;
- }
- Mock_gethostbyname::HostEntry::~HostEntry(){
- if(h_name) LIBC_SYMBOLS.free((void*)h_name);
- freeList(h_aliases); h_aliases=0;
- freeList(h_addr_list); h_addr_list=0;
- }
- Mock_gethostbyname::HostEntry& Mock_gethostbyname::HostEntry::addAlias(
- const char* alias) {
- h_aliases=appendString(h_aliases,alias);
- return *this;
- }
- Mock_gethostbyname::HostEntry& Mock_gethostbyname::HostEntry::addAddress(
- const char* addr4) {
- h_addr_list=appendString(h_addr_list,addr4,4);
- return *this;
- }
- // *****************************************************************************
- // calloc
- #ifndef USING_DUMA
- DECLARE_WRAPPER(void*,calloc,(size_t p1, size_t p2)){
- if(!Mock_calloc::mock_)
- return CALL_REAL(calloc,(p1,p2));
- return Mock_calloc::mock_->call(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; i<requested.size();i++)
- CALL_REAL(free,(requested[i]));
- #endif
- }
- int Mock_free_noop::getFreeCount(void* p){
- int cnt=0;
- synchronized(mx);
- for(unsigned i=0;i<requested.size();i++)
- if(requested[i]==p)cnt++;
- return cnt;
- }
- bool Mock_free_noop::isFreed(void* p){
- synchronized(mx);
- for(unsigned i=0;i<requested.size();i++)
- if(requested[i]==p)return true;
- return false;
- }
- Mock_free_noop* Mock_free_noop::mock_=0;
- // *****************************************************************************
- // socket
- int socket(int domain, int type, int protocol){
- if (!Mock_socket::mock_)
- return LIBC_SYMBOLS.socket(domain,type,protocol);
- return Mock_socket::mock_->callSocket(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
|