macFD.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:10k
源码类别:

Symbian

开发平台:

Visual C++

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