From: John Hodge Date: Tue, 22 Jan 2013 09:26:02 +0000 (+0800) Subject: Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2 X-Git-Tag: rel0.15~597^2~13 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=b0da731b2d89b9dd58de2c98eaf6218a41a21920;hp=a01b96ccf4ec884e5b894d08a819a37ea3f5f749;p=tpg%2Facess2.git Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2 --- diff --git a/.travis.yml b/.travis.yml index 336c3d14..6154547a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,6 @@ before_install: - sudo apt-get update -qq - sudo apt-get install -qq nasm env: - - ARCH=host HOST_ARCH=x86 + - ARCH=host HOST_ARCH=x86 USE_ACPICA=0 - ARCH=host HOST_ARCH=x86_64 CC="$CC -m64" script: "make all" diff --git a/AcessNative/acesskernel_src/Makefile b/AcessNative/acesskernel_src/Makefile index b4b7c11d..d17e3bb8 100644 --- a/AcessNative/acesskernel_src/Makefile +++ b/AcessNative/acesskernel_src/Makefile @@ -13,7 +13,8 @@ endif KERNEL_SRC = ../../KernelLand/Kernel/ -KERNEL_OBJ := logging.o adt.o lib.o libc.o debug.o messages.o drvutil_disk.o drvutil_video.o +KERNEL_OBJ := logging.o adt.o lib.o debug.o messages.o drvutil_disk.o drvutil_video.o +#KERNEL_OBJ += libc.o KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o KERNEL_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o vfs/select.o KERNEL_OBJ += vfs/fs/root.o vfs/fs/devfs.o @@ -36,7 +37,8 @@ DEPFILES := $(DEPFILES:%=%.dep) KCPPFLAGS = -I include/ -I $(KERNEL_SRC)include/ CFLAGS += -Wall -g -std=gnu99 -LDFLAGS += -lSDL -lSDLmain -g -Wl,--defsym,__buildnum=$(BUILD_NUM) +CPPFLAGS += $(shell sdl-config --cflags) -I /usr/include/ +LDFLAGS += $(shell sdl-config --libs) -g -Wl,--defsym,__buildnum=$(BUILD_NUM) ifeq ($(PLATFORM),win) BIN := ../AcessKernel.exe @@ -69,7 +71,7 @@ $(OBJ): obj-$(PLATFORM)/%.o: %.c $(K_OBJ): $(KERNEL_SRC)obj-native-$(PLATFORM)/%.o: $(KERNEL_SRC)%.c @mkdir -p $(dir $@) @echo [CC] -o $@ - $(CC) -ffreestanding -c $< -o $@ $(CFLAGS) $(KCPPFLAGS) $(CPPFLAGS) + @$(CC) -ffreestanding -c $< -o $@ $(CFLAGS) $(KCPPFLAGS) $(CPPFLAGS) @$(CC) -ffreestanding -M $(KCPPFLAGS) $(CPPFLAGS) -MT $@ -o $@.dep $< @@ -81,12 +83,13 @@ $(N_OBJ): obj-$(PLATFORM)/%.o: %.c $(BUILDINFO_SRC): $(filter-out $(BUILDINFO_OBJ), $(OBJ)) Makefile @echo "" > $@ - $(eval _GITHASH=$(shell (git log -n 1 | head -n 1 | awk '{print $$2}') || echo UNK)) - $(eval _GITCHANGED=$(shell (git status --porcelain | grep -c '^ M ') || echo UNK)) + $(eval _GITHASH=$(shell (git log -n 1 | head -n 1 | awk '{print $$2}') 2>/dev/null || echo UNK)) + $(eval _GITCHANGED=$(shell (git status --porcelain | grep -c '^ M ') 2>/dev/null || echo UNK)) + $(eval _HOSTNAME=$(shell hostname --fqdn 2>/dev/null || hostname || echo UNK)) @echo "const char gsKernelVersion[] = \"$(ACESS_VERSION)\";" >> $@ @echo "const char gsGitHash[] = \"$(_GITHASH)\";" >> $@ - @echo "const char gsBuildInfo[] = \"Acess2 v$(KERNEL_VERSION) $(ARCH)-$(PLATFORM)\\\\r\\\\n\"" >> $@ - @echo " \"Build $(shell hostname --fqdn):$(BUILD_NUM) Git $(_GITHASH) - $(_GITCHANGED) modified\";" >> $@ + @echo "const char gsBuildInfo[] = \"AcessNative $(ACESS_VERSION) $(ARCH)-$(PLATFORM)\\\\r\\\\n\"" >> $@ + @echo " \"Build $(_HOSTNAME):$(BUILD_NUM) Git $(_GITHASH) - $(_GITCHANGED) modified\";" >> $@ @echo "const int giBuildNumber = $(BUILD_NUM);" >> $@ $(BUILDINFO_OBJ): $(BUILDINFO_SRC) @echo [CC] -o $@ diff --git a/AcessNative/acesskernel_src/helpers.c b/AcessNative/acesskernel_src/helpers.c index 3cf273e4..6396d166 100644 --- a/AcessNative/acesskernel_src/helpers.c +++ b/AcessNative/acesskernel_src/helpers.c @@ -9,6 +9,7 @@ #include #include #include +#include #if 0 void LogF(const char *Fmt, ...) @@ -67,10 +68,14 @@ void KernelPanic_PutChar(char ch) void Debug_PutCharDebug(char ch) { printf("%c", ch); + if( ch == '\n' ) + fflush(stdout); } void Debug_PutStringDebug(const char *String) { printf("%s", String); + if( strchr(String, '\n') ) + fflush(stdout); } void *Heap_Allocate(const char *File, int Line, int ByteCount) @@ -93,6 +98,11 @@ void Heap_Deallocate(void *Ptr) free(Ptr); } +char *Heap_StringDup(const char *File, int Line, const char *Str) +{ + return strdup(Str); +} + void Heap_Dump(void) { } @@ -130,3 +140,59 @@ void IPStack_SendDebugText(const char *str) // nop } +int strpos(const char *str, char ch) +{ + const char *retptr = strchr(str, ch); + int rv = retptr ? retptr - str : -1; + return rv; +} + +int CheckString(const char *string) +{ + if( (intptr_t)string < 0x1000 ) + return 0; + return 1; +} + +int CheckMem(const void *buf, size_t len) +{ + if( (intptr_t)buf < 0x1000 ) + return 0; + return 1; +} + +void itoa(char *buf, Uint64 num, int base, int minLength, char pad) +{ + static const char cUCDIGITS[] = "0123456789ABCDEF"; + char tmpBuf[64+1]; + int pos=0, i; + Uint64 rem; + + // Sanity check + if(!buf) return; + + // Sanity Check + if(base > 16 || base < 2) { + buf[0] = 0; + return; + } + + // Convert + while(num > base-1) { + rem = num % base; + num = num / base; // Shift `num` and get remainder + tmpBuf[pos] = cUCDIGITS[ rem ]; + pos++; + } + tmpBuf[pos++] = cUCDIGITS[ num ]; // Last digit of `num` + + // Put in reverse + i = 0; + minLength -= pos; + while(minLength-- > 0) + buf[i++] = pad; + while(pos-- > 0) + buf[i++] = tmpBuf[pos]; // Reverse the order of characters + buf[i] = 0; +} + diff --git a/AcessNative/acesskernel_src/include/arch.h b/AcessNative/acesskernel_src/include/arch.h index 1307e0c6..e99948c9 100644 --- a/AcessNative/acesskernel_src/include/arch.h +++ b/AcessNative/acesskernel_src/include/arch.h @@ -29,7 +29,6 @@ typedef intptr_t tPAddr; typedef int BOOL; #include -#undef NULL #undef offsetof struct sShortSpinlock diff --git a/AcessNative/acesskernel_src/include/heap.h b/AcessNative/acesskernel_src/include/heap.h index 287250ca..8bf7d8ec 100644 --- a/AcessNative/acesskernel_src/include/heap.h +++ b/AcessNative/acesskernel_src/include/heap.h @@ -11,6 +11,7 @@ extern void *Heap_Reallocate(const char *File, int Line, void *Ptr, size_t Bytes extern void Heap_Deallocate(void *Ptr); extern int Heap_IsHeapAddr(void *Ptr); extern void Heap_Validate(void); +extern char *Heap_StringDup(const char *File, int Line, const char *Str); #define malloc(size) Heap_Allocate(_MODULE_NAME_"/"__FILE__, __LINE__, (size)) #define calloc(num,size) Heap_AllocateZero(_MODULE_NAME_"/"__FILE__, __LINE__, (num)*(size)) @@ -18,6 +19,6 @@ extern void Heap_Validate(void); #define free(ptr) Heap_Deallocate((ptr)) #define IsHeap(ptr) Heap_IsHeapAddr((ptr)) -#define strdup(Str) _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str)) +#define strdup(Str) Heap_StringDup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str)) #endif diff --git a/AcessNative/acesskernel_src/include/threads_int.h b/AcessNative/acesskernel_src/include/threads_int.h index 1294a5f4..8061f1e9 100644 --- a/AcessNative/acesskernel_src/include/threads_int.h +++ b/AcessNative/acesskernel_src/include/threads_int.h @@ -50,7 +50,7 @@ struct sThread tProcess *Process; - Uint32 Events, WaitMask; + Uint32 EventState, WaitMask; void *EventSem; // Should be SDL_sem, but I don't want SDL in this header // Message queue diff --git a/AcessNative/acesskernel_src/nativefs.c b/AcessNative/acesskernel_src/nativefs.c index 0e791b8f..cca9e7d8 100644 --- a/AcessNative/acesskernel_src/nativefs.c +++ b/AcessNative/acesskernel_src/nativefs.c @@ -5,11 +5,13 @@ * nativefs.c * - Host filesystem access */ -#define DEBUG 0 +#define DEBUG 1 #define off_t _acess_off_t +#define sprintf _acess_sprintf #include // Acess #include // Acess #undef off_t +#undef sprintf #include // Posix #include // Posix #include // Posix @@ -203,8 +205,9 @@ size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void * LEAVE('i', 0); return 0; } - LEAVE('-'); - return fread( Buffer, 1, Length, (FILE *)(tVAddr)Node->Inode ); + size_t ret = fread( Buffer, 1, Length, (FILE *)(tVAddr)Node->Inode ); + LEAVE('x', ret); + return ret; } size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer) diff --git a/AcessNative/acesskernel_src/syscalls.c b/AcessNative/acesskernel_src/syscalls.c index d14a1d9f..44588463 100644 --- a/AcessNative/acesskernel_src/syscalls.c +++ b/AcessNative/acesskernel_src/syscalls.c @@ -4,7 +4,7 @@ * * Syscall Distribution */ -#define DEBUG 0 +#define DEBUG 1 #include #include #include @@ -30,7 +30,7 @@ typedef int (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int a3 = *(_t3*)Args;Args+=sizeof(_t3);\ a4 = *(_t4*)Args;Args+=sizeof(_t4);\ a5 = *(_t5*)Args;Args+=sizeof(_t5);\ - LOG("SYSCALL5 '%s' %p %p %p %p %p %p", Fmt, (intptr_t)a0,(intptr_t)a1,(intptr_t)a2,(intptr_t)a3,(intptr_t)a4,(intptr_t)a5);\ + LOG("SYSCALL6 '%s' %p %p %p %p %p %p", Fmt, (intptr_t)a0,(intptr_t)a1,(intptr_t)a2,(intptr_t)a3,(intptr_t)a4,(intptr_t)a5);\ _call\ } #define SYSCALL5(_name, _fmtstr, _t0, _t1, _t2, _t3, _t4, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\ @@ -89,7 +89,7 @@ typedef int (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int } // === CODE === -int Syscall_Null(Uint*Errno, const char *Format, void *Args, int *Sizes) +int Syscall_Null(Uint *Errno, const char *Format, void *Args, int *Sizes) { return 0; } @@ -100,7 +100,9 @@ SYSCALL1(Syscall_Exit, "i", int, ); SYSCALL2(Syscall_Open, "si", const char *, int, - return VFS_Open(a0, a1|VFS_OPENFLAG_USER); + int rv = VFS_Open(a0, a1|VFS_OPENFLAG_USER); + if(rv == -1) *Errno = errno; + return rv; ); SYSCALL1(Syscall_Close, "i", int, VFS_Close(a0); @@ -111,12 +113,18 @@ SYSCALL3(Syscall_Read, "iid", int, int, void *, Log_Warning("Syscalls", "Read - %i < %i", Sizes[2], a1); return -1; } - return VFS_Read(a0, a1, a2); + size_t rv = VFS_Read(a0, a1, a2); + if(rv == -1) *Errno = errno; + return rv; ); SYSCALL3(Syscall_Write, "iid", int, int, const void *, - if( Sizes[2] < a1 ) + if( Sizes[2] < a1 ) { + *Errno = EINVAL; return -1; - return VFS_Write(a0, a1, a2); + } + size_t rv = VFS_Write(a0, a1, a2); + if(rv == -1) *Errno = errno; + return rv; ); SYSCALL3(Syscall_Seek, "iIi", int, int64_t, int, return VFS_Seek(a0, a1, a2); @@ -129,7 +137,7 @@ SYSCALL3(Syscall_IOCtl, "iid", int, int, void *, ); SYSCALL3(Syscall_FInfo, "idi", int, void *, int, if( Sizes[1] < sizeof(tFInfo)+a2*sizeof(tVFS_ACL)) { - LOG("offsetof(size) = %i", offsetof(tFInfo, size)); + //LOG("offsetof(size) = %i", offsetof(tFInfo, size)); LOG("Bad size %i < %i", Sizes[1], sizeof(tFInfo)+a2*sizeof(tVFS_ACL)); *Errno = -EINVAL; return -1; @@ -273,12 +281,15 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) int argListLen = 0; int i, retVal; tRequestHeader *ret; - int retValueCount = 1; - int retDataLen = sizeof(Uint64); + int retValueCount; + int retDataLen; void *returnData[Request->NParams]; int argSizes[Request->NParams]; Uint ret_errno = 0; + // Clear errno (Acess verson) at the start of the request + errno = 0; + // Sanity check if( Request->CallID >= ciNumSyscalls ) { Log_Notice("Syscalls", "Unknown syscall number %i", Request->CallID); @@ -289,7 +300,11 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) Log_Notice("Syscalls", "Unimplemented syscall %i", Request->CallID); return NULL; } - + + // Init return count/size + retValueCount = 2; + retDataLen = sizeof(Uint64) + sizeof(Uint32); + // Get size of argument list for( i = 0; i < Request->NParams; i ++ ) { @@ -310,12 +325,19 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) case ARG_TYPE_DATA: formatString[i] = 'd'; argListLen += sizeof(void*); + // Prepare the return values + if( Request->Params[i].Flags & ARG_FLAG_RETURN ) + { + retDataLen += Request->Params[i].Length; + retValueCount ++; + } break; case ARG_TYPE_STRING: formatString[i] = 's'; argListLen += sizeof(char*); break; default: + Log_Error("Syscalls", "Unknown param type %i", Request->Params[i].Type); return NULL; // ERROR! } } @@ -356,13 +378,6 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) // Data gets special handling, because only it can be returned to the user // (ARG_TYPE_DATA is a pointer) case ARG_TYPE_DATA: - // Prepare the return values - if( Request->Params[i].Flags & ARG_FLAG_RETURN ) - { - retDataLen += Request->Params[i].Length; - retValueCount ++; - } - // Check for non-resident data if( Request->Params[i].Length == 0 ) { @@ -392,9 +407,17 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) } } + // --- Perform request retVal = caSyscalls[Request->CallID](&ret_errno, formatString, argListData, argSizes); } + // ---------- Return + + if( ret_errno == 0 && errno != 0 ) { + ret_errno = errno; + LOG("errno = %i", errno); + } + // Allocate the return size_t msglen = sizeof(tRequestHeader) + retValueCount * sizeof(tRequestValue) + retDataLen; ret = malloc(msglen); @@ -411,9 +434,18 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) *(Uint64*)inData = retVal; inData += sizeof(Uint64); + // Static Uint32 errno value + ret->Params[1].Type = ARG_TYPE_INT32; + ret->Params[1].Flags = 0; + ret->Params[1].Length = sizeof(Uint32); + *(Uint32*)inData = ret_errno; + inData += sizeof(Uint32); + + LOG("Ret: %llx, errno=%i", retVal, ret_errno); + //Log_Debug("Syscalls", "Return 0x%llx", retVal); - retValueCount = 1; + retValueCount = 2; for( i = 0; i < Request->NParams; i ++ ) { if( Request->Params[i].Type != ARG_TYPE_DATA ) continue; @@ -434,9 +466,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) retValueCount ++; } - *ReturnLength = sizeof(tRequestHeader) - + retValueCount * sizeof(tRequestValue) - + retDataLen; + *ReturnLength = ret->MessageLength; return ret; } diff --git a/AcessNative/acesskernel_src/threads.c b/AcessNative/acesskernel_src/threads.c index 661d584b..7296a58e 100644 --- a/AcessNative/acesskernel_src/threads.c +++ b/AcessNative/acesskernel_src/threads.c @@ -339,7 +339,7 @@ Uint32 Threads_WaitEvents(Uint32 Mask) //Log_Debug("Threads", "Mask = %x, ->Events = %x", Mask, gpCurrentThread->Events); gpCurrentThread->WaitMask = Mask; - if( !(gpCurrentThread->Events & Mask) ) + if( !(gpCurrentThread->EventState & Mask) ) { if( Threads_Glue_SemWait(gpCurrentThread->EventSem, INT_MAX) == -1 ) { Log_Warning("Threads", "Wait on eventsem of %p, %p failed", @@ -347,8 +347,8 @@ Uint32 Threads_WaitEvents(Uint32 Mask) } //Log_Debug("Threads", "Woken from nap (%i here)", SDL_SemValue(gpCurrentThread->EventSem)); } - rv = gpCurrentThread->Events & Mask; - gpCurrentThread->Events &= ~Mask; + rv = gpCurrentThread->EventState & Mask; + gpCurrentThread->EventState &= ~Mask; gpCurrentThread->WaitMask = -1; //Log_Debug("Threads", "- rv = %x", rv); @@ -358,7 +358,7 @@ Uint32 Threads_WaitEvents(Uint32 Mask) void Threads_PostEvent(tThread *Thread, Uint32 Events) { - Thread->Events |= Events; + Thread->EventState |= Events; // Log_Debug("Threads", "Trigger event %x (->Events = %p) on %p", Events, Thread->Events, Thread); if( Events == 0 || Thread->WaitMask & Events ) { @@ -369,6 +369,6 @@ void Threads_PostEvent(tThread *Thread, Uint32 Events) void Threads_ClearEvent(Uint32 EventMask) { - gpCurrentThread->Events &= ~EventMask; + gpCurrentThread->EventState &= ~EventMask; } diff --git a/AcessNative/acesskernel_src/video.c b/AcessNative/acesskernel_src/video.c index da18f482..3cce4848 100644 --- a/AcessNative/acesskernel_src/video.c +++ b/AcessNative/acesskernel_src/video.c @@ -14,8 +14,8 @@ // === PROTOTYPES === int Video_Install(char **Arguments); -Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); -Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer); +size_t Video_Read(tVFS_Node *Node, Uint64 Offset, size_t Length, void *Buffer); +size_t Video_Write(tVFS_Node *Node, Uint64 Offset, size_t Length, const void *Buffer); int Video_IOCtl(tVFS_Node *Node, int ID, void *Data); // --- 2D Acceleration Functions -- void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour); @@ -55,7 +55,7 @@ int Video_Install(char **Arguments) /** * \brief Read from framebuffer (unimplemented) */ -Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +size_t Video_Read(tVFS_Node *Node, Uint64 Offset, size_t Length, void *Buffer) { return 0; } @@ -63,7 +63,7 @@ Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) /** * \brief Write to the framebuffer */ -Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer) +size_t Video_Write(tVFS_Node *Node, Uint64 Offset, size_t Length, const void *Buffer) { int i; ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); diff --git a/AcessNative/ld-acess_src/Makefile b/AcessNative/ld-acess_src/Makefile index bbaef1de..78e07856 100644 --- a/AcessNative/ld-acess_src/Makefile +++ b/AcessNative/ld-acess_src/Makefile @@ -11,7 +11,8 @@ OBJ := $(addprefix obj-$(PLATFORM)/,$(OBJ)) ifeq ($(PLATFORM),win) BIN := ../ld-acess.exe - LDFLAGS += -lws2_32 + LINKADDR := 0x70000000 + LDFLAGS += -lws2_32 -Wl,--image-base,$(LINKADDR) endif ifeq ($(PLATFORM),lin) BIN := ../ld-acess diff --git a/AcessNative/ld-acess_src/binary.c b/AcessNative/ld-acess_src/binary.c index d04ac6d2..59be8295 100644 --- a/AcessNative/ld-acess_src/binary.c +++ b/AcessNative/ld-acess_src/binary.c @@ -65,9 +65,9 @@ char *Binary_LocateLibrary(const char *Name) strcat(tmp, "/"); strcat(tmp, Name); - fd = acess_open(tmp, 4); // OPENFLAG_EXEC + fd = acess__SysOpen(tmp, 4); // OPENFLAG_EXEC if(fd != -1) { - acess_close(fd); + acess__SysClose(fd); return strdup(tmp); } } @@ -84,9 +84,9 @@ char *Binary_LocateLibrary(const char *Name) printf("Binary_LocateLibrary: tmp = '%s'\n", tmp); #endif - fd = acess_open(tmp, 4); // OPENFLAG_EXEC + fd = acess__SysOpen(tmp, 4); // OPENFLAG_EXEC if(fd != -1) { - acess_close(fd); + acess__SysClose(fd); return strdup(tmp); } } @@ -156,22 +156,22 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint) } } - fd = acess_open(Filename, 2|1); // Execute and Read + fd = acess__SysOpen(Filename, 2|1); // Execute and Read if( fd == -1 ) { // TODO: Handle libary directories perror("Opening binary"); return NULL; } - acess_read(fd, &dword, 4); - acess_seek(fd, 0, ACESS_SEEK_SET); + acess__SysRead(fd, &dword, 4); + acess__SysSeek(fd, 0, ACESS_SEEK_SET); if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) { fmt = &gElf_FormatDef; } else { fprintf(stderr, "Unknown executable format (0x%08x)\n", dword); - acess_close(fd); + acess__SysClose(fd); return NULL; } @@ -179,7 +179,7 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint) printf("fmt->Load(0x%x)...\n", fd); #endif ret = fmt->Load(fd); - acess_close(fd); + acess__SysClose(fd); #if DEBUG printf("fmt->Load(0x%x): %p\n", fd, ret); #endif diff --git a/AcessNative/ld-acess_src/common.h b/AcessNative/ld-acess_src/common.h index 63db8612..9f67e9c6 100644 --- a/AcessNative/ld-acess_src/common.h +++ b/AcessNative/ld-acess_src/common.h @@ -31,11 +31,12 @@ static inline void AddLoaded(const char *Path, void *Base) Binary_SetReadyToUse(Base); } -static inline int SysSetMemFlags(uintptr_t Addr, unsigned int flags, unsigned int mask) +static inline int _SysSetMemFlags(uintptr_t Addr, unsigned int flags, unsigned int mask) { return 0; } + extern int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount); extern uintptr_t FindFreeRange(size_t ByteCount, int MaxBits); diff --git a/AcessNative/ld-acess_src/elf_load.c b/AcessNative/ld-acess_src/elf_load.c index d661622e..19a8c13f 100644 --- a/AcessNative/ld-acess_src/elf_load.c +++ b/AcessNative/ld-acess_src/elf_load.c @@ -42,7 +42,7 @@ void *Elf_Load(int FD) Elf64_Ehdr hdr; // Read ELF Header - acess_read(FD, &hdr, sizeof(hdr)); + acess__SysRead(FD, &hdr, sizeof(hdr)); // Check the file type if(hdr.e_ident[0] != 0x7F || hdr.e_ident[1] != 'E' || hdr.e_ident[2] != 'L' || hdr.e_ident[3] != 'F') { @@ -89,8 +89,8 @@ void *Elf32Load(int FD, Elf32_Ehdr *hdr) return NULL; } LOG("hdr.phoff = 0x%08x\n", hdr->phoff); - acess_seek(FD, hdr->phoff, ACESS_SEEK_SET); - acess_read(FD, phtab, sizeof(Elf32_Phdr) * hdr->phentcount); + acess__SysSeek(FD, hdr->phoff, ACESS_SEEK_SET); + acess__SysRead(FD, phtab, sizeof(Elf32_Phdr) * hdr->phentcount); // Count Pages iPageCount = 0; @@ -146,8 +146,8 @@ void *Elf32Load(int FD, Elf32_Ehdr *hdr) char *tmp; //if(ret->Interpreter) continue; tmp = malloc(phtab[i].FileSize); - acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET); - acess_read(FD, tmp, phtab[i].FileSize); + acess__SysSeek(FD, phtab[i].Offset, ACESS_SEEK_SET); + acess__SysRead(FD, tmp, phtab[i].FileSize); //ret->Interpreter = Binary_RegInterp(tmp); LOG("Interpreter '%s'\n", tmp); free(tmp); @@ -168,8 +168,8 @@ void *Elf32Load(int FD, Elf32_Ehdr *hdr) return NULL; } - acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET); - acess_read(FD, PTRMK(void, addr), phtab[i].FileSize); + acess__SysSeek(FD, phtab[i].Offset, ACESS_SEEK_SET); + acess__SysRead(FD, PTRMK(void, addr), phtab[i].FileSize); memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize ); } @@ -211,8 +211,8 @@ void *Elf64Load(int FD, Elf64_Ehdr *hdr) return NULL; } LOG("hdr.phoff = 0x%08llx\n", (long long)hdr->e_phoff); - acess_seek(FD, hdr->e_phoff, ACESS_SEEK_SET); - acess_read(FD, phtab, sizeof(Elf64_Phdr) * hdr->e_phnum); + acess__SysSeek(FD, hdr->e_phoff, ACESS_SEEK_SET); + acess__SysRead(FD, phtab, sizeof(Elf64_Phdr) * hdr->e_phnum); // Count Pages iPageCount = 0; @@ -270,8 +270,8 @@ void *Elf64Load(int FD, Elf64_Ehdr *hdr) //if(ret->Interpreter) continue; tmp = malloc(phtab[i].p_filesz+1); tmp[ phtab[i].p_filesz ] = 0; - acess_seek(FD, phtab[i].p_offset, ACESS_SEEK_SET); - acess_read(FD, tmp, phtab[i].p_filesz); + acess__SysSeek(FD, phtab[i].p_offset, ACESS_SEEK_SET); + acess__SysRead(FD, tmp, phtab[i].p_filesz); //ret->Interpreter = Binary_RegInterp(tmp); LOG("Interpreter '%s'\n", tmp); free(tmp); @@ -295,8 +295,8 @@ void *Elf64Load(int FD, Elf64_Ehdr *hdr) return NULL; } - acess_seek(FD, phtab[i].p_offset, ACESS_SEEK_SET); - acess_read(FD, PTRMK(void, addr), phtab[i].p_filesz); + acess__SysSeek(FD, phtab[i].p_offset, ACESS_SEEK_SET); + acess__SysRead(FD, PTRMK(void, addr), phtab[i].p_filesz); memset( PTRMK(char, addr) + phtab[i].p_filesz, 0, phtab[i].p_memsz - phtab[i].p_filesz ); } diff --git a/AcessNative/ld-acess_src/exports.c b/AcessNative/ld-acess_src/exports.c index 07662a5b..dcfc526a 100644 --- a/AcessNative/ld-acess_src/exports.c +++ b/AcessNative/ld-acess_src/exports.c @@ -11,7 +11,8 @@ #include #include -#define DEBUG(v...) do{}while(0)//Debug(v) +#define DEBUG(v...) Debug(v) +//#define DEBUG(v...) do{}while(0)//Debug(v) #define PAGE_SIZE 4096 typedef struct sFILE FILE; @@ -41,12 +42,12 @@ char *gsExecutablePath = "./ld-acess"; // === CODE === // --- VFS Calls -int acess_chdir(const char *Path) +int acess__SysChdir(const char *Path) { return _Syscall(SYS_CHDIR, ">s", Path); } -int acess_open(const char *Path, int Flags) +int acess__SysOpen(const char *Path, int Flags) { if( strncmp(Path, "$$$$", 4) == 0 ) { @@ -56,7 +57,8 @@ int acess_open(const char *Path, int Flags) return _Syscall(SYS_OPEN, ">s >i", Path, Flags); } -void acess_close(int FD) { +void acess__SysClose(int FD) +{ if(FD & NATIVE_FILE_MASK) { return native_close(FD & (NATIVE_FILE_MASK-1)); } @@ -64,12 +66,12 @@ void acess_close(int FD) { _Syscall(SYS_CLOSE, ">i", FD); } -int acess_reopen(int FD, const char *Path, int Flags) { +int acess__SysReopen(int FD, const char *Path, int Flags) { DEBUG("reopen(0x%x, \"%s\", 0x%x)", FD, Path, Flags); return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags); } -size_t acess_read(int FD, void *Dest, size_t Bytes) { +size_t acess__SysRead(int FD, void *Dest, size_t Bytes) { if(FD & NATIVE_FILE_MASK) return native_read(FD & (NATIVE_FILE_MASK-1), Dest, Bytes); // if( FD > 2 ) @@ -77,7 +79,7 @@ size_t acess_read(int FD, void *Dest, size_t Bytes) { return _Syscall(SYS_READ, ">i >i 2 ) @@ -85,7 +87,8 @@ size_t acess_write(int FD, const void *Src, size_t Bytes) { return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src); } -int acess_seek(int FD, int64_t Ofs, int Dir) { +int acess__SysSeek(int FD, int64_t Ofs, int Dir) +{ if(FD & NATIVE_FILE_MASK) { return native_seek(FD & (NATIVE_FILE_MASK-1), Ofs, Dir); } @@ -93,14 +96,15 @@ int acess_seek(int FD, int64_t Ofs, int Dir) { return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir); } -uint64_t acess_tell(int FD) { +uint64_t acess__SysTell(int FD) +{ if(FD & NATIVE_FILE_MASK) return native_tell( FD & (NATIVE_FILE_MASK-1) ); DEBUG("tell(0x%x)", FD); return _Syscall(SYS_TELL, ">i", FD); } -int acess_ioctl(int fd, int id, void *data) { +int acess__SysIOCtl(int fd, int id, void *data) { int len; DEBUG("ioctl(%i, %i, %p)", fd, id, data); // NOTE: The length here is hacky and could break @@ -110,7 +114,7 @@ int acess_ioctl(int fd, int id, void *data) { len = PAGE_SIZE - ((uintptr_t)data % PAGE_SIZE); return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, len, data); } -int acess_finfo(int fd, t_sysFInfo *info, int maxacls) { +int acess__SysFInfo(int fd, t_sysFInfo *info, int maxacls) { // DEBUG("offsetof(size, t_sysFInfo) = %i", offsetof(t_sysFInfo, size)); DEBUG("finfo(%i, %p, %i)", fd, info, maxacls); return _Syscall(SYS_FINFO, ">i i", @@ -120,12 +124,12 @@ int acess_finfo(int fd, t_sysFInfo *info, int maxacls) { ); } -int acess_SysReadDir(int fd, char *dest) { +int acess__SysReadDir(int fd, char *dest) { DEBUG("SysReadDir(%i, %p)", fd, dest); return _Syscall(SYS_READDIR, ">i i ?d ?d ?d >d >i", nfds, @@ -137,12 +141,6 @@ int acess__SysSelect(int nfds, fd_set *read, fd_set *write, fd_set *error, time_ ); } -int acess_select(int nfds, fd_set *read, fd_set *write, fd_set *error, time_t *timeout) -{ - return acess__SysSelect(nfds, read, write, error, timeout, 0); -} - - int acess__SysOpenChild(int fd, char *name, int flags) { DEBUG("_SysOpenChild(0x%x, '%s', 0x%x)", fd, name, flags); return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags); @@ -166,7 +164,7 @@ int acess__SysSetFaultHandler(int (*Handler)(int)) { } // --- Memory Management --- -uint64_t acess__SysAllocate(uint vaddr) +uint64_t acess__SysAllocate(uintptr_t vaddr) { if( AllocateMemory(vaddr, 0x1000) == -1 ) // Allocate a page return 0; @@ -175,7 +173,7 @@ uint64_t acess__SysAllocate(uint vaddr) } // --- Process Management --- -int acess_clone(int flags, void *stack) +int acess__SysClone(int flags, void *stack) { #ifdef __WIN32__ Warning("Win32 does not support anything like fork(2), cannot emulate"); @@ -211,7 +209,7 @@ int acess_clone(int flags, void *stack) #endif } -int acess_execve(char *path, char **argv, const char **envp) +int acess__SysExecVE(char *path, char **argv, const char **envp) { int i, argc; @@ -288,13 +286,13 @@ int acess__SysSpawn(const char *binary, const char **argv, const char **envp, in return kernel_tid; } -void acess_sleep(void) -{ - DEBUG("%s()", __func__); - _Syscall(SYS_SLEEP, ""); -} +//void acess_sleep(void) +//{ +// DEBUG("%s()", __func__); +// _Syscall(SYS_SLEEP, ""); +//} -int acess_waittid(int TID, int *ExitStatus) +int acess__SysWaitTID(int TID, int *ExitStatus) { DEBUG("%s(%i, %p)", __func__, TID, ExitStatus); return _Syscall(SYS_WAITTID, ">i i >d", DestTID, Length, Data); } -int acess_SysGetMessage(int *SourceTID, int BufLen, void *Data) +int acess__SysGetMessage(int *SourceTID, int BufLen, void *Data) { DEBUG("%s(%p, %p)", __func__, SourceTID, Data); return _Syscall(SYS_GETMSG, "= 0x1000 ); + tmp = VirtualAlloc((void*)base, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); if( tmp == NULL ) { - printf("ERROR: Unable to allocate memory (0x%x)\n", (int)GetLastError()); + printf("ERROR: Unable to allocate memory %p+%x (0x%x)\n", + (void*)base, size, + (int)GetLastError()); return -1; } #else diff --git a/AcessNative/ld-acess_src/request.c b/AcessNative/ld-acess_src/request.c index 5bcf8cd3..2fa481a7 100644 --- a/AcessNative/ld-acess_src/request.c +++ b/AcessNative/ld-acess_src/request.c @@ -1,6 +1,6 @@ /* */ -#define DEBUG 0 +#define DEBUG 1 #if DEBUG @@ -51,6 +51,7 @@ void Request_Preinit(void) memset((void *)&gSyscall_ServerAddr, '\0', sizeof(struct sockaddr_in)); gSyscall_ServerAddr.sin_family = AF_INET; gSyscall_ServerAddr.sin_port = htons(SERVER_PORT); + gSyscall_ServerAddr.sin_addr.s_addr = htonl(0x7F000001); } int _InitSyscalls(void) @@ -80,20 +81,13 @@ int _InitSyscalls(void) exit(0); } - #if 0 - // Set client address - memset((void *)&client, '\0', sizeof(struct sockaddr_in)); - client.sin_family = AF_INET; - client.sin_port = htons(0); - client.sin_addr.s_addr = htonl(0x7F000001); - #endif - #if USE_TCP if( connect(gSocket, (struct sockaddr *)&gSyscall_ServerAddr, sizeof(struct sockaddr_in)) < 0 ) { fprintf(stderr, "[ERROR -] Cannot connect to server (localhost:%i)\n", SERVER_PORT); perror("_InitSyscalls"); #if __WIN32__ + fprintf(stderr, "[ERROR -] - WSAGetLastError said %i", WSAGetLastError()); closesocket(gSocket); WSACleanup(); #else @@ -104,6 +98,11 @@ int _InitSyscalls(void) #endif #if 0 + // Set client address + memset((void *)&client, '\0', sizeof(struct sockaddr_in)); + client.sin_family = AF_INET; + client.sin_port = htons(0); + client.sin_addr.s_addr = htonl(0x7F000001); // Bind if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 ) { @@ -309,7 +308,11 @@ int ReadData(void *Dest, int MaxLength, int Timeout) } if( ret == 0 ) { fprintf(stderr, "[ERROR %i] Connection closed.\n", giSyscall_ClientID); + #if __WIN32__ + closesocket(gSocket); + #else close(gSocket); + #endif exit(0); } diff --git a/AcessNative/ld-acess_src/syscalls.c b/AcessNative/ld-acess_src/syscalls.c index 26f6c44c..c649f28f 100644 --- a/AcessNative/ld-acess_src/syscalls.c +++ b/AcessNative/ld-acess_src/syscalls.c @@ -9,7 +9,9 @@ #include #include #include -#include // posix_spawn +#ifndef __WIN32__ +# include // posix_spawn +#endif #include "request.h" #if SYSCALL_TRACE @@ -18,6 +20,13 @@ #define DEBUG(...) do{}while(0) #endif +#define assert(cnd) do{ \ + if( !(cnd) ) { \ + fprintf(stderr, "%s:%i - assert failed - " #cnd, __FILE__, __LINE__);\ + exit(-1); \ + } \ +}while(0) + #define MAX_FPS 16 // === Types === @@ -161,7 +170,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) { va_list args; int paramCount, dataLength; - int retCount = 1, retLength = sizeof(uint64_t); + int retCount = 2, retLength = sizeof(uint64_t) + sizeof(uint32_t); void **retPtrs; // Pointers to return buffers const char *str; tRequestHeader *req; @@ -234,38 +243,33 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) } va_end(args); - // Send syscall request + // --- Send syscall request if( SendRequest(req, dataLength, retLength) < 0 ) { fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID); exit(127); } - // Parse return value - dataPtr = &req->Params[req->NParams]; - retValue = 0; - if( req->NParams >= 1 ) - { - switch(req->Params[0].Type) - { - case ARG_TYPE_INT64: - retValue = *(uint64_t*)dataPtr; - dataPtr += req->Params[0].Length; - break; - case ARG_TYPE_INT32: - retValue = *(uint32_t*)dataPtr; - dataPtr += req->Params[0].Length; - break; - } - } + Debug("req->NParams = %i", req->NParams); + assert(req->NParams >= 2); + // return + assert(req->Params[0].Type == ARG_TYPE_INT64); + assert(req->Params[0].Length == sizeof(uint64_t)); + retValue = *(uint64_t*)dataPtr; + dataPtr += sizeof(uint64_t); + // errno + assert(req->Params[1].Type == ARG_TYPE_INT32); + assert(req->Params[1].Length == sizeof(uint32_t)); + acess__errno = *(uint32_t*)dataPtr; + dataPtr += sizeof(uint32_t); // Write changes to buffers - if( req->NParams - 1 != retCount ) { + if( req->NParams - 2 != retCount ) { fprintf(stderr, "syscalls.c: Return count inbalance (%i - 1 != exp %i) [Call %i]\n", req->NParams, retCount, SyscallID); exit(127); } retCount = 0; - for( i = 1; i < req->NParams; i ++ ) + for( i = 2; i < req->NParams; i ++ ) { #if 0 int j; @@ -274,6 +278,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) printf(" %02x", ((uint8_t*)dataPtr)[j]); printf("\n"); #endif + assert( req->Params[i].Type == ARG_TYPE_DATA ); memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length ); dataPtr += req->Params[i].Length; } @@ -341,7 +346,11 @@ int native_spawn(const char *filename, const char *const argv[], const char *con { int rv; + #if __WIN32__ + rv = _spawnve(_P_NOWAIT, filename, argv, envp); + #else rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp); + #endif return rv; } diff --git a/AcessNative/syscalls.h b/AcessNative/syscalls.h index 21a9cb53..b9661bcf 100644 --- a/AcessNative/syscalls.h +++ b/AcessNative/syscalls.h @@ -35,84 +35,20 @@ typedef struct sRequestHeader { tRequestValue Params[]; } tRequestHeader; -enum eSyscalls { - SYS_NULL, - - SYS_EXIT, - - SYS_OPEN, - SYS_CLOSE, - SYS_READ, - SYS_WRITE, - SYS_SEEK, - SYS_TELL, - SYS_IOCTL, - SYS_FINFO, - SYS_READDIR, - SYS_OPENCHILD, - SYS_GETACL, - SYS_MOUNT, - SYS_REOPEN, - SYS_CHDIR, - - SYS_WAITTID, - SYS_SETUID, - SYS_SETGID, - - SYS_GETTID, - SYS_GETPID, - SYS_GETUID, - SYS_GETGID, - // IPC - SYS_SLEEP, - SYS_AN_FORK, - SYS_AN_SPAWN, - SYS_SENDMSG, - SYS_GETMSG, - SYS_SELECT, - SYS_WAITEVENT, - +enum eSyscalls { + #define _(n) n + #include "syscalls_list.h" + #undef _ N_SYSCALLS }; #ifndef DONT_INCLUDE_SYSCALL_NAMES static const char * casSYSCALL_NAMES[] = { - "SYS_NULL", - - "SYS_EXIT", - - "SYS_OPEN", - "SYS_CLOSE", - "SYS_READ", - "SYS_WRITE", - "SYS_SEEK", - "SYS_TELL", - "SYS_IOCTL", - "SYS_FINFO", - "SYS_READDIR", - "SYS_OPENCHILD", - "SYS_GETACL", - "SYS_MOUNT", - "SYS_REOPEN", - "SYS_CHDIR", - - "SYS_WAITTID", - "SYS_SETUID", - "SYS_SETGID", - - "SYS_GETTID", - "SYS_GETPID", - "SYS_GETUID", - "SYS_GETGID", - - // IPC - "SYS_SLEEP", - "SYS_AN_FORK", - "SYS_SENDMSG", - "SYS_GETMSG", - "SYS_SELECT", - "SYS_WAITEVENT" + #define _(n) #n + #include "syscalls_list.h" + #undef _ + "-" }; #endif diff --git a/AcessNative/syscalls_list.h b/AcessNative/syscalls_list.h new file mode 100644 index 00000000..9ab9098c --- /dev/null +++ b/AcessNative/syscalls_list.h @@ -0,0 +1,37 @@ +_(SYS_NULL), + +_(SYS_EXIT), + +_(SYS_OPEN), +_(SYS_CLOSE), +_(SYS_READ), +_(SYS_WRITE), +_(SYS_SEEK), +_(SYS_TELL), +_(SYS_IOCTL), +_(SYS_FINFO), +_(SYS_READDIR), +_(SYS_OPENCHILD), +_(SYS_GETACL), +_(SYS_MOUNT), +_(SYS_REOPEN), +_(SYS_CHDIR), + +_(SYS_WAITTID), +_(SYS_SETUID), +_(SYS_SETGID), + +_(SYS_GETTID), +_(SYS_GETPID), +_(SYS_GETUID), +_(SYS_GETGID), + +// IPC +_(SYS_SLEEP), +_(SYS_AN_FORK), +_(SYS_AN_SPAWN), +_(SYS_SENDMSG), +_(SYS_GETMSG), +_(SYS_SELECT), +_(SYS_WAITEVENT), + diff --git a/KernelLand/Kernel/arch/x86/acpica.c b/KernelLand/Kernel/arch/x86/acpica.c index 43a18549..57d7fe85 100644 --- a/KernelLand/Kernel/arch/x86/acpica.c +++ b/KernelLand/Kernel/arch/x86/acpica.c @@ -5,7 +5,7 @@ * acpica.c * - ACPICA Interface */ -#define ACPI_DEBUG_OUTPUT 1 +#define ACPI_DEBUG_OUTPUT 0 #define DEBUG 0 #define _AcpiModuleName "Shim" #define _COMPONENT "Acess" diff --git a/KernelLand/Kernel/arch/x86/vm8086.c b/KernelLand/Kernel/arch/x86/vm8086.c index 397ec14f..77b0d1a7 100644 --- a/KernelLand/Kernel/arch/x86/vm8086.c +++ b/KernelLand/Kernel/arch/x86/vm8086.c @@ -77,7 +77,7 @@ int VM8086_Install(char **Arguments) // Create BIOS Call process pid = Proc_Clone(CLONE_VM); - Log_Debug("VM8086", "pid = %i", pid); + //Log_Debug("VM8086", "pid = %i", pid); if(pid == -1) { Log_Error("VM8086", "Unable to clone kernel into VM8086 worker"); @@ -89,7 +89,7 @@ int VM8086_Install(char **Arguments) Uint16 * volatile rmstack; // Real Mode Stack int i; - Log_Debug("VM8086", "Initialising worker"); + //Log_Debug("VM8086", "Initialising worker"); // Set Image Name Threads_SetName("VM8086"); diff --git a/KernelLand/Kernel/arch/x86_64/pci.c b/KernelLand/Kernel/arch/x86_64/pci.c deleted file mode 120000 index cac29a8f..00000000 --- a/KernelLand/Kernel/arch/x86_64/pci.c +++ /dev/null @@ -1 +0,0 @@ -../x86/pci.c \ No newline at end of file diff --git a/KernelLand/Kernel/arch/x86_64/pci.c b/KernelLand/Kernel/arch/x86_64/pci.c new file mode 100644 index 00000000..a85e06c3 --- /dev/null +++ b/KernelLand/Kernel/arch/x86_64/pci.c @@ -0,0 +1 @@ +#include "../x86/pci.c" diff --git a/KernelLand/Kernel/debug.c b/KernelLand/Kernel/debug.c index cb11f5f5..1cea00cf 100644 --- a/KernelLand/Kernel/debug.c +++ b/KernelLand/Kernel/debug.c @@ -150,7 +150,7 @@ void Debug(const char *Fmt, ...) va_list args; #if LOCK_DEBUG_OUTPUT - SHORTLOCK(&glDebug_Lock); + if(!CPU_HAS_LOCK(&glDebug_Lock)) SHORTLOCK(&glDebug_Lock); #endif Debug_Puts(0, "Debug: "); @@ -228,7 +228,8 @@ void Panic(const char *Fmt, ...) va_list args; #if LOCK_DEBUG_OUTPUT - SHORTLOCK(&glDebug_Lock); + if( !CPU_HAS_LOCK(&glDebug_Lock) ) + SHORTLOCK(&glDebug_Lock); #endif // And never SHORTREL diff --git a/KernelLand/Kernel/drv/fifo.c b/KernelLand/Kernel/drv/fifo.c index 2adaec7c..1e6fcdb7 100644 --- a/KernelLand/Kernel/drv/fifo.c +++ b/KernelLand/Kernel/drv/fifo.c @@ -1,5 +1,9 @@ -/* AcessOS - * FIFO Pipe Driver +/* + * Acess2 Kernel + * - By John Hodge (thePowersGang) + * + * drv/fifo.c + * - FIFO Pipe Driver */ #define DEBUG 0 #include @@ -126,9 +130,8 @@ tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename) if(Filename[0] == '\0') return NULL; // Anon Pipe - if(Filename[0] == 'a' && Filename[1] == 'n' - && Filename[2] == 'o' && Filename[3] == 'n' - && Filename[4] == '\0') { + if( strcmp(Filename, "anon") == 0 ) + { tmp = FIFO_Int_NewPipe(DEFAULT_RING_SIZE, "anon"); return &tmp->Node; } @@ -277,6 +280,7 @@ size_t FIFO_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) // Mark some flags if( pipe->ReadPos == pipe->WritePos ) { + LOG("%i == %i, marking none to read", pipe->ReadPos, pipe->WritePos); VFS_MarkAvaliable(Node, 0); } VFS_MarkFull(Node, 0); // Buffer can't still be full @@ -312,9 +316,12 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff while(remaining) { // Wait for buffer to empty - if(pipe->Flags & PF_BLOCKING) { - if( pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize ) + if(pipe->Flags & PF_BLOCKING) + { + if( pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize ) { + LOG("Blocking write on FIFO"); VFS_SelectNode(Node, VFS_SELECT_WRITE, NULL, "FIFO_Write"); + } len = remaining; if( pipe->ReadPos > pipe->WritePos ) @@ -346,11 +353,14 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff if(len > pipe->BufSize - pipe->WritePos) { int ofs = pipe->BufSize - pipe->WritePos; + LOG("pipe->Buffer = %p, pipe->WritePos = %i, ofs=%i, len=%i", + pipe->Buffer, pipe->WritePos, ofs, len); memcpy(&pipe->Buffer[pipe->WritePos], Buffer, ofs); - memcpy(&pipe->Buffer, (Uint8*)Buffer + ofs, len-ofs); + memcpy(&pipe->Buffer[0], (Uint8*)Buffer + ofs, len-ofs); } else { + LOG("pipe->Buffer = %p, pipe->WritePos = %i", pipe->Buffer, pipe->WritePos); memcpy(&pipe->Buffer[pipe->WritePos], Buffer, len); } @@ -360,6 +370,7 @@ size_t FIFO_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff // Mark some flags if( pipe->ReadPos == pipe->WritePos ) { + LOG("Buffer is full"); VFS_MarkFull(Node, 1); // Buffer full } VFS_MarkAvaliable(Node, 1); @@ -384,11 +395,13 @@ tPipe *FIFO_Int_NewPipe(int Size, const char *Name) tPipe *ret; int namelen = strlen(Name) + 1; int allocsize = sizeof(tPipe) + sizeof(tVFS_ACL) + Size + namelen; - + + ENTER("iSize sName", Size, Name); + ret = calloc(1, allocsize); - if(!ret) return NULL; + if(!ret) LEAVE_RET('n', NULL); - // Clear Return + // Set default flags ret->Flags = PF_BLOCKING; // Allocate Buffer @@ -417,6 +430,8 @@ tPipe *FIFO_Int_NewPipe(int Size, const char *Name) = ret->Node.MTime = ret->Node.ATime = now(); ret->Node.Type = &gFIFO_PipeNodeType; + + LEAVE('p', ret); return ret; } diff --git a/KernelLand/Kernel/drv/proc.c b/KernelLand/Kernel/drv/proc.c index 9c7d909a..930616ae 100644 --- a/KernelLand/Kernel/drv/proc.c +++ b/KernelLand/Kernel/drv/proc.c @@ -150,6 +150,10 @@ int SysFS_RegisterFile(const char *Path, const char *Data, int Length) if( !child ) { child = calloc( 1, sizeof(tSysFS_Ent)+tmp+1 ); + if( !child ) { + Log_Error("SysFS", "calloc(%i) failure", sizeof(tSysFS_Ent)+tmp+1); + return -1; + } child->Next = NULL; memcpy(child->Name, &Path[start], tmp); child->Name[tmp] = '\0'; @@ -174,7 +178,8 @@ int SysFS_RegisterFile(const char *Path, const char *Data, int Length) ent->Node.Size ++; else gSysFS_DriverInfo.RootNode.Size ++; - Log_Log("SysFS", "Added directory '%s'", child->Name); + Log_Log("SysFS", "Added directory '%.*s'", tmp, &Path[start]); + Log_Log("SysFS", "Added directory '%.*s'", tmp, child->Name); } ent = child; diff --git a/KernelLand/Kernel/drv/vterm.c b/KernelLand/Kernel/drv/vterm.c index fc6dea26..3ff1a53f 100644 --- a/KernelLand/Kernel/drv/vterm.c +++ b/KernelLand/Kernel/drv/vterm.c @@ -114,11 +114,11 @@ int VT_Install(char **Arguments) if( strcmp(opt, "Video") == 0 ) { if( !gsVT_OutputDevice ) - gsVT_OutputDevice = strdup(val); + gsVT_OutputDevice = val; } else if( strcmp(opt, "Input") == 0 ) { if( !gsVT_InputDevice ) - gsVT_InputDevice = strdup(val); + gsVT_InputDevice = val; } else if( strcmp(opt, "Width") == 0 ) { giVT_RealWidth = atoi( val ); @@ -129,6 +129,9 @@ int VT_Install(char **Arguments) else if( strcmp(opt, "Scrollback") == 0 ) { giVT_Scrollback = atoi( val ); } + else { + Log_Notice("VTerm", "Unknown option '%s'", opt); + } } } @@ -448,8 +451,8 @@ size_t VT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer // - Sanity Checking size = term->Width*term->Height*4; if( Offset > size ) { - Log_Notice("VTerm", "VT_Write: Offset (0x%llx) > FBSize (0x%x)", - Offset, size); + Log_Notice("VTerm", "VT_Write: %i Offset (0x%llx) > FBSize (0x%x)", + (int)Node->Inode, Offset, size); return 0; } if( Offset + Length > size ) { diff --git a/KernelLand/Kernel/drv/vterm.h b/KernelLand/Kernel/drv/vterm.h index 55eea0e5..abd786cb 100644 --- a/KernelLand/Kernel/drv/vterm.h +++ b/KernelLand/Kernel/drv/vterm.h @@ -112,7 +112,7 @@ extern void VT_InitInput(void); extern void VT_KBCallBack(Uint32 Codepoint); // --- VT100 Emulation --- extern void VT_int_ParseEscape_StandardLarge(tVTerm *Term, char CmdChar, int argc, int *args); -extern int VT_int_ParseEscape(tVTerm *Term, const char *Buffer); +extern int VT_int_ParseEscape(tVTerm *Term, const char *Buffer, size_t Bytes); // --- Terminal Buffer --- extern void VT_int_PutString(tVTerm *Term, const Uint8 *Buffer, Uint Count); extern void VT_int_PutChar(tVTerm *Term, Uint32 Ch); diff --git a/KernelLand/Kernel/drv/vterm_termbuf.c b/KernelLand/Kernel/drv/vterm_termbuf.c index 7c296566..525f1a4b 100644 --- a/KernelLand/Kernel/drv/vterm_termbuf.c +++ b/KernelLand/Kernel/drv/vterm_termbuf.c @@ -15,24 +15,27 @@ */ void VT_int_PutString(tVTerm *Term, const Uint8 *Buffer, Uint Count) { - Uint32 val; int i; // Iterate for( i = 0; i < Count; i++ ) { // Handle escape sequences - if( Buffer[i] == 0x1B ) + if( Buffer[i] == 0x1B && Count - i > 1 ) { - i ++; - i += VT_int_ParseEscape(Term, (const char*)&Buffer[i]) - 1; - continue; + int ret = VT_int_ParseEscape(Term, (const char*)&Buffer[i+1], Count-(i+1)); + if( ret > 0 ) + { + i += ret; + continue; + } } // Fast check for non UTF-8 if( Buffer[i] < 128 ) // Plain ASCII VT_int_PutChar(Term, Buffer[i]); else { // UTF-8 + Uint32 val; i += ReadUTF8(&Buffer[i], &val) - 1; VT_int_PutChar(Term, val); } diff --git a/KernelLand/Kernel/drv/vterm_vt100.c b/KernelLand/Kernel/drv/vterm_vt100.c index fb152a30..d86ee0fb 100644 --- a/KernelLand/Kernel/drv/vterm_vt100.c +++ b/KernelLand/Kernel/drv/vterm_vt100.c @@ -211,30 +211,39 @@ void VT_int_ParseEscape_StandardLarge(tVTerm *Term, char CmdChar, int argc, int * \fn int VT_int_ParseEscape(tVTerm *Term, const char *Buffer) * \brief Parses a VT100 Escape code */ -int VT_int_ParseEscape(tVTerm *Term, const char *Buffer) +int VT_int_ParseEscape(tVTerm *Term, const char *Buffer, size_t Bytes) { char c; - int argc = 0, j = 1; + int argc = 0, j = 0; int args[6] = {0,0,0,0}; int bQuestionMark = 0; - - switch(Buffer[0]) + + if( Bytes == j ) return j; + c = Buffer[j++]; + + switch(c) { //Large Code case '[': // Get Arguments + if(Bytes == j) return j; c = Buffer[j++]; if(c == '?') { bQuestionMark = 1; + if(Bytes == j) return j; c = Buffer[j++]; } if( '0' <= c && c <= '9' ) { do { - if(c == ';') c = Buffer[j++]; + if(c == ';') { + if(Bytes == j) return j; + c = Buffer[j++]; + } while('0' <= c && c <= '9') { args[argc] *= 10; args[argc] += c-'0'; + if(Bytes == j) return j; c = Buffer[j++]; } argc ++; @@ -242,51 +251,64 @@ int VT_int_ParseEscape(tVTerm *Term, const char *Buffer) } // Get Command - if( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) + if( !('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') ) { - if( bQuestionMark ) + // Error + return j; + } + + if( bQuestionMark ) + { + switch(c) { - switch(c) + // DEC Private Mode Set + case 'h': + if(argc != 1) break; + switch(args[0]) { - // DEC Private Mode Set - case 'h': - if(argc != 1) break; - switch(args[0]) - { - case 25: - Term->Flags &= ~VT_FLAG_HIDECSR; - break; - case 1047: - VT_int_ToggleAltBuffer(Term, 1); - break; - } + case 25: + Term->Flags &= ~VT_FLAG_HIDECSR; + break; + case 1047: + VT_int_ToggleAltBuffer(Term, 1); break; - case 'l': - if(argc != 1) break; - switch(args[0]) - { - case 25: - Term->Flags |= VT_FLAG_HIDECSR; - break; - case 1047: - VT_int_ToggleAltBuffer(Term, 0); - break; - } + } + break; + case 'l': + if(argc != 1) break; + switch(args[0]) + { + case 25: + Term->Flags |= VT_FLAG_HIDECSR; break; - default: - Log_Warning("VTerm", "Unknown control sequence '\\x1B[?%c'", c); + case 1047: + VT_int_ToggleAltBuffer(Term, 0); break; } + break; + default: + Log_Warning("VTerm", "Unknown control sequence '\\x1B[?%c'", c); + break; } - else - { - VT_int_ParseEscape_StandardLarge(Term, c, argc, args); - } + } + else + { + VT_int_ParseEscape_StandardLarge(Term, c, argc, args); } break; - + case '\0': + // Ignore \0 + break; default: - Log_Notice("VTerm", "TODO: Handle short escape codes"); + //Log_Notice("VTerm", "TODO: Handle short escape codes"); + { + static volatile int tmp = 0; + if(tmp == 0) { + tmp = 1; + Debug("VTerm: Unknown short 0x%x", c); + tmp = 0; + } + } break; } diff --git a/KernelLand/Kernel/include/events.h b/KernelLand/Kernel/include/events.h index dc9d6543..17143e86 100644 --- a/KernelLand/Kernel/include/events.h +++ b/KernelLand/Kernel/include/events.h @@ -25,6 +25,8 @@ //! General purpose event for short waits //! e.g. waiting for an IRQ in a Read() call #define THREAD_EVENT_SHORTWAIT 0x00000010 +//! Fired when a child process quits +#define THREAD_EVENT_DEADCHILD 0x00000020 #define THREAD_EVENT_USER1 0x10000000 #define THREAD_EVENT_USER2 0x20000000 diff --git a/KernelLand/Kernel/include/threads_int.h b/KernelLand/Kernel/include/threads_int.h index 578fdcf1..48452649 100644 --- a/KernelLand/Kernel/include/threads_int.h +++ b/KernelLand/Kernel/include/threads_int.h @@ -71,7 +71,10 @@ struct sThread struct sProcess *Process; //!< Thread Group / Process struct sThread *Parent; //!< Parent Thread char *ThreadName; //!< Name of thread - + + struct sThread *LastDeadChild; //!< Last child to die (will have the \a DeadChildren lock) + tMutex DeadChildLock; //!< Lock to prevent clobbering of \a LastDeadChild, acquired by child, released by parent + // --- arch/proc.c's responsibility //! Kernel Stack Base tVAddr KernelStack; diff --git a/KernelLand/Kernel/include/vfs_ext.h b/KernelLand/Kernel/include/vfs_ext.h index 44c70f86..a130ac65 100644 --- a/KernelLand/Kernel/include/vfs_ext.h +++ b/KernelLand/Kernel/include/vfs_ext.h @@ -143,6 +143,10 @@ typedef struct sFInfo tVFS_ACL acls[]; //!< ACL buffer (size is passed in the \a MaxACLs argument to VFS_FInfo) } PACKED tFInfo; +// --- fd_set -- +#include "../../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h" + +#if 0 /** * \brief fd_set for select() */ @@ -170,6 +174,7 @@ typedef struct * \param fdsetp Set to modify */ #define FD_ISSET(fd, fdsetp) ((fdsetp)->flags[(fd)/16]&(1<<((fd)%16))) +#endif // === FUNCTIONS === /** diff --git a/KernelLand/Kernel/logging.c b/KernelLand/Kernel/logging.c index aab25a10..5149e021 100644 --- a/KernelLand/Kernel/logging.c +++ b/KernelLand/Kernel/logging.c @@ -93,7 +93,7 @@ void Log_AddEvent(const char *Ident, int Level, const char *Format, va_list Args if( Level >= NUM_LOG_LEVELS ) return; va_copy(args_tmp, Args); - len = vsnprintf(NULL, 256, Format, args_tmp); + len = vsnprintf(NULL, 0, Format, args_tmp); #if USE_RING_BUFFER || !CACHE_MESSAGES { diff --git a/KernelLand/Kernel/messages.c b/KernelLand/Kernel/messages.c index 82374233..b9d7a6fd 100644 --- a/KernelLand/Kernel/messages.c +++ b/KernelLand/Kernel/messages.c @@ -88,10 +88,11 @@ int Proc_GetMessage(Uint *Source, Uint BufSize, void *Buffer) void *tmp; tThread *cur = Proc_GetCurThread(); - ENTER("pSource pBuffer", Source, Buffer); + ENTER("pSource xBufSize pBuffer", Source, BufSize, Buffer); // Check if queue has any items if(!cur->Messages) { + LOG("empty queue"); LEAVE('i', 0); return 0; } diff --git a/KernelLand/Kernel/syscalls.c b/KernelLand/Kernel/syscalls.c index 1f2f7980..635f69ac 100644 --- a/KernelLand/Kernel/syscalls.c +++ b/KernelLand/Kernel/syscalls.c @@ -29,8 +29,8 @@ #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_NUM_NULLOK( tmp, sizeof(char**) ); \ + for(i=0;tmp&&tmp[i];i++) { \ CHECK_STR_NONULL( tmp[i] ); \ CHECK_NUM_NONULL( &tmp[i+1], sizeof(char*) ); \ }\ @@ -172,7 +172,8 @@ void SyscallHandler(tSyscallRegs *Regs) CHECK_STR_NONULL((const char*)Regs->Arg1); CHECK_STR_ARRAY((const char**)Regs->Arg2); CHECK_STR_ARRAY((const char**)Regs->Arg3); - CHECK_NUM_NULLOK((void*)Regs->Arg5, Regs->Arg4*sizeof(int)); + if( Regs->Arg4 > 0 ) + 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 diff --git a/KernelLand/Kernel/system.c b/KernelLand/Kernel/system.c index 9224db55..7938723a 100644 --- a/KernelLand/Kernel/system.c +++ b/KernelLand/Kernel/system.c @@ -48,6 +48,8 @@ void System_Init(char *CommandLine) if(Proc_Clone(CLONE_VM|CLONE_NOUSER) == 0) { const char *args[] = {gsInitBinary, 0}; + VFS_Open("/Devices/VTerm/0", VFS_OPENFLAG_READ|VFS_OPENFLAG_USER); // 0: stdin + VFS_Open("/Devices/VTerm/0", VFS_OPENFLAG_WRITE|VFS_OPENFLAG_USER); // 1: stdout Proc_Execve(gsInitBinary, args, &args[1], 0); Log_KernelPanic("System", "Unable to spawn init '%s'", gsInitBinary); } diff --git a/KernelLand/Kernel/threads.c b/KernelLand/Kernel/threads.c index 92a7a576..a86eba07 100644 --- a/KernelLand/Kernel/threads.c +++ b/KernelLand/Kernel/threads.c @@ -11,6 +11,7 @@ #include #include #include // VFS Handle maintainence +#include // Configuration #define DEBUG_TRACE_TICKETS 0 // Trace ticket counts @@ -442,9 +443,30 @@ tThread *Threads_CloneThreadZero(void) tTID Threads_WaitTID(int TID, int *Status) { // Any Child - if(TID == -1) { - Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child"); - return -1; + if(TID == -1) + { + Uint32 ev = Threads_WaitEvents(THREAD_EVENT_DEADCHILD); + tTID ret = -1; + if( ev & THREAD_EVENT_DEADCHILD ) + { + // A child died, get the TID + tThread *us = Proc_GetCurThread(); + ASSERT(us->LastDeadChild); + ret = us->LastDeadChild->TID; + // - Mark as dead (as opposed to undead) + ASSERT(us->LastDeadChild->Status == THREAD_STAT_ZOMBIE); + us->LastDeadChild->Status = THREAD_STAT_DEAD; + // - Set return status + if(Status) + *Status = us->LastDeadChild->RetStatus; + us->LastDeadChild = NULL; + Mutex_Release(&us->DeadChildLock); + } + else + { + Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child"); + } + return ret; } // Any peer/child thread @@ -460,33 +482,14 @@ tTID Threads_WaitTID(int TID, int *Status) } // Specific Thread - if(TID > 0) { - tThread *t = Threads_GetThread(TID); + if(TID > 0) + { tTID ret; - - // Wait for the thread to die! - // TODO: Handle child also being suspended if wanted - while(t->Status != THREAD_STAT_ZOMBIE) { - Threads_Sleep(); - Log_Debug("Threads", "%i waiting for %i, t->Status = %i", - Threads_GetTID(), t->TID, t->Status); - } - - // Set return status - ret = t->TID; - switch(t->Status) + // NOTE: Race condition - Other child dies, desired child dies, first death is 'lost' + while( (ret = Threads_WaitTID(-1, Status)) != TID ) { - case THREAD_STAT_ZOMBIE: - // Kill the thread - t->Status = THREAD_STAT_DEAD; - // TODO: Child return value? - if(Status) *Status = t->RetStatus; - // add to delete queue - Threads_Delete( t ); - break; - default: - if(Status) *Status = -1; - break; + if( ret == -1 ) + break; } return ret; } @@ -685,8 +688,10 @@ void Threads_Kill(tThread *Thread, int Status) Thread->Status = THREAD_STAT_ZOMBIE; SHORTREL( &glThreadListLock ); - // TODO: Send something like SIGCHLD - Threads_Wake( Thread->Parent ); + // TODO: It's possible that we could be timer-preempted here, should disable that... somehow + Mutex_Acquire( &Thread->Parent->DeadChildLock ); // released by parent + Thread->Parent->LastDeadChild = Thread; + Threads_PostEvent( Thread->Parent, THREAD_EVENT_DEADCHILD ); Log("Thread %i went *hurk* (%i)", Thread->TID, Status); diff --git a/KernelLand/Kernel/vfs/handle.c b/KernelLand/Kernel/vfs/handle.c index 1f3e3790..cb4fae12 100644 --- a/KernelLand/Kernel/vfs/handle.c +++ b/KernelLand/Kernel/vfs/handle.c @@ -196,7 +196,14 @@ void *VFS_SaveHandles(int NumFDs, int *FDs) tVFS_Handle *h; if( FDs == NULL ) h = &gaUserHandles[i]; - else { + else if( FDs[i] == -1 ) + { + Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (-1), ignorning", i); + memset(&ret[i], 0, sizeof(tVFS_Handle)); + continue ; + } + else + { h = VFS_GetHandle(FDs[i] & (VFS_KERNEL_FLAG - 1)); if(!h) { Log_Warning("VFS", "VFS_SaveHandles - Invalid FD %i", diff --git a/KernelLand/Kernel/vfs/select.c b/KernelLand/Kernel/vfs/select.c index 412cb1ae..8bd0deba 100644 --- a/KernelLand/Kernel/vfs/select.c +++ b/KernelLand/Kernel/vfs/select.c @@ -129,8 +129,8 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set tThread *thisthread = Proc_GetCurThread(); int ret; - ENTER("iMaxHandle pReadHandles pWriteHandles pErrHandles pTimeout bIsKernel", - MaxHandle, ReadHandles, WriteHandles, ErrHandles, Timeout, IsKernel); + ENTER("iMaxHandle pReadHandles pWriteHandles pErrHandles pTimeout xExtraEvents bIsKernel", + MaxHandle, ReadHandles, WriteHandles, ErrHandles, Timeout, ExtraEvents, IsKernel); // Notes: The idea is to make sure we only enter wait (Threads_WaitEvents) // if we are going to be woken up (either by an event at a later time, @@ -140,6 +140,8 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set // or the semaphore is incremeneted (or both, but never none) // Register with nodes + if( ReadHandles ) + LOG(" - ReadHandles[0] = %x", ReadHandles->flags[0]); ret = VFS_int_Select_Register(thisthread, MaxHandle, ReadHandles, 0, IsKernel); ret += VFS_int_Select_Register(thisthread, MaxHandle, WriteHandles, 1, IsKernel); ret += VFS_int_Select_Register(thisthread, MaxHandle, ErrHandles, 2, IsKernel); @@ -149,9 +151,11 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set // If there were events waiting, de-register and return if( ret > 0 ) { + LOG(" - ReadHandles[0] = %x", ReadHandles->flags[0]); ret = VFS_int_Select_Deregister(thisthread, MaxHandle, ReadHandles, 0, IsKernel); ret += VFS_int_Select_Deregister(thisthread, MaxHandle, WriteHandles, 1, IsKernel); ret += VFS_int_Select_Deregister(thisthread, MaxHandle, ErrHandles, 2, IsKernel); + LOG(" - ReadHandles[0] = %x", ReadHandles->flags[0]); LEAVE('i', ret); return ret; } @@ -306,8 +310,10 @@ int VFS_int_Select_Register(tThread *Thread, int MaxHandle, fd_set *Handles, int } // Check for the flag - if( !!*flag == !!wantedFlagValue ) + if( !!*flag == !!wantedFlagValue ) { + LOG(" %i == want %i", !!*flag, !!wantedFlagValue); numFlagged ++; + } } LEAVE('i', numFlagged); @@ -348,8 +354,6 @@ int VFS_int_Select_Deregister(tThread *Thread, int MaxHandle, fd_set *Handles, i continue; } - // Get the type of the listen - // Get the type of the listen if( VFS_int_Select_GetType(Type, handle->Node, &list, &flag, &wantedFlagValue, NULL) ) { LEAVE('i', 0); @@ -362,6 +366,8 @@ int VFS_int_Select_Deregister(tThread *Thread, int MaxHandle, fd_set *Handles, i // Check for the flag if( !!*flag == !!wantedFlagValue ) { numFlagged ++; + LOG(" %i == want %i", !!*flag, !!wantedFlagValue); + FD_SET(i, Handles); } else { FD_CLR(i, Handles); diff --git a/KernelLand/Modules/Display/BochsGA/bochsvbe.c b/KernelLand/Modules/Display/BochsGA/bochsvbe.c index 5988ee7c..50e76d33 100644 --- a/KernelLand/Modules/Display/BochsGA/bochsvbe.c +++ b/KernelLand/Modules/Display/BochsGA/bochsvbe.c @@ -82,6 +82,7 @@ Uint *gBGA_Framebuffer; const tBGA_Mode *gpBGA_CurrentMode; const tBGA_Mode gBGA_Modes[] = { {640,480,32, 640*480*4}, + {800,480,32, 800*480*4}, // Nice mode for VM testing {800,600,32, 800*600*4}, {1024,768,32, 1024*768*4} }; diff --git a/KernelLand/Modules/Display/RPi/main.c b/KernelLand/Modules/Display/RPi/main.c new file mode 100644 index 00000000..a0df9031 --- /dev/null +++ b/KernelLand/Modules/Display/RPi/main.c @@ -0,0 +1,61 @@ +/** + * Acess2 Raspberry Pi (BCM2835) + * - By John Hodge (thePowersGang) + * + * main.c + * - Driver core + * + * http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/screen01.html + */ +#define DEBUG 0 +#define VERSION ((0<<8)|1) +#include +#include +#include +#include +#include +#include +#include + +// === PROTOCOLS === + int RPiVid_Install(const char **Arguments); +// - GPU Communication + int RPiVid_int_MBoxCheck(Uint8 Box); +Uint32 RPiVid_int_MBoxRecv(Uint8 Box); +void RPiVid_int_MBoxSend(Uint8 Box, Uint32 Message); + +// === GLOBALS === +MODULE_DEFINE(0, VERSION, RPiVid, RPiVid_Install, NULL, NULL); + +// === CODE === +int RPiVid_Install(const char **Arguments) +{ + return 0; +} + + +// --- GPU Comms --- +int RPiVid_int_MBoxCheck(Uint8 Box) +{ + return 0; +} + +Uint32 RPiVid_int_MBoxRecv(Uint8 Box) +{ + Uint32 val; + do { + while( gRPiVid_Mbox->Status & (1 << 30) ) + ; + val = gRPiVid_Mbox->Read; + } while( (val & 0xF) != Box ); + + return 0; +} + +void RPiVid_int_MBoxSend(Uint8 Box, Uint32 Message) +{ + while( gRPiVid_Mbox.Status & (1 << 31) ) + ; + gRPiVid_Mbox.Write = (Message << 4) | (Box & 0xF); +} + diff --git a/KernelLand/Modules/Filesystems/InitRD/Makefile b/KernelLand/Modules/Filesystems/InitRD/Makefile index 5aa0e653..5758f991 100644 --- a/KernelLand/Modules/Filesystems/InitRD/Makefile +++ b/KernelLand/Modules/Filesystems/InitRD/Makefile @@ -13,4 +13,8 @@ LDFLAGS += @files.$(ARCH).c.ldopts files.$(ARCH).c: GenerateInitRD.php files.lst ARCH=$(ARCH) ACESSDIR=$(ACESSDIR) php GenerateInitRD.php files.lst $@ $@.ldopts $@.dep +# Override default install method, because the floppy is small :) +install: + true + -include files.$(ARCH).c.dep diff --git a/KernelLand/Modules/Filesystems/InitRD/files.lst b/KernelLand/Modules/Filesystems/InitRD/files.lst index ccbbe0c3..5b17070d 100644 --- a/KernelLand/Modules/Filesystems/InitRD/files.lst +++ b/KernelLand/Modules/Filesystems/InitRD/files.lst @@ -13,6 +13,7 @@ Dir "Bin" { File "ping" "__BIN__/Bin/ping" File "telnet" "__BIN__/Bin/telnet" File "irc" "__BIN__/Bin/irc" + File "bomb" "__BIN__/Bin/bomb" File "dhcpc" "__BIN__/SBin/dhcpc" } Dir "Libs" { @@ -26,9 +27,10 @@ Dir "Libs" { File "libaxwin3.so" "__BIN__/Libs/libaxwin3.so" File "libposix.so" "__BIN__/Libs/libposix.so" File "libpsocket.so" "__BIN__/Libs/libpsocket.so" + File "libunicode.so" "__BIN__/Libs/libunicode.so" } Dir "Conf" { - File "BootConf.cfg" "__FS__/Conf/BootConf.cfg" + File "inittab" "__FS__/Conf/inittab" } Dir "Apps" { Dir "AxWin" { @@ -36,6 +38,7 @@ Dir "Apps" { File "AxWinWM" "__BIN__/Apps/AxWin/3.0/AxWinWM" File "AxWinUI" "__BIN__/Apps/AxWin/3.0/AxWinUI" File "ate" "__BIN__/Apps/AxWin/3.0/ate" + File "terminal" "__BIN__/Apps/AxWin/3.0/terminal" File "AcessLogoSmall.sif" "__SRC__/Usermode/Applications/axwin3_src/AcessLogoSmall.sif" } } diff --git a/KernelLand/Modules/IPStack/udp.c b/KernelLand/Modules/IPStack/udp.c index 1d805692..ae3806b4 100644 --- a/KernelLand/Modules/IPStack/udp.c +++ b/KernelLand/Modules/IPStack/udp.c @@ -268,7 +268,7 @@ size_t UDP_Channel_Write(tVFS_Node *Node, off_t Offset, size_t Length, const voi UDP_SendPacketTo(chan, ep->AddrType, &ep->Addr, ep->Port, data, (size_t)Length - ofs); - return 0; + return Length; } /** diff --git a/KernelLand/Modules/Network/VIARhineII/rhine2.c b/KernelLand/Modules/Network/VIARhineII/rhine2.c index f9f4d254..9bdbafb6 100644 --- a/KernelLand/Modules/Network/VIARhineII/rhine2.c +++ b/KernelLand/Modules/Network/VIARhineII/rhine2.c @@ -80,11 +80,9 @@ int Rhine2_Install(char **Options) { int id = -1; int i = 0; -// Uint16 base; tCard *card; giRhine2_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID); - Log_Debug("Rhine2", "giRhine2_CardCount = %i", giRhine2_CardCount); if( giRhine2_CardCount == 0 ) return MODULE_ERR_NOTNEEDED; gaRhine2_Cards = calloc( giRhine2_CardCount, sizeof(tCard) ); diff --git a/KernelLand/Modules/Storage/FDDv2/main.c b/KernelLand/Modules/Storage/FDDv2/main.c index f6290d90..90cff7f4 100644 --- a/KernelLand/Modules/Storage/FDDv2/main.c +++ b/KernelLand/Modules/Storage/FDDv2/main.c @@ -115,7 +115,7 @@ int FDD_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]) { if(Pos < 0 || Pos > MAX_DISKS ) return -ENOENT; - if(gaFDD_Disks[Pos].bValid) + if(!gaFDD_Disks[Pos].bValid) return 1; Dest[0] = '0' + Pos; diff --git a/Makefile b/Makefile index 32f1ffb4..c2ef59ff 100644 --- a/Makefile +++ b/Makefile @@ -12,12 +12,12 @@ SUBMAKE = $(MAKE) --no-print-directory USRLIBS := crt0.o acess.ld ld-acess.so libc.so libposix.so USRLIBS += libreadline.so libnet.so liburi.so libpsocket.so -USRLIBS += libimage_sif.so +USRLIBS += libimage_sif.so libunicode.so USRAPPS := init login CLIShell cat ls mount USRAPPS += bomb lspci USRAPPS += ip dhcpclient ping telnet irc wget telnetd -USRAPPS += axwin3 gui_ate +USRAPPS += axwin3 gui_ate gui_shell ALL_DYNMODS = $(addprefix all-,$(DYNMODS)) ALL_MODULES := $(addprefix all-,$(MODULES)) diff --git a/Notes/3D.txt b/Notes/3D.txt new file mode 100644 index 00000000..a530e3cc --- /dev/null +++ b/Notes/3D.txt @@ -0,0 +1,8 @@ +GL control channel: + App -> GUI -> VTerm -> Driver +- App creates 3D window +- GUI passes X,Y WxH to VTerm (and can issue resize notices upwards) +- VTerm passes to driver (and can disable display of local regions when VT switch) + +Allocates command ring buffer for libgl + diff --git a/Tools/GCCProxy/gccproxy.sh b/Tools/GCCProxy/gccproxy.sh index a3183d34..477c4766 100755 --- a/Tools/GCCProxy/gccproxy.sh +++ b/Tools/GCCProxy/gccproxy.sh @@ -55,6 +55,16 @@ while [[ $# -gt 0 ]]; do -l*|-L*) _libs=$_libs" $1" ;; + -v|--version|-V) + _verarg=$_verarg" $1" + ;; + --inv=ld) + _actas=ld + ;; + -print-prog-name=ld) + echo $0 --inv=ld + exit 0 + ;; *) _miscargs=$_miscargs" $1" ;; @@ -63,7 +73,7 @@ while [[ $# -gt 0 ]]; do done run() { -# echo --- $* + #echo --- $* $* return $? } @@ -75,6 +85,11 @@ rm $cfgfile #echo "_compile = $_compile, _preproc = $_preproc" +if [[ "x$_actas" == "xld" ]]; then + run $_LD $LDFLAGS $_ldflags $_outfile $_miscargs $LIBGCC_PATH $_libs + exit $? +fi + if [[ $_preproc -eq 1 ]]; then run $_CC -E $CFLAGS $_cflags $_miscargs $_outfile elif [[ $_makedep -eq 1 ]]; then @@ -84,8 +99,10 @@ elif [[ $_compile -eq 1 ]]; then elif echo " $_miscargs" | grep '\.c' >/dev/null; then tmpout=`mktemp acess_gccproxy.XXXXXXXXXX.o --tmpdir` run $_CC $CFLAGS $_cflags $_miscargs -c -o $tmpout - run $_LD $LDFLAGS $_ldflags $_libs $tmpout $_outfile -lgcc $_libs + run $_LD $LDFLAGS $_ldflags $_libs $tmpout $_outfile $LIBGCC_PATH $_libs + _rv=$? rm $tmpout + exit $_rv else run $_LD$_ldflags $_miscargs $_outfile $LDFLAGS $_libs fi diff --git a/Usermode/Applications/axwin3_src/Interface/main.c b/Usermode/Applications/axwin3_src/Interface/main.c index e8b58348..a0986147 100644 --- a/Usermode/Applications/axwin3_src/Interface/main.c +++ b/Usermode/Applications/axwin3_src/Interface/main.c @@ -111,14 +111,16 @@ void create_sidebar(void) void mainmenu_app_textedit(void *unused) { - const char *args[] = {"ate",NULL}; // _SysDebug("TODO: Launch text editor"); + const char *args[] = {"ate",NULL}; _SysSpawn("/Acess/Apps/AxWin/3.0/ate", args, (const char **)gEnvion, 0, NULL, NULL); } void mainmenu_app_terminal(void *unused) { - _SysDebug("TODO: Launch terminal emulator"); + _SysDebug("Launch terminal emulator"); + const char *args[] = {"terminal",NULL}; + _SysSpawn("/Acess/Apps/AxWin/3.0/terminal", args, (const char **)gEnvion, 0, NULL, NULL); } void mainmenu_run_dialog(void *unused) diff --git a/Usermode/Applications/axwin3_src/WM/Makefile b/Usermode/Applications/axwin3_src/WM/Makefile index 1d674507..1112ffea 100644 --- a/Usermode/Applications/axwin3_src/WM/Makefile +++ b/Usermode/Applications/axwin3_src/WM/Makefile @@ -7,7 +7,7 @@ CFLAGS += -std=gnu99 DIR := Apps/AxWin/3.0 BIN := AxWinWM -OBJ := main.o input.o video.o ipc.o image.o utf-8.o +OBJ := main.o input.o video.o ipc.o image.o OBJ += wm.o wm_input.o wm_render.o wm_render_text.o wm_hotkeys.o OBJ += decorator.o OBJ += renderers/framebuffer.o @@ -23,7 +23,7 @@ OBJ += renderers/widget/textinput.o OBJ += renderers/widget/spacer.o OBJ += renderers/widget/subwin.o -LDFLAGS += -limage_sif -luri -lnet +LDFLAGS += -limage_sif -luri -lnet -lunicode -include ../../Makefile.tpl diff --git a/Usermode/Applications/axwin3_src/WM/include/utf8.h b/Usermode/Applications/axwin3_src/WM/include/utf8.h deleted file mode 100644 index 3ecaeb08..00000000 --- a/Usermode/Applications/axwin3_src/WM/include/utf8.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Acess2 GUI (AxWin) Version 3 - * - By John Hodge (thePowersGang) - * - * utf8.h - * - UTF-8 Parsing header - */ -#ifndef _UTF8_H_ -#define _UTF8_H_ - -#include - -extern int ReadUTF8(const char *Input, uint32_t *Val); -extern int ReadUTF8Rev(const char *Base, int Offset, uint32_t *Val); -extern int WriteUTF8(char *buf, uint32_t Val); - -#endif - diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index 5b600ee8..7874335c 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -461,8 +461,8 @@ int IPC_Msg_FocusWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg) ASSERT(Msg->ID == IPCMSG_FOCUSWINDOW); // Don't allow the focus to be changed unless the client has the focus - if(!gpWM_FocusedWindow) return 1; - if(gpWM_FocusedWindow->Client != Client) return 1; +// if(!gpWM_FocusedWindow) return 1; +// if(gpWM_FocusedWindow->Client != Client) return 1; win = IPC_int_GetWindow(Client, Msg->Window); if(!win) return 1; diff --git a/Usermode/Applications/axwin3_src/WM/main.c b/Usermode/Applications/axwin3_src/WM/main.c index 7d2d3914..9db1c15c 100644 --- a/Usermode/Applications/axwin3_src/WM/main.c +++ b/Usermode/Applications/axwin3_src/WM/main.c @@ -66,10 +66,12 @@ int main(int argc, char *argv[]) Renderer_RichText_Init(); WM_Initialise(); - // TODO: Config + // TODO: Move these to config uint32_t keys[4]; keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_r; WM_Hotkey_Register(2, keys, "Interface>Run"); + keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_t; + WM_Hotkey_Register(2, keys, "Interface>Terminal"); // Spawn interface root { @@ -83,7 +85,7 @@ int main(int argc, char *argv[]) sprintf(server_info, "AXWIN3_SERVER=%i", server_tid); // TODO: Does the client need FDs? int rv = _SysSpawn(csInterfaceApp, argv, envp, 0, NULL, NULL); - if( rv ) { + if( rv < 0 ) { _SysDebug("_SysSpawn chucked a sad, rv=%i, errno=%i", rv, _errno); } } diff --git a/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c b/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c index fc838cb0..68a3f8cc 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c @@ -16,7 +16,6 @@ typedef struct { short W, H; void *Data; - char _data[]; } tFBBuffer; typedef struct { @@ -162,7 +161,7 @@ int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data) buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4); buf->W = msg->W; buf->H = msg->H; - buf->Data = buf->_data; + buf->Data = buf + 1; info->Buffers[msg->Buffer] = buf; diff --git a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c index 28be1aeb..c62dd7f5 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c @@ -224,6 +224,27 @@ void Renderer_RichText_Redraw(tWindow *Window) Window->W, (info->DispLines-i)*info->LineHeight, info->DefaultBG ); + + // HACK! + info->DispCols = Window->W / 8; + + // TODO: Text cursor + _SysDebug("Cursor at %i,%i", info->CursorCol, info->CursorRow); + _SysDebug(" Range [%i+%i],[%i+%i]", info->FirstVisRow, info->DispLines, info->FirstVisCol, info->DispCols); + if( info->CursorRow >= info->FirstVisRow && info->CursorRow < info->FirstVisRow + info->DispLines ) + { + if( info->CursorCol >= info->FirstVisCol && info->CursorCol < info->FirstVisCol + info->DispCols ) + { + // TODO: Kill hardcoded 8 with cached text distance + WM_Render_FillRect(Window, + (info->CursorCol - info->FirstVisCol) * 8, + (info->CursorRow - info->FirstVisRow) * info->LineHeight, + 1, + info->LineHeight, + info->DefaultFG + ); + } + } } int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data) @@ -241,6 +262,10 @@ int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void case _ATTR_DEFFG: info->DefaultFG = msg->Value; break; + case _ATTR_CURSORPOS: + info->CursorRow = msg->Value >> 12; + info->CursorCol = msg->Value & 0xFFF; + break; case _ATTR_SCROLL: // TODO: Set scroll flag break; @@ -298,7 +323,9 @@ int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const voi } line->ByteLength = Len - sizeof(*msg); memcpy(line->Data, msg->LineData, Len - sizeof(*msg)); - + + WM_Invalidate( Window ); + return 0; } @@ -312,6 +339,10 @@ int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const voi if(Len < sizeof(*msg)) return -1; info->DispLines = msg->H / info->LineHeight; return 1; } + case WNDMSG_KEYDOWN: + case WNDMSG_KEYUP: + case WNDMSG_KEYFIRE: + return 1; } return 0; } diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c index 6d34a8e3..fc7e1077 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c @@ -10,7 +10,7 @@ #include #include "./common.h" #include "./colours.h" -#include +#include #include // TODO: Include a proper keysym header diff --git a/Usermode/Applications/axwin3_src/WM/utf-8.c b/Usermode/Applications/axwin3_src/WM/utf-8.c deleted file mode 100644 index 93e0318b..00000000 --- a/Usermode/Applications/axwin3_src/WM/utf-8.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Acess2 GUI (AxWin) Version 3 - * - By John Hodge (thePowersGang) - * - * utf-8.c - * - UTF-8 Parsing code - */ -#include -#include - -/** - * \brief Read a UTF-8 character from a string - * \param Input Source UTF-8 encoded string - * \param Val Destination for read codepoint - * \return Number of bytes read/used - */ -int ReadUTF8(const char *Input, uint32_t *Val) -{ - const uint8_t *str = (const uint8_t *)Input; - *Val = 0xFFFD; // Assume invalid character - - // ASCII - if( !(*str & 0x80) ) { - *Val = *str; - return 1; - } - - // Middle of a sequence - if( (*str & 0xC0) == 0x80 ) { - return 1; - } - - // Two Byte - if( (*str & 0xE0) == 0xC0 ) { - *Val = (*str & 0x1F) << 6; // Upper 6 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F); // Lower 6 Bits - return 2; - } - - // Three Byte - if( (*str & 0xF0) == 0xE0 ) { - *Val = (*str & 0x0F) << 12; // Upper 4 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F) << 6; // Middle 6 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F); // Lower 6 Bits - return 3; - } - - // Four Byte - if( (*str & 0xF8) == 0xF0 ) { - *Val = (*str & 0x07) << 18; // Upper 3 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F) << 12; // Middle-upper 6 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F) << 6; // Middle-lower 6 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F); // Lower 6 Bits - return 4; - } - - // UTF-8 Doesn't support more than four bytes - return 4; -} - -/** - * \brief Get the UTF-8 character before the - * \ - */ -int ReadUTF8Rev(const char *Base, int Offset, uint32_t *Val) -{ - int len = 0; - - // Scan backwards for the beginning of the character - while( Offset > 0 && (Base[Offset--] & 0xC0) == 0x80 ) - len ++; - // Invalid string (no beginning) - if(Offset == 0 && (Base[Offset] & 0xC0) == 0x80 ) - return len; - - len ++; // First character - if( ReadUTF8(Base+Offset, Val) != len ) { - *Val = 0xFFFD; - } - return len; -} - -/** - * \brief Write a UTF-8 character sequence to a string - * \param buf Destination buffer (must have at least 4 bytes available) - * \param Val Unicode codepoint to write - * \return Number of bytes written - * \note Does not NULL terminate the string in \a buf - */ -int WriteUTF8(char *buf, uint32_t Val) -{ - uint8_t *str = (void*)buf; - - // ASCII - if( Val < 128 ) { - if(str) { - *str = Val; - } - return 1; - } - - // Two Byte - if( Val < 0x8000 ) { - if(str) { - *str = 0xC0 | (Val >> 6); - str ++; - *str = 0x80 | (Val & 0x3F); - } - return 2; - } - - // Three Byte - if( Val < 0x10000 ) { - if(str) { - *str = 0xE0 | (Val >> 12); - str ++; - *str = 0x80 | ((Val >> 6) & 0x3F); - str ++; - *str = 0x80 | (Val & 0x3F); - } - return 3; - } - - // Four Byte - if( Val < 0x110000 ) { - if(str) { - *str = 0xF0 | (Val >> 18); - str ++; - *str = 0x80 | ((Val >> 12) & 0x3F); - str ++; - *str = 0x80 | ((Val >> 6) & 0x3F); - str ++; - *str = 0x80 | (Val & 0x3F); - } - return 4; - } - - // UTF-8 Doesn't support more than four bytes - return 0; -} - diff --git a/Usermode/Applications/axwin3_src/WM/video.c b/Usermode/Applications/axwin3_src/WM/video.c index 60f2155e..1b9ffaba 100644 --- a/Usermode/Applications/axwin3_src/WM/video.c +++ b/Usermode/Applications/axwin3_src/WM/video.c @@ -87,7 +87,7 @@ void Video_Update(void) _SysDebug("Video_Update - Updating lines %i to %i (0x%x+0x%x px)", giVideo_FirstDirtyLine, giVideo_LastDirtyLine, ofs, size); - _SysSeek(giTerminalFD, ofs*4, 1); + _SysSeek(giTerminalFD, ofs*4, SEEK_SET); _SysDebug("Video_Update - Sending FD %i %p 0x%x", giTerminalFD, gpScreenBuffer+ofs, size*4); _SysWrite(giTerminalFD, gpScreenBuffer+ofs, size*4); _SysDebug("Video_Update - Done"); diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index f9592db5..8886af19 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -173,6 +173,8 @@ void WM_FocusWindow(tWindow *Destination) { struct sWndMsg_Bool _msg; + _SysDebug("WM_FocusWindow(%p)", Destination); + if( gpWM_FocusedWindow == Destination ) return ; if( Destination && !(Destination->Flags & WINFLAG_SHOW) ) diff --git a/Usermode/Applications/axwin3_src/WM/wm_render_text.c b/Usermode/Applications/axwin3_src/WM/wm_render_text.c index 6ad72be6..8258531b 100644 --- a/Usermode/Applications/axwin3_src/WM/wm_render_text.c +++ b/Usermode/Applications/axwin3_src/WM/wm_render_text.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include // INT_MAX // === TYPES === diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c index fd1cf391..9fed5449 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c @@ -10,6 +10,7 @@ #include "include/internal.h" #include #include +#include //#include // === TYPES === @@ -23,6 +24,16 @@ typedef struct sRichText_Window // === CODE === int AxWin3_RichText_MessageHandler(tHWND Window, int MessageID, int Size, void *Data) { + tRichText_Window *info = AxWin3_int_GetDataPtr(Window); + struct sWndMsg_KeyAction *keyaction = Data; + _SysDebug("MessageID = %i", MessageID); + switch(MessageID) + { + case WNDMSG_KEYFIRE: + if(Size < sizeof(*keyaction)) return -1; + info->KeyCallback(Window, 2, keyaction->KeySym, keyaction->UCS32); + return 1; + } return 0; } diff --git a/Usermode/Applications/dhcpclient_src/main.c b/Usermode/Applications/dhcpclient_src/main.c index b9b28149..73e85d8e 100644 --- a/Usermode/Applications/dhcpclient_src/main.c +++ b/Usermode/Applications/dhcpclient_src/main.c @@ -528,7 +528,7 @@ void SetAddress(tInterface *Iface, void *Addr, void *Mask, void *Router) _SysIOCtl(Iface->IfaceFD, 6, Addr); _SysIOCtl(Iface->IfaceFD, 7, &mask_bits); - if( Router ); + if( Router ) { uint8_t *addr = Router; _SysDebug("Router %i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]); diff --git a/Usermode/Applications/gui_shell_src/Makefile b/Usermode/Applications/gui_shell_src/Makefile index 7ccfff46..a38f1355 100644 --- a/Usermode/Applications/gui_shell_src/Makefile +++ b/Usermode/Applications/gui_shell_src/Makefile @@ -2,9 +2,9 @@ -include ../Makefile.cfg -LDFLAGS += -laxwin3 +LDFLAGS += -laxwin3 -lunicode -OBJ = main.o +OBJ = main.o vt100.o display.o BIN = terminal DIR := Apps/AxWin/3.0 diff --git a/Usermode/Applications/gui_shell_src/display.c b/Usermode/Applications/gui_shell_src/display.c new file mode 100644 index 00000000..1665e448 --- /dev/null +++ b/Usermode/Applications/gui_shell_src/display.c @@ -0,0 +1,250 @@ +/* + * Acess GUI Terminal + * - By John Hodge (thePowersGang) + * + * display.c + * - Abstract display manipulation methods + */ +#include "include/display.h" +#include // _SysDebug +#include // exit +#include +#include +#include +#include +#include + +#define UNIMPLIMENTED() do{_SysDebug("UNIMPLIMENTED %s", __func__); exit(-1);}while(0) + +// === EXTERN == +extern tHWND gMainWindow; + +// === GLOBALS === + int giDisplayCols; + int giDisplayLines; + int giDisplayTotalLines; + int giDisplayBufSize; + int giCurrentLine; + int giCurrentLinePos; // byte offset, not column + int giCurrentCol; + int giFirstDispLine; // First displayed line + int giFirstLine; // Ring buffer start +char **gasDisplayLines; + int *gaiDisplayLineSizes; +char *gabDisplayLinesDirty; + +// === CODE === +void Display_Init(int Cols, int Lines, int ExtraScrollbackLines) +{ + giDisplayCols = Cols; + giDisplayLines = Lines; + giDisplayTotalLines = Lines + ExtraScrollbackLines; + gasDisplayLines = calloc( sizeof(char*), (Lines + ExtraScrollbackLines) ); + gaiDisplayLineSizes = calloc( sizeof(int), (Lines + ExtraScrollbackLines) ); + gabDisplayLinesDirty = calloc( sizeof(char), (Lines + ExtraScrollbackLines) ); + + AxWin3_RichText_SetLineCount(gMainWindow, Lines+ExtraScrollbackLines); + AxWin3_RichText_SetCursorType(gMainWindow, 1); // TODO: enum +} + +void Display_int_PushString(int Length, const char *Text) +{ + _SysDebug("Line %i += %i '%*C'", giCurrentLine, Length, Length, Text); + if( !gasDisplayLines[giCurrentLine] || giCurrentLinePos + Length >= gaiDisplayLineSizes[giCurrentLine] ) + { + int reqsize = giCurrentLinePos + Length; + gaiDisplayLineSizes[giCurrentLine] = (reqsize + 32-1) & ~(32-1); + void *tmp = realloc(gasDisplayLines[giCurrentLine], gaiDisplayLineSizes[giCurrentLine]); + if( !tmp ) perror("Display_AddText - realloc"); + gasDisplayLines[giCurrentLine] = tmp; + } + + memcpy(gasDisplayLines[giCurrentLine]+giCurrentLinePos, Text, Length); + gabDisplayLinesDirty[giCurrentLine] = 1; + gasDisplayLines[giCurrentLine][giCurrentLinePos+Length] = 0; + giCurrentLinePos += Length; + +} + +void Display_AddText(int Length, const char *UTF8Text) +{ + _SysDebug("%i '%.*s'", Length, Length, UTF8Text); + // Copy as many characters (not bytes, have to trim off the last char) as we can to the current line + // - then roll over to the next line + while( Length > 0 ) + { + int space = giDisplayCols - giCurrentCol; + int bytes = 0; + while( space && bytes < Length ) + { + uint32_t cp; + bytes += ReadUTF8(UTF8Text+bytes, &cp); + if( Unicode_IsPrinting(cp) ) { + space --; + giCurrentCol ++; + } + } + + Display_int_PushString(bytes, UTF8Text); + + UTF8Text += bytes; + _SysDebug("Length(%i) -= bytes(%i)", Length, bytes); + Length -= bytes; + if( Length != 0 ) + { + // Next line + giCurrentLinePos = 0; + giCurrentCol = 0; + giCurrentLine ++; + } + } +} + +void Display_Newline(int bCarriageReturn) +{ + Display_Flush(); + + // Going down! + giCurrentLine ++; + if( giCurrentLine == giDisplayLines ) + giCurrentLine = 0; + if( giCurrentLine == giFirstLine ) + { + giFirstLine ++; + if(giFirstLine == giDisplayLines) + giFirstLine = 0; + } + + if( bCarriageReturn ) { + giCurrentLinePos = 0; + giCurrentCol = 0; + } + else { + giCurrentLinePos = 0; + int i = giCurrentCol; + if( !gasDisplayLines[giCurrentLine] ) + { + giCurrentCol = 0; + while(i--) + Display_AddText(1, " "); + } + else + { + while( i -- ) + { + uint32_t cp; + giCurrentLinePos += ReadUTF8(gasDisplayLines[giCurrentLine]+giCurrentLinePos, &cp); + if( !Unicode_IsPrinting(cp) ) + i ++; + } + } + } +} + +void Display_SetCursor(int Row, int Col) +{ + UNIMPLIMENTED(); +} + +void Display_MoveCursor(int RelRow, int RelCol) +{ + if( RelRow < 0 ) + { + for( ; RelRow < 0; RelRow ++ ) + { + uint32_t cp; + int delta = ReadUTF8Rev(gasDisplayLines[giCurrentLine], giCurrentLinePos, &cp); + if( !Unicode_IsPrinting(cp) ) + RelRow --; + else + giCurrentCol --; + giCurrentLinePos -= delta; + } + } + else + { + UNIMPLIMENTED(); + } +} + +void Display_ClearLine(int Dir) // 0: All, 1: Forward, -1: Reverse +{ + if( Dir == 0 ) + { + // Completely clear line + if( gasDisplayLines[giCurrentLine] ) + free(gasDisplayLines[giCurrentLine]); + gasDisplayLines[giCurrentLine] = NULL; + gabDisplayLinesDirty[giCurrentLine] = 1; + } + else if( Dir == 1 ) + { + // Forward clear (truncate) + } + else if( Dir == -1 ) + { + // Reverse clear (replace with spaces) + } + else + { + // BUGCHECK + } +} + +void Display_ClearLines(int Dir) // 0: All, 1: Forward, -1: Reverse +{ + if( Dir == 0 ) + { + // Push giDisplayLines worth of empty lines + // Move cursor back up by giDisplayLines + } + else if( Dir == 1 ) + { + // Push (giDisplayLines - (giCurrentLine-giFirstDispLine)) and reverse + } + else if( Dir == -1 ) + { + // Reverse clear (replace with spaces) + } + else + { + // BUGCHECK + } +} + +void Display_SetForeground(uint32_t RGB) +{ + char buf[7+1]; + sprintf(buf, "\1%06x", RGB&0xFFFFFF); + Display_int_PushString(7, buf); +} + +void Display_SetBackground(uint32_t RGB) +{ + char buf[7+1]; + sprintf(buf, "\2%06x", RGB&0xFFFFFF); + Display_int_PushString(7, buf); +} + +void Display_Flush(void) +{ + int i; + for( i = 0; i < giDisplayCols; i ++ ) + { + int line = (giFirstLine + i) % giDisplayTotalLines; + if( !gabDisplayLinesDirty[line] ) + continue; + _SysDebug("Line %i+%i '%s'", giFirstLine, i, gasDisplayLines[line]); + AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] ); + gabDisplayLinesDirty[line] = 0; + } + + // force redraw? + AxWin3_RichText_SetCursorPos(gMainWindow, giCurrentLine, giCurrentCol); +} + +void Display_ShowAltBuffer(int AltBufEnabled) +{ + UNIMPLIMENTED(); +} + diff --git a/Usermode/Applications/gui_shell_src/include/display.h b/Usermode/Applications/gui_shell_src/include/display.h index 80bc69ca..4feaf352 100644 --- a/Usermode/Applications/gui_shell_src/include/display.h +++ b/Usermode/Applications/gui_shell_src/include/display.h @@ -3,11 +3,15 @@ * - By John Hodge (thePowersGang) * * display.h - * - RichText Termianl Translation + * - RichText terminal translation */ #ifndef _DISPLAY_H_ #define _DISPLAY_H_ +#include + +extern void Display_Init(int Cols, int Lines, int ExtraScrollbackLines); + extern void Display_AddText(int Length, const char *UTF8Text); extern void Display_Newline(int bCarriageReturn); extern void Display_SetCursor(int Row, int Col); @@ -16,6 +20,16 @@ extern void Display_ClearLine(int Dir); // 0: All, 1: Forward, -1: Reverse extern void Display_ClearLines(int Dir); // 0: All, 1: Forward, -1: Reverse extern void Display_SetForeground(uint32_t RGB); extern void Display_SetBackground(uint32_t RGB); +/** + * \brief Ensure that recent updates are flushed to the server + * \note Called at the end of an "input" buffer + */ +extern void Display_Flush(void); + +/** + * \brief Switch the display to the alternate buffer (no scrollback) + */ +extern void Display_ShowAltBuffer(int AltBufEnabled); #endif diff --git a/Usermode/Applications/gui_shell_src/main.c b/Usermode/Applications/gui_shell_src/main.c index c7aac852..4b82d0e0 100644 --- a/Usermode/Applications/gui_shell_src/main.c +++ b/Usermode/Applications/gui_shell_src/main.c @@ -8,14 +8,19 @@ #include #include #include +#include #include +#include #include "include/display.h" #include "include/vt100.h" +#include +#include // === PROTOTYPES === int main(int argc, char *argv[], const char **envp); int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated); int Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col); +void Term_HandleOutput(int Len, const char *Buf); // === GLOBALS === tHWND gMainWindow; @@ -52,22 +57,30 @@ int main(int argc, char *argv[], const char **envp) // AxWin3_RichText_SetLineCount(gMainWindow, 3); AxWin3_RichText_SendLine(gMainWindow, 0, "First line!"); - AxWin3_RichText_SendLine(gMainWindow, 2, "Third line! \x01""ff0000A red"); + AxWin3_RichText_SendLine(gMainWindow, 2, "Third line! \1ff0000A red"); // - AxWin3_ResizeWindow(gMainWindow, 600, 400); - AxWin3_MoveWindow(gMainWindow, 50, 50); + Display_Init(80, 25, 100); + AxWin3_ResizeWindow(gMainWindow, 80*8, 25*16); + AxWin3_MoveWindow(gMainWindow, 20, 50); AxWin3_ShowWindow(gMainWindow, 1); AxWin3_FocusWindow(gMainWindow); // Spawn shell - giChildStdout = open("/Devices/FIFO/anon", O_RDWR); - giChildStdin = open("/Devices/FIFO/anon", O_RDWR); + giChildStdin = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE); + giChildStdout = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE); + if( giChildStdout == -1 || giChildStdin == -1 ) { + perror("Oh, fsck"); + _SysDebug("out,in = %i,%i", giChildStdout, giChildStdin); + return -1; + } { int fds[] = {giChildStdin, giChildStdout, giChildStdout}; const char *argv[] = {"CLIShell", NULL}; - _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL); + int pid = _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL); + if( pid < 0 ) + _SysDebug("ERROR: Shell spawn failed"); } // Main loop @@ -81,9 +94,10 @@ int main(int argc, char *argv[], const char **envp) if( FD_ISSET(giChildStdout, &fds) ) { + _SysDebug("Activity on child stdout"); // Read and update screen char buf[32]; - int len = read(giChildStdout, buf, sizeof(buf)); + int len = _SysRead(giChildStdout, buf, sizeof(buf)); if( len <= 0 ) break; Term_HandleOutput(len, buf); @@ -101,35 +115,51 @@ int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translat #define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=1<<(bit);}while(0) switch(KeySym) { - case KEY_LCTRL: - _bitset(ctrl_state, 0, bPress); + case KEYSYM_LEFTCTRL: + _bitset(ctrl_state, 0, bPress!=0); return 0; - case KEY_RCTRL: - _bitset(ctrl_state, 0, bPress); + case KEYSYM_RIGHTCTRL: + _bitset(ctrl_state, 1, bPress!=0); return 0; } #undef _bitset // Handle shortcuts // - Ctrl-A -- Ctrl-Z - if( ctrl_state && KeySym >= KEY_a && KeySym <= KEY_z ) + if( ctrl_state && KeySym >= KEYSYM_a && KeySym <= KEYSYM_z ) { - Translated = KeySym - KEY_a + 1; + Translated = KeySym - KEYSYM_a + 1; } - if( Translated ) + // == 2 :: FIRE + if( bPress == 2 ) { - // Encode and send + if( Translated ) + { + char buf[6]; + int len; + + // Encode and send + len = WriteUTF8(buf, Translated); + + _SysDebug("Keystroke translated to '%.*s'", len, buf); + _SysWrite(giChildStdin, buf, len); + + return 0; + } - return 0; - } - - // No translation, look for escape sequences to send - switch(KeySym) - { - case KEY_LEFTARROW: - // str = "\x1b[D"; - break; + // No translation, look for escape sequences to send + const char *str = NULL; + switch(KeySym) + { + case KEYSYM_LEFTARROW: + str = "\x1b[D"; + break; + } + if( str ) + { + _SysWrite(giChildStdin, str, strlen(str)); + } } return 0; } @@ -153,8 +183,10 @@ void Term_HandleOutput(int Len, const char *Buf) Display_AddText(-esc_len, Buf + ofs); esc_len = -esc_len; } - Len -= esc_len; ofs += esc_len; + _SysDebug("Len = %i, ofs = %i", Len, ofs); } + + Display_Flush(); } diff --git a/Usermode/Applications/gui_shell_src/vt100.c b/Usermode/Applications/gui_shell_src/vt100.c index 51c8016f..2a87ca4f 100644 --- a/Usermode/Applications/gui_shell_src/vt100.c +++ b/Usermode/Applications/gui_shell_src/vt100.c @@ -2,42 +2,86 @@ * Acess GUI Terminal * - By John Hodge (thePowersGang) * - * main.c - * - Core + * vt100.c + * - VT100/xterm Emulation */ #include +#include #include "include/vt100.h" #include "include/display.h" +#include // isalpha +#include // _SysDebug + +const uint32_t caVT100Colours[] = { + // Black, Red, Green, Yellow, Blue, Purple, Cyan, Gray + // Same again, but bright + 0x000000, 0x770000, 0x007700, 0x777700, 0x000077, 0x770077, 0x007777, 0xAAAAAAA, + 0xCCCCCC, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFFF +}; + + int Term_HandleVT100_Long(int Len, const char *Buf); + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} int Term_HandleVT100(int Len, const char *Buf) { - const int max_length = 16; - static char inc_buf[max_length] + #define MAX_VT100_ESCAPE_LEN 16 + static char inc_buf[MAX_VT100_ESCAPE_LEN]; static int inc_len = 0; if( inc_len > 0 || *Buf == '\x1b' ) { - memcpy(inc_buf + inc_len, Buf, min(max_length - inc_len, Len)); // Handle VT100 (like) escape sequence - - inc_len = 0; - return 1; + int new_bytes = min(MAX_VT100_ESCAPE_LEN - inc_len, Len); + int ret = 0, old_inc_len = inc_len; + memcpy(inc_buf + inc_len, Buf, new_bytes); + + inc_len += new_bytes; + + if( inc_len <= 1 ) + return 1; // Skip 1 character (the '\x1b') + + switch(inc_buf[1]) + { + case '[': // Multibyte, funtime starts + ret = Term_HandleVT100_Long(inc_len-2, inc_buf+2); + if( ret > 0 ) { + ret += 2; + } + break; + default: + ret = 2; + break; + } + + if( ret != 0 ) { + inc_len = 0; + ret -= old_inc_len; // counter cached bytes + } + return ret; } switch( *Buf ) { case '\b': // TODO: Backspace + Display_MoveCursor(-1, 0); + Display_AddText(1, " "); + Display_MoveCursor(-1, 0); return 1; case '\t': - // TODO: tab + // TODO: tab (get current cursor pos, space until multiple of 8) return 1; case '\n': Display_Newline(1); return 1; case '\r': // TODO: Carriage return - return ; + Display_MoveCursor(INT_MIN, 0); + return 1; } int ret = 0; @@ -52,3 +96,100 @@ int Term_HandleVT100(int Len, const char *Buf) } return -ret; } + +int Term_HandleVT100_Long(int Len, const char *Buffer) +{ + char c; + int argc = 0, j = 0; + int args[6] = {0,0,0,0,0,0}; + int bQuestionMark = 0; + + // Get Arguments + if(j == Len) return 0; + c = Buffer[j++]; + if(c == '?') { + bQuestionMark = 1; + if(j == Len) return 0; + c = Buffer[j++]; + } + if( '0' <= c && c <= '9' ) + { + do { + if(c == ';') { + if(j == Len) return 0; + c = Buffer[j++]; + } + while('0' <= c && c <= '9') { + args[argc] *= 10; + args[argc] += c-'0'; + if(j == Len) return 0; + c = Buffer[j++]; + } + argc ++; + } while(c == ';'); + } + + // Get Command + if( !isalpha(c) ) { + // Bother. + _SysDebug("Unexpected char 0x%x in VT100 escape code", c); + return 1; + } + + if( bQuestionMark ) + { + // Special commands + switch( c ) + { + default: + _SysDebug("Unknown VT100 extended escape char 0x%x", c); + break; + } + } + else + { + // Standard commands + switch( c ) + { + case 'J': + if( argc == 0 ) + Display_ClearLine(0); + else if( args[0] == 2 ) + Display_ClearLines(0); // Entire screen! + else + _SysDebug("TODO: VT100 %i J", args[0]); + break; + case 'm': + if( argc == 0 ) + { + // Reset + } + else + { + int i; + for( i = 0; i < argc; i ++ ) + { + if( args[i] < 8 ) + { + // Flags? + } + else if( 30 <= args[i] && args[i] <= 37 ) + { + // TODO: Bold/bright + Display_SetForeground( caVT100Colours[ args[i]-30 ] ); + } + else if( 40 <= args[i] && args[i] <= 47 ) + { + // TODO: Bold/bright + Display_SetBackground( caVT100Colours[ args[i]-30 ] ); + } + } + } + break; + default: + _SysDebug("Unknown VT100 escape char 0x%x", c); + break; + } + } + return j; +} diff --git a/Usermode/Applications/init_src/common.h b/Usermode/Applications/init_src/common.h new file mode 100644 index 00000000..406fe6fd --- /dev/null +++ b/Usermode/Applications/init_src/common.h @@ -0,0 +1,55 @@ +/* + * Acess2 Userland init(8) + * - Userland root process + * + * common.h + * - Common type definitions + */ +#ifndef _COMMON_H_ +#define _COMMON_H_ + +typedef struct sInitProgram tInitProgram; + +struct sKTerm +{ + int ID; +}; + +struct sSTerm +{ + uint32_t FormatBits; + unsigned int BaudRate; + char Path[]; +}; + +struct sDaemon +{ + char *StdoutPath; // heap + char *StderrPath; // heap +}; + +union uProgTypes +{ + struct sKTerm KTerm; + struct sSTerm STerm; + struct sDaemon Daemon; +}; + +enum eProgType +{ + PT_KTERM, + PT_STERM, + PT_DAEMON +}; + +struct sInitProgram +{ + tInitProgram *Next; + enum eProgType Type; + int CurrentPID; + char **Command; + union uProgTypes TypeInfo; +}; + +#endif + diff --git a/Usermode/Applications/init_src/main.c b/Usermode/Applications/init_src/main.c index 51b91942..a3d737d9 100644 --- a/Usermode/Applications/init_src/main.c +++ b/Usermode/Applications/init_src/main.c @@ -4,16 +4,37 @@ #include #include #include -//#include "common.h" +#include +#include "common.h" +#include // === CONSTANTS === -#define NUM_TERMS 4 -#define DEFAULT_TERMINAL "/Devices/VTerm/0" #define DEFAULT_SHELL "/Acess/SBin/login" +#define INITTAB_FILE "/Acess/Conf/inittab" #define ARRAY_SIZE(x) ((sizeof(x))/(sizeof((x)[0]))) // === PROTOTYPES === + int ProcessInittab(const char *Path); +char *ReadQuotedString(FILE *FP); +char **ReadCommand(FILE *FP); +void FreeCommand(char **Command); + +tInitProgram *AllocateProgram(char **Command, enum eProgType Type, size_t ExtraSpace); +void RespawnProgam(tInitProgram *Program); + + int AddKTerminal(int TerminalSpec, char **Command); + int AddSerialTerminal(const char *DevPathSegment, const char *ModeStr, char **Command); + int AddDaemon(char *StdoutPath, char *StderrPath, char **Command); + + int SpawnCommand(int c_stdin, int c_stdout, int c_stderr, char **ArgV); + int SpawnKTerm(tInitProgram *Program); + int SpawnSTerm(tInitProgram *Program); + int SpawnDaemon(tInitProgram *Program); + +// === GLOBALS === +const char *gsInittabPath = INITTAB_FILE; +tInitProgram *gpInitPrograms; // === CODE === /** @@ -22,33 +43,411 @@ */ int main(int argc, char *argv[]) { - int tid; - int i; - char termpath[sizeof(DEFAULT_TERMINAL)] = DEFAULT_TERMINAL; - char *child_argv[2] = {DEFAULT_SHELL, 0}; + // Parse commandline args + // TODO: cmdline + + // TODO: Behave differently if not invoked as first process? + + // Begin init process + if( ProcessInittab(gsInittabPath) != 0 ) + { + // No inittab file found, default to: + _SysDebug("inittab '%s' is invalid, falling back to one VT", gsInittabPath); + + #if 0 + for( ;; ) + { + int pid = SpawnCommand(0, 1, 1, (char *[]){DEFAULT_SHELL, NULL}); + // TODO: Detect errors + _SysWaitTID(pid, NULL); + } + #else + return 41; + #endif + } + + // TODO: Implement message watching + for(;;) + { + int pid, status; + pid = _SysWaitTID(-1, &status); + _SysDebug("PID %i died, looking for respawn entry", pid); + } - // - Parse init script + return 42; +} + +char *ReadQuotedString(FILE *FP) +{ + char ch; + + while( isblank(ch = fgetc(FP)) ) + ; + + if( ch == '\n' ) { + return NULL; + } + + char *retstr = NULL; + int mode = 0; + int pos = 0, space = 0; + for( ; !feof(FP); ch = fgetc(FP) ) + { + int skip; + skip = 1; + if( mode & 4 ) { + // Add escaped/special character + skip = 0; + mode &= 3; + } + else if( mode == 0 ) + { + if( isspace(ch) ) { + fseek(FP, -1, SEEK_CUR); + break; + } + else if( ch == '\\' ) + mode |= 4; + else if( ch == '"' ) + mode = 1; + else if( ch == '\'') + mode = 2; + else { + // Add character + skip = 0; + } + } + // Double-quoted string + else if( mode == 1 ) + { + if( ch == '"' ) + mode = 0; + else if( ch == '\\' ) + mode |= 4; + else { + // Add character + skip = 0; + } + } + // Single-quoted string + else if( mode == 2 ) + { + if( ch == '\'' ) + mode = 0; + else if( ch == '\\' ) + mode |= 4; + else { + // Add character + skip = 0; + } + } - // - Start virtual terminals - for( i = 0; i < NUM_TERMS; i++ ) - { - tid = _SysClone(CLONE_VM, 0); - if(tid == 0) + if( !skip ) { - termpath[sizeof(DEFAULT_TERMINAL)-2] = '0' + i; + if( pos == space ) { + space += 32; + void *tmp = realloc(retstr, space+1); + if( !tmp ) { + _SysDebug("ReadQuotedString - realloc(%i) failure", space+1); + free(retstr); + return NULL; + } + retstr = tmp; + } + retstr[pos++] = ch; + } + } + retstr[pos] = '\0'; + return retstr; +} + +char **ReadCommand(FILE *FP) +{ + const int space = 8; + int pos = 0; + char **ret = malloc(space*sizeof(char*)); + char *arg; + do { + arg = ReadQuotedString(FP); + if(arg == NULL) + break; + if( pos == space - 1 ) { + _SysDebug("Too many arguments %i", pos); + ret[pos] = NULL; + FreeCommand(ret); + return NULL; + } + ret[pos++] = arg; + } while(arg != NULL); + ret[pos] = NULL; + return ret; +} + +void FreeCommand(char **Command) +{ + int pos = 0; + while( Command[pos] ) + { + free(Command[pos]); + pos ++; + } + free(Command); +} + +int ProcessInittab(const char *Path) +{ + FILE *fp = fopen(Path, "r"); + + if( !fp ) + return 1; + + while(!feof(fp)) + { + char cmdbuf[64+1]; + + int rv; + if( (rv = fscanf(fp, "%64s%*[ \t]", &cmdbuf)) != 1 ) { + _SysDebug("fscanf rv %i != exp 1", rv); + break; + } + + // Clear comments + if( cmdbuf[0] == '#' ) { + while( !feof(fp) && fgetc(fp) != '\n' ) + ; + continue ; + } + if( cmdbuf[0] == '\0' ) { + char ch = fgetc(fp); + if( ch != '\n' && ch != -1 ) { + fclose(fp); + _SysDebug("Unexpected char 0x%x, expecting EOL", ch); + return 2; // Unexpected character? + } + continue ; + } + + // Check commands + if( strcmp(cmdbuf, "ktty") == 0 ) { + // ktty + // - Spins off a console on the specified kernel TTY + int id = 0; + if( fscanf(fp, "%d ", &id) != 1 ) { + _SysDebug("init[ktty] - TTY ID read failed"); + goto lineError; + } + char **command = ReadCommand(fp); + if( !command ) { + _SysDebug("init[ktty] - Command read failure"); + goto lineError; + } + AddKTerminal(id, command); + free(command); + } + else if(strcmp(cmdbuf, "stty") == 0 ) { + // stty [78][NOE][012][bB] + char path_seg[32+1]; + char modespec[4+6+1]; + if( fscanf(fp, "%32s %6s ", &path_seg, &modespec) != 2 ) { + goto lineError; + } + char **command = ReadCommand(fp); + if( !command ) + goto lineError; + AddSerialTerminal(path_seg, modespec, command); + } + else if(strcmp(cmdbuf, "daemon") == 0 ) { + // daemon + // - Runs a daemon (respawning) that logs to the specified files + // - Will append a header whenever the daemon starts + char *stdout_path = ReadQuotedString(fp); + char *stderr_path = ReadQuotedString(fp); + char **command = ReadCommand(fp); - _SysOpen(termpath, OPENFLAG_READ); // Stdin - _SysOpen(termpath, OPENFLAG_WRITE); // Stdout - _SysOpen(termpath, OPENFLAG_WRITE); // Stderr - _SysExecVE(DEFAULT_SHELL, child_argv, NULL); - for(;;) ; + AddDaemon(stdout_path, stderr_path, command); + } + else if(strcmp(cmdbuf, "exec") == 0 ) { + // exec + // - Runs a command and waits for it to complete before continuing + // - NOTE: No other commands will respawn while this is running + char **command = ReadCommand(fp); + if(!command) + goto lineError; + + int handles[] = {0, 1, 2}; + int pid = _SysSpawn(command[0], (const char **)command, NULL, 3, handles, NULL); + int retstatus; + _SysWaitTID(pid, &retstatus); + _SysDebug("Command '%s' returned %i", command[0], retstatus); + + FreeCommand(command); + } + else { + // Unknown command. + _SysDebug("Unknown command '%s'", cmdbuf); + goto lineError; } + fscanf(fp, " "); + continue; + lineError: + _SysDebug("label lineError: goto'd"); + while( !feof(fp) && fgetc(fp) != '\n' ) + ; + continue ; } + + fclose(fp); + return 0; +} + +tInitProgram *AllocateProgram(char **Command, enum eProgType Type, size_t ExtraSpace) +{ + tInitProgram *ret; - // TODO: Implement message watching - for(;;) - _SysWaitEvent(THREAD_EVENT_IPCMSG); + ret = malloc( sizeof(tInitProgram) - sizeof(union uProgTypes) + ExtraSpace ); + ret->Next = NULL; + ret->CurrentPID = 0; + ret->Type = Type; + ret->Command = Command; - return 42; + // Append + ret->Next = gpInitPrograms; + gpInitPrograms = ret; + + return ret; +} + +void RespawnProgam(tInitProgram *Program) +{ + int rv = 0; + switch(Program->Type) + { + case PT_KTERM: rv = SpawnKTerm(Program); break; + case PT_STERM: rv = SpawnSTerm(Program); break; + case PT_DAEMON: rv = SpawnDaemon(Program); break; + default: + _SysDebug("BUGCHECK - Program Type %i unknown", Program->Type); + break; + } + if( !rv ) { + _SysDebug("Respawn failure!"); + // TODO: Remove from list? + } +} + +int AddKTerminal(int TerminalID, char **Command) +{ + // TODO: Smarter validation + if( TerminalID < 0 || TerminalID > 7 ) + return -1; + + tInitProgram *ent = AllocateProgram(Command, PT_KTERM, sizeof(struct sKTerm)); + ent->TypeInfo.KTerm.ID = TerminalID; + + RespawnProgam(ent); + return 0; +} + +int AddSerialTerminal(const char *DevPathSegment, const char *ModeStr, char **Command) +{ + char dbit, parity, sbit; + int baud; + + // Parse mode string + if( sscanf(ModeStr, "%1[78]%1[NOE]%1[012]%*1[bB]%d", &dbit, &parity, &sbit, &baud) != 5 ) { + // Oops? + return -1; + } + + // Validate baud rate / build mode word + // TODO: Does baud rate need validation? + uint32_t modeword = 0; + modeword |= (dbit == '7' ? 1 : 0) << 0; + modeword |= (parity == 'O' ? 1 : (parity == 'E' ? 2 : 0)) << 1; + modeword |= (sbit - '0') << 3; + + // Create info + const char DEVPREFIX[] = "/Devices/"; + int pathlen = sizeof(DEVPREFIX) + strlen(DevPathSegment); + tInitProgram *ent = AllocateProgram(Command, PT_STERM, sizeof(struct sSTerm)+pathlen); + ent->TypeInfo.STerm.FormatBits = modeword; + ent->TypeInfo.STerm.BaudRate = baud; + strcpy(ent->TypeInfo.STerm.Path, DEVPREFIX); + strcat(ent->TypeInfo.STerm.Path, DevPathSegment); + + RespawnProgam(ent); + return 0; +} + +int AddDaemon(char *StdoutPath, char *StderrPath, char **Command) +{ + tInitProgram *ent = AllocateProgram(Command, PT_DAEMON, sizeof(struct sDaemon)); + ent->TypeInfo.Daemon.StdoutPath = StdoutPath; + ent->TypeInfo.Daemon.StderrPath = StderrPath; + + RespawnProgam(ent); + return 0; +} + +int SpawnCommand(int c_stdin, int c_stdout, int c_stderr, char **ArgV) +{ + int handles[] = {c_stdin, c_stdout, c_stderr}; + + int rv = _SysSpawn(ArgV[0], (const char **)ArgV, NULL, 3, handles, NULL); + + _SysClose(c_stdin); + if( c_stdout != c_stdin ) + _SysClose(c_stdout); + if( c_stderr != c_stdin && c_stderr != c_stdout ) + _SysClose(c_stderr); + + return rv; +} + +int SpawnKTerm(tInitProgram *Program) +{ + const char fmt[] = "/Devices/VTerm/%i"; + char path[sizeof(fmt)]; + + snprintf(path, sizeof(path), fmt, Program->TypeInfo.KTerm.ID); + + int in = _SysOpen(path, OPENFLAG_READ); + int out = _SysOpen(path, OPENFLAG_WRITE); + + return SpawnCommand(in, out, out, Program->Command); +} + +int SpawnSTerm(tInitProgram *Program) +{ + int in = _SysOpen(Program->TypeInfo.STerm.Path, OPENFLAG_READ); + int out = _SysOpen(Program->TypeInfo.STerm.Path, OPENFLAG_WRITE); + + #if 0 + if( _SysIOCtl(in, 0, NULL) != DRV_TYPE_SERIAL ) + { + // Oops? + return -2; + } + _SysIOCtl(in, SERIAL_IOCTL_GETSETBAUD, &Program->TypeInfo.STerm.BaudRate); + _SysIOCtl(in, SERIAL_IOCTL_GETSETFORMAT, &Program->TypeInfo.STerm.FormatBits); + #endif + + return SpawnCommand(in, out, out, Program->Command); +} + +int SpawnDaemon(tInitProgram *Program) +{ + int in = _SysOpen("/Devices/null", OPENFLAG_READ); + int out = _SysOpen(Program->TypeInfo.Daemon.StdoutPath, OPENFLAG_WRITE); + int err = _SysOpen(Program->TypeInfo.Daemon.StderrPath, OPENFLAG_WRITE); + + if( in == -1 || out == -1 || err == -1 ) { + _SysClose(in); + _SysClose(out); + _SysClose(err); + return -2; + } + + return SpawnCommand(in, out, err, Program->Command); } diff --git a/Usermode/Applications/irc_src/main.c b/Usermode/Applications/irc_src/main.c index 9e5a0757..16eee395 100644 --- a/Usermode/Applications/irc_src/main.c +++ b/Usermode/Applications/irc_src/main.c @@ -78,7 +78,7 @@ char *gsNickname = "acess"; tServer *gpServers; tWindow gWindow_Status = { NULL, NULL, NULL, // No next, empty list, no server - 0, "" // No activity, empty name (rendered as status) + 0, {""} // No activity, empty name (rendered as status) }; tWindow *gpWindows = &gWindow_Status; tWindow *gpCurrentWindow = &gWindow_Status; diff --git a/Usermode/Applications/telnetd_src/main.c b/Usermode/Applications/telnetd_src/main.c index a4f5e0da..bf6de999 100644 --- a/Usermode/Applications/telnetd_src/main.c +++ b/Usermode/Applications/telnetd_src/main.c @@ -55,17 +55,17 @@ int main(int argc, char *argv[]) return 0; } +static void FD_SET_MAX(fd_set *set, int fd, int *maxfd) +{ + FD_SET(fd, set); + if(*maxfd < fd) *maxfd = fd; +} + void EventLoop(void) { fd_set fds; int maxfd; - void FD_SET_MAX(fd_set *set, int fd, int *maxfd) - { - FD_SET(fd, set); - if(*maxfd < fd) *maxfd = fd; - } - for( ;; ) { FD_ZERO(&fds); diff --git a/Usermode/Filesystem/Conf/inittab b/Usermode/Filesystem/Conf/inittab new file mode 100644 index 00000000..a64bfc0c --- /dev/null +++ b/Usermode/Filesystem/Conf/inittab @@ -0,0 +1,8 @@ +exec /Acess/Bin/dhcpc + +ktty 0 /Acess/SBin/login +ktty 1 /Acess/SBin/login +stty serial/0 /Acess/SBin/login + + +#vim: ft=text diff --git a/Usermode/Filesystem/Makefile b/Usermode/Filesystem/Makefile index 7eb06940..a49d887d 100644 --- a/Usermode/Filesystem/Makefile +++ b/Usermode/Filesystem/Makefile @@ -5,7 +5,7 @@ DIRS = Bin SBin Libs Modules Apps DIRS += Conf Conf/Auth -FILES = Conf/BootConf.cfg +FILES = Conf/inittab # Conf/Auth/Users Conf/Auth/Passwords Conf/Auth/Groups #DIRS := $(addprefix $(DISTROOT)/,$(DIRS)) diff --git a/Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h b/Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h index 2c85b14e..351c8414 100644 --- a/Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h +++ b/Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h @@ -100,9 +100,23 @@ _errno: .long 0 @ Placed in .text, to allow use of relative addressing // Override the clone syscall #define _exit _exit_raw #define _clone _clone_raw +#define _SysSeek _SysSeek_borken #include "syscalls.s.h" #undef _exit #undef _clone +#undef _SysSeek + +// NOTE: _SysSeek needs special handling for alignment +.globl _SysSeek +_SysSeek: + push {lr} + mov r1,r2 + mov r2,r3 + ldr r3, [sp,#4] + svc #SYS_SEEK + ldr r3, =_errno + str r2, [r3] + pop {pc} .globl _clone _clone: @@ -120,6 +134,7 @@ _clone_ret: pop {r4} mov pc, lr + .globl _exit _exit: svc #0 diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h index 07939010..b2367d19 100644 --- a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h +++ b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/fd_set.h @@ -21,9 +21,29 @@ typedef struct } fd_set; -extern void FD_ZERO(fd_set *fdsetp); -extern void FD_CLR(int fd, fd_set *fdsetp); -extern void FD_SET(int fd, fd_set *fdsetp); -extern int FD_ISSET(int fd, fd_set *fdsetp); +static inline void FD_ZERO(fd_set *fdsetp) +{ + int i = FD_SETSIZE/16; + while( i-- ) + fdsetp->flags[i] = 0; +} +static inline void FD_CLR(int fd, fd_set *fdsetp) +{ + if(fd < 0 || fd > FD_SETSIZE) return; + fd_set_ent_t mask = 1 << (fd % 16); + fdsetp->flags[fd/16] &= ~mask; +} +static inline void FD_SET(int fd, fd_set *fdsetp) +{ + if(fd < 0 || fd > FD_SETSIZE) return; + fd_set_ent_t mask = 1 << (fd % 16); + fdsetp->flags[fd/16] |= mask; +} +static inline int FD_ISSET(int fd, fd_set *fdsetp) +{ + if(fd < 0 || fd > FD_SETSIZE) return 0; + fd_set_ent_t mask = 1 << (fd % 16); + return !!( fdsetp->flags[fd/16] & mask ); +} #endif diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h index c7987027..d9d31735 100644 --- a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h +++ b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h @@ -33,6 +33,8 @@ #define GETMSG_IGNORE ((void*)-1) #define FILEFLAG_DIRECTORY 0x10 #define FILEFLAG_SYMLINK 0x20 +#define CLONE_VM 0x10 + // === TYPES === diff --git a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h deleted file mode 120000 index 93c2064e..00000000 --- a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../KernelLand/Kernel/include/keysyms.h \ No newline at end of file diff --git a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h new file mode 100644 index 00000000..6517a405 --- /dev/null +++ b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/keysyms.h @@ -0,0 +1 @@ +#include "../../../../../KernelLand/Kernel/include/keysyms.h" diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile index 31adb5c2..c29e0e5f 100644 --- a/Usermode/Libraries/libc.so_src/Makefile +++ b/Usermode/Libraries/libc.so_src/Makefile @@ -10,7 +10,7 @@ LDFLAGS += -soname libc.so -Map map.txt INCFILES := stdio.h stdlib.h -OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o select.o rand.o +OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o rand.o OBJ += perror.o scanf.o signals.o strtoi.o strtof.o OBJ += arch/$(ARCHDIR).ao # signals.o diff --git a/Usermode/Libraries/libc.so_src/scanf.c b/Usermode/Libraries/libc.so_src/scanf.c index 6a1d584f..3d45ed13 100644 --- a/Usermode/Libraries/libc.so_src/scanf.c +++ b/Usermode/Libraries/libc.so_src/scanf.c @@ -152,6 +152,8 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char // int offset = -1; enum e_vcscanf_sizes size = _VCSCANF_UNDEF; enum e_vcscanf_types valtype; + int fail = 0; + int nnewch; const char *set_start; int set_len; @@ -161,6 +163,7 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char { while( (ich = __getc(h)) && isspace(ich) ) nch ++; + if(ich) __rewind(h); continue ; } @@ -262,22 +265,30 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char { // Decimal integer case 'd': - nch += _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival); + nnewch = _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival); + if(nnewch==0) fail=1; + nch += nnewch; valtype = _VCSCANF_INT; break; // variable-base integer case 'i': - nch += _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival); + nnewch = _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival); + if(nnewch==0) fail=1; + nch += nnewch; valtype = _VCSCANF_INT; break; // Octal integer case 'o': - nch += _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival); + nnewch = _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival); + if(nnewch==0) fail=1; + nch += nnewch; valtype = _VCSCANF_INT; break; // Hexadecimal integer case 'x': case 'X': - nch += _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival); + nnewch = _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival); + if(nnewch==0) fail=1; + nch += nnewch; valtype = _VCSCANF_INT; break; // strtod format float @@ -304,13 +315,14 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char maxlen = -1; ich = 0; - while( maxlen -- && (ich = __getc(h)) && !isblank(ich) ) + while( maxlen -- && (ich = __getc(h)) && !isspace(ich) ) { if(ptr._char) *ptr._char++ = ich; nch ++; } if( maxlen >= 0 && ich ) __rewind(h); + if(ptr._char) *ptr._char++ = 0; valtype = _VCSCANF_NOTYPE; break; // match a set of characters @@ -329,6 +341,8 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char fch = *format++; } while( fch && fch != ']' ); + if( maxlen == 0 ) + maxlen = -1; ich = 0; while( maxlen -- && (ich = __getc(h)) && memchr(set_start, set_len, ich) ) { @@ -337,6 +351,7 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char } if( maxlen >= 0 && ich ) __rewind(h); + if(ptr._char) *ptr._char++ = 0; valtype = _VCSCANF_NOTYPE; break; case 'p': // read back printf("%p") @@ -354,7 +369,10 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char valtype = _VCSCANF_NOTYPE; break; } - + + if(fail) + break; + switch(valtype) { case _VCSCANF_NOTYPE: @@ -406,7 +424,8 @@ int vsscanf(const char *str, const char *format, va_list ap) int _vfscanf_getc(void *h) { - return fgetc(h); // TODO: Handle -1 -> 0 + int ch = fgetc(h); + return ch == -1 ? 0 : ch; } void _vfscanf_rewind(void *h) { diff --git a/Usermode/Libraries/libc.so_src/select.c b/Usermode/Libraries/libc.so_src/select.c deleted file mode 100644 index c42848c4..00000000 --- a/Usermode/Libraries/libc.so_src/select.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Acess2 C Library - * - By John Hodge (thePowersGang) - * - * select.c - */ - -//#include -#include - -void FD_ZERO(fd_set *fdsetp) -{ - int i = FD_SETSIZE/16; - while( i-- ) - fdsetp->flags[i]=0; -} - -void FD_CLR(int fd, fd_set *fdsetp) -{ - if(fd < 0 || fd > FD_SETSIZE) return; - fdsetp->flags[fd/16] &= (fd_set_ent_t) ((~1 << (fd%16))) & 0xFFFF; -} - -void FD_SET(int fd, fd_set *fdsetp) -{ - if(fd < 0 || fd > FD_SETSIZE) return; - fdsetp->flags[fd/16] |= (fd_set_ent_t) (1 << (fd%16)); -} - -int FD_ISSET(int fd, fd_set *fdsetp) -{ - if(fd < 0 || fd > FD_SETSIZE) return 0; - return !!( fdsetp->flags[fd/16] & (1<<(fd%16)) ); -} - diff --git a/Usermode/Libraries/libc.so_src/stdio.c b/Usermode/Libraries/libc.so_src/stdio.c index 840e24d4..39d37a4b 100644 --- a/Usermode/Libraries/libc.so_src/stdio.c +++ b/Usermode/Libraries/libc.so_src/stdio.c @@ -348,6 +348,12 @@ EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) } else { ret = _SysRead(fp->FD, ptr, size*num); + if( ret == (size_t)-1) + return -1; + if( ret == 0 && size*num > 0 ) { + fp->Flags |= FILE_FLAG_EOF; + return 0; + } ret /= size; } @@ -403,7 +409,7 @@ EXPORT int putchar(int c) EXPORT int fgetc(FILE *fp) { char ret = 0; - if( fread(&ret, 1, 1, fp) == (size_t)-1 ) + if( fread(&ret, 1, 1, fp) != 1 ) return -1; return ret; } @@ -452,7 +458,7 @@ EXPORT int vsprintf(char * __s, const char *__format, va_list __args) return vsnprintf(__s, 0x7FFFFFFF, __format, __args); } -//sprintfv + /** * \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args) * \brief Prints a formatted string to a buffer @@ -470,11 +476,11 @@ EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list arg uint64_t arg; int bLongLong, bPadLeft; - void _addchar(char ch) - { - if(buf && pos < __maxlen) buf[pos] = ch; - pos ++; - } + #define _addchar(ch) do { \ + if(buf && pos < __maxlen) buf[pos] = (ch); \ + else (void)(ch); \ + pos ++; \ + } while(0) tmp[32] = '\0'; @@ -637,6 +643,7 @@ EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list arg } _addchar('\0'); pos --; + #undef _addchar //_SysDebug("vsnprintf: buf = '%s'", buf); @@ -708,7 +715,7 @@ EXPORT int printf(const char *format, ...) va_end(args); // Send to stdout - _SysWrite(_stdout, buf, size+1); + _SysWrite(_stdout, buf, size); // Free buffer free(buf); diff --git a/Usermode/Libraries/libposix.so_src/include_exp/sys/types.h b/Usermode/Libraries/libposix.so_src/include_exp/sys/types.h index db78b5a4..9b7aac0f 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/sys/types.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/sys/types.h @@ -13,8 +13,6 @@ typedef unsigned int u_int; typedef struct stat t_fstat; -#define CLONE_VM 0x10 - typedef unsigned int id_t; typedef unsigned long pid_t; typedef unsigned long tid_t; diff --git a/Usermode/Libraries/libunicode.so_src/Makefile b/Usermode/Libraries/libunicode.so_src/Makefile new file mode 100644 index 00000000..d515f3d0 --- /dev/null +++ b/Usermode/Libraries/libunicode.so_src/Makefile @@ -0,0 +1,14 @@ +# Acess 2 "libunicode" +# + +include ../Makefile.cfg + +CPPFLAGS += +CFLAGS += -Wall +LDFLAGS += -lc -soname libunicode.so + +OBJ = main.o utf-8.o +BIN = libunicode.so + +include ../Makefile.tpl + diff --git a/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h b/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h new file mode 100644 index 00000000..ef0eb56e --- /dev/null +++ b/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h @@ -0,0 +1,31 @@ +/* + * Acess2 "libunicode" UTF Parser + * - By John Hodge (thePowersGang) + * + * unicode.h + * - Main header + */ +#ifndef _LIBUNICODE__UNICODE_H_ +#define _LIBUNICODE__UNICODE_H_ + +#include + +/** + * \breif Read a single codepoint from a UTF-8 stream + * \return Number of bytes read + */ +extern int ReadUTF8(const char *Input, uint32_t *Val); +/** + * \brief Read backwards in the stream + */ +extern int ReadUTF8Rev(const char *Base, int Offset, uint32_t *Val); +/** + * \breif Write a single codepoint to a UTF-8 stream + */ +extern int WriteUTF8(char *buf, uint32_t Val); + + +static inline int Unicode_IsPrinting(uint32_t Codepoint) { return 1; } + +#endif + diff --git a/Usermode/Libraries/libunicode.so_src/main.c b/Usermode/Libraries/libunicode.so_src/main.c new file mode 100644 index 00000000..e39dc9bb --- /dev/null +++ b/Usermode/Libraries/libunicode.so_src/main.c @@ -0,0 +1,12 @@ +/* + * Acess2 "libunicode" + * - By John Hoge + * + * main.c + * - Stub main + */ + +int SoMain(void) +{ + return 0; +} diff --git a/Usermode/Libraries/libunicode.so_src/utf-8.c b/Usermode/Libraries/libunicode.so_src/utf-8.c new file mode 100644 index 00000000..3aa9d1a8 --- /dev/null +++ b/Usermode/Libraries/libunicode.so_src/utf-8.c @@ -0,0 +1,153 @@ +/* + * Acess2 "libunicode" UTF Parser + * - By John Hodge (thePowersGang) + * + * utf-8.c + * - UTF-8 Parsing code + */ +#include +#include + +/** + * \brief Read a UTF-8 character from a string + * \param Input Source UTF-8 encoded string + * \param Val Destination for read codepoint + * \return Number of bytes read/used + */ +int ReadUTF8(const char *Input, uint32_t *Val) +{ + const uint8_t *str = (const uint8_t *)Input; + *Val = 0xFFFD; // Assume invalid character + + // ASCII + if( !(*str & 0x80) ) { + *Val = *str; + return 1; + } + + // Middle of a sequence + if( (*str & 0xC0) == 0x80 ) { + return 1; + } + + // Two Byte + if( (*str & 0xE0) == 0xC0 ) { + *Val = (*str & 0x1F) << 6; // Upper 6 Bits + str ++; + if( (*str & 0xC0) != 0x80) return -1; // Validity check + *Val |= (*str & 0x3F); // Lower 6 Bits + return 2; + } + + // Three Byte + if( (*str & 0xF0) == 0xE0 ) { + *Val = (*str & 0x0F) << 12; // Upper 4 Bits + str ++; + if( (*str & 0xC0) != 0x80) return -1; // Validity check + *Val |= (*str & 0x3F) << 6; // Middle 6 Bits + str ++; + if( (*str & 0xC0) != 0x80) return -1; // Validity check + *Val |= (*str & 0x3F); // Lower 6 Bits + return 3; + } + + // Four Byte + if( (*str & 0xF8) == 0xF0 ) { + *Val = (*str & 0x07) << 18; // Upper 3 Bits + str ++; + if( (*str & 0xC0) != 0x80) return -1; // Validity check + *Val |= (*str & 0x3F) << 12; // Middle-upper 6 Bits + str ++; + if( (*str & 0xC0) != 0x80) return -1; // Validity check + *Val |= (*str & 0x3F) << 6; // Middle-lower 6 Bits + str ++; + if( (*str & 0xC0) != 0x80) return -1; // Validity check + *Val |= (*str & 0x3F); // Lower 6 Bits + return 4; + } + + // UTF-8 Doesn't support more than four bytes + return 4; +} + +/** + * \brief Get the UTF-8 character before the + * \ + */ +int ReadUTF8Rev(const char *Base, int Offset, uint32_t *Val) +{ + int len = 0; + + // Scan backwards for the beginning of the character + while( Offset > 0 && (Base[Offset--] & 0xC0) == 0x80 ) + len ++; + // Invalid string (no beginning) + if(Offset == 0 && (Base[Offset] & 0xC0) == 0x80 ) + return len; + + len ++; // First character + if( ReadUTF8(Base+Offset, Val) != len ) { + *Val = 0xFFFD; + } + return len; +} + +/** + * \brief Write a UTF-8 character sequence to a string + * \param buf Destination buffer (must have at least 4 bytes available) + * \param Val Unicode codepoint to write + * \return Number of bytes written + * \note Does not NULL terminate the string in \a buf + */ +int WriteUTF8(char *buf, uint32_t Val) +{ + uint8_t *str = (void*)buf; + + // ASCII + if( Val < 128 ) { + if(str) { + *str = Val; + } + return 1; + } + + // Two Byte + if( Val < 0x8000 ) { + if(str) { + *str = 0xC0 | (Val >> 6); + str ++; + *str = 0x80 | (Val & 0x3F); + } + return 2; + } + + // Three Byte + if( Val < 0x10000 ) { + if(str) { + *str = 0xE0 | (Val >> 12); + str ++; + *str = 0x80 | ((Val >> 6) & 0x3F); + str ++; + *str = 0x80 | (Val & 0x3F); + } + return 3; + } + + // Four Byte + if( Val < 0x110000 ) { + if(str) { + *str = 0xF0 | (Val >> 18); + str ++; + *str = 0x80 | ((Val >> 12) & 0x3F); + str ++; + *str = 0x80 | ((Val >> 6) & 0x3F); + str ++; + *str = 0x80 | (Val & 0x3F); + } + return 4; + } + + // UTF-8 Doesn't support more than four bytes + return 0; +} +