tRequestHeader *hdr = (void*)lbuf;
size_t len = recv(Client->Socket, (void*)hdr, sizeof(*hdr), 0);
// Log_Debug("Server", "%i bytes of header", len);
- if( len == 0 ) break;
+ if( len == 0 ) {
+ Log_Notice("Server", "Zero RX on %i (worker %p)", Client->Socket, Client);
+ break;
+ }
if( len == -1 ) {
perror("recv header");
// Log_Warning("Server", "recv() error - %s", strerror(errno));
// === IMPORTS ===
extern int Threads_Fork(void); // AcessNative only function
+extern int Threads_Spawn(int nFD, int FDs[], const void *info);
// === TYPES ===
typedef int (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes);
return *a0;
);
+SYSCALL3(Syscall_AN_Spawn, "ddd", int *, int *, void *,
+ if(Sizes[0] < sizeof(int))
+ return -1;
+ *a0 = Threads_Spawn(Sizes[1] / sizeof(int), a1, a2);
+ return *a0;
+);
+
SYSCALL2(Syscall_SendMessage, "id", int, void *,
return Proc_SendMessage(a0, Sizes[1], a1);
);
Syscall_Sleep,
Syscall_AN_Fork,
- NULL,
+ Syscall_AN_Spawn,
Syscall_SendMessage,
Syscall_GetMessage,
#include <acess.h>
#include <mutex.h>
#include "../../KernelLand/Kernel/include/semaphore.h"
+typedef signed long long int time_t;
+#include "../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h"
#include <rwlock.h>
#include <events.h>
#include <threads_int.h>
#define THREAD_EVENT_WAKEUP 0x80000000
// === IMPORTS ===
-void VFS_CloneHandleList(int PID);
+extern void VFS_CloneHandleList(int PID);
+extern void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[]);
// === STRUCTURES ===
// === PROTOTYPES ===
{
tThread *thread = Threads_CloneTCB(gpCurrentThread);
thread->PID = thread->TID;
+
// Duplicate the VFS handles (and nodes) from vfs_handle.c
-
VFS_CloneHandleList(thread->PID);
return thread->PID;
}
+int Threads_Spawn(int nFD, int FDs[], struct s_sys_spawninfo *info)
+{
+ tThread *thread = Threads_CloneTCB(gpCurrentThread);
+ thread->PID = thread->TID;
+ if( info )
+ {
+ // TODO: PGID?
+ //if( info->flags & SPAWNFLAG_NEWPGID )
+ // thread->PGID = thread->PID;
+ if( info->gid && thread->UID == 0 )
+ thread->GID = info->gid;
+ if( info->uid && thread->UID == 0 ) // last because ->UID is used above
+ thread->UID = info->uid;
+ }
+
+ VFS_CloneHandlesFromList(thread->PID, nFD, FDs);
+
+ Log_Debug("Threads", "_spawn: %i", thread->PID);
+ return thread->PID;
+}
+
// --------------------------------------------------------------------
// Mutexes
// --------------------------------------------------------------------
void Threads_PostEvent(tThread *Thread, Uint32 Events)
{
Thread->Events |= Events;
- Log_Debug("Threads", "Trigger event %x (->Events = %p) on %p", Events, Thread->Events, Thread);
-
+// Log_Debug("Threads", "Trigger event %x (->Events = %p) on %p", Events, Thread->Events, Thread);
+
if( Events == 0 || Thread->WaitMask & Events ) {
Threads_Glue_SemSignal( Thread->EventSem, 1 );
// Log_Debug("Threads", "Waking %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
}
}
+void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[])
+{
+ tUserHandles *ent;
+ tUserHandles *cur;
+ int i, maxhandles;
+
+ cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
+ if(!cur) return ; // Don't need to do anything if the current list is empty
+
+ ent = VFS_int_GetUserHandles(PID, 1);
+
+ maxhandles = *Threads_GetMaxFD();
+ if( nFD > maxhandles )
+ nFD = maxhandles;
+ for( i = 0; i < nFD; i ++ )
+ {
+ if( FDs[i] >= maxhandles ) {
+ ent->Handles[i].Node = NULL;
+ continue ;
+ }
+ memcpy(&ent->Handles[i], &cur->Handles[ FDs[i] ], sizeof(tVFS_Handle));
+ }
+ for( ; i < maxhandles; i ++ )
+ cur->Handles[i].Node = NULL;
+
+ for( i = 0; i < maxhandles; i ++ )
+ {
+ if(!cur->Handles[i].Node) continue;
+
+ if(ent->Handles[i].Node->Type->Reference)
+ ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
+ }
+}
+
/**
* \fn tVFS_Handle *VFS_GetHandle(int FD)
* \brief Gets a pointer to the handle information structure
int acess__SysSpawn(const char *binary, const char **argv, const char **envp, int nfd, int fds[], struct s_sys_spawninfo *info)
{
+ int argc = 0;
+ while( argv[argc++] );
+
+ Debug("_SysSpawn('%s', %p (%i), %p, %i, %p, %p)",
+ binary, argv, argc, envp, nfd, fds, info);
+
int kernel_tid;
int newID;
- newID = _Syscall(SYS_AN_SPAWN, "<d>d>d", sizeof(int), &kernel_tid,
+ newID = _Syscall(SYS_AN_SPAWN, "<d >d >d", sizeof(int), &kernel_tid,
nfd*sizeof(int), fds,
info ? sizeof(*info) : 0, info);
- int argc = 0;
- while( argv[argc++] );
-
const char *new_argv[5+argc+1];
int new_argc = 0, i;
char client_id_str[11];
}
if( ret == 0 ) {
fprintf(stderr, "[ERROR %i] Connection closed.\n", giSyscall_ClientID);
+ close(gSocket);
exit(0);
}