LibCMocks.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * Copyright 2008, Yahoo! Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <cstdlib>
  17. #include <cstdarg>
  18. #include <iostream>
  19. #include <stdarg.h>
  20. #include "Util.h"
  21. #include "LibCMocks.h"
  22. #undef USING_DUMA
  23. using namespace std;
  24. // *****************************************************************************
  25. // gethostbyname
  26. struct hostent* gethostbyname(const char *name) {
  27. if(!Mock_gethostbyname::mock_)
  28. return LIBC_SYMBOLS.gethostbyname(name);
  29. return Mock_gethostbyname::mock_->call(name);
  30. }
  31. Mock_gethostbyname* Mock_gethostbyname::mock_=0;
  32. Mock_gethostbyname::~Mock_gethostbyname(){
  33. mock_=0;
  34. for(unsigned int i=0;i<gethostbynameReturns.size();i++)
  35. delete gethostbynameReturns[i];
  36. }
  37. Mock_gethostbyname::HostEntry& Mock_gethostbyname::addHostEntry(
  38. const char* hostName, short addrtype) {
  39. gethostbynameReturns.push_back(new HostEntry(hostName, addrtype));
  40. return *gethostbynameReturns.back();
  41. }
  42. hostent* Mock_gethostbyname::call(const char* name) {
  43. assert("Must add one or more mock hostent entries first"&&
  44. (gethostbynameReturns.size()!=0));
  45. return gethostbynameReturns[current++ % gethostbynameReturns.size()];
  46. }
  47. static char** appendString(char **list,const char* str,int len=0){
  48. const int SIZE_INCREMENT=16;
  49. if(list==0)
  50. list=(char**)LIBC_SYMBOLS.calloc(SIZE_INCREMENT,sizeof(char*));
  51. // find the first available slot
  52. int count=0;
  53. for(char** ptr=list; *ptr!=0; ptr++,count++);
  54. if(((count+1)%SIZE_INCREMENT)==0){
  55. list=(char**)LIBC_SYMBOLS.realloc(list,(count+1+SIZE_INCREMENT)*sizeof(char*));
  56. memset(list+count+1,0,SIZE_INCREMENT*sizeof(char*));
  57. }
  58. if(len==0){
  59. len=strlen(str)+1;
  60. }
  61. char* ptr=(char*)malloc(len);
  62. memcpy(ptr,str,len);
  63. list[count]=ptr;
  64. return list;
  65. }
  66. static void freeList(char **list){
  67. if(list==0) return;
  68. for(char** ptr=list; *ptr!=0; ptr++)
  69. LIBC_SYMBOLS.free((void*)*ptr);
  70. LIBC_SYMBOLS.free((void*)list);
  71. }
  72. Mock_gethostbyname::HostEntry::HostEntry(const char* hostName, short addrtype) {
  73. h_name=strdup(hostName);
  74. h_addrtype=addrtype;
  75. if(addrtype==AF_INET)
  76. h_length=4;
  77. else{
  78. #ifdef AF_INET6
  79. h_length=6; // TODO: not really sure, verify!
  80. #else
  81. assert("AF_INET6 not supported yet"&&false);
  82. #endif
  83. }
  84. h_aliases=h_addr_list=0;
  85. }
  86. Mock_gethostbyname::HostEntry::~HostEntry(){
  87. if(h_name) LIBC_SYMBOLS.free((void*)h_name);
  88. freeList(h_aliases); h_aliases=0;
  89. freeList(h_addr_list); h_addr_list=0;
  90. }
  91. Mock_gethostbyname::HostEntry& Mock_gethostbyname::HostEntry::addAlias(
  92. const char* alias) {
  93. h_aliases=appendString(h_aliases,alias);
  94. return *this;
  95. }
  96. Mock_gethostbyname::HostEntry& Mock_gethostbyname::HostEntry::addAddress(
  97. const char* addr4) {
  98. h_addr_list=appendString(h_addr_list,addr4,4);
  99. return *this;
  100. }
  101. // *****************************************************************************
  102. // calloc
  103. #ifndef USING_DUMA
  104. DECLARE_WRAPPER(void*,calloc,(size_t p1, size_t p2)){
  105. if(!Mock_calloc::mock_)
  106. return CALL_REAL(calloc,(p1,p2));
  107. return Mock_calloc::mock_->call(p1,p2);
  108. }
  109. #endif
  110. void* Mock_calloc::call(size_t p1, size_t p2){
  111. #ifndef USING_DUMA
  112. if(counter++ ==callsBeforeFailure){
  113. counter=0;
  114. errno=errnoOnFailure;
  115. return 0;
  116. }
  117. return CALL_REAL(calloc,(p1,p2));
  118. #else
  119. return 0;
  120. #endif
  121. }
  122. Mock_calloc* Mock_calloc::mock_=0;
  123. // *****************************************************************************
  124. // realloc
  125. #ifndef USING_DUMA
  126. void* realloc(void* p, size_t s){
  127. if(!Mock_realloc::mock_)
  128. return LIBC_SYMBOLS.realloc(p,s);
  129. return Mock_realloc::mock_->call(p,s);
  130. }
  131. #endif
  132. Mock_realloc* Mock_realloc::mock_=0;
  133. void* Mock_realloc::call(void* p, size_t s){
  134. if(counter++ ==callsBeforeFailure){
  135. counter=0;
  136. errno=errnoOnFailure;
  137. return 0;
  138. }
  139. return LIBC_SYMBOLS.realloc(p,s);
  140. }
  141. // *****************************************************************************
  142. // random
  143. RANDOM_RET_TYPE random(){
  144. if(!Mock_random::mock_)
  145. return LIBC_SYMBOLS.random();
  146. return Mock_random::mock_->call();
  147. }
  148. void srandom(unsigned long seed){
  149. if (!Mock_random::mock_)
  150. LIBC_SYMBOLS.srandom(seed);
  151. else
  152. Mock_random::mock_->setSeed(seed);
  153. }
  154. Mock_random* Mock_random::mock_=0;
  155. int Mock_random::call(){
  156. assert("Must specify one or more random integers"&&(randomReturns.size()!=0));
  157. return randomReturns[currentIdx++ % randomReturns.size()];
  158. }
  159. // *****************************************************************************
  160. // free
  161. #ifndef USING_DUMA
  162. DECLARE_WRAPPER(void,free,(void* p)){
  163. if(Mock_free_noop::mock_ && !Mock_free_noop::mock_->nested)
  164. Mock_free_noop::mock_->call(p);
  165. else
  166. CALL_REAL(free,(p));
  167. }
  168. #endif
  169. void Mock_free_noop::call(void* p){
  170. // on cygwin libc++ is linked statically
  171. // push_back() may call free(), hence the nesting guards
  172. synchronized(mx);
  173. nested++;
  174. callCounter++;
  175. requested.push_back(p);
  176. nested--;
  177. }
  178. void Mock_free_noop::freeRequested(){
  179. #ifndef USING_DUMA
  180. synchronized(mx);
  181. for(unsigned i=0; i<requested.size();i++)
  182. CALL_REAL(free,(requested[i]));
  183. #endif
  184. }
  185. int Mock_free_noop::getFreeCount(void* p){
  186. int cnt=0;
  187. synchronized(mx);
  188. for(unsigned i=0;i<requested.size();i++)
  189. if(requested[i]==p)cnt++;
  190. return cnt;
  191. }
  192. bool Mock_free_noop::isFreed(void* p){
  193. synchronized(mx);
  194. for(unsigned i=0;i<requested.size();i++)
  195. if(requested[i]==p)return true;
  196. return false;
  197. }
  198. Mock_free_noop* Mock_free_noop::mock_=0;
  199. // *****************************************************************************
  200. // socket
  201. int socket(int domain, int type, int protocol){
  202. if (!Mock_socket::mock_)
  203. return LIBC_SYMBOLS.socket(domain,type,protocol);
  204. return Mock_socket::mock_->callSocket(domain,type,protocol);
  205. }
  206. int close(int fd){
  207. if (!Mock_socket::mock_)
  208. return LIBC_SYMBOLS.close(fd);
  209. return Mock_socket::mock_->callClose(fd);
  210. }
  211. int getsockopt(int s,int level,int optname,void *optval,socklen_t *optlen){
  212. if (!Mock_socket::mock_)
  213. return LIBC_SYMBOLS.getsockopt(s,level,optname,optval,optlen);
  214. return Mock_socket::mock_->callGet(s,level,optname,optval,optlen);
  215. }
  216. int setsockopt(int s,int level,int optname,const void *optval,socklen_t optlen){
  217. if (!Mock_socket::mock_)
  218. return LIBC_SYMBOLS.setsockopt(s,level,optname,optval,optlen);
  219. return Mock_socket::mock_->callSet(s,level,optname,optval,optlen);
  220. }
  221. int connect(int s,const struct sockaddr *addr,socklen_t len){
  222. if (!Mock_socket::mock_)
  223. return LIBC_SYMBOLS.connect(s,addr,len);
  224. return Mock_socket::mock_->callConnect(s,addr,len);
  225. }
  226. ssize_t send(int s,const void *buf,size_t len,int flags){
  227. if (!Mock_socket::mock_)
  228. return LIBC_SYMBOLS.send(s,buf,len,flags);
  229. return Mock_socket::mock_->callSend(s,buf,len,flags);
  230. }
  231. ssize_t recv(int s,void *buf,size_t len,int flags){
  232. if (!Mock_socket::mock_)
  233. return LIBC_SYMBOLS.recv(s,buf,len,flags);
  234. return Mock_socket::mock_->callRecv(s,buf,len,flags);
  235. }
  236. Mock_socket* Mock_socket::mock_=0;
  237. // *****************************************************************************
  238. // fcntl
  239. extern "C" int fcntl(int fd,int cmd,...){
  240. va_list va;
  241. va_start(va,cmd);
  242. void* arg = va_arg(va, void *);
  243. va_end (va);
  244. if (!Mock_fcntl::mock_)
  245. return LIBC_SYMBOLS.fcntl(fd,cmd,arg);
  246. return Mock_fcntl::mock_->call(fd,cmd,arg);
  247. }
  248. Mock_fcntl* Mock_fcntl::mock_=0;
  249. // *****************************************************************************
  250. // select
  251. int select(int nfds,fd_set *rfds,fd_set *wfds,fd_set *efds,struct timeval *timeout){
  252. if (!Mock_select::mock_)
  253. return LIBC_SYMBOLS.select(nfds,rfds,wfds,efds,timeout);
  254. return Mock_select::mock_->call(nfds,rfds,wfds,efds,timeout);
  255. }
  256. Mock_select* Mock_select::mock_=0;
  257. // *****************************************************************************
  258. // poll
  259. Mock_poll* Mock_poll::mock_=0;
  260. int poll(struct pollfd *fds, POLL_NFDS_TYPE nfds, int timeout){
  261. if (!Mock_poll::mock_)
  262. return LIBC_SYMBOLS.poll(fds,nfds,timeout);
  263. return Mock_poll::mock_->call(fds,nfds,timeout);
  264. }
  265. // *****************************************************************************
  266. // gettimeofday
  267. int gettimeofday(struct timeval *tp, GETTIMEOFDAY_ARG2_TYPE tzp){
  268. if (!Mock_gettimeofday::mock_)
  269. return LIBC_SYMBOLS.gettimeofday(tp,tzp);
  270. return Mock_gettimeofday::mock_->call(tp,tzp);
  271. }
  272. Mock_gettimeofday* Mock_gettimeofday::mock_=0;