macfd.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 330 行
C
330 行
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: macFD.c,v 1.3.36.3 2004/07/09 01:44:14 hubbe Exp $
*
* Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file,
* are subject to the current version of the RealNetworks Public
* Source License (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (the "RCSL") available at
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
* will apply. You may also obtain the license terms directly from
* RealNetworks. You may not use this file except in compliance with
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
* the rights, obligations and limitations governing use of the
* contents of the file.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
// if we're building mach-o we already have honest implementations of all this.
#ifndef _MAC_MACHO
#include <assert.h>
#include "macFD.h"
#include "platform/mac/socketerrors.h"
FD gFDs[FD_SETSIZE];
Boolean gFDInitialized = FALSE;
// init_fds initializes the FD array. This MUST be called at program startup
void init_fds(void)
{
int i;
if(gFDInitialized)
return;
for(i = 0; i < FD_SETSIZE; i++)
{
FD *temp = &gFDs[i];
temp->index = i;
temp->owner = NULL;
temp->available = TRUE;
temp->readReady = FALSE;
temp->writeReady = FALSE;
temp->error = 0;
temp->type = 0;
}
gFDInitialized = TRUE;
}
// fd_get_owner returns the FD object's owner
void *fd_get_owner(int fd)
{
FD *temp;
// validate fd
assert(gFDInitialized);
if(!FD_VALID(fd))
{
errno = EBADF;
return NULL;
}
temp = &gFDs[fd];
return (temp->owner);
}
// free_fd marks the FD object referenced by fd as free
int free_fd(int fd)
{
FD *temp;
// validate fd
assert(gFDInitialized);
if(!FD_VALID(fd))
{
errno = EBADF;
return - 1;
}
temp = &gFDs[fd];
// if(temp->owner)
// delete temp->owner;
temp->owner = NULL;
temp->readReady = FALSE;
temp->writeReady = FALSE;
temp->error = 0;
temp->available = TRUE;
temp->type = 0;
return 0;
}
void fd_register(int fd, void *owner, int type)
{
FD *theFD = get_fd_object(fd);
if(theFD)
{
theFD->owner = owner;
theFD->type = type;
}
}
// get_fd_object returns a pointer to the actual FD object referenced by
// fd. returns NULL if fd is not a valid file descriptor
FD *get_fd_object(int fd)
{
assert(gFDInitialized);
// validate fd
if(!FD_VALID(fd))
{
errno = EBADF;
return NULL;
}
return &gFDs[fd];
}
// get_free_fd returns a file descriptor (fd) reference if there is a
// free FD object in the FD array
int get_free_fd(void)
{
int i;
Boolean found = FALSE;
assert(gFDInitialized);
for(i = 0; i < FD_SETSIZE; i++)
{
if(gFDs[i].available)
{
gFDs[i].available = 0; // mark FD as not available
found = TRUE;
break;
}
}
if(!found)
{
errno = EMFILE;
return -1;
}
else
return i;
}
int close(int fd)
{
return free_fd(fd);
}
// select scans the requested file descriptors to check if they are ready for
// reading and/or writing. NOTE: timeout is ignored. This version of select is
// only for polling the fds.
/*
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
select - synchronous I/O multiplexing
DESCRIPTION
Select() examines the I/O descriptor sets whose addresses are passed in
readfds, writefds, and exceptfds to see if some of their descriptors are
ready for reading, are ready for writing, or have an exceptional condi-
tion pending, respectively. The first nfds descriptors are checked in
each set; i.e., the descriptors from 0 through nfds-1 in the descriptor
sets are examined. On return, select() replaces the given descriptor
sets with subsets consisting of those descriptors that are ready for the
requested operation. Select() returns the total number of ready descrip-
tors in all the sets.
The descriptor sets are stored as bit fields in arrays of integers. The
following macros are provided for manipulating such descriptor sets:
FD_ZERO(&fdsetx) initializes a descriptor set fdset to the null set.
FD_SET(fd, &fdset) includes a particular descriptor fd in fdset.
FD_CLR(fd, &fdset) removes fd from fdset. FD_ISSET(fd, &fdset) is non-
zero if fd is a member of fdset, zero otherwise. The behavior of these
macros is undefined if a descriptor value is less than zero or greater
than or equal to FD_SETSIZE, which is normally at least equal to the max-
imum number of descriptors supported by the system.
If timeout is a non-nil pointer, it specifies a maximum interval to wait
for the selection to complete. If timeout is a nil pointer, the select
blocks indefinitely. To affect a poll, the timeout argument should be
non-nil, pointing to a zero-valued timeval structure.
Any of readfds, writefds, and exceptfds may be given as nil pointers if
no descriptors are of interest.
RETURN VALUES
Select() returns the number of ready descriptors that are contained in
the descriptor sets, or -1 if an error occurred. If the time limit ex-
pires, select() returns 0. If select() returns with an error, including
one due to an interrupted call, the descriptor sets will be unmodified.
ERRORS
An error return from select() indicates:
[EBADF] One of the descriptor sets specified an invalid descriptor.
[EINTR] A signal was delivered before the time limit expired and
before any of the selected events occurred.
[EINVAL] The specified time limit is invalid. One of its components
is negative or too large.
SEE ALSO
accept(2), connect(2), getdtablesize(2), gettimeofday(2), read(2),
recv(2), send(2), write(2)
BUGS
Although the provision of getdtablesize(2) was intended to allow user
programs to be written independent of the kernel limit on the number of
open files, the dimension of a sufficiently large bit field for select
remains a problem. The default size FD_SETSIZE (currently 256) is some-
what larger than the current kernel limit to the number of open files.
However, in order to accommodate programs which might potentially use a
larger number of open files with select, it is possible to increase this
size within a kernel by providing a larger definition of FD_SETSIZE in
kernel configuration file and rebuilding a kernel. To increase default
limit user program must define its own FD_SETSIZE which is less or equal
new kernel FD_SETSIZE before the inclusion of any header which includes
<sys/types.h>.
Select() should probably return the time remaining from the original
timeout, if any, by modifying the time value in place. This may be im-
plemented in future versions of the system. Thus, it is unwise to assume
that the timeout value will be unmodified by the select() call.
*/
int select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
int count = 0;
int s;
assert(gFDInitialized);
// check for valid fds
for (s = 0; s < width ; s++)
{
if ((readfds && FD_ISSET(s,readfds)) ||(writefds && FD_ISSET(s,writefds)) || (exceptfds && FD_ISSET(s,exceptfds)))
{
if (gFDs[s].owner == NULL)
return EBADF;
}
}
// check for read/write/exception ready
for (s = 0; s < width ; s++)
{
Boolean ready = FALSE;
if(readfds)
{
if (gFDs[s].readReady && FD_ISSET(s,readfds))
ready = TRUE;
else
FD_CLR(s,readfds);
}
if(writefds)
{
if (gFDs[s].writeReady && FD_ISSET(s,writefds))
ready = TRUE;
else
FD_CLR(s,writefds);
}
if(exceptfds)
{
if (gFDs[s].error && FD_ISSET(s,exceptfds))
ready = TRUE;
else
FD_CLR(s,exceptfds);
}
if(ready)
count++;
}
return count;
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?