macFD.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:9k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. // if we're building mach-o we already have honest implementations of all this.
  36. #ifndef _MAC_MACHO
  37. #include <assert.h>
  38. #include "macFD.h"
  39. #include "platform/mac/socketerrors.h"
  40. FD gFDs[FD_SETSIZE];
  41. Boolean gFDInitialized = FALSE;
  42. // init_fds initializes the FD array. This MUST be called at program startup
  43. void init_fds(void)
  44. {
  45. int i;
  46. if(gFDInitialized)
  47. return;
  48. for(i = 0; i < FD_SETSIZE; i++)
  49. {
  50. FD *temp = &gFDs[i];
  51. temp->index = i;
  52. temp->owner = NULL;
  53. temp->available = TRUE;
  54. temp->readReady = FALSE;
  55. temp->writeReady = FALSE;
  56. temp->error = 0;
  57. temp->type = 0;
  58. }
  59. gFDInitialized = TRUE;
  60. }
  61. // fd_get_owner returns the FD object's owner
  62. void *fd_get_owner(int fd)
  63. {
  64. FD *temp;
  65. // validate fd
  66. assert(gFDInitialized);
  67. if(!FD_VALID(fd))
  68. {
  69. errno = EBADF;
  70. return NULL;
  71. }
  72. temp = &gFDs[fd];
  73. return (temp->owner);
  74. }
  75. // free_fd marks the FD object referenced by fd as free
  76. int free_fd(int fd)
  77. {
  78. FD *temp;
  79. // validate fd
  80. assert(gFDInitialized);
  81. if(!FD_VALID(fd))
  82. {
  83. errno = EBADF;
  84. return - 1;
  85. }
  86. temp = &gFDs[fd];
  87. // if(temp->owner)
  88. // delete temp->owner;
  89. temp->owner = NULL;
  90. temp->readReady = FALSE;
  91. temp->writeReady = FALSE;
  92. temp->error = 0;
  93. temp->available = TRUE;
  94. temp->type = 0;
  95. return 0;
  96. }
  97. void fd_register(int fd, void *owner, int type)
  98. {
  99. FD *theFD = get_fd_object(fd);
  100. if(theFD)
  101. {
  102. theFD->owner = owner;
  103. theFD->type = type;
  104. }
  105. }
  106. // get_fd_object returns a pointer to the actual FD object referenced by
  107. // fd. returns NULL if fd is not a valid file descriptor
  108. FD *get_fd_object(int fd)
  109. {
  110. assert(gFDInitialized);
  111. // validate fd
  112. if(!FD_VALID(fd))
  113. {
  114. errno = EBADF;
  115. return NULL;
  116. }
  117. return &gFDs[fd];
  118. }
  119. // get_free_fd returns a file descriptor (fd) reference if there is a 
  120. // free FD object in the FD array
  121. int get_free_fd(void)
  122. {
  123. int i;
  124. Boolean found = FALSE;
  125. assert(gFDInitialized);
  126. for(i = 0; i < FD_SETSIZE; i++)
  127. {
  128. if(gFDs[i].available)
  129. {
  130. gFDs[i].available = 0; // mark FD as not available
  131. found = TRUE;
  132. break;
  133. }
  134. }
  135. if(!found)
  136. {
  137. errno = EMFILE;
  138. return -1;
  139. }
  140. else
  141. return i;
  142. }
  143. int close(int fd)
  144. {
  145. return free_fd(fd);
  146. }
  147. // select scans the requested file descriptors to check if they are ready for
  148. // reading and/or writing. NOTE: timeout is ignored. This version of select is
  149. // only for polling the fds.
  150. /*
  151. int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
  152.      select - synchronous I/O multiplexing
  153. DESCRIPTION
  154.      Select() examines the I/O descriptor sets whose addresses are passed in
  155.      readfds, writefds, and exceptfds to see if some of their descriptors are
  156.      ready for reading, are ready for writing, or have an exceptional condi-
  157.      tion pending, respectively.  The first nfds descriptors are checked in
  158.      each set; i.e., the descriptors from 0 through nfds-1 in the descriptor
  159.      sets are examined.  On return, select() replaces the given descriptor
  160.      sets with subsets consisting of those descriptors that are ready for the
  161.      requested operation.  Select() returns the total number of ready descrip-
  162.      tors in all the sets.
  163.      The descriptor sets are stored as bit fields in arrays of integers.  The
  164.      following macros are provided for manipulating such descriptor sets:
  165.      FD_ZERO(&fdsetx) initializes a descriptor set fdset to the null set.
  166.      FD_SET(fd, &fdset) includes a particular descriptor fd in fdset.
  167.      FD_CLR(fd, &fdset) removes fd from fdset. FD_ISSET(fd, &fdset) is non-
  168.      zero if fd is a member of fdset, zero otherwise.  The behavior of these
  169.      macros is undefined if a descriptor value is less than zero or greater
  170.      than or equal to FD_SETSIZE, which is normally at least equal to the max-
  171.      imum number of descriptors supported by the system.
  172.      If timeout is a non-nil pointer, it specifies a maximum interval to wait
  173.      for the selection to complete.  If timeout is a nil pointer, the select
  174.      blocks indefinitely.  To affect a poll, the timeout argument should be
  175.      non-nil, pointing to a zero-valued timeval structure.
  176.      Any of readfds, writefds, and exceptfds may be given as nil pointers if
  177.      no descriptors are of interest.
  178. RETURN VALUES
  179.      Select() returns the number of ready descriptors that are contained in
  180.      the descriptor sets, or -1 if an error occurred.  If the time limit ex-
  181.      pires, select() returns 0.  If select() returns with an error, including
  182.      one due to an interrupted call, the descriptor sets will be unmodified.
  183. ERRORS
  184.      An error return from select() indicates:
  185.      [EBADF]       One of the descriptor sets specified an invalid descriptor.
  186.      [EINTR]       A signal was delivered before the time limit expired and
  187.                    before any of the selected events occurred.
  188.      [EINVAL]      The specified time limit is invalid.  One of its components
  189.                    is negative or too large.
  190. SEE ALSO
  191.      accept(2),  connect(2),  getdtablesize(2),  gettimeofday(2),  read(2),
  192.      recv(2),  send(2),  write(2)
  193. BUGS
  194.      Although the provision of getdtablesize(2) was intended to allow user
  195.      programs to be written independent of the kernel limit on the number of
  196.      open files, the dimension of a sufficiently large bit field for select
  197.      remains a problem.  The default size FD_SETSIZE (currently 256) is some-
  198.      what larger than the current kernel limit to the number of open files.
  199.      However, in order to accommodate programs which might potentially use a
  200.      larger number of open files with select, it is possible to increase this
  201.      size within a kernel by providing a larger definition of FD_SETSIZE in
  202.      kernel configuration file and rebuilding a kernel.  To increase default
  203.      limit user program must define its own FD_SETSIZE which is less or equal
  204.      new kernel FD_SETSIZE before the inclusion of any header which includes
  205.      <sys/types.h>.
  206.      Select() should probably return the time remaining from the original
  207.      timeout, if any, by modifying the time value in place.  This may be im-
  208.      plemented in future versions of the system.  Thus, it is unwise to assume
  209.      that the timeout value will be unmodified by the select() call.
  210. */
  211. int select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
  212. {
  213. int count = 0;
  214. int s;
  215. assert(gFDInitialized);
  216. // check for valid fds
  217. for (s = 0; s < width ; s++)
  218. {
  219. if ((readfds && FD_ISSET(s,readfds)) ||(writefds && FD_ISSET(s,writefds)) || (exceptfds && FD_ISSET(s,exceptfds)))
  220. {
  221. if (gFDs[s].owner == NULL)
  222. return EBADF;
  223. }
  224. }
  225. // check for read/write/exception ready
  226. for (s = 0; s < width ; s++)
  227. {
  228. Boolean ready = FALSE;
  229. if(readfds)
  230. {
  231. if (gFDs[s].readReady && FD_ISSET(s,readfds))
  232. ready = TRUE;
  233. else
  234. FD_CLR(s,readfds);
  235. }
  236. if(writefds)
  237. {
  238. if (gFDs[s].writeReady && FD_ISSET(s,writefds))
  239. ready = TRUE;
  240. else
  241. FD_CLR(s,writefds);
  242. }
  243. if(exceptfds)
  244. {
  245. if (gFDs[s].error && FD_ISSET(s,exceptfds))
  246. ready = TRUE;
  247. else
  248. FD_CLR(s,exceptfds);
  249. }
  250. if(ready)
  251. count++;
  252. }
  253. return count;
  254. }
  255. #endif