static int ctrl_download_data(p_Buffer * buffer, void *stateptr) { /* Decode an addconfig message */ int debugID, OSinfo1, OSinfo2, reason, subreason, count, err; word nbytes; word status; IGNORE(stateptr); count = unpack_message(BUFFERDATA(*buffer), "%w%w%w%w%w%w", &reason, &debugID, &OSinfo1, &OSinfo2, &subreason, &nbytes); LogInfo(LOG_CTRL, ( "ctrl_download_data(nbytes = %d)\n", nbytes)); status = angelOS_LoadConfigData(OSinfo1, OSinfo2, nbytes, BUFFERDATA(*buffer) + count); if (status == RDIError_NoError && loadagent_address != -1) loadagent_sofar += nbytes; /* We make sure we release the buffer here as it may be the long one */ angel_ChannelReleaseBuffer(*buffer); *buffer = NULL; err = msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Download_Data, status); return err; }
static int ctrl_settopmem(p_Buffer * buffer, void *stateptr) { #ifdef ICEMAN2 /* Set the top of memory we report on a HEAPINFO SWI */ int debugID, OSinfo1, OSinfo2, subreason; word topmem; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &topmem); LogInfo(LOG_CTRL, ( "ctrl_settopmem(topmem = 0x%x)\n", topmem)); angel_SetTopMem((unsigned)topmem); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SetTopMem, RDIError_NoError); #else IGNORE(buffer); IGNORE(stateptr); return -1; #endif }
static int ctrl_start_agent(p_Buffer * buffer, void *stateptr) { /* Decode an loadagent message */ int debugID, OSinfo1, OSinfo2, subreason, err; word startaddress; word status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &startaddress); LogInfo(LOG_CTRL, ( "ctrl_start_agent(startaddress = %x)\n", startaddress)); if (loadagent_sofar == loadagent_size && startaddress >= loadagent_address && startaddress < (loadagent_address + loadagent_size)) status = RDIError_NoError; else status = RDIError_BadConfigData; err = msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Start_Agent, status); if (err == RDIError_NoError && status == RDIError_NoError) angelOS_ExecuteNewAgent(startaddress); return err; }
static int ctrl_download_agent(p_Buffer * buffer, void *stateptr) { /* Decode an loadagent message */ int debugID, OSinfo1, OSinfo2, subreason; word loadaddress, nbytes; word status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &loadaddress, &nbytes); LogInfo(LOG_CTRL, ( "ctrl_download_agent(loadadr = 0x%x, nbytes = %d)\n", loadaddress, nbytes)); status = angelOS_LoadAgent(OSinfo1, OSinfo2, loadaddress, nbytes); if (status == RDIError_NoError) { loadagent_address = loadaddress; loadagent_size = nbytes; loadagent_sofar = 0; } return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Download_Agent, status); }
static int ctrl_semihosting_getthumbswi(p_Buffer * buffer, void *stateptr) { #ifdef ICEMAN2 /* Reads the value of the semi-hosting vector. */ int debugID, OSinfo1, OSinfo2, subreason; word semihosting_thumbswi, status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason); status = angelOS_SemiHosting_GetThumbSWI(OSinfo1, OSinfo2, &semihosting_thumbswi); LogInfo(LOG_CTRL, ("ctrl_semihosting_getthumbswi -> %08x\n", semihosting_thumbswi)); return msgsend(CI_HADP, "%w%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SemiHosting_GetThumbSWI, status, semihosting_thumbswi); #else IGNORE(buffer); IGNORE(stateptr); LogInfo(LOG_CTRL, ( "ctrl_semihosting_getthumbswi - unsupported\n")); return -1; #endif }
static int ctrl_download_supported(p_Buffer * buffer, void *stateptr) { int debugID, OSinfo1, OSinfo2; /* For Angel return CantLoadConfig - we can't do that * for EmbeddedICE (ICEman) say we can * for EICEADP - the ADP over JTAG software say we can't */ #if defined(ICEMAN2) && !defined(JTAG_ADP_SUPPORTED) word status = RDIError_NoError; #else word status = RDIError_CantLoadConfig; #endif IGNORE(stateptr); LogInfo(LOG_CTRL, ( "ctrl_download_supported -> %d\n", status)); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Download_Supported, status); }
/* * This routine allocates a buffer, puts the data supplied as * parameters into the buffer and sends the message. It does *NOT* * wait for a reply. */ extern int msgsend(ChannelID chan, const char *format,...) { unsigned int length; p_Buffer buffer; va_list args; # ifndef TARGET Packet *packet; packet = DevSW_AllocatePacket(Armsd_BufferSize); buffer = packet->pk_buffer; # else buffer = angel_ChannelAllocBuffer(Angel_ChanBuffSize); # endif if (buffer != NULL) { va_start(args, format); length = vmsgbuild(BUFFERDATA(buffer), format, args); # ifdef TARGET angel_ChannelSend(CH_DEFAULT_DEV, chan, buffer, length); # else packet->pk_length = length; Adp_ChannelWrite(chan, packet); # endif va_end(args); return 0; } else return -1; }
static int ctrl_semihosting_setarmswi(p_Buffer * buffer, void *stateptr) { #ifdef ICEMAN2 /* Set the semi-hosting ARM SWI. */ int debugID, OSinfo1, OSinfo2, subreason; word semihosting_armswi, status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &semihosting_armswi); LogInfo(LOG_CTRL, ( "ctrl_semihosting_setarmswi(swi 0x%x)\n", semihosting_armswi)); status = angelOS_SemiHosting_SetARMSWI(OSinfo1, OSinfo2, semihosting_armswi); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SemiHosting_SetARMSWI, status); #else IGNORE(buffer); IGNORE(stateptr); LogInfo(LOG_CTRL, ( "ctrl_semihosting_setarmswi -> unsupported\n")); return -1; #endif }
static int ctrl_nop(p_Buffer * buffer, void *stateptr) { /* Return an RDIError_NoError to indicate ctrl calls are available. */ int debugID, OSinfo1, OSinfo2; word status = RDIError_NoError; IGNORE(stateptr); LogInfo(LOG_CTRL, ( "ctrl_nop()\n")); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_NOP, status); }
static int ctrl_vectorcatch(p_Buffer * buffer, void *stateptr) { /* Specify which hardware exceptions should be reported to the debugger. */ int debugID, OSinfo1, OSinfo2, subreason; word status = RDIError_NoError; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &debug_VectorCatch); LogInfo(LOG_CTRL, ( "ctrl_vectorcatch(vectorcatch = 0x%x)\n", debug_VectorCatch)); status = angelOS_VectorCatch(OSinfo1, OSinfo2, debug_VectorCatch); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_VectorCatch, status); }
static int ctrl_pointstatus_break(p_Buffer * buffer, void *stateptr) { /* Return information about a breakpoint given a handle. */ int debugID, OSinfo1, OSinfo2, subreason; word status, hwresource, type; word handle; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &handle); LogInfo(LOG_CTRL, ( "ctrl_pointstatus_break(handle = 0x%x)\n", handle)); status = angelOS_BreakPointStatus(OSinfo1, OSinfo2, handle, &hwresource, &type); return msgsend(CI_HADP, "%w%w%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_PointStatus_Break, status, hwresource, type); }
static int ctrl_log(p_Buffer * buffer, void *stateptr) { /* Read logging level. */ int debugID, OSinfo1, OSinfo2; word status = RDIError_NoError; word logsetting; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); LogInfo(LOG_CTRL, ( "ctrl_log -> 0x%x\n", logsetting)); status = angelOS_Ctrl_Log(OSinfo1, OSinfo2, &logsetting); return msgsend(CI_HADP, "%w%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Log, status, logsetting); }
static int ctrl_semihosting_setvector(p_Buffer * buffer, void *stateptr) { /* Set the semi-hosting vector. */ int debugID, OSinfo1, OSinfo2, subreason; word semihosting_vector, status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &semihosting_vector); LogInfo(LOG_CTRL, ( "ctrl_semihosting_setvector(vec = 0x%x)\n", semihosting_vector)); status = angelOS_SemiHosting_SetVector(OSinfo1, OSinfo2, semihosting_vector); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SemiHosting_SetVector, status); }
static int ctrl_semihosting_setstate(p_Buffer * buffer, void *stateptr) { /* Set whether or not semi-hosting is enabled. */ int debugID, OSinfo1, OSinfo2, subreason; word semihosting_state, status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &semihosting_state); LogInfo(LOG_CTRL, ("ctrl_semihosting_setstate(state = %d)\n", semihosting_state)); status = angelOS_SemiHosting_SetState(OSinfo1, OSinfo2, semihosting_state); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SemiHosting_SetState, status); }
static int ctrl_setlog(p_Buffer * buffer, void *stateptr) { /* Set logging level. */ int debugID, OSinfo1, OSinfo2, subreason; word logsetting; word status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &logsetting); LogInfo(LOG_CTRL, ( "ctrl_setlog(logsetting = 0x%x)\n", logsetting)); /* Range check logsetting. */ if ((logsetting & 0x7) == logsetting) status = angelOS_Ctrl_SetLog(OSinfo1, OSinfo2, logsetting); else status = RDIError_Error; return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SetLog, status); }
int HandleSysMessage(Packet *packet, hsys_state *stateptr) { unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0; long posn, fl; char character; int err; /* Note: We must not free the buffer passed in as the callback handler */ /* expects to do this. Freeing any other buffers we have malloced */ /* ourselves is acceptable */ unsigned char *buffp = ((unsigned char *)BUFFERDATA(packet->pk_buffer))+16; /* buffp points to the parameters*/ /* the invidual messages, excluding*/ /* standard SYS fields (debugID, */ /* osinfo and reasoncode) */ unsigned char *buffhead = (unsigned char *)(packet->pk_buffer); int DebugID, OSInfo1, OSInfo2, count; const char* fmode[] = {"r","rb","r+","r+b", "w","wb","w+","w+b", "a","ab","a+","a+b", "r","r","r","r"} /* last 4 are illegal */ ; FILEHANDLE fh; /* fh is used as an index to the real file handle * in OSptr */ FILE *fhreal; unpack_message(BUFFERDATA(buffhead), "%w%w%w%w", &reason_code, &DebugID, &OSInfo1, &OSInfo2); /* Extract reason code from buffer. */ reason_code &= 0xFFFF; /* Strip away direction bit, OSInfo and */ /* DebugInfo fields. Will want to do some */ /* sort of validation on this later. */ switch(reason_code) { case CL_WriteC: /* Write a character to the terminal. */ /* byte data -> word status */ { #ifdef DEBUG int c = (int)(*buffp); printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.'); #endif stateptr->hostif->writec(stateptr->hostif->hostosarg, (int)(*buffp)); DevSW_FreePacket(packet); return msgsend(CI_CLIB,"%w%w%w%w%w", CL_WriteC|HtoT, DebugID, OSInfo1, OSInfo2, NoError); } case CL_Write0: /* Write a null terminated string to the terminal. */ { unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Write0", TRUE, len, buffp+4); stateptr->hostif->write(stateptr->hostif->hostosarg, (char *) buffp+4, len); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Write0|HtoT, DebugID, OSInfo1, OSInfo2, NoError); } case CL_ReadC: /* Read a byte from the terminal */ { DebugPrintF(("CL_ReadC: ")); DevSW_FreePacket(packet); character = stateptr->hostif->readc(stateptr->hostif->hostosarg); DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character, isprint(character) ? character : '.')); return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT, DebugID, OSInfo1, OSInfo2, NoError, character); } case CL_System: /* Pass NULL terminated string to the hosts command * interpreter. As it is nULL terminated we dont need * the length */ { unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_System", TRUE, len, buffp+4); err = system((char *)buffp+4); /* Use the string in the buffer */ stateptr->last_errno = errno; DebugCheckErr("system", TRUE, err, stateptr->last_errno); err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT, DebugID, OSInfo1, OSInfo2, NoError, err); DevSW_FreePacket(packet); return err; } case CL_GetCmdLine: /* Returns the command line used to call the program */ { /* Note: we reuse the packet here, this may not always be desirable */ /* /* TODO: Use long buffers if possible */ DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr->CommandLine))); if (buffhead!=NULL) { len = strlen(*(stateptr->CommandLine)); if (len > Armsd_BufferSize-24) len = Armsd_BufferSize-24; packet->pk_length = len + msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_GetCmdLine|HtoT, DebugID, OSInfo1, OSInfo2, NoError, len); strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine), len); Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */ return 0; } else return -1; } case CL_Clock: /* Return the number of centiseconds since the support */ /* code started executing */ { time_t retTime = time(NULL); if (retTime == (time_t)-1) stateptr->last_errno = errno; else retTime *=100; DebugPrintF(("CL_Clock: %lu\n", retTime)); DebugCheckErr("time", TRUE, (retTime == (time_t)-1), stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT, DebugID, OSInfo1, OSInfo2, NoError, retTime); } case CL_Time: /* return time, in seconds since the start of 1970 */ { time_t retTime = time(NULL); if (retTime == (time_t)-1) stateptr->last_errno = errno; DebugPrintF(("CL_Time: %lu\n", retTime)); DebugCheckErr("time", TRUE, (retTime == (time_t)-1), stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT, DebugID, OSInfo1, OSInfo2, NoError, retTime); } case CL_Remove: /* delete named in the null terminated string */ { /* Removing an open file will cause problems but once again * its not our problem, likely result is a tangled FileTable */ /* As the filename is passed with a null terminator we can use it * straight out of the buffer without copying it.*/ unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4); err=remove((char *)buffp+4); stateptr->last_errno = errno; DevSW_FreePacket(packet); DebugCheckErr("remove", TRUE, err, stateptr->last_errno); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT, DebugID, OSInfo1, OSInfo2, err?-1:NoError); } case CL_Rename: /* rename file */ { /* Rename(word nbytes, bytes oname, word nbytes, bytes nname) * return(byte status) */ unsigned int len2; unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Rename", FALSE, len, buffp+4); unpack_message(buffp+5+len, "%w", &len2); DebugCheckNullTermString("to", TRUE, len2, buffp+9+len); /* Both names are passed with null terminators so we can use them * directly from the buffer. */ err = rename((char *)buffp+4, (char *)buffp+9+len); stateptr->last_errno = errno; DebugCheckErr("rename", TRUE, err, stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Rename|HtoT, DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1); } case CL_Open: /* open the file */ { /* Open(word nbytes, bytes name, byte mode) * return(word handle) */ unpack_message(buffp, "%w", &len); /* get the open mode */ unpack_message((buffp)+4+len+1, "%w", &mode); DebugCheckNullTermString("CL_Open", FALSE, len, buffp+4); DebugPrintF(("mode: %d\n", mode)); /* do some checking on the file first? */ /* check if its a tty */ if (strcmp((char *)buffp+4, ":tt")==0 && (mode==0||mode==1)) { /* opening tty "r" */ fhreal = stdin; stateptr->last_errno = errno; DebugPrintF(("\tstdin ")); } else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) { /* opening tty "w" */ fhreal = stdout; stateptr->last_errno = errno; DebugPrintF(("\tstdout ")); } else { fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]); stateptr->last_errno = errno; DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno); } DevSW_FreePacket(packet); c = NONHANDLE; if (fhreal != NULL) { /* update filetable */ for (c=3; c < HSYS_FOPEN_MAX; c++) { /* allow for stdin, stdout, stderr (!!! WHY? MJG) */ if (stateptr->OSptr->FileTable[c] == NULL) { stateptr->OSptr->FileTable[c]= fhreal; stateptr->OSptr->FileFlags[c]= mode & 1; DebugPrintF(("fh: %d\n", c)); break; } else if (c == HSYS_FOPEN_MAX) { /* no filehandles free */ DebugPrintF(("no free fh: %d\n", c)); stateptr->last_errno = EMFILE; } } } else { /* c = NULL;*/ DebugPrintF(("error fh: %d\n", c)); } (void) msgsend(CI_CLIB, "%w%w%w%w%w", CL_Open|HtoT, DebugID, OSInfo1, OSInfo2, c); return 0; } case CL_Close: /* close the file pointed to by the filehandle */ { unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_Close: fh %d\n", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) err = -1; else { if (fhreal == stdin || fhreal == stdout || fhreal == stderr) { stateptr->last_errno = errno; DebugPrintF(("\tskipping close of std*\n")); err = 0; } else { err = fclose(fhreal); if (err == 0) stateptr->OSptr->FileTable[fh]=NULL; stateptr->last_errno = errno; DebugCheckErr("fclose", TRUE, err, stateptr->last_errno); } } return msgsend(CI_CLIB,"%w%w%w%w%w", CL_Close|HtoT, DebugID, OSInfo1, OSInfo2, err); } case CL_Write: { /* Write(word handle, word nbtotal, word nbytes, bytes data) * return(word nbytes) * WriteX(word nbytes, bytes data) * return(word nbytes) */ unsigned char *rwdata = NULL, *rwhead = NULL; unsigned char *write_source = NULL; char flags; FILE *fhreal; unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */ err = -1; /* err == 0 is fwrite() error indication */ unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes); DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n", fh, nbtotal, nbytes)); fhreal = hsysGetRealFileHandle(stateptr, fh, &flags); nbtogo = nbtotal; /* deal with the file handle */ if (fhreal == NULL) err = 0; else { if (flags & READOP) fseek(fhreal,0,SEEK_CUR); stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP; nbtogo -= nbytes; if (nbtogo > 0) { write_source = rwdata = rwhead = (unsigned char *)malloc(nbtotal); if (rwhead == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); return -1; } memcpy(rwdata, buffp+12, nbytes); rwdata += nbytes; } else write_source = buffp+12; } do { /* at least once!! */ if (nbtogo == 0 && err != 0) { /* Do the actual write! */ if (fhreal == stdout || fhreal == stderr) { stateptr->hostif->write(stateptr->hostif->hostosarg, (char *)write_source, nbtotal); } else err = fwrite(write_source, 1, nbtotal, fhreal); stateptr->last_errno = errno; DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno); } DevSW_FreePacket(packet); if (msgsend(CI_CLIB,"%w%w%w%w%w%w", ack_reason|HtoT, DebugID, OSInfo1, OSInfo2, (err == 0), nbtogo)) { fprintf(stderr, "COULD NOT REPLY at line %d in %s\n", __LINE__, __FILE__); if (rwhead != NULL) free(rwhead); return -1; } if (nbtogo == 0 || err == 0) { DebugPrintF(("\twrite complete - returning\n")); if (rwhead != NULL) free(rwhead); return 0; } else { /* await extension */ ack_reason = CL_WriteX; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); if (rwhead != NULL) free(rwhead); return -1; } Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL); Adp_ChannelRead(CI_CLIB, &packet); Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleSysMessage, stateptr); buffhead = packet->pk_buffer; unpack_message(BUFFERDATA(buffhead), "%w%w%w%w%w", &reason_code, &DebugID, &OSInfo1, &OSInfo2, &nbytes); if (reason_code != (CL_WriteX|TtoH)) { DevSW_FreePacket(packet); free(rwhead); fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n", reason_code, __LINE__, __FILE__); return -1; } DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes)); memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes); rwdata += nbytes; nbtogo -= nbytes; } } while (TRUE); /* will return when done */ } case CL_WriteX: /* * NOTE: if we've got here something has gone wrong * CL_WriteX's should all be picked up within the * CL_Write loop, probably best to return an error here * do this for the moment just so we do actually return */ fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n"); return -1; case CL_Read: { /* Read(word handle, word nbtotal) * return(word nbytes, word nbmore, bytes data) */ /* ReadX() * return(word nbytes, word nbmore, bytes data) */ unsigned char *rwdata, *rwhead; int gotlen; unsigned int max_data_in_buffer=Armsd_BufferSize-28; char flags; FILE *fhreal; unsigned int nbleft = 0, reason = CL_Read; err = NoError; unpack_message(buffp, "%w%w", &fh, &nbtotal); DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal)); rwdata = rwhead = (unsigned char *)malloc(nbtotal); if (rwdata == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); DevSW_FreePacket(packet); return -1; } /* perform the actual read */ fhreal = hsysGetRealFileHandle(stateptr, fh, &flags); if (fhreal == NULL) { /* bad file handle */ err = -1; nbytes = 0; gotlen = 0; } else { if (flags & WRITEOP) fseek(fhreal,0,SEEK_CUR); stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP; if (isatty_(fhreal)) { /* reading from a tty, so do some nasty stuff, reading into rwdata */ if (angel_hostif->gets(stateptr->hostif->hostosarg, (char *)rwdata, nbtotal) != 0) gotlen = strlen((char *)rwdata); else gotlen = 0; stateptr->last_errno = errno; DebugPrintF(("ttyread %d\n", gotlen)); } else { /* not a tty, reading from a real file */ gotlen = fread(rwdata, 1, nbtotal, fhreal); stateptr->last_errno = errno; DebugCheckErr("fread", FALSE, (gotlen == 0), stateptr->last_errno); DebugPrintF(("(%d)\n", gotlen)); } } nbtogo = gotlen; do { /* at least once */ if ((unsigned int) nbtogo <= max_data_in_buffer) nbytes = nbtogo; else nbytes = max_data_in_buffer; nbtogo -= nbytes; /* last ReadX needs subtle adjustment to returned nbtogo */ if (nbtogo == 0 && err == NoError && reason == CL_ReadX) nbleft = nbtotal - gotlen; else nbleft = nbtogo; count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w", reason|HtoT, 0, ADP_HandleUnknown, ADP_HandleUnknown, err, nbytes, nbleft); if (err == NoError) { /* copy data into buffptr */ memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes); rwdata += nbytes; count += nbytes; } DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n", err, nbytes, nbtogo)); packet->pk_length = count; Adp_ChannelWrite(CI_CLIB, packet); if (nbtogo == 0 || err != NoError) { /* done */ free(rwhead); return 0; } else { /* await extension */ reason = CL_ReadX; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); free(rwhead); return -1; } Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL); Adp_ChannelRead(CI_CLIB, &packet); Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleSysMessage, stateptr); buffhead = packet->pk_buffer; unpack_message(BUFFERDATA(buffhead),"%w", &reason_code); if (reason_code != (CL_ReadX|TtoH)) { fprintf(stderr, "EXPECTING CL_ReadX GOT %u at line %d in %s\n", reason_code, __LINE__, __FILE__); DevSW_FreePacket(packet); free(rwdata); return -1; } } } while (TRUE); /* will return above on error or when done */ } case CL_ReadX: /* If we're here something has probably gone wrong */ fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n"); return -1; case CL_Seek: { unpack_message(buffp, "%w%w", &fh, &posn); DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) err = -1; else { err = fseek(fhreal, posn, SEEK_SET); stateptr->last_errno = errno; DebugCheckErr("fseek", TRUE, err, stateptr->last_errno); } return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT, DebugID, OSInfo1, OSInfo2, err); } case CL_Flen: { unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_Flen: fh %d ", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) fl = -1; else { posn = ftell(fhreal); if (fseek(fhreal, 0L, SEEK_END) < 0) { fl=-1; } else { fl = ftell(fhreal); fseek(fhreal, posn, SEEK_SET); } stateptr->last_errno = errno; } DebugPrintF(("returning len %ld\n", fl)); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1, OSInfo2, fl); } case CL_IsTTY: { int ttyOrNot; unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_IsTTY: fh %d ", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) ttyOrNot = FALSE; else { ttyOrNot = isatty_(fhreal); stateptr->last_errno = errno; } DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)")); return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT, DebugID, OSInfo1, OSInfo2, ttyOrNot); } case CL_TmpNam: { char *name; unsigned int tnamelen, TargetID; unpack_message(buffp, "%w%w", &tnamelen, &TargetID); DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ", tnamelen, TargetID)); DevSW_FreePacket(packet); TargetID = TargetID & 0xFF; if (stateptr->OSptr->TempNames[TargetID] == NULL) { if ((stateptr->OSptr->TempNames[TargetID] = (char *)malloc(L_tmpnam)) == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); return -1; } tmpnam(stateptr->OSptr->TempNames[TargetID]); } name = stateptr->OSptr->TempNames[TargetID]; len = strlen(name) + 1; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); return -1; } buffhead = packet->pk_buffer; if (len > tnamelen) { DebugPrintF(("TMPNAME TOO LONG!\n")); count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w", CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, -1); } else { DebugPrintF(("returning \"%s\"\n", name)); count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, 0, len); strcpy((char *)BUFFERDATA(buffhead)+count, name); count +=len+1; } packet->pk_length = count; Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */ return 0; } case CL_Unrecognised: DebugPrintF(("CL_Unrecognised!!\n")); return 0; default: fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code); break; /* Need some sort of error handling here. */ /* A call to CL_Unrecognised should suffice */ } return -1; /* Stop a potential compiler warning */ }