CPPFLAGS += -I./include -I./arch/$(ARCHDIR)/include -D_MODULE_NAME_=\"Kernel\"
CPPFLAGS += -D ARCH=$(ARCH) -D ARCHDIR=$(ARCHDIR) -D PLATFORM=\"$(PLATFORM)\" -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
CPPFLAGS += -D KERNEL_VERSION=$(KERNEL_VERSION) -ffreestanding
-CFLAGS += -Wall -fno-stack-protector -Wstrict-prototypes -std=gnu99 -g
+CFLAGS += -Wall -fno-stack-protector -Wstrict-prototypes -std=gnu99 -g -fno-omit-frame-pointer
CFLAGS += -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wuninitialized
CFLAGS += -O3
LDFLAGS += -T arch/$(ARCHDIR)/link.ld -g
* drv/dgram_pipe.c
* - Connection+Datagram based local IPC
*/
-#define DEBUG 1
+#define DEBUG 0
#include <vfs.h>
#include <fs_devfs.h>
#include <modules.h>
gpVT_CurTerm->Buffer = malloc( gpVT_CurTerm->Width*gpVT_CurTerm->Height*4 );
if( gpVT_CurTerm->Width < giVT_RealWidth )
{
- int line;
Uint ofs = 0;
Uint32 *dest = gpVT_CurTerm->Buffer;
// Slower scanline copy
- for( line = 0; line < gpVT_CurTerm->Height; line ++ )
+ for( int line = 0; line < gpVT_CurTerm->Height; line ++ )
{
VFS_ReadAt(giVT_OutputDevHandle, ofs, gpVT_CurTerm->Width*4, dest);
ofs += giVT_RealWidth * 4;
gpVT_CurTerm->Buffer
);
}
+ LOG("Cached screen contents");
}
// Update current terminal ID
#define SYS_OPENPIPE 67 // Open a FIFO pipe pair
#define SYS_CLOSE 68 // Close a file
#define SYS_COPYFD 69 // Create a copy of a file handle
-#define SYS_FDCTL 70 // Modify properties of a file descriptor
+#define SYS_FDCTL 70 // Modify flags of a file descriptor
#define SYS_READ 71 // Read from an open file
#define SYS_WRITE 72 // Write to an open file
#define SYS_IOCTL 73 // Perform an IOCtl Call
%define SYS_OPENPIPE 67 ;Open a FIFO pipe pair
%define SYS_CLOSE 68 ;Close a file
%define SYS_COPYFD 69 ;Create a copy of a file handle
-%define SYS_FDCTL 70 ;Modify properties of a file descriptor
+%define SYS_FDCTL 70 ;Modify flags of a file descriptor
%define SYS_READ 71 ;Read from an open file
%define SYS_WRITE 72 ;Write to an open file
%define SYS_IOCTL 73 ;Perform an IOCtl Call
SYS_OPENPIPE Open a FIFO pipe pair
SYS_CLOSE Close a file
SYS_COPYFD Create a copy of a file handle
-SYS_FDCTL Modify properties of a file descriptor
+SYS_FDCTL Modify flags of a file descriptor
SYS_READ Read from an open file
SYS_WRITE Write to an open file
SYS_IOCTL Perform an IOCtl Call
*/
int IPStack_AddFile(tSocketFile *File)
{
- Log_Log("IPStack", "Added file '%s'", File->Name);
+// Log_Log("IPStack", "Added file '%s'", File->Name);
File->Next = gIP_FileTemplates;
gIP_FileTemplates = File;
return 0;
{
tCard **cardptr = Arg;
tCard *Card = *cardptr;
- int rxd = (Arg - (void*)Card->RXDescs) / sizeof(tRXDesc);
-
+ int rxd = (Arg - (void*)Card->RXBackHandles) / sizeof(void*);
+
+ LOG("RXD %p %i being released", Card, rxd);
+ ASSERT(rxd >= 0 && rxd < NUM_RX_DESC);
+
Card->RXDescs[rxd].Status = 0;
Mutex_Acquire(&Card->lRXDescs);
if( rxd == REG32(Card, REG_RDT) ) {
--- /dev/null
+PTYs
+
+Need support for toggling echo and line buffering
+- This needs to be communicated to pty owner somehow
+ > Second FD? Nominated data structure? Out of band data?
+- API for the pty control?
+ > "_SysSetFileFlag"/"_SysGetFileFlag"?
+ Provides arbitary flags for each node
+ E.g. Terminal graphics mode, echo and buffering
QEMU_PARAMS=$QEMU_PARAMS" -hda AcessHDD.img"
QEMU_PARAMS=$QEMU_PARAMS" -vga std"
QEMU_PARAMS=$QEMU_PARAMS" -smp 2"
-QEMU_PARAMS=$QEMU_PARAMS" -net nic"
+QEMU_PARAMS=$QEMU_PARAMS" -net nic,model=e1000"
+#QEMU_PARAMS=$QEMU_PARAMS" -net nic,model=rtl8139"
-_NETTYPE="user"
+_NETTYPE="user,hostfwd=tcp::5555-:23"
_EVAL=eval
done
run() {
- #echo --- $*
+ if [[ "x$GCCPROXY_DEBUG" != "x" ]]; then
+ echo --- $*
+ fi
$*
return $?
}
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 $LIBGCC_PATH $_libs
+ run $_LD $LDFLAGS $_ldflags $_libs $tmpout $_outfile $_libs $LIBGCC_PATH
_rv=$?
rm $tmpout
exit $_rv
else
- run $_LD $_ldflags $_miscargs $_outfile $LDFLAGS $LIBGCC_PATH $_libs
+ run $_LD $_ldflags $_miscargs $_outfile $LDFLAGS $_libs $LIBGCC_PATH
fi
CPPFLAGS += $(addprefix -I,$(wildcard $(ACESSUSERDIR)Libraries/*/include_exp/))
CPPFLAGS += -I$(ACESSUSERDIR)/include/ -DARCHDIR_is_$(ARCHDIR)
+CFLAGS += -std=c99
LDFLAGS += -rpath-link $(OUTPUTDIR)Libs
# Extra-verbose errors!
_SysDebug("DoRun pressed");
char *cmd = AxWin3_Widget_GetText(gRunInput);
_SysDebug("Command string '%s'", cmd);
+
+ // TODO: Parse the command string into components
+ // TODO: Call _SysSpawn
+
AxWin3_ShowWindow(gRunDialog, 0);
return 0;
}
#define AXWIN_VERSION 0x300
+static inline int MIN(int a, int b) { return (a < b) ? a : b; }
+static inline int MAX(int a, int b) { return (a > b) ? a : b; }
+
// === GLOBALS ===
extern int giTerminalFD;
extern const char *gsTerminalDevice;
#define WINFLAG_MAXIMIZED 0x00000004
//! Window is contained within the parent
#define WINFLAG_RELATIVE 0x00000008
+//! Window needs to be reblitted (child moved or contents changed)
+#define WINFLAG_NEEDREBLIT 0x00000020
//! Window contents are valid
#define WINFLAG_CLEAN 0x00000040
//! All child windows are un-changed
extern tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int Flags, const char *Renderer);
extern void WM_DestroyWindow(tWindow *Window);
extern tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID);
-extern void WM_Invalidate(tWindow *Window);
+extern void WM_Invalidate(tWindow *Window, int bClearClean);
extern void WM_SetWindowTitle(tWindow *Window, const char *Title);
extern void WM_FocusWindow(tWindow *Destination);
extern void WM_RaiseWindow(tWindow *Window);
int IPC_Type_IPCPipe_Compare(const void *Ident1, const void *Ident2);
void IPC_Type_IPCPipe_Send(const void *Ident, size_t Length, const void *Data);
tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident);
+void IPC_int_DropClient(tIPC_Client *Client);
void IPC_Handle(tIPC_Client *Client, size_t MsgLen, tAxWin_IPCMessage *Msg);
// === GLOBALS ===
if( giIPCPipeHandle != -1 && FD_ISSET(giIPCPipeHandle, set) )
{
int newfd = _SysOpenChild(giIPCPipeHandle, "newclient", OPENFLAG_READ|OPENFLAG_WRITE);
- _SysDebug("newfd = %i");
+ _SysDebug("newfd = %i", newfd);
IPC_int_GetClient(&gIPC_Type_IPCPipe, &newfd);
}
char staticBuf[STATICBUF_SIZE];
size_t len;
len = _SysRead(fd, staticBuf, sizeof(staticBuf));
+ if( len == (size_t)-1 ) {
+ // TODO: Check errno for EINTR
+ IPC_int_DropClient(gIPC_Clients[i]);
+ break;
+ }
IPC_Handle( gIPC_Clients[i], len, (void*)staticBuf );
}
}
return a->IPCType->CompareIdent(a->Ident, b->Ident);
}
+int IPC_int_BSearchClients(const tIPC_Client *TargetClient, int *Pos)
+{
+ int div;
+ int cmp = -1;
+ int pos = 0;
+
+ div = giIPC_ClientCount;
+ pos = div/2;
+ while(div > 0)
+ {
+ div /= 2;
+ cmp = _CompareClientPtrs(&TargetClient, &gIPC_Clients[pos]);
+// _SysDebug("Checking against %i gives %i", pos, cmp);
+ if(cmp == 0) break;
+ if(cmp < 0)
+ pos -= div;
+ else
+ pos += div;
+ }
+
+ // - Return if found
+ if(cmp == 0) {
+ *Pos = pos;
+ return 1;
+ }
+
+ // Adjust pos to be the index where the new client will be placed
+ if(cmp > 0) pos ++;
+ *Pos = pos;
+ return 0;
+}
+
tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident)
{
int pos = 0; // Position where the new client will be inserted
if(giIPC_ClientCount > 0)
{
tIPC_Client target;
- int div;
- int cmp = -1;
-
target.IPCType = IPCType;
target.Ident = Ident;
- ret = ⌖ // Abuse ret to get a pointer
-
- div = giIPC_ClientCount;
- pos = div/2;
- while(div > 0)
- {
- div /= 2;
- cmp = _CompareClientPtrs(&ret, &gIPC_Clients[pos]);
-// _SysDebug("Checking against %i gives %i", pos, cmp);
- if(cmp == 0) break;
- if(cmp < 0)
- pos -= div;
- else
- pos += div;
- }
-
- // - Return if found
- if(cmp == 0)
+ if( IPC_int_BSearchClients(&target, &pos) )
return gIPC_Clients[pos];
-
- // Adjust pos to be the index where the new client will be placed
- if(cmp > 0) pos ++;
}
return ret;
}
+void IPC_int_DropClient(tIPC_Client *Client)
+{
+ // Remove from client list
+ int pos;
+ if( !IPC_int_BSearchClients(Client, &pos) ) {
+ _SysDebug("IPC_int_DropClient: Can't find client %p", Client);
+ return ;
+ }
+
+ giIPC_ClientCount --;
+ memmove(&gIPC_Clients[pos], &gIPC_Clients[pos+1], (giIPC_ClientCount-pos)*sizeof(tIPC_Client*));
+
+ // Terminate client's windows
+ // - If there were active windows, show an error?
+ int nWindowsDestroyed = 0;
+ for(int i = 0; i < Client->nWindows; i ++)
+ {
+ if( Client->Windows[i] )
+ {
+ _SysDebug("Window %p:%i %p still exists", Client, i, Client->Windows[i]);
+ WM_DestroyWindow(Client->Windows[i]);
+ nWindowsDestroyed ++;
+ }
+ }
+ if( nWindowsDestroyed )
+ {
+ _SysDebug("TODO: Show notice that application exited without destroying windows");
+ }
+
+ // Free client structure
+ free(Client);
+ _SysDebug("Dropped client %p", Client);
+}
+
tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID)
{
if( WindowID == -1 )
return 0;
WM_DestroyWindow(win);
+ IPC_int_SetWindow(Client, Msg->Window, NULL);
return 0;
}
{
tWindow *win = IPC_int_GetWindow(Client, Msg->Window);
if( !win ) {
- _SysDebug("WARNING: NULL window in message %i", Msg->ID);
+ _SysDebug("WARNING: NULL window in message %i (%x)", Msg->ID, Msg->Window);
return ;
}
tWMRenderer *renderer = win->Renderer;
{
info->HilightedItem = new_hilight;
// TODO: Change sub-menu
- WM_Invalidate(Window);
+ WM_Invalidate(Window, 1);
}
return 0; }
struct sRichText_Line *Next;
struct sRichText_Line *Prev;
int Num;
+ char bIsClean;
// TODO: Pre-rendered cache?
short ByteLength;
short Space;
tColour DefaultFG;
tColour DefaultBG;
tFont *Font;
+ char bNeedsFullRedraw;
short LineHeight;
} tRichText_Window;
void Renderer_RichText_Redraw(tWindow *Window)
{
tRichText_Window *info = Window->RendererInfo;
- int i;
tRichText_Line *line = info->FirstVisLine;
if( !line ) {
while( line && line->Prev && line->Prev->Num > info->FirstVisRow )
line = line->Prev;
+ int i;
for( i = 0; i < info->DispLines && line; i ++ )
{
if( i >= info->nLines - info->FirstVisRow )
break;
- // TODO: Dirty rectangles?
+ // Empty line is noted by a discontinuity
+ if( line->Num > info->FirstVisRow + i ) {
+ // Clear line if window needs full redraw
+ if( info->bNeedsFullRedraw ) {
+ WM_Render_FillRect(Window,
+ 0, i*info->LineHeight,
+ Window->W, info->LineHeight,
+ info->DefaultBG
+ );
+ }
+ else {
+ // Hack to clear cursor on NULL lines
+ WM_Render_FillRect(Window,
+ 0, i*info->LineHeight,
+ 1, info->LineHeight,
+ info->DefaultBG
+ );
+ }
+ continue ;
+ }
+
+ if( info->bNeedsFullRedraw || !line->bIsClean )
+ {
+ WM_Render_FillRect(Window,
+ 0, i*info->LineHeight,
+ Window->W, info->LineHeight,
+ info->DefaultBG
+ );
+
+ // Formatted text out
+ Renderer_RichText_RenderText(Window, i, line->Data);
+ _SysDebug("RichText: %p - Render %i '%.*s'", Window,
+ line->Num, line->ByteLength, line->Data);
+ line->bIsClean = 1;
+ }
+
+ line = line->Next;
+ }
+ // Clear out lines i to info->DispLines-1
+ if( info->bNeedsFullRedraw )
+ {
+ _SysDebug("RichText: %p - Clear %i px lines with %06x starting at %i",
+ Window, (info->DispLines-i)*info->LineHeight, info->DefaultBG, i*info->LineHeight);
WM_Render_FillRect(Window,
0, i*info->LineHeight,
- Window->W, info->LineHeight,
+ Window->W, (info->DispLines-i)*info->LineHeight,
info->DefaultBG
);
- if( line->Num > info->FirstVisRow + i )
- continue ;
- // TODO: Horizontal scrolling?
- // TODO: Formatting
-
- // Formatted text out
- Renderer_RichText_RenderText(Window, i, line->Data);
- _SysDebug("RichText: %p - Render %i '%.*s'", Window,
- line->Num, line->ByteLength, line->Data);
-
- line = line->Next;
}
- // Clear out i -- info->DispLines
- _SysDebug("RichText: %p - Clear %i px lines with %06x starting at %i",
- Window, (info->DispLines-i)*info->LineHeight, info->DefaultBG, i*info->LineHeight);
- WM_Render_FillRect(Window,
- 0, i*info->LineHeight,
- Window->W, (info->DispLines-i)*info->LineHeight,
- info->DefaultBG
- );
+ info->bNeedsFullRedraw = 0;
- // HACK!
+ // HACK: Hardcoded text width of 8
info->DispCols = Window->W / 8;
- // TODO: Text cursor
+ // 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 )
}
}
+tRichText_Line *Renderer_RichText_int_GetLine(tWindow *Window, int LineNum, tRichText_Line **Prev)
+{
+ tRichText_Window *info = Window->RendererInfo;
+ tRichText_Line *line = info->FirstLine;
+ tRichText_Line *prev = NULL;
+ while(line && line->Num < LineNum)
+ prev = line, line = line->Next;
+
+ if( Prev )
+ *Prev = prev;
+
+ if( !line || line->Num > LineNum )
+ return NULL;
+ return line;
+}
+
int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data)
{
tRichText_Window *info = Window->RendererInfo;
case _ATTR_DEFFG:
info->DefaultFG = msg->Value;
break;
- case _ATTR_CURSORPOS:
- info->CursorRow = msg->Value >> 12;
- info->CursorCol = msg->Value & 0xFFF;
- break;
+ case _ATTR_CURSORPOS: {
+ int newRow = msg->Value >> 12;
+ int newCol = msg->Value & 0xFFF;
+ // Force redraw of old and new row
+ tRichText_Line *line = Renderer_RichText_int_GetLine(Window, info->CursorRow, NULL);
+ if( line )
+ line->bIsClean = 0;
+ if( newRow != info->CursorRow ) {
+ line = Renderer_RichText_int_GetLine(Window, newRow, NULL);
+ if(line)
+ line->bIsClean = 0;
+ }
+ info->CursorRow = newRow;
+ info->CursorCol = newCol;
+ WM_Invalidate(Window, 1);
+ break; }
case _ATTR_SCROLL:
// TODO: Set scroll flag
break;
if( Len < sizeof(*msg) ) return -1;
if( msg->Line >= info->nLines ) return 1; // Bad count
- tRichText_Line *line = info->FirstLine;
tRichText_Line *prev = NULL;
- while(line && line->Num < msg->Line)
- prev = line, line = line->Next;
- if( !line || line->Num > msg->Line )
+ tRichText_Line *line = Renderer_RichText_int_GetLine(Window, msg->Line, &prev);
+ if( !line )
{
// New line!
// Round up to 32
int space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1);
tRichText_Line *new = malloc(sizeof(*line) + space);
// TODO: Bookkeeping on how much memory each window uses
- new->Next = line;
+ new->Next = (prev ? prev->Next : NULL);
new->Prev = prev;
new->Num = msg->Line;
new->Space = space;
}
line->ByteLength = Len - sizeof(*msg);
memcpy(line->Data, msg->LineData, Len - sizeof(*msg));
+ line->bIsClean = 0;
- WM_Invalidate( Window );
+// WM_Invalidate(Window, 1);
- return 0;
+ return 0;
}
int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
const struct sWndMsg_Resize *msg = Data;
if(Len < sizeof(*msg)) return -1;
info->DispLines = msg->H / info->LineHeight;
+ info->bNeedsFullRedraw = 1; // force full rerender
return 1; }
case WNDMSG_KEYDOWN:
case WNDMSG_KEYUP:
}
// TODO: Have a Widget_ function to do this instead
- WM_Invalidate(Element->Window);
+ WM_Invalidate(Element->Window, 1);
return 0;
}
_SysDebug("Video_Update - Sending FD %i %p 0x%x", giTerminalFD, gpScreenBuffer+ofs, size*4);
_SysWrite(giTerminalFD, gpScreenBuffer+ofs, size*4);
_SysDebug("Video_Update - Done");
- giVideo_FirstDirtyLine = 0;
+ giVideo_FirstDirtyLine = giScreenHeight;
giVideo_LastDirtyLine = 0;
}
if( W <= 0 || H <= 0 ) return;
- if( DstY < giVideo_FirstDirtyLine )
- giVideo_FirstDirtyLine = DstY;
- if( DstY + H > giVideo_LastDirtyLine )
- giVideo_LastDirtyLine = DstY + H;
+ giVideo_FirstDirtyLine = MIN(DstY, giVideo_FirstDirtyLine);
+ giVideo_LastDirtyLine = MAX(DstY+H, giVideo_LastDirtyLine);
buf = gpScreenBuffer + DstY*giScreenWidth + DstX;
if(drawW != giScreenWidth || W != giScreenWidth)
else
Window->Parent->LastChild = prev;
}
- WM_Invalidate(Window->Parent);
+ // - Full invalidate
+ WM_Invalidate(Window, 1);
// - Remove from inheritance tree?
if( Window->Renderer->DestroyWindow )
Window->Renderer->DestroyWindow(Window);
else
- _SysDebug("WARN: Renderer %s does not have a destroy function", Window->Renderer->Name);
+ _SysDebug("WARN: Renderer '%s' does not have a destroy function", Window->Renderer->Name);
// - Tell client to clean up
WM_SendMessage(NULL, Window, WNDMSG_DESTROY, 0, NULL);
_msg.Val = 1;
WM_SendMessage(NULL, Destination, WNDMSG_FOCUS, sizeof(_msg), &_msg);
}
-
- WM_Invalidate(gpWM_FocusedWindow);
- WM_Invalidate(Destination);
+
+ // TODO: Leave it up to the renderer to decide to invalidate
+ WM_Invalidate(gpWM_FocusedWindow, 1);
+ WM_Invalidate(Destination, 1);
gpWM_FocusedWindow = Destination;
}
if( !!(Window->Flags & WINFLAG_SHOW) == bShow )
return ;
+
+ // Window is being hidden, invalidate parents
+ if( !bShow )
+ WM_Invalidate(Window, 0);
// Message window
_msg.Val = !!bShow;
_SysDebug("Window %p hidden", Window);
}
- WM_Invalidate(Window);
+ // Window has been shown, invalidate everything
+ if( bShow )
+ WM_Invalidate(Window, 1);
}
void WM_DecorateWindow(tWindow *Window, int bDecorate)
Window->RenderBuffer = NULL;
}
- WM_Invalidate(Window);
+ WM_Invalidate(Window, 1);
}
void WM_SetRelative(tWindow *Window, int bRelativeToParent)
}
// TODO: Re-sanitise
+ if( Window->X == X && Window->Y == Y ) {
+ _SysDebug("WM_MoveWindow: Equal (%i,%i)", X, Y);
+ return 0;
+ }
+
+ if( Window->Parent )
+ Window->Parent->Flags |= WINFLAG_NEEDREBLIT;
+
_SysDebug("WM_MoveWindow: (%i,%i)", X, Y);
Window->X = X; Window->Y = Y;
// Mark up the tree that a child window has changed
- while( (Window = Window->Parent) )
- Window->Flags &= ~WINFLAG_CHILDCLEAN;
+ WM_Invalidate(Window, 0);
return 0;
}
if( Window->W == W && Window->H == H )
return 0;
+
+ // If the window size has decreased, force the parent to reblit
+ if( Window->Parent && (Window->W > W || Window->H > H) )
+ Window->Parent->Flags |= WINFLAG_NEEDREBLIT;
- _SysDebug("WM_ResizeWindow: %ix%i", W, H);
+ _SysDebug("WM_ResizeWindow: %p:%i %ix%i", Window->Client, Window->ID, W, H);
Window->W = W; Window->H = H;
if(Window->RenderBuffer) {
free(Window->RenderBuffer);
Window->RenderBuffer = NULL;
}
- WM_Invalidate(Window);
+ WM_Invalidate(Window, 1);
{
struct sWndMsg_Resize msg;
return 0;
}
-void WM_Invalidate(tWindow *Window)
+void WM_Invalidate(tWindow *Window, int bClearClean)
{
if(!Window) return ;
-// _SysDebug("Invalidating %p", Window);
- // Don't invalidate twice (speedup)
-// if( !(Window->Flags & WINFLAG_CLEAN) ) return;
-
+
+ // Don't bother invalidating if the window isn't shown
+ if( !(Window->Flags & WINFLAG_SHOW) )
+ return ;
+
// Mark for re-render
- Window->Flags &= ~WINFLAG_CLEAN;
+ if( bClearClean )
+ Window->Flags &= ~WINFLAG_CLEAN;
// Mark up the tree that a child window has changed
- while( (Window = Window->Parent) )
+ while( (Window = Window->Parent) && (Window->Flags & WINFLAG_SHOW) )
Window->Flags &= ~WINFLAG_CHILDCLEAN;
}
}
Window->Renderer->Redraw(Window);
- Window->Flags |= WINFLAG_CLEAN;
+ Window->Flags |= WINFLAG_CLEAN|WINFLAG_NEEDREBLIT;
}
// Process children
Decorator_Redraw(Window);
}
-void WM_int_BlitWindow(tWindow *Window)
+void WM_int_BlitWindow(tWindow *Window, int bForceReblit)
{
tWindow *child;
// _SysDebug("Blit %p (%p) to (%i,%i) %ix%i", Window, Window->RenderBuffer,
// Window->RealX, Window->RealY, Window->RealW, Window->RealH);
- Video_Blit(Window->RenderBuffer, Window->RealX, Window->RealY, Window->RealW, Window->RealH);
+ // TODO Don't blit unless:
+ // a) A parent has been reblitted (thus clobbering the existing content)
+ // b) A child has moved (exposing a previously hidden area)
+ if( bForceReblit || (Window->Flags & WINFLAG_NEEDREBLIT) )
+ {
+ Video_Blit(Window->RenderBuffer, Window->RealX, Window->RealY, Window->RealW, Window->RealH);
+ Window->Flags &= ~WINFLAG_NEEDREBLIT;
+ bForceReblit = 1;
+ }
if( Window == gpWM_FocusedWindow && Window->CursorW )
{
for( child = Window->FirstChild; child; child = child->NextSibling )
{
- WM_int_BlitWindow(child);
+ WM_int_BlitWindow(child, bForceReblit);
}
}
WM_int_UpdateWindow(gpWM_RootWindow);
// - Draw windows from back to front to the render buffer
- WM_int_BlitWindow(gpWM_RootWindow);
+ WM_int_BlitWindow(gpWM_RootWindow, 0);
Video_Update();
}
*/
enum eWM_WindowMessages
{
- WNDMSG_NULL,
+ WNDMSG_NULL, // 0
- WNDMSG_CREATE,
- WNDMSG_DESTROY,
- WNDMSG_CLOSE,
- WNDMSG_FOCUS, // Called on change
- WNDMSG_SHOW, // Called on change
+ WNDMSG_CREATE, // 1
+ WNDMSG_DESTROY, // 2
+ WNDMSG_CLOSE, // 3
+ WNDMSG_FOCUS, // 4 Called on change
+ WNDMSG_SHOW, // 5 Called on change
- WNDMSG_RESIZE,
+ WNDMSG_RESIZE, // 6
- WNDMSG_MOUSEMOVE,
- WNDMSG_MOUSEBTN,
- WNDMSG_KEYDOWN,
- WNDMSG_KEYFIRE,
- WNDMSG_KEYUP,
+ WNDMSG_MOUSEMOVE, // 7
+ WNDMSG_MOUSEBTN, // 8
+ WNDMSG_KEYDOWN, // 9
+ WNDMSG_KEYFIRE, // 10
+ WNDMSG_KEYUP, // 11
WNDMSG_HOTKEY,
{
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;
+ case WNDMSG_KEYDOWN:
+ if(Size < sizeof(*keyaction)) return -1;
+ info->KeyCallback(Window, 1, keyaction->KeySym, keyaction->UCS32);
+ return 1;
+ case WNDMSG_KEYUP:
+ if(Size < sizeof(*keyaction)) return -1;
+ info->KeyCallback(Window, 0, keyaction->KeySym, 0);
+ return 1;
}
return 0;
}
#include <widget_messages.h>
#include <string.h>
+//static const int ciBaseElementCount = 16;
+static const int ciStepElementCount = 16;
+
// === STRUCTURES ===
struct sAxWin3_Widget
{
}
if( newID == Info->nElements )
{
- const int size_step = 4;
- Info->nElements += 4;
+ Info->nElements += ciStepElementCount;
Info->Elements = realloc(Info->Elements, sizeof(*Info->Elements)*Info->nElements);
- newID = Info->nElements - 4;
- memset( &Info->Elements[newID+1], 0, (size_step-1)*sizeof(Info->Elements));
+ newID = Info->nElements - ciStepElementCount;
+ memset( &Info->Elements[newID+1], 0, (ciStepElementCount-1)*sizeof(Info->Elements));
_SysDebug("Widget: Expanded to %i and allocated %i", Info->nElements, newID);
}
else
switch(MessageID)
{
+// case WNDMSG_DESTROY: {
+// return 0; }
case MSG_WIDGET_FIRE: {
tWidgetMsg_Fire *msg = Data;
if(Size < sizeof(*msg)) return -1;
widget = AxWin3_Widget_int_GetElementByID(Window, msg->WidgetID);
if(widget->Fire) widget->Fire(widget);
+ return 1; }
+ case MSG_WIDGET_KEYPRESS: {
+ return 0; }
+ case MSG_WIDGET_MOUSEBTN: {
+ // TODO: Do something
return 1; }
default:
return 0;
return block->Windows[ServerID];
}
+void AxWin3_int_DelWindowByID(uint32_t ServerID)
+{
+ int orig_id = ServerID;
+ tWindowBlock *block = &gAxWin3_WindowList;
+ while(block && ServerID > WINDOWS_PER_ALLOC) {
+ block = block->Next;
+ ServerID -= WINDOWS_PER_ALLOC;
+ }
+ if( !block || !block->Windows[ServerID] )
+ _SysDebug("AxWin3_int_DelWindowByID - Id %i out of range", orig_id);
+ else
+ block->Windows[ServerID] = NULL;
+}
+
tWindow *AxWin3_int_AllocateWindowInfo(int DataBytes, int *WinID)
{
int idx, newWinID;
case WNDMSG_DESTROY:
_SysDebug("TODO: Check that WNDMSG_DESTROY was from us calling _DestroyWindow");
// TODO: Finalise cleanup of window, this will be the last message sent to this window
+ AxWin3_int_DelWindowByID(Win->ServerID);
return 1;
default:
return 0;
Display_int_PushString(bytes, UTF8Text);
UTF8Text += bytes;
- _SysDebug("Length(%i) -= bytes(%i)", Length, bytes);
Length -= bytes;
if( Length != 0 )
{
void Display_Newline(int bCarriageReturn)
{
- Display_Flush();
+// Display_Flush();
// Going down!
giCurrentLine ++;
AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] );
gabDisplayLinesDirty[line] = 0;
}
-
- // force redraw?
AxWin3_RichText_SetCursorPos(gMainWindow, giCurrentLine, giCurrentCol);
}
{
_SysDebug("Activity on child stdout");
// Read and update screen
- char buf[32];
+ char buf[128];
int len = _SysRead(giChildStdout, buf, sizeof(buf));
if( len <= 0 ) break;
static int ctrl_state = 0;
// Handle modifiers
- #define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=1<<(bit);}while(0)
+ #define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=~(1<<(bit));}while(0)
switch(KeySym)
{
case KEYSYM_LEFTCTRL:
if( ctrl_state && KeySym >= KEYSYM_a && KeySym <= KEYSYM_z )
{
Translated = KeySym - KEYSYM_a + 1;
+ _SysDebug("Ctrl-%c: KS %x => Trans %x", 'A'+(KeySym-KEYSYM_a), KeySym, Translated);
}
// == 2 :: FIRE
// Encode and send
len = WriteUTF8(buf, Translated);
- _SysDebug("Keystroke translated to '%.*s'", len, buf);
+ _SysDebug("Keystroke %x:%x translated to '%.*s'", KeySym, Translated, len, buf);
_SysWrite(giChildStdin, buf, len);
return 0;
esc_len = -esc_len;
}
ofs += esc_len;
- _SysDebug("Len = %i, ofs = %i", Len, ofs);
+ //_SysDebug("Len = %i, ofs = %i", Len, ofs);
}
Display_Flush();
return 0;\r
}\r
\r
+\r
+void Cmd_join(char *ArgString)\r
+{\r
+ int pos=0;\r
+ char *channel_name = GetValue(ArgString, &pos);\r
+ \r
+ if( gpCurrentWindow->Server )\r
+ {\r
+ writef(gpCurrentWindow->Server->FD, "JOIN :%s\n", channel_name);\r
+ }\r
+}\r
+\r
+void Cmd_quit(char *ArgString)\r
+{\r
+ const char *quit_message = ArgString;\r
+ if( quit_message == NULL || quit_message[0] == '\0' )\r
+ quit_message = "/quit - Acess2 IRC Client";\r
+ \r
+ for( tServer *srv = gpServers; srv; srv = srv->Next )\r
+ {\r
+ writef(srv->FD, "QUIT :%s\n", quit_message);\r
+ }\r
+ \r
+ exit(0);\r
+}\r
+\r
+void Cmd_window(char *ArgString)\r
+{\r
+ int pos = 0;\r
+ char *window_id = GetValue(ArgString, &pos);\r
+ int window_num = atoi(window_id);\r
+ \r
+ if( window_num > 0 )\r
+ {\r
+ tWindow *win;\r
+ window_num --; // Move to base 0\r
+ // Get `window_num`th window\r
+ for( win = gpWindows; win && window_num--; win = win->Next );\r
+ if( win ) {\r
+ gpCurrentWindow = win;\r
+ Redraw_Screen();\r
+ }\r
+ // Otherwise, silently ignore\r
+ }\r
+ else\r
+ {\r
+ window_num = 1;\r
+ for( tWindow *win = gpWindows; win; win = win->Next, window_num ++ )\r
+ {\r
+ if( win->Name[0] ) {\r
+ Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "",\r
+ "%i: %s/%s", window_num, win->Server->Name, win->Name);\r
+ }\r
+ else {\r
+ Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "",\r
+ "%i: (status)", window_num);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+const struct {\r
+ const char *Name;\r
+ void (*Fcn)(char *ArgString);\r
+} caCommands[] = {\r
+ {"join", Cmd_join},\r
+ {"quit", Cmd_quit},\r
+ {"window", Cmd_window},\r
+ {"win", Cmd_window},\r
+ {"w", Cmd_window},\r
+};\r
+const int ciNumCommands = sizeof(caCommands)/sizeof(caCommands[0]);\r
+\r
/**\r
* \brief Handle a line from the prompt\r
*/\r
char *command;\r
int pos = 0;\r
\r
- command = GetValue(String, &pos);\r
- \r
- if( strcmp(command, "/join") == 0 )\r
- {\r
- char *channel_name = GetValue(String, &pos);\r
- \r
- if( gpCurrentWindow->Server )\r
- {\r
- writef(gpCurrentWindow->Server->FD, "JOIN :%s\n", channel_name);\r
- }\r
- }\r
- else if( strcmp(command, "/quit") == 0 )\r
+ command = GetValue(String, &pos)+1;\r
+\r
+ // TODO: Prefix matches\r
+ int cmdIdx = -1;\r
+ for( int i = 0; i < ciNumCommands; i ++ )\r
{\r
- char *quit_message = String + pos;\r
- tServer *srv;\r
- \r
- if( quit_message == NULL || quit_message[0] == '\0' )\r
- quit_message = "/quit - Acess2 IRC Client";\r
- \r
- for( srv = gpServers; srv; srv = srv->Next )\r
- {\r
- writef(srv->FD, "QUIT :%s\n", quit_message);\r
+ if( strcmp(command, caCommands[i].Name) == 0 ) {\r
+ cmdIdx = i;\r
+ break;\r
}\r
- \r
- exit(0);\r
}\r
- else if( strcmp(command, "/window") == 0 || strcmp(command, "/win") == 0 || strcmp(command, "/w") == 0 )\r
- {\r
- char *window_id = GetValue(String, &pos);\r
- int window_num = atoi(window_id);\r
- \r
- if( window_num > 0 )\r
- {\r
- tWindow *win;\r
- window_num --; // Move to base 0\r
- // Get `window_num`th window\r
- for( win = gpWindows; win && window_num--; win = win->Next );\r
- if( win ) {\r
- gpCurrentWindow = win;\r
- Redraw_Screen();\r
- }\r
- // Otherwise, silently ignore\r
- }\r
- else\r
- {\r
- tWindow *win;\r
- window_num = 1;\r
- for( win = gpWindows; win; win = win->Next, window_num ++ )\r
- {\r
- if( win->Name[0] ) {\r
- Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "",\r
- "%i: %s/%s", window_num, win->Server->Name, win->Name);\r
- }\r
- else {\r
- Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "",\r
- "%i: (status)", window_num);\r
- }\r
- }\r
- }\r
+ if( cmdIdx != -1 ) {\r
+ caCommands[cmdIdx].Fcn(String+pos);\r
}\r
else\r
{\r
for(;;)
{
sUsername = GetUsername();
+ if(!sUsername) continue;
sPassword = GetPassword();
+ if(!sPassword) continue;
if( (uid = ValidateUser(sUsername, sPassword)) == -1 )
{
printf("\nInvalid username or password\n");
+ _SysDebug("Auth failure: '%s':'%s'", sUsername, sPassword);
free(sUsername);
free(sPassword);
}
return 0;
}
-/**
- * \fn char *GetUsername()
- */
-char *GetUsername()
+char *_GetString(int bEcho)
{
- char ret[BUFLEN] = {0};
+ char ret[BUFLEN];
int pos = 0;
char ch;
- // Prompt the user
- printf("Username: ");
- fflush(stdout);
-
// Read in text
while( (ch = fgetc(stdin)) != -1 && ch != '\n' )
{
+ // Handle backspace
if(ch == '\b') {
if( pos <= 0 ) continue;
pos --;
ret[pos] = '\0';
}
+ // Ctrl-C : Cancel
+ else if( ch == 'c'-'a'+1)
+ pos = 0;
+ // Ctrl-U : Clear
+ else if( ch == 'u'-'a'+1)
+ pos = 0;
+ // Ignore \r
+ else if( ch == '\r' )
+ continue;
else
ret[pos++] = ch;
- // Echo out to the screen
- fputc(ch, stdout);
- fflush(stdout);
+ // Don't echo out to the screen
+ if( bEcho ) {
+ fputc(ch, stdout);
+ fflush(stdout);
+ }
if(pos == BUFLEN-1) break;
}
- // Finish String
ret[pos] = '\0';
printf("\n");
}
/**
- * \fn char *GetPassword()
+ * \fn char *GetUsername()
*/
-char *GetPassword()
+char *GetUsername()
{
- char ret[BUFLEN];
+ char ret[BUFLEN] = {0};
int pos = 0;
char ch;
// Prompt the user
- printf("Password: ");
+ printf("Username: ");
fflush(stdout);
- // Read in text
- while( (ch = fgetc(stdin)) != -1 && ch != '\n' )
- {
- if(ch == '\b') {
- if( pos <= 0 ) continue;
- pos --;
- ret[pos] = '\0';
- }
- else
- ret[pos++] = ch;
-
- // Don't echo out to the screen
- //fputc(stdout, ch);
-
- if(pos == BUFLEN-1) break;
- }
-
- ret[pos] = '\0';
+ return _GetString(1);
+}
+
+/**
+ * \fn char *GetPassword()
+ */
+char *GetPassword()
+{
+ // Prompt the user
+ printf("Password: ");
+ fflush(stdout);
- printf("\n");
- return strdup(ret);
+ return _GetString(0);
}
// If no directory was passed (we want to use the mount list)
// or we are not root (we need to use the mount list)
// Check the mount list
- if(sDir == NULL || getuid() != 0)
+ if(sDir == NULL || _SysGetUID() != 0)
{
// Check if it is defined in the mounts file
// - At this point sDevice could be a device name or a mount point
MAKEDEP = $(CC) -M
ifeq ($(ARCHDIR),native)
-ASFLAGS += -D ARCHDIR=$(ARCHDIR) -D __ASSEMBLER__=1
-LDFLAGS := -lacess-native
-#CPPFLAGS := -D SoMain="__attribute__ ((constructor(101))) libacessnative_init"
+ ASFLAGS += -D ARCHDIR=$(ARCHDIR) -D __ASSEMBLER__=1
+ LDFLAGS := -lacess-native
+ #CPPFLAGS := -D SoMain="__attribute__ ((constructor(101))) libacessnative_init"
ifeq ($(PLATFORM),windows)
else
LDFLAGS += -Wl,-init,SoMain
SYSCALL2(_SysWaitTID, SYS_WAITTID)
SYSCALL0(gettid, SYS_GETTID)
-SYSCALL0(getpid, SYS_GETPID)
-SYSCALL0(getuid, SYS_GETUID)
-SYSCALL0(getgid, SYS_GETGID)
+SYSCALL0(_SysGetPID, SYS_GETPID)
+SYSCALL0(_SysGetUID, SYS_GETUID)
+SYSCALL0(_SysGetGID, SYS_GETGID)
SYSCALL1(setuid, SYS_SETUID)
SYSCALL1(setgid, SYS_SETGID)
SYSCALL3(_SysOpenChild, SYS_OPENCHILD) // int, char*, int
SYSCALL3(_SysReopen, SYS_REOPEN) // int, char*, int
SYSCALL2(_SysCopyFD, SYS_COPYFD) // int, int
+SYSCALL3(_SysFDFlags, SYS_FDCTL) // int, int, int
SYSCALL1(_SysClose, SYS_CLOSE) // int
SYSCALL3(_SysRead, SYS_READ) // int, uint, void*
SYSCALL3(_SysWrite, SYS_WRITE) // int, uint, void*
extern int _SysExecVE(const char *path, char **argv, char **envp);
extern int _SysSpawn(const char *Path, const char **argv, const char **envp, int nFDs, int *FDs, struct s_sys_spawninfo *info);
extern int gettid(void);
-extern int getpid(void);
+extern int _SysGetPID(void);
extern int _SysSetFaultHandler(int (*Handler)(int));
extern void _SysSetName(const char *Name);
extern int _SysGetName(char *NameDest);
extern int64_t _SysTimestamp(void);
// --- Permissions ---
-extern int getuid(void);
-extern int getgid(void);
+extern int _SysGetUID(void);
+extern int _SysGetGID(void);
extern void setuid(int id);
extern void setgid(int id);
extern int _SysOpenPipe(int *read, int *write, int flags);
extern int _SysReopen(int fd, const char *path, int flags);
extern int _SysCopyFD(int srcfd, int dstfd);
+extern int _SysFDFlags(int fd, int mask, int newflags);
extern size_t _SysRead(int fd, void *buffer, size_t length);
extern int _SysClose(int fd);
extern int _SysFDCtl(int fd, int option, ...);
extern int _SysGetACL(int fd, t_sysACL *dest);
extern int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options);
extern int _SysSelect(int nfds, fd_set *read, fd_set *write, fd_set *err, int64_t *timeout, unsigned int extraevents);
-#define select(nfs, rdfds, wrfds, erfds, timeout) _SysSelect(nfs, rdfds, wrfds, erfds, timeout, 0)
+//#define select(nfs, rdfds, wrfds, erfds, timeout) _SysSelect(nfs, rdfds, wrfds, erfds, timeout, 0)
extern int _SysUnlink(const char *pathname);
// --- IPC ---
\r
OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o rand.o\r
OBJ += perror.o scanf.o signals.o strtoi.o strtof.o\r
-OBJ += printf.o\r
+OBJ += printf.o time.o\r
OBJ += arch/$(ARCHDIR).ao\r
# signals.o\r
DEPFILES := $(OBJ:%.o=%.d)\r
ENODEV, // ???
EADDRNOTAVAIL, // ?
EINPROGRESS, // ?
+ EROFS,
EAGAIN, // Try again
typedef void (*sighandler_t)(int);
+#define SIG_IGN ((void*)1)
#define SIG_DFL ((void*)0)
#define SIG_ERR ((void*)-1)
extern size_t fread(void *buf, size_t size, size_t n, FILE *fp);
extern size_t fwrite(const void *buf, size_t size, size_t n, FILE *fp);
extern int fgetc(FILE *fp);
+#define getc(fp) fgetc(fp)
extern char *fgets(char *s, int size, FILE *fp);
extern int fputc(int ch, FILE *fp);
extern int fputs(const char *s, FILE *fp);
typedef signed long long clock_t;
-extern clock_t clock();
+extern clock_t clock(void);
+
+extern time_t time(time_t *t);
#endif
}
return tmp;
}
+
+long atol(const char *str)
+{
+ long long tmp = strtoll(str, NULL, 0);
+ if( tmp > LONG_MAX || tmp < LONG_MIN ) {
+ errno = ERANGE;
+ return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;
+ }
+ return tmp;
+}
+
+long atoll(const char *str)
+{
+ long long tmp = strtoll(str, NULL, 0);
+ return tmp;
+}
--- /dev/null
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * time.c
+ * - POSIX/stdc time functions
+ */
+#include <time.h>
+#include <acess/sys.h>
+
+clock_t clock(void)
+{
+ return _SysTimestamp();
+}
+
+time_t time(time_t *t)
+{
+ time_t ret = _SysTimestamp() / 1000;
+ if(t)
+ *t = ret;
+ return ret;
+}
ASFLAGS +=\r
LDFLAGS += -soname libposix.so -Map map.txt -lc\r
\r
-OBJ = main.o unistd.o dirent.o stat.o\r
+OBJ = main.o unistd.o dirent.o stat.o utmpx.o termios.o\r
+OBJ += pwd.o syslog.o sys_time.o sys_ioctl.o sys_resource.o\r
DEPFILES := $(OBJ:%.o=%.d)\r
BIN = libposix.so\r
\r
#ifndef _FCNTL_H_
#define _FCNTL_H_
-//#include <sys/sys.h>
-
-// Hacks to handle different behaviors in Acess
-
-// Open doesn't take a chmod
-//#define open(_1,_2,...) open(_1, _2)
-
-// Close returns void
-//#define close(_1) (close(_1),0)
-
-// Acess doesn't implement lseek
-#define lseek(_1,_2,_3) (seek(_1,_2,_3),tell(_1))
+struct flock
+{
+ short l_type;
+ short l_whece;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+};
enum e_fcntl_cmds
{
- F_SETFL
+ F_DUPFD, // (long)
+ //F_DUPFD_CLOEXEC, // (long) - Non POSIX
+ F_GETFD, // (void)
+ F_SETFD, // (long)
+ F_GETFL, // (void)
+ F_SETFL, // (long)
+
+ F_SETLK, // (struct flock *)
+ F_SETLKW, // (struct flock *)
+ F_GETLK, // (struct flock *)
};
static inline int fcntl(int fd __attribute__((unused)), int cmd __attribute__((unused)), ...) { return -1; }
#ifndef _LIBPOSIX__PWD_H_
#define _LIBPOSIX__PWD_H_
+#include <stddef.h> // size_t
#include <sys/types.h> // gid_t/uid_t
struct passwd
#ifndef _LIBPOSIX__IOCTL_H_
#define _LIBPOSIX__IOCTL_H_
-
+extern int ioctl(int d, int request, ...);
#endif
rlim_t rlim_max;
};
+// (get|set)r(limit|usage) resource values
enum
{
RLIMIT_AS, // Address space size
};
extern int getpriority(int, id_t);
-extern int getrlimit(int, struct rlimit *);
-extern int getrusage(int, struct rusage *);
+extern int getrlimit(int resource, struct rlimit *rlim);
+extern int getrusage(int resource, struct rusage *rusage);
extern int setpriority(int, id_t, int);
-extern int setrlimit(int, const struct rlimit *);
+extern int setrlimit(int resource, const struct rlimit *rlim);
#endif
#include <acess/fd_set.h>
#include <sys/time.h>
-extern int select(int nfds, fd_set *readfds, fd_set *writefds, struct timeval *timeout);
+extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *execptfds, struct timeval *timeout);
// TODO: pselect?
#endif
extern int stat(const char *path, struct stat *buf);
extern int lstat(const char *path, struct stat *buf);
extern int fstat(int fd, struct stat *buf);
+extern int mkdir(const char *pathname, mode_t mode);
#endif
#ifndef _LIBPOSIX__SYS__TIME_H_
#define _LIBPOSIX__SYS__TIME_H_
+#include <time.h>
+
typedef unsigned long suseconds_t;
struct timeval
suseconds_t tv_usec;
};
+// struct timezone . tz_dsttime
+enum
+{
+ DST_NONE, // No DST
+ DST_USA, // USA style DST
+ DST_AUST, // Australian style DST
+ DST_WET, // Western European DST
+ DST_MET, // Middle European DST
+ DST_EET, // Eastern European DST
+ DST_CAN, // Canada
+ DST_GB, // Great Britain and Eire
+ DST_RUM, // Rumania
+ DST_TUR, // Turkey
+ DST_AUSTALT, // Australia with 1986 shift
+};
+
+struct timezone
+{
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
struct itimerval
{
struct timeval it_interval;
// TODO: This should also define fd_set and select()
-extern int getitimer(int, struct itimerval *);
-extern int setitimer(int, const struct itimerval *, struct itimerval *);
-extern int gettimeofday(struct timeval *, void *);
+extern int getitimer(int which, struct itimerval *current_value);
+extern int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
+extern int gettimeofday(struct timeval *tv, struct timezone *tz);
+// extern int settimeofday(const struct timeval *tv, const struct timezone *tz); //ifdef _BSD_SOURCE
// select
extern int utimes(const char *, const struct timeval [2]);
typedef struct stat t_fstat;
+typedef unsigned long uid_t;
+typedef unsigned long gid_t;
typedef unsigned int id_t;
typedef unsigned long pid_t;
typedef unsigned long tid_t;
* - By John Hodge (thePowersGang)
*
* syslog.h
- * - Centra Loggin
+ * - Central Logging
*/
#ifndef _LIBPOSIX__SYSLOG_H_
#define _LIBPOSIX__SYSLOG_H_
cc_t c_cc[NCCS];
};
+extern int tcgetattr(int fd, struct termios *termios_p);
+
+#define TCSANOW 0x01
+#define TCSADRAIN 0x02
+#define TCSAFLUSH 0x04
+extern int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
+
+// ioctl() calls for terminals
+enum
+{
+ TIOCGWINSZ,
+ TIOCSWINSZ
+};
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel; /* unused */
+ unsigned short ws_ypixel; /* unused */
+};
+
+
#endif
extern int dup2(int oldfd, int newfd);
+extern int chown(const char *path, uid_t owner, gid_t group);
+
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00300
+#define S_IXUSR 00100
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+#define S_IRWXO 0007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+extern int chmod(const char *path, mode_t mode);
+
+extern pid_t setsid(void);
+
+extern uid_t getuid(void);
+extern uid_t geteuid(void);
+extern pid_t getpid(void);
+
+// signal.h / sys/types.h
+#define SIGWINCH 101
+#define SIGTSTP 102
+extern int kill(pid_t pid, int sig);
+
+extern int chdir(const char *dir);
+
+// Deprecated POSIX.1-2001
+#define PASS_MAX 63
+extern char *getpass(void);
+
#endif
--- /dev/null
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * utmpx.h
+ * - User login records
+ */
+#ifndef _LIBPOSIX__UTMPX_H_
+#define _LIBPOSIX__UTMPX_H_
+
+#include <sys/time.h> // struct timeval
+
+#define UTMPX_FILE "/Acess/var/utmpx"
+
+enum e_utmpx_type_vals
+{
+ EMPTY, //!< No information
+ BOOT_TIME, //!< Identifies time of system boot
+ OLD_TIME, //!< Old time when system time was changed
+ NEW_TIME, //!< New time when system time was changed
+ USER_PROCESS, //!< Any process
+ INIT_PROCESS, //!< Process spawned by init
+ LOGIN_PROCESS, //!< Session leader for a logged-in user
+ DEAD_PROCESS //!< Exited session leader
+};
+
+#define UT_USER_MAX 32
+#define UT_ID_MAX 8
+#define UT_LINE_MAX 32
+
+struct utmpx
+{
+ char ut_user[UT_USER_MAX];
+ char ut_id[UT_ID_MAX];
+ char ut_line[UT_LINE_MAX];
+ pid_t ut_pid;
+ short ut_type;
+ struct timeval ut_tv;
+};
+
+extern void endutxent(void);
+extern struct utmpx *getutxent(void);
+extern struct utmpx *getutxid(const struct utmpx *);
+extern struct utmpx *getutxline(const struct utmpx *);
+extern struct utmpx *pututxline(const struct utmpx *);
+extern void setutxent(void);
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * pwd.c
+ * - Password Structure
+ */
+#include <pwd.h>
+#include <errno.h>
+#include <string.h>
+
+// TODO: Parse something like '/Acess/Conf/Users'
+
+// === GLOBALS ===
+static const struct passwd gPwd_RootInfo = {
+ .pw_name = "root",
+ .pw_uid = 0,
+ .pw_gid = 0,
+ .pw_dir = "/Acess/Root",
+ .pw_shell = "/Acess/Bin/CLIShell",
+ .pw_passwd = "",
+};
+
+// === CODE ===
+struct passwd *getpwnam(const char *name)
+{
+ static struct passwd ret_struct;
+ static char ret_buf[64];
+ struct passwd *ret_ptr;
+ errno = getpwnam_r(name, &ret_struct, ret_buf, sizeof(ret_buf), &ret_ptr);
+ return ret_ptr;
+}
+
+struct passwd *getpwuid(uid_t uid)
+{
+ static struct passwd ret_struct;
+ static char ret_buf[64];
+ struct passwd *ret_ptr;
+ errno = getpwuid_r(uid, &ret_struct, ret_buf, sizeof(ret_buf), &ret_ptr);
+ return ret_ptr;
+}
+
+static int fill_pwd(const struct passwd *tpl, struct passwd *pwd, char *buf, size_t buflen)
+{
+ size_t ofs = 0;
+ #define _setstr(field) do { \
+ if( ofs + strlen(tpl->field)+1 > buflen ) \
+ return ERANGE; \
+ pwd->field = buf + ofs; \
+ strcpy(pwd->field, tpl->field); \
+ } while(0)
+ _setstr(pw_name);
+ pwd->pw_uid = tpl->pw_uid;
+ pwd->pw_gid = tpl->pw_gid;
+ _setstr(pw_dir);
+ _setstr(pw_shell);
+ _setstr(pw_passwd);
+ return 0;
+}
+
+int getpwnam_r(const char *name, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result)
+{
+ *result = NULL;
+ if( strcmp(name, "root") == 0 ) {
+ int ret = fill_pwd(&gPwd_RootInfo, pwd, buf, buflen);
+ if(ret) return ret;
+ *result = pwd;
+ }
+ return 0;
+}
+
+int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result)
+{
+ *result = NULL;
+ if( uid == 0 ) {
+ int ret = fill_pwd(&gPwd_RootInfo, pwd, buf, buflen);
+ if(ret) return ret;
+ *result = pwd;
+ }
+ return 0;
+}
+
+void endpwent(void)
+{
+}
+
+struct passwd *getpwent(void)
+{
+ return NULL;
+}
+
+void setpwent(void)
+{
+
+}
+
--- /dev/null
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * sys_ioctl.c
+ * - IOCtl hacks
+ */
+#include <sys/ioctl.h>
+#include <acess/sys.h>
+#include <errno.h>
+
+// === CODE ===
+int ioctl(int fd, int request, ...)
+{
+ if( fd < 0 ) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if( request < 0 ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ // #1. Get device type (IOCtl 0)
+ int devtype = _SysIOCtl(fd, 0, NULL);
+
+ switch(devtype)
+ {
+ // 0: Normal file (no ioctls we care about)
+ case 0:
+ // 1: Has the ident set of ioctls, nothing else
+ case 1:
+ return -1;
+ // TODO: Terminals
+
+ // NFI
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * sys_resource.c
+ * - (XSI) Resource Operations
+ */
+#include <sys/resource.h>
+#include <acess/sys.h>
+
+// === CODE ===
+int getrlimit(int resource, struct rlimit *rlim)
+{
+ _SysDebug("TODO: getrlimit(%i)", resource);
+ rlim->rlim_cur = 0;
+ rlim->rlim_max = 0;
+ return 0;
+}
+
+int setrlimit(int resource, const struct rlimit *rlim)
+{
+ _SysDebug("TODO: setrlimit(%i,{%i,%i})", resource, rlim->rlim_cur, rlim->rlim_max);
+ return 0;
+}
+
--- /dev/null
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * sys/time.h
+ * - Timing calls
+ */
+#include <sys/time.h>
+#include <acess/sys.h>
+
+// === CODE ===
+#if 0
+int getitimer(int which, struct itimerval *current_value)
+{
+
+}
+
+int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value)
+{
+
+}
+#endif
+
+int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ const int correction_2k_to_unix = 30*365*24*3600;
+ long long int ts = _SysTimestamp();
+ if( tv )
+ {
+ tv->tv_sec = ts / 1000 + correction_2k_to_unix;
+ tv->tv_usec = (ts % 1000) * 1000;
+ }
+ if( tz )
+ {
+ // TODO: Determine timezone?
+ tz->tz_minuteswest = 0;
+ tz->tz_dsttime = 0;
+ }
+ return 0;
+}
+
+// ifdef _BSD_SOURCE
+//int settimeofday(const struct timeval *tv, const struct timezone *tz);
--- /dev/null
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * syslog.h
+ * - Central Logging
+ */
+#include <syslog.h>
+#include <stdio.h> // vsnprintf
+#include <stdlib.h> // free
+#include <string.h> // strdup
+#include <stdarg.h>
+#include <acess/sys.h>
+
+// === GLOBALS ===
+char *gsSyslogPrefix = NULL;
+ int gSyslogOptions;
+ int gSyslogFacility;
+ int gSyslogMask = -1;
+
+// === CODE ===
+/*
+ * Close global logging handle
+ */
+void closelog(void)
+{
+}
+
+void openlog(const char *name, int option, int facility)
+{
+ if( gsSyslogPrefix )
+ free(gsSyslogPrefix);
+ gsSyslogPrefix = strdup(name);
+ gSyslogOptions = option;
+ gSyslogFacility = facility;
+
+ if( option & LOG_NOWAIT )
+ {
+ // Open the logging handle!
+ }
+}
+
+extern int setlogmask(int mask)
+{
+ int ret = gSyslogMask;
+ gSyslogMask = mask;
+ return ret;
+}
+
+extern void syslog(int priority, const char *str, ...)
+{
+ char staticbuf[512];
+ va_list args;
+ va_start(args, str);
+ vsnprintf(staticbuf, sizeof(staticbuf), str, args);
+ va_end(args);
+ if( gSyslogOptions & (1 << priority) )
+ {
+ // TODO: Proper syslog
+ _SysDebug("syslog(%i: %s) - %s", priority, gsSyslogPrefix, staticbuf);
+ }
+}
+
--- /dev/null
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * termios.c
+ * - Terminal Control
+ */
+#include <termios.h>
+#include <errno.h>
+#include <string.h>
+
+// === CODE ===
+int tcgetattr(int fd, struct termios *termios_p)
+{
+ if( fd == -1 ) {
+ errno = EBADF;
+ return -1;
+ }
+ // Double-check `fd` describes a terminal
+
+ // Fill defaults
+ memset(termios_p, 0, sizeof(struct termios));
+
+ // Query kernel for other params
+
+ return 0;
+}
+
+int tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
+{
+ if( fd == -1 ) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if( !termios_p || (optional_actions & ~(7)) ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return 0;
+}
+
#include <unistd.h>
#include <acess/sys.h>
#include <stdarg.h>
+#include <sys/select.h>
+#include <stdio.h>
// === CODE ===
int unlink(const char *pathname)
return _SysExecVE(b, v, NULL);
}
+int dup(int oldfd)
+{
+ // NOTE: Acess's CopyFD doesn't cause offset sharing
+ // TODO: Check that -1 does cause a new allocation
+ return _SysCopyFD(oldfd, -1);
+}
+
int dup2(int oldfd, int newfd)
{
// NOTE: Acess's CopyFD doesn't cause offset sharing
return _SysCopyFD(oldfd, newfd);
}
+
+/*
+ * Set session ID to PID
+ */
+pid_t setsid(void)
+{
+ // TODO: actual syscall for this
+ return _SysGetPID();
+}
+
+pid_t getpid(void)
+{
+ return _SysGetPID();
+}
+
+uid_t getuid(void)
+{
+ return _SysGetUID();
+}
+
+uid_t geteuid(void)
+{
+ // TODO: Impliment EUIDs in-kernel?
+ return _SysGetUID();
+}
+
+int kill(pid_t pid, int signal)
+{
+ // TODO: Need special handling?
+ return _SysKill(pid, signal);
+}
+
+int select(int nfd, fd_set *rfd, fd_set *wfd, fd_set *efd, struct timeval *timeout)
+{
+
+ if( timeout )
+ {
+ long long int ltimeout = 0;
+ ltimeout = timeout->tv_sec*1000 + timeout->tv_usec / 1000;
+ int ret = _SysSelect(nfd, rfd, wfd, efd, <imeout, 0);
+ return ret;
+ }
+ else
+ {
+ return _SysSelect(nfd, rfd, wfd, efd, NULL, 0);
+ }
+}
+
+int pipe(int pipefd[2])
+{
+ pipefd[0] = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
+ pipefd[1] = _SysCopyFD(pipefd[0], -1);
+ _SysFDFlags(pipefd[1], OPENFLAG_READ|OPENFLAG_WRITE, OPENFLAG_WRITE);
+ return 0;
+}
+
+int chdir(const char *dir)
+{
+ return _SysChdir(dir);
+}
+
+int mkdir(const char *pathname, mode_t mode)
+{
+ _SysDebug("TODO: POSIX mkdir(%i, 0%o)", pathname, mode);
+ return -1;
+}
+
+char *getpass(void)
+{
+ static char passbuf[PASS_MAX+1];
+ fprintf(stderr, "Password: ");
+ fgets(passbuf, PASS_MAX+1, stdin);
+ fprintf(stderr, "\n");
+ return passbuf;
+}
+
--- /dev/null
+/*
+ * Acess2 POSIX Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * utmpx.c
+ * - User login records
+ */
+#include <stddef.h>
+#include <utmpx.h>
+
+/*
+ * Rewind UTMPX file pointer
+ */
+void setutxent(void)
+{
+}
+
+/*
+ * Close UTMPX file
+ */
+void endutxent(void)
+{
+}
+
+/*
+ * Read from current position in UTMPX file
+ */
+struct utmpx *getutxent(void)
+{
+ return NULL;
+}
+
+/*
+ * Locate an entry in the UTMPX file for a given id
+ */
+struct utmpx *getutxid(const struct utmpx *utmpx __attribute__((unused)))
+{
+ return NULL;
+}
+
+struct utmpx *getutxline(const struct utmpx *utmpx __attribute__((unused)))
+{
+ utmpx = NULL;
+ return NULL;
+}
+
+struct utmpx *pututxline(const struct utmpx *utmpx __attribute__((unused)))
+{
+ utmpx = NULL;
+ return NULL;
+}
+
return _SysWrite(sockfd, buffer, length);
}
+
+int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len)
+{
+ return 0;
+}
+
+int getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len)
+{
+ return 0;
+}
+
+int getsockname(int socket, struct sockaddr *addr, socklen_t *addrlen)
+{
+ return 0;
+}
+
+int getpeername(int socket, struct sockaddr *addr, socklen_t *addrlen)
+{
+ return 0;
+}
+
+int shutdown(int socket, int how)
+{
+ return 0;
+}
+