+ tVFS_SelectThread *thread_info;
+ int ret, type;
+
+ ENTER("pNode iTypeFlags pTimeout", Node, TypeFlags, Timeout);
+
+ thread_info = malloc(sizeof(tVFS_SelectThread));
+ if(!thread_info) LEAVE_RET('i', -1);
+
+ Semaphore_Init(&thread_info->SleepHandle, 0, 0, "VFS_SelectNode()", Name);
+
+ // Initialise
+ for( type = 0; type < 3; type ++ )
+ {
+ tVFS_SelectList **list;
+ int *flag, wanted, maxAllowed;
+ if( !(TypeFlags & (1 << type)) ) continue;
+ if( VFS_int_Select_GetType(type, Node, &list, &flag, &wanted, &maxAllowed) ) {
+ free(thread_info);
+ LEAVE('i', -1);
+ return -1;
+ }
+
+ // Alloc if needed
+ if( !*list ) *list = calloc(1, sizeof(tVFS_SelectList));
+
+ VFS_int_Select_AddThread(*list, thread_info, maxAllowed);
+ if( *flag == wanted )
+ {
+ VFS_int_Select_RemThread(*list, thread_info);
+ free(thread_info);
+ LEAVE('i', 1);
+ return 1;
+ }
+ }
+
+ // - Fast return for polling
+ if( Timeout && *Timeout == 0 ) return 0;
+
+ // Wait for things
+ if( !Timeout || *Timeout > 0 )
+ {
+ LOG("Semaphore_Wait()");
+ // TODO: Actual timeout
+ Semaphore_Wait(&thread_info->SleepHandle, 1);
+ }
+
+ // Get return value
+ ret = 0;
+ for( type = 0; type < 3; type ++ )
+ {
+ tVFS_SelectList **list;
+ int *flag, wanted, maxAllowed;
+ if( !(TypeFlags & (1 << type)) ) continue;
+ VFS_int_Select_GetType(type, Node, &list, &flag, &wanted, &maxAllowed);
+ LOG("VFS_int_Select_RemThread()");
+ VFS_int_Select_RemThread(*list, thread_info);
+ ret = ret || *flag == wanted;
+ }
+
+ free(thread_info);
+
+ LEAVE('i', ret);
+ return ret;
+}
+
+int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set *ErrHandles, tTime *Timeout, BOOL IsKernel)
+{
+ tVFS_SelectThread *thread_info;