// --- Save File, ArgV and EnvP
size = Binary_int_CacheArgs( &Binary, &ArgV, &EnvP, NULL );
- cachebuf = alloca( size );
+ cachebuf = malloc( size );
Binary_int_CacheArgs( &Binary, &ArgV, &EnvP, cachebuf );
// Cache the VFS handles
{
VFS_RestoreHandles(nFD, handles);
VFS_FreeSavedHandles(nFD, handles);
+ // Frees cachebuf
Proc_Execve(Binary, ArgV, EnvP, size);
for(;;);
}
/* AcessOS
* FIFO Pipe Driver
*/
+#define DEBUG 0
#include <acess.h>
#include <modules.h>
#include <fs_devfs.h>
char *FIFO_ReadDir(tVFS_Node *Node, int Id);
tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename);
int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+void FIFO_Reference(tVFS_Node *Node);
void FIFO_Close(tVFS_Node *Node);
int FIFO_Relink(tVFS_Node *Node, const char *OldName, const char *NewName);
Uint64 FIFO_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
.TypeName = "FIFO Pipe Node",
.Read = FIFO_Read,
.Write = FIFO_Write,
- .Close = FIFO_Close
+ .Close = FIFO_Close,
+ .Reference = FIFO_Reference
};
tDevFS_Driver gFIFO_DriverInfo = {
NULL, "fifo",
return 0;
}
+void FIFO_Reference(tVFS_Node *Node)
+{
+ if(!Node->ImplPtr) return ;
+
+ Node->ReferenceCount ++;
+}
+
/**
* \fn void FIFO_Close(tVFS_Node *Node)
* \brief Close a FIFO end
pipe = Node->ImplPtr;
if(strcmp(pipe->Name, "anon") == 0) {
+ Log_Debug("FIFO", "Pipe %p closed", Node->ImplPtr);
free(Node->ImplPtr);
return ;
}
tPipe *pipe = Node->ImplPtr;
Uint len;
Uint remaining = Length;
-
+
if(!pipe) return 0;
+ ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+
while(remaining)
{
// Wait for buffer to fill
if(pipe->Flags & PF_BLOCKING)
{
- #if 0
- len = Semaphore_Wait( &pipe->Semaphore, remaining );
- #else
- VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "FIFO_Read");
- // Read buffer
- // TODO: Rethink this, it might not work on buffer overflow
- if(pipe->WritePos - pipe->ReadPos < remaining)
- len = pipe->WritePos - pipe->ReadPos;
- else
- len = remaining;
- #endif
+ if( pipe->ReadPos == pipe->WritePos )
+ VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "FIFO_Read");
+
}
else
{
if(pipe->ReadPos == pipe->WritePos)
+ {
+ VFS_MarkAvaliable(Node, 0);
+ LEAVE('i', 0);
return 0;
- // Read buffer
- if(pipe->WritePos - pipe->ReadPos < remaining)
- len = pipe->WritePos - pipe->ReadPos;
- else
- len = remaining;
+ }
}
-
+
+ len = remaining;
+ if( pipe->ReadPos < pipe->WritePos )
+ {
+ int avail_bytes = pipe->WritePos - pipe->ReadPos;
+ if( avail_bytes < remaining ) len = avail_bytes;
+ }
+ else
+ {
+ int avail_bytes = pipe->WritePos + pipe->BufSize - pipe->ReadPos;
+ if( avail_bytes < remaining ) len = avail_bytes;
+ }
+
+ LOG("len = %i, remaining = %i", len, remaining);
+
// Check if read overflows buffer
if(len > pipe->BufSize - pipe->ReadPos)
{
remaining -= len;
// Increment Buffer address
Buffer = (Uint8*)Buffer + len;
+
+ // TODO: Option to read differently
+ LEAVE('i', len);
+ return len;
}
+ LEAVE('i', Length);
return Length;
}
Uint remaining = Length;
if(!pipe) return 0;
+
+ ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
while(remaining)
{
// Wait for buffer to empty
if(pipe->Flags & PF_BLOCKING) {
- #if 0
- len = Semaphore_Signal( &pipe->Semaphore, remaining );
- #else
- VFS_SelectNode(Node, VFS_SELECT_WRITE, NULL, "FIFO_Write");
- if(pipe->ReadPos - pipe->WritePos < remaining)
- len = pipe->ReadPos - pipe->WritePos;
+ if( pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize )
+ VFS_SelectNode(Node, VFS_SELECT_WRITE, NULL, "FIFO_Write");
+
+ len = remaining;
+ if( pipe->ReadPos > pipe->WritePos )
+ {
+ int rem_space = pipe->ReadPos - pipe->WritePos;
+ if(rem_space < remaining) len = rem_space;
+ }
else
- len = remaining;
- #endif
+ {
+ int rem_space = pipe->ReadPos + pipe->BufSize - pipe->WritePos;
+ if(rem_space < remaining) len = rem_space;
+ }
}
else
{
if(pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize)
+ {
+ LEAVE('i', 0);
return 0;
+ }
// Write buffer
if(pipe->ReadPos - pipe->WritePos < remaining)
len = pipe->ReadPos - pipe->WritePos;
Buffer = (Uint8*)Buffer + len;
}
+ LEAVE('i', Length);
return Length;
}
int namelen = strlen(Name) + 1;
int allocsize = sizeof(tPipe) + sizeof(tVFS_ACL) + Size + namelen;
- ret = malloc(allocsize);
+ ret = calloc(1, allocsize);
if(!ret) return NULL;
// Clear Return
- memset(ret, 0, allocsize);
ret->Flags = PF_BLOCKING;
// Allocate Buffer
//Semaphore_Init( &ret->Semaphore, 0, Size, "FIFO", ret->Name );
// Set Node
+ ret->Node.ReferenceCount = 1;
ret->Node.Size = 0;
ret->Node.ImplPtr = ret;
ret->Node.UID = Threads_GetUID();
if(!(v)||!Syscall_Valid((size),(v))){ret=-1;err=-EINVAL;break;}
#define CHECK_STR_NONULL(v) \
if(!(v)||!Syscall_ValidString((v))){ret=-1;err=-EINVAL;break;}
+#define CHECK_STR_ARRAY(arr) do {\
+ int i;\
+ char **tmp = (char**)arr; \
+ CHECK_NUM_NONULL( tmp, sizeof(char**) ); \
+ for(i=0;tmp[i];i++) { \
+ CHECK_STR_NONULL( tmp[i] ); \
+ CHECK_NUM_NONULL( &tmp[i+1], sizeof(char*) ); \
+ }\
+ if(tmp[i]) break;\
+} while(0)
// === IMPORTS ===
extern Uint Binary_Load(const char *file, Uint *entryPoint);
// ---
// Binary Control
// ---
+ // -- Create a new process
+ case SYS_SPAWN:
+ CHECK_STR_NONULL((const char*)Regs->Arg1);
+ CHECK_STR_ARRAY((const char**)Regs->Arg2);
+ CHECK_STR_ARRAY((const char**)Regs->Arg3);
+ CHECK_NUM_NONULL((void*)Regs->Arg5, Regs->Arg4*sizeof(int));
+ ret = Proc_SysSpawn(
+ (const char*)Regs->Arg1, (const char**)Regs->Arg2, (const char**)Regs->Arg3,
+ Regs->Arg4, (int*)Regs->Arg5
+ );
+ break;
// -- Replace the current process with another
case SYS_EXECVE:
CHECK_STR_NONULL((char*)Regs->Arg1);
- // Check the argument arrays
- {
- int i;
- char **tmp = (char**)Regs->Arg2;
- // Check ArgV (traverse array checking all string pointers)
- CHECK_NUM_NONULL( tmp, sizeof(char**) );
- //Log("tmp = %p", tmp);
- for(i=0;tmp[i];i++) {
- CHECK_NUM_NONULL( &tmp[i], sizeof(char*) );
- CHECK_STR_NONULL( tmp[i] );
- }
- if(ret == -1) break;
- // Check EnvP also
- // - EnvP can be NULL
- if( Regs->Arg3 )
- {
- tmp = (char**)Regs->Arg3;
- CHECK_NUM_NONULL(tmp, sizeof(char**));
- for(i=0;tmp[i];i++) {
- CHECK_NUM_NONULL( &tmp[i], sizeof(char*) );
- CHECK_STR_NONULL( tmp[i] );
- }
- if(ret == -1) break;
- }
- }
+ CHECK_STR_ARRAY( (char**)Regs->Arg2 );
+ if( Regs->Arg3 )
+ CHECK_STR_ARRAY( (char**)Regs->Arg3 );
LEAVE('s', "Assuming 0");
// Path, **Argv, **Envp, DataSize (=0 to tell it to create a copy)
- ret = Proc_Execve( (const char*)Regs->Arg1, (const char**)Regs->Arg2, (const char**)Regs->Arg3, 0 );
+ ret = Proc_Execve(
+ (const char*)Regs->Arg1, (const char**)Regs->Arg2, (const char**)Regs->Arg3,
+ 0
+ );
break;
// -- Load a binary into the current process
case SYS_LOADBIN:
- if( !Syscall_ValidString( (char*) Regs->Arg1)
- || !Syscall_Valid(sizeof(Uint), (Uint*)Regs->Arg2) ) {
- err = -EINVAL;
- ret = 0;
- break;
- }
+ CHECK_STR_NONULL( (char*)Regs->Arg1 );
+ CHECK_NUM_NONULL( (Uint*)Regs->Arg2, sizeof(Uint) );
// Path, *Entrypoint
ret = Binary_Load((char*)Regs->Arg1, (Uint*)Regs->Arg2);
break;
// Open a file that is a entry in an open directory
case SYS_OPENCHILD:
CHECK_STR_NONULL( (char*)Regs->Arg2 );
- ret = VFS_OpenChild( Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3);
+ ret = VFS_OpenChild( Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3 | VFS_OPENFLAG_USER);
break;
// Change Directory
tThread *thisthread = Proc_GetCurThread();
int ret, type;
- ENTER("pNode iTypeFlags pTimeout", Node, TypeFlags, Timeout);
+ ENTER("pNode iTypeFlags pTimeout sName", Node, TypeFlags, Timeout, Name);
// Initialise
for( type = 0; type < 3; type ++ )
// Mark a node as having a full buffer
int VFS_MarkFull(tVFS_Node *Node, BOOL IsBufferFull)
{
- ENTER("pNode bIsDataAvaliable", Node, IsBufferFull);
+ ENTER("pNode bIsBufferFull", Node, IsBufferFull);
Node->BufferFull = !!IsBufferFull;
if( !Node->BufferFull )
VFS_int_Select_SignalAll(Node->WriteThreads);
// Mark a node as errored
int VFS_MarkError(tVFS_Node *Node, BOOL IsErrorState)
{
- ENTER("pNode bIsDataAvaliable", Node, IsErrorState);
+ ENTER("pNode bIsErrorState", Node, IsErrorState);
Node->ErrorOccurred = !!IsErrorState;
if( Node->ErrorOccurred )
VFS_int_Select_SignalAll(Node->ErrorThreads);
tTCPConnection *conn;
Log_Log("TCP", "TCP_GetPacket: <Local>:%i from [%s]:%i, Flags= %s%s%s%s%s%s%s%s",
- ntohs(hdr->SourcePort),
- IPStack_PrintAddress(Interface->Type, Address),
ntohs(hdr->DestPort),
+ IPStack_PrintAddress(Interface->Type, Address),
+ ntohs(hdr->SourcePort),
(hdr->Flags & TCP_FLAG_CWR) ? "CWR " : "",
(hdr->Flags & TCP_FLAG_ECE) ? "ECE " : "",
(hdr->Flags & TCP_FLAG_URG) ? "URG " : "",
if(conn->RemotePort != ntohs(hdr->SourcePort)) continue;
// Check Source IP
- if( IPStack_CompareAddress(conn->Interface->Type, &conn->RemoteIP, Address, -1) != 0 )
+ Log_Debug("TCP", "TCP_GetPacket: conn->RemoteIP(%s)",
+ IPStack_PrintAddress(conn->Interface->Type, &conn->RemoteIP));
+ Log_Debug("TCP", " == Address(%s)",
+ IPStack_PrintAddress(conn->Interface->Type, Address));
+ if( IPStack_CompareAddress(conn->Interface->Type, &conn->RemoteIP, Address, -1) == 0 )
continue ;
Log_Log("TCP", "TCP_GetPacket: Matches connection %p", conn);
srv->ConnectionsTail = conn;
if(!srv->NewConnections)
srv->NewConnections = conn;
+ VFS_MarkAvaliable( &srv->Node, 1 );
SHORTREL(&srv->lConnections);
// Send the SYN ACK
{
tTCPListener *srv;
- srv = malloc( sizeof(tTCPListener) );
+ srv = calloc( 1, sizeof(tTCPListener) );
if( srv == NULL ) {
Log_Warning("TCP", "malloc failed for listener (%i) bytes", sizeof(tTCPListener));
if( srv->NewConnections != NULL ) break;
SHORTREL( &srv->lConnections );
Threads_Yield(); // TODO: Sleep until poked
- continue;
}
// normal list)
conn = srv->NewConnections;
srv->NewConnections = conn->Next;
+
+ if( srv->NewConnections == NULL )
+ VFS_MarkAvaliable( Node, 0 );
SHORTREL( &srv->lConnections );
if(conn->Node.ImplInt == id) break;
}
SHORTREL( &srv->lConnections );
+
+ // If not found, ret NULL
+ if(!conn) {
+ LOG("Connection %i not found", id);
+ LEAVE('n');
+ return NULL;
+ }
}
// Empty Name - Check for a new connection and if it's there, open it
else
conn = srv->NewConnections;
if( conn != NULL )
srv->NewConnections = conn->Next;
+ VFS_MarkAvaliable( Node, srv->NewConnections != NULL );
SHORTREL( &srv->lConnections );
+ if( !conn ) {
+ LOG("No new connections");
+ LEAVE('n');
+ return NULL;
+ }
}
- // If not found, ret NULL
- if(!conn) {
- LOG("Connection %i not found", id);
- LEAVE('n');
- return NULL;
- }
-
// Return node
LEAVE('p', &conn->Node);
return &conn->Node;
shift
QEMU_PARAMS=$QEMU_PARAMS" "$1
;;
+ -fwd)
+ _NETTYPE=$_NETTYPE",hostfwd=tcp::10023-10.0.2.10:23"
+ ;;
-tuntap)
_NETTYPE="tap"
esac
gaClients = calloc(giConfig_MaxClients, sizeof(tClient));
// Open server
- giServerFD = Net_OpenSocket(0, NULL, "tcps");
+ {
+ uint8_t data[16];
+ int addrtype = Net_ParseAddress("10.0.2.10", data);
+ int port = 23;
+ giServerFD = Net_OpenSocket(addrtype, data, "tcps");
+ ioctl(giServerFD, 4, &port); // Set port and start listening
+ }
// Event loop
EventLoop();
for( ;; )
{
+ FD_ZERO(&fds);
maxfd = 0;
// Fill select
FD_SET_MAX(&fds, giServerFD, &maxfd);
for( int i = 0; i < giConfig_MaxClients; i ++ )
{
+ if( gaClients[i].Socket == 0 ) continue ;
+ _SysDebug("Socket = %i, stdout = %i",
+ gaClients[i].Socket, gaClients[i].stdout);
FD_SET_MAX(&fds, gaClients[i].Socket, &maxfd);
FD_SET_MAX(&fds, gaClients[i].stdout, &maxfd);
}
}
// Accept the connection
clt->Socket = _SysOpenChild(FD, "", O_RDWR);
- giNumClients ++;
+ giNumClients ++;
// Create stdin/stdout
- clt->stdin = open("/Devices/fifo", O_RDWR);
- clt->stdout = open("/Devices/fifo", O_RDWR);
+ clt->stdin = open("/Devices/fifo/anon", O_RDWR);
+ clt->stdout = open("/Devices/fifo/anon", O_RDWR);
// TODO: Arguments and envp
{
int fds[3] = {clt->stdin, clt->stdout, clt->stdout};
- _SysSpawn("/Acess/SBin/login", NULL, NULL, 3, fds);
+ const char *argv[] = {NULL};
+ _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds);
}
}
int len;
len = read(Client->Socket, buf, BUFSIZ);
+ if( len <= 0 ) return ;
write(Client->stdin, buf, len);
}
int len;
len = read(Client->stdout, buf, BUFSIZ);
+ if( len <= 0 ) return ;
write(Client->Socket, buf, len);
}
SYSCALL3(SysSendMessage, SYS_SENDMSG)
SYSCALL3(SysGetMessage, SYS_GETMSG)
-SYSCALL3(SysSpawn, SYS_SPAWN)
+SYSCALL5(_SysSpawn, SYS_SPAWN)
SYSCALL3(execve, SYS_EXECVE)
SYSCALL2(SysLoadBin, SYS_LOADBIN)
SYSCALL1(SysUnloadBin, SYS_UNLOADBIN)
EXP(SysSendMessage),
EXP(SysGetMessage),
- //EXP(SysSpawn),
+ EXP(_SysSpawn),
EXP(execve),
EXP(SysLoadBin),
EXP(SysUnloadBin),