diff options
author | Marcelo Araujo <araujo@FreeBSD.org> | 2009-08-21 00:54:33 +0000 |
---|---|---|
committer | Marcelo Araujo <araujo@FreeBSD.org> | 2009-08-21 00:54:33 +0000 |
commit | 8cbd3957fb9309b77590faad70c31ada2caee71f (patch) | |
tree | 6e6dc53459a6b9a79b032994edb9301bd33d61c2 /devel/psptoolchain-newlib/files/patch-newlib-libc-sys-psp-select.c | |
parent | Update to the 20090818 snapshot of GCC 4.4.2. (diff) |
The PlayStation Portable Toolchain is a collection of tools and utilities
for homebrew PSP development.
WWW: http://www.ps2dev.org
PR: ports/132323, ports/132324, ports/132325, ports/132326
ports/132327, ports/132328, ports/132329, ports/132330
Submitted by: Tassilo Philipp <tphilipp@potion-studios.com>
Notes
Notes:
svn path=/head/; revision=240002
Diffstat (limited to 'devel/psptoolchain-newlib/files/patch-newlib-libc-sys-psp-select.c')
-rw-r--r-- | devel/psptoolchain-newlib/files/patch-newlib-libc-sys-psp-select.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/devel/psptoolchain-newlib/files/patch-newlib-libc-sys-psp-select.c b/devel/psptoolchain-newlib/files/patch-newlib-libc-sys-psp-select.c new file mode 100644 index 000000000000..0f457b01ae57 --- /dev/null +++ b/devel/psptoolchain-newlib/files/patch-newlib-libc-sys-psp-select.c @@ -0,0 +1,202 @@ +--- newlib/libc/sys/psp/select.c.orig 1970-01-01 02:00:00.000000000 +0200 ++++ newlib/libc/sys/psp/select.c 2007-06-01 17:45:11.000000000 +0300 +@@ -0,0 +1,199 @@ ++/* ++ * PSP Software Development Kit - http://www.pspdev.org ++ * ----------------------------------------------------------------------- ++ * Licensed under the BSD license, see LICENSE in PSPSDK root for details. ++ * ++ * select.c - Socket wrappers to provide similar functions to normal unix ++ * ++ * Copyright (c) 2006 Rafael Cabezas <rafpsp@gmail.com> ++ * ++ * - 20070701 Alper Akcan "anhanguera" <distchx@yahoo.com> ++ * select EBADF fix ++ * ++ */ ++#include <fcntl.h> ++#include <errno.h> ++#include <sys/select.h> ++#include <psptypes.h> ++#include <pspthreadman.h> ++ ++#include "fdman.h" ++ ++#define SELECT_POLLING_DELAY_IN_us 100 ++ ++static int __psp_poll_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds); ++ ++int select(int n, fd_set *readfds, fd_set *writefds, ++ fd_set *exceptfds, struct timeval *timeout) ++{ ++ int count; ++ clock_t start_time, time; ++ ++ start_time = clock(); ++ ++ count = 0; ++ ++ if (timeout) { ++ time = (timeout->tv_sec * CLOCKS_PER_SEC) + (timeout->tv_usec * (1*1000*1000/CLOCKS_PER_SEC)); ++ } ++ else { ++ time = 0; ++ } ++ ++ for (;;) { ++ count = __psp_poll_select(n, readfds, writefds, exceptfds); ++ /* If timeout == NULL, then don't timeout! */ ++ if ( (count > 0) || ((timeout != NULL) && ((clock() - start_time) >= time)) ) { ++ break; ++ } ++ if (count < 0) { ++ /* anhanguera - 20070701 ++ * error, lets let the caller to handle error state ++ */ ++ break; ++ } ++ else { ++ /* Nothing found, and not timed-out yet; let's yield for SELECT_POLLING_DELAY_IN_us, so we're not in a busy loop */ ++ sceKernelDelayThread(SELECT_POLLING_DELAY_IN_us); ++ } ++ } ++ ++ return count; ++} ++ ++#define SCE_FD_SET(n, p) \ ++ ((p)->fds_bits[((n) & 0xFF) /__NFDBITS] |= (1 << ((n) % __NFDBITS))) ++ ++static int __psp_poll_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) ++{ ++ int fd, count; ++ fd_set ready_readfds, ready_writefds, ready_exceptfds; ++ fd_set scereadfds, scewritefds, sceexceptfds; ++ SceKernelMppInfo info; ++ struct timeval scetv; ++ ++ FD_ZERO(&ready_readfds); ++ FD_ZERO(&ready_writefds); ++ FD_ZERO(&ready_exceptfds); ++ ++ info.size = sizeof(info); ++ scetv.tv_sec = 0; ++ scetv.tv_usec = 0; ++ count = 0; ++ ++ for (fd = 0; fd < n; fd++) ++ { ++ if (__psp_descriptormap[fd] != NULL) { ++ switch(__psp_descriptormap[fd]->type) ++ { ++ case __PSP_DESCRIPTOR_TYPE_PIPE: ++ if (readfds && FD_ISSET(fd, readfds)) { ++ if (sceKernelReferMsgPipeStatus(__psp_descriptormap[fd]->sce_descriptor, &info) == 0) { ++ if (info.bufSize != info.freeSize) { ++ FD_SET(fd, &ready_readfds); ++ count++; ++ } ++ } ++ else { ++ FD_SET(fd, &ready_exceptfds); ++ count++; ++ } ++ } ++ if (writefds && FD_ISSET(fd, writefds)) { ++ if (sceKernelReferMsgPipeStatus(__psp_descriptormap[fd]->sce_descriptor, &info) == 0) { ++ if (info.freeSize > 0) { ++ FD_SET(fd, &ready_writefds); ++ count++; ++ } ++ } ++ else { ++ FD_SET(fd, &ready_exceptfds); ++ count++; ++ } ++ } ++ break; ++ case __PSP_DESCRIPTOR_TYPE_FILE: ++ if (readfds && FD_ISSET(fd, readfds)) { ++ if (readfds && FD_ISSET(fd, readfds)) { ++ /** Just set it for now */ ++ FD_SET(fd, &ready_readfds); ++ count++; ++ } ++ } ++ break; ++ case __PSP_DESCRIPTOR_TYPE_SOCKET: ++ if (readfds && FD_ISSET(fd, readfds)) { ++ int sce_ret, sce_fd; ++ sce_fd = __psp_descriptormap[fd]->sce_descriptor; ++ FD_ZERO(&scereadfds); ++ SCE_FD_SET(sce_fd, &scereadfds); ++ errno = 0; ++ sce_ret = sceNetInetSelect (sce_fd+1, &scereadfds, NULL, NULL, &scetv); ++ if (sce_ret>0) { ++ FD_SET(fd, &ready_readfds); ++ count++; ++ } ++ else if (sce_ret == -1) { ++ errno = sceNetInetGetErrno(); ++ if (exceptfds && FD_ISSET(fd, exceptfds)) { ++ FD_SET(fd, &ready_exceptfds); ++ count++; ++ } else { ++ count = -1; ++ } ++ } ++ } ++ if (writefds && FD_ISSET(fd, writefds)) { ++ int sce_ret; ++ FD_ZERO(&scewritefds); ++ SCE_FD_SET(__psp_descriptormap[fd]->sce_descriptor, &scewritefds); ++ sce_ret = sceNetInetSelect (__psp_descriptormap[fd]->sce_descriptor+1, NULL, &scewritefds, NULL, &scetv); ++ if (sce_ret>0) { ++ FD_SET(fd, &ready_writefds); ++ count++; ++ } ++ else if (sce_ret == -1) { ++ if (exceptfds && FD_ISSET(fd, exceptfds)) { ++ FD_SET(fd, &ready_exceptfds); ++ count++; ++ } ++ else { ++ count = -1; ++ } ++ } ++ } ++ break; ++ } ++ } else { ++ /* anhanguera - 20070701 ++ * ++ * here we know that, system has no idea about 'fd'. if caller requested ++ * information about 'fd', return '-1' and set errno to 'EBADF'. we should ++ * increse the count and set exceptfd for fd, but it is safe to obey select ++ * manual. ++ * ++ * from manual; ++ * On error, -1 is returned, and errno is set appropriately; the sets and ++ * timeout become undefined, so do not rely on their contents after an error. ++ */ ++ if ((readfds && FD_ISSET(fd, readfds)) || ++ (writefds && FD_ISSET(fd, writefds)) || ++ (exceptfds && FD_ISSET(fd, exceptfds))) { ++ errno = EBADF; ++ return -1; ++ } ++ } ++ } ++ ++ if (count > 0) { ++ if (readfds) ++ *readfds = ready_readfds; ++ if (writefds) ++ *writefds = ready_writefds; ++ if (exceptfds) ++ *exceptfds = ready_exceptfds; ++ } ++ ++ return count; ++} ++ |