extern char **Threads_GetChroot(void);
extern int Proc_SendMessage(Uint Dest, int Length, void *Data);
-extern int Proc_GetMessage(Uint *Source, void *Buffer);
+extern int Proc_GetMessage(Uint *Source, Uint BufSize, void *Buffer);
#endif
* \fn int Proc_GetMessage(Uint *Source, void *Buffer)
* \brief Gets a message
* \param Source Where to put the source TID
+ * \param BufSize Size of \a Buffer, only this many bytes will be copied
* \param Buffer Buffer to place the message data (set to NULL to just get message length)
* \return Message length
*/
-int Proc_GetMessage(Uint *Source, void *Buffer)
+int Proc_GetMessage(Uint *Source, Uint BufSize, void *Buffer)
{
int ret;
void *tmp;
// Get message
if(Buffer != GETMSG_IGNORE)
{
- if( !CheckMem( Buffer, cur->Messages->Length ) )
+ if( !CheckMem( Buffer, BufSize ) )
{
LOG("Invalid buffer");
errno = -EINVAL;
LEAVE('i', -1);
return -1;
}
+ if( BufSize < cur->Messages->Length )
+ Log_Notice("Threads", "Buffer of 0x%x passed, but 0x%x long message, truncated",
+ BufSize, cur->Messages->Length);
+ else if( BufSize < cur->Messages->Length )
+ BufSize = cur->Messages->Length;
+ else
+ ; // equal
LOG("Copied to buffer");
- memcpy(Buffer, cur->Messages->Data, cur->Messages->Length);
+ memcpy(Buffer, cur->Messages->Data, BufSize);
}
ret = cur->Messages->Length;
// -- Check for messages
case SYS_GETMSG:
CHECK_NUM_NULLOK( (Uint*)Regs->Arg1, sizeof(Uint) );
- // NOTE: Can't do range checking as we don't know the size
- // - Should be done by Proc_GetMessage
- if( Regs->Arg2 && Regs->Arg2 != -1 && !MM_IsUser(Regs->Arg2) ) {
- err = -EINVAL; ret = -1; break;
- }
+ if( Regs->Arg3 != -1 )
+ CHECK_NUM_NULLOK((void*)Regs->Arg3, Regs->Arg2);
// *Source, *Data
- ret = Proc_GetMessage((Uint*)Regs->Arg1, (void*)Regs->Arg2);
+ ret = Proc_GetMessage((Uint*)Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3);
break;
// -- Get the current timestamp
}
}
- while(SysGetMessage(NULL, NULL))
+ size_t len;
+ pid_t tid;
+ while( (len = SysGetMessage(&tid, 0, NULL)) )
{
- pid_t tid;
- int len = SysGetMessage(&tid, NULL);
char data[len];
- SysGetMessage(NULL, data);
+ SysGetMessage(NULL, len, data);
IPC_Handle(&gIPC_Type_SysMessage, &tid, len, (void*)data);
// _SysDebug("IPC_HandleSelect: Message handled");
pid_t tid;
// Wait for a message to arrive
- while( !(len = SysGetMessage(&tid, NULL)) )
+ while( !(len = SysGetMessage(&tid, 0, NULL)) )
{
_SysWaitEvent(THREAD_EVENT_IPCMSG);
}
if( gAxWin3_MessageCallback )
gAxWin3_MessageCallback(tid, len);
else
- SysGetMessage(NULL, GETMSG_IGNORE);
+ SysGetMessage(NULL, 0, GETMSG_IGNORE);
continue ;
}
ret = malloc(len);
if(ret == NULL) {
_SysDebug("malloc() failed, ignoring message");
- SysGetMessage(NULL, GETMSG_IGNORE);
+ SysGetMessage(NULL, 0, GETMSG_IGNORE);
return NULL;
}
- SysGetMessage(NULL, ret);
+ SysGetMessage(NULL, len, ret);
break;
}
break;
// --- IPC ---
extern int SysSendMessage(pid_t dest, uint length, const void *Data);
-extern int SysGetMessage(pid_t *src, void *Data);
+extern int SysGetMessage(pid_t *src, uint buflen, void *Data);
// --- MEMORY ---
uint64_t _SysGetPhys(uint vaddr);