2 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
4 * This software may be freely used, copied, modified, and distributed
5 * provided that the above copyright notice is preserved in all copies of the
10 * Host C Library support functions.
31 #include "channels.h" /* Channel interface. */
32 #include "angel_endian.h"
33 #include "logging.h" /* Angel support functions. */
36 #include "hsys.h" /* Function and structure declarations. */
39 #define FILEHANDLE int
41 /* Note: no statics allowed. All globals must be malloc()ed on the heap.
42 The state struct is used for this purpose. See 'hsys.h'. */
43 /* This is the message handler function passed to the channel manager in
44 HostSysInit. It is called whenever a message is received. 'buffptr'
45 points to the message body. Functionality is provided by the debugger
46 toolkit. The routine is very loosely based on the HandleSWI routine from
47 armos.c in the armulator source. */
48 /* These routines could be tested by providing a simple interface to armsd,
49 and running them in that. */
52 /* taken staight from armulator source */
54 extern int _fisatty(FILE *);
55 # define isatty_(f) _fisatty(f)
58 int _kernel_escape_seen(void) { return 0 ;}
60 # if defined(_WINDOWS) || defined(_CONSOLE)
61 # define isatty_(f) (f == stdin || f == stdout)
65 # define isatty_(f) isatty((f)->_file)
69 # define isatty_(f) (~ioctl((f)->_file,FIOINTERACTIVE,NULL))
71 # define isatty_(f) isatty(fileno(f))
77 /* Set up the state block, filetable and register the C lib callback fn */
78 int HostSysInit(const struct Dbg_HostosInterface *hostif, char **cmdline,
79 hsys_state **stateptr)
81 ChannelCallback HandleMessageFPtr = (ChannelCallback) HandleSysMessage;
83 *stateptr = (hsys_state *)malloc(sizeof(hsys_state));
85 if (*stateptr == NULL) return RDIError_OutOfStore;
87 (*stateptr)->hostif=hostif;
88 (*stateptr)->last_errno=0;
89 (*stateptr)->OSptr=(OSblock *)malloc(sizeof(OSblock));
90 if ((*stateptr)->OSptr == NULL) return RDIError_OutOfStore;
91 for (i=0; i<UNIQUETEMPS; i++) (*stateptr)->OSptr->TempNames[i]=NULL;
92 for (i=0; i<HSYS_FOPEN_MAX; i++) {
93 (*stateptr)->OSptr->FileTable[i]=NULL;
94 (*stateptr)->OSptr->FileFlags[i]=0;
96 (*stateptr)->CommandLine=cmdline;
98 return Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleMessageFPtr,
102 /* Shut down the Clib support, this will probably never get called though */
103 int HostSysExit(hsys_state *stateptr)
105 free(stateptr->OSptr);
107 return RDIError_NoError;
111 static void DebugCheckNullTermString(char *prefix, bool nl,
112 unsigned int len, unsigned char *strp)
114 printf("%s: %d: ", prefix, len);
116 printf("\"%s\"", strp);
118 printf("NOT NULL TERMINATED");
128 #ifdef NEED_SYSERRLIST
130 extern char *sys_errlist[];
133 static char *DebugStrError(int last_errno)
135 if (last_errno < sys_nerr)
136 return sys_errlist[last_errno];
138 return "NO MSG (errno>sys_nerr)";
141 static void DebugCheckErr(char *prefix, bool nl, int err, int last_errno)
143 printf("\t%s: returned ", prefix);
147 printf("%d, errno = %d \"%s\"", err, last_errno,
148 DebugStrError(last_errno));
158 static void DebugCheckNonNull(char *prefix, bool nl,
159 void *handle, int last_errno)
161 printf("\t%s: returned ", prefix);
163 printf("okay [%08x]", (unsigned int)handle);
165 printf("NULL, errno = %d \"%s\"", last_errno,
166 DebugStrError(last_errno));
176 #define DebugPrintF(c) printf c;
180 #define DebugCheckNullTermString(p, n, l, s) ((void)(0))
181 #define DebugCheckErr(p, n, e, l) ((void)(0))
182 #define DebugCheckNonNull(p, n, h, l) ((void)(0))
183 #define DebugPrintF(c) ((void)(0))
185 #endif /* ifdef DEBUG ... else */
187 static FILE *hsysGetRealFileHandle(hsys_state *stateptr, int fh, char *flags)
191 if (fh < 0 || fh >= HSYS_FOPEN_MAX)
193 stateptr->last_errno = EBADF;
194 DebugPrintF(("\tfh %d out-of-bounds!\n", fh));
199 file_p = stateptr->OSptr->FileTable[fh];
200 if (file_p != NULL) {
202 *flags = stateptr->OSptr->FileFlags[fh];
205 stateptr->last_errno = EBADF;
206 DebugPrintF(("\tFileTable[%d] is NULL\n", fh));
213 int HandleSysMessage(Packet *packet, hsys_state *stateptr)
215 unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0;
220 /* Note: We must not free the buffer passed in as the callback handler */
221 /* expects to do this. Freeing any other buffers we have malloced */
222 /* ourselves is acceptable */
224 unsigned char *buffp = ((unsigned char *)BUFFERDATA(packet->pk_buffer))+16;
225 /* buffp points to the parameters*/
226 /* the invidual messages, excluding*/
227 /* standard SYS fields (debugID, */
228 /* osinfo and reasoncode) */
229 unsigned char *buffhead = (unsigned char *)(packet->pk_buffer);
231 int DebugID, OSInfo1, OSInfo2, count;
233 const char* fmode[] = {"r","rb","r+","r+b",
236 "r","r","r","r"} /* last 4 are illegal */ ;
238 FILEHANDLE fh; /* fh is used as an index to the real file handle
241 unpack_message(BUFFERDATA(buffhead), "%w%w%w%w", &reason_code,
242 &DebugID, &OSInfo1, &OSInfo2);
243 /* Extract reason code from buffer. */
244 reason_code &= 0xFFFF; /* Strip away direction bit, OSInfo and */
245 /* DebugInfo fields. Will want to do some */
246 /* sort of validation on this later. */
251 case CL_WriteC: /* Write a character to the terminal. */
252 /* byte data -> word status */
255 int c = (int)(*buffp);
256 printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.');
258 stateptr->hostif->writec(stateptr->hostif->hostosarg, (int)(*buffp));
259 DevSW_FreePacket(packet);
260 return msgsend(CI_CLIB,"%w%w%w%w%w", CL_WriteC|HtoT,
261 DebugID, OSInfo1, OSInfo2, NoError);
264 case CL_Write0: /* Write a null terminated string to the terminal. */
266 unpack_message(buffp, "%w", &len);
267 DebugCheckNullTermString("CL_Write0", TRUE, len, buffp+4);
268 stateptr->hostif->write(stateptr->hostif->hostosarg,
269 (char *) buffp+4, len);
270 DevSW_FreePacket(packet);
271 return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Write0|HtoT, DebugID,
272 OSInfo1, OSInfo2, NoError);
275 case CL_ReadC: /* Read a byte from the terminal */
277 DebugPrintF(("CL_ReadC: "));
278 DevSW_FreePacket(packet);
280 character = stateptr->hostif->readc(stateptr->hostif->hostosarg);
281 DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character,
282 isprint(character) ? character : '.'));
284 return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT,
285 DebugID, OSInfo1, OSInfo2, NoError, character);
288 case CL_System: /* Pass NULL terminated string to the hosts command
289 * interpreter. As it is nULL terminated we dont need
293 unpack_message(buffp, "%w", &len);
294 DebugCheckNullTermString("CL_System", TRUE, len, buffp+4);
296 err = system((char *)buffp+4); /* Use the string in the buffer */
297 stateptr->last_errno = errno;
298 DebugCheckErr("system", TRUE, err, stateptr->last_errno);
300 err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT,
301 DebugID, OSInfo1, OSInfo2, NoError, err);
302 DevSW_FreePacket(packet);
306 case CL_GetCmdLine: /* Returns the command line used to call the program */
308 /* Note: we reuse the packet here, this may not always be desirable */
309 /* /* TODO: Use long buffers if possible */
310 DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr->CommandLine)));
312 if (buffhead!=NULL) {
313 len = strlen(*(stateptr->CommandLine));
314 if (len > Armsd_BufferSize-24) len = Armsd_BufferSize-24;
315 packet->pk_length = len + msgbuild(BUFFERDATA(buffhead),
316 "%w%w%w%w%w%w", CL_GetCmdLine|HtoT,
317 DebugID, OSInfo1, OSInfo2,
319 strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine),
322 Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
328 case CL_Clock: /* Return the number of centiseconds since the support */
329 /* code started executing */
331 time_t retTime = time(NULL);
332 if (retTime == (time_t)-1)
333 stateptr->last_errno = errno;
337 DebugPrintF(("CL_Clock: %lu\n", retTime));
338 DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
339 stateptr->last_errno);
341 DevSW_FreePacket(packet);
342 return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT,
343 DebugID, OSInfo1, OSInfo2, NoError, retTime);
346 case CL_Time: /* return time, in seconds since the start of 1970 */
348 time_t retTime = time(NULL);
349 if (retTime == (time_t)-1)
350 stateptr->last_errno = errno;
352 DebugPrintF(("CL_Time: %lu\n", retTime));
353 DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
354 stateptr->last_errno);
356 DevSW_FreePacket(packet);
357 return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT,
358 DebugID, OSInfo1, OSInfo2, NoError, retTime);
361 case CL_Remove: /* delete named in the null terminated string */
363 /* Removing an open file will cause problems but once again
364 * its not our problem, likely result is a tangled FileTable */
365 /* As the filename is passed with a null terminator we can use it
366 * straight out of the buffer without copying it.*/
368 unpack_message(buffp, "%w", &len);
369 DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4);
371 err=remove((char *)buffp+4);
372 stateptr->last_errno = errno;
373 DevSW_FreePacket(packet);
374 DebugCheckErr("remove", TRUE, err, stateptr->last_errno);
376 return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT,
377 DebugID, OSInfo1, OSInfo2, err?-1:NoError);
380 case CL_Rename: /* rename file */
382 /* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
383 * return(byte status)
387 unpack_message(buffp, "%w", &len);
388 DebugCheckNullTermString("CL_Rename", FALSE, len, buffp+4);
389 unpack_message(buffp+5+len, "%w", &len2);
390 DebugCheckNullTermString("to", TRUE, len2, buffp+9+len);
392 /* Both names are passed with null terminators so we can use them
393 * directly from the buffer. */
394 err = rename((char *)buffp+4, (char *)buffp+9+len);
395 stateptr->last_errno = errno;
396 DebugCheckErr("rename", TRUE, err, stateptr->last_errno);
397 DevSW_FreePacket(packet);
399 return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Rename|HtoT,
400 DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1);
403 case CL_Open: /* open the file */
405 /* Open(word nbytes, bytes name, byte mode)
406 * return(word handle)
408 unpack_message(buffp, "%w", &len);
409 /* get the open mode */
410 unpack_message((buffp)+4+len+1, "%w", &mode);
411 DebugCheckNullTermString("CL_Open", FALSE, len, buffp+4);
412 DebugPrintF(("mode: %d\n", mode));
414 /* do some checking on the file first? */
415 /* check if its a tty */
416 if (strcmp((char *)buffp+4, ":tt")==0 && (mode==0||mode==1)) {
417 /* opening tty "r" */
419 stateptr->last_errno = errno;
420 DebugPrintF(("\tstdin "));
422 else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) {
423 /* opening tty "w" */
425 stateptr->last_errno = errno;
426 DebugPrintF(("\tstdout "));
430 fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]);
431 stateptr->last_errno = errno;
432 DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno);
434 DevSW_FreePacket(packet);
437 if (fhreal != NULL) {
438 /* update filetable */
439 for (c=3; c < HSYS_FOPEN_MAX; c++) {
440 /* allow for stdin, stdout, stderr (!!! WHY? MJG) */
441 if (stateptr->OSptr->FileTable[c] == NULL) {
442 stateptr->OSptr->FileTable[c]= fhreal;
443 stateptr->OSptr->FileFlags[c]= mode & 1;
444 DebugPrintF(("fh: %d\n", c));
447 else if (c == HSYS_FOPEN_MAX) {
448 /* no filehandles free */
449 DebugPrintF(("no free fh: %d\n", c));
450 stateptr->last_errno = EMFILE;
456 DebugPrintF(("error fh: %d\n", c));
458 (void) msgsend(CI_CLIB, "%w%w%w%w%w", CL_Open|HtoT,
459 DebugID, OSInfo1, OSInfo2, c);
463 case CL_Close: /* close the file pointed to by the filehandle */
465 unpack_message(buffp, "%w", &fh);
466 DebugPrintF(("CL_Close: fh %d\n", fh));
467 DevSW_FreePacket(packet);
469 fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
473 if (fhreal == stdin || fhreal == stdout || fhreal == stderr) {
474 stateptr->last_errno = errno;
475 DebugPrintF(("\tskipping close of std*\n"));
479 err = fclose(fhreal);
481 stateptr->OSptr->FileTable[fh]=NULL;
482 stateptr->last_errno = errno;
483 DebugCheckErr("fclose", TRUE, err, stateptr->last_errno);
486 return msgsend(CI_CLIB,"%w%w%w%w%w", CL_Close|HtoT, DebugID,
487 OSInfo1, OSInfo2, err);
492 /* Write(word handle, word nbtotal, word nbytes, bytes data)
493 * return(word nbytes)
494 * WriteX(word nbytes, bytes data)
495 * return(word nbytes)
497 unsigned char *rwdata = NULL, *rwhead = NULL;
498 unsigned char *write_source = NULL;
501 unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */
503 err = -1; /* err == 0 is fwrite() error indication */
504 unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes);
505 DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n",
506 fh, nbtotal, nbytes));
508 fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
511 /* deal with the file handle */
516 fseek(fhreal,0,SEEK_CUR);
517 stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
522 write_source = rwdata = rwhead = (unsigned char *)malloc(nbtotal);
523 if (rwhead == NULL) {
524 fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
528 memcpy(rwdata, buffp+12, nbytes);
532 write_source = buffp+12;
536 /* at least once!! */
538 if (nbtogo == 0 && err != 0) {
539 /* Do the actual write! */
540 if (fhreal == stdout || fhreal == stderr) {
541 stateptr->hostif->write(stateptr->hostif->hostosarg,
542 (char *)write_source, nbtotal);
545 err = fwrite(write_source, 1, nbtotal, fhreal);
546 stateptr->last_errno = errno;
547 DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno);
550 DevSW_FreePacket(packet);
551 if (msgsend(CI_CLIB,"%w%w%w%w%w%w", ack_reason|HtoT,
552 DebugID, OSInfo1, OSInfo2, (err == 0), nbtogo))
554 fprintf(stderr, "COULD NOT REPLY at line %d in %s\n",
561 if (nbtogo == 0 || err == 0) {
562 DebugPrintF(("\twrite complete - returning\n"));
568 /* await extension */
569 ack_reason = CL_WriteX;
571 packet = DevSW_AllocatePacket(Armsd_BufferSize);
574 fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
580 Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
581 Adp_ChannelRead(CI_CLIB, &packet);
582 Adp_ChannelRegisterRead(CI_CLIB,
583 (ChannelCallback)HandleSysMessage,
586 buffhead = packet->pk_buffer;
587 unpack_message(BUFFERDATA(buffhead), "%w%w%w%w%w", &reason_code,
588 &DebugID, &OSInfo1, &OSInfo2, &nbytes);
589 if (reason_code != (CL_WriteX|TtoH)) {
590 DevSW_FreePacket(packet);
592 fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n",
593 reason_code, __LINE__, __FILE__);
597 DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes));
598 memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes);
603 } while (TRUE); /* will return when done */
607 * NOTE: if we've got here something has gone wrong
608 * CL_WriteX's should all be picked up within the
609 * CL_Write loop, probably best to return an error here
610 * do this for the moment just so we do actually return
612 fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n");
617 /* Read(word handle, word nbtotal)
618 * return(word nbytes, word nbmore, bytes data)
621 * return(word nbytes, word nbmore, bytes data) */
622 unsigned char *rwdata, *rwhead;
624 unsigned int max_data_in_buffer=Armsd_BufferSize-28;
627 unsigned int nbleft = 0, reason = CL_Read;
631 unpack_message(buffp, "%w%w", &fh, &nbtotal);
632 DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal));
634 rwdata = rwhead = (unsigned char *)malloc(nbtotal);
635 if (rwdata == NULL) {
636 fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
638 DevSW_FreePacket(packet);
642 /* perform the actual read */
643 fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
646 /* bad file handle */
654 fseek(fhreal,0,SEEK_CUR);
655 stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
656 if (isatty_(fhreal)) {
657 /* reading from a tty, so do some nasty stuff, reading into rwdata */
658 if (angel_hostif->gets(stateptr->hostif->hostosarg, (char *)rwdata,
660 gotlen = strlen((char *)rwdata);
663 stateptr->last_errno = errno;
664 DebugPrintF(("ttyread %d\n", gotlen));
667 /* not a tty, reading from a real file */
668 gotlen = fread(rwdata, 1, nbtotal, fhreal);
669 stateptr->last_errno = errno;
670 DebugCheckErr("fread", FALSE, (gotlen == 0), stateptr->last_errno);
671 DebugPrintF(("(%d)\n", gotlen));
680 if ((unsigned int) nbtogo <= max_data_in_buffer)
683 nbytes = max_data_in_buffer;
686 /* last ReadX needs subtle adjustment to returned nbtogo */
687 if (nbtogo == 0 && err == NoError && reason == CL_ReadX)
688 nbleft = nbtotal - gotlen;
692 count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w",
693 reason|HtoT, 0, ADP_HandleUnknown,
694 ADP_HandleUnknown, err, nbytes, nbleft);
696 if (err == NoError) {
697 /* copy data into buffptr */
698 memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes);
703 DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n",
704 err, nbytes, nbtogo));
706 packet->pk_length = count;
707 Adp_ChannelWrite(CI_CLIB, packet);
709 if (nbtogo == 0 || err != NoError) {
715 /* await extension */
718 packet = DevSW_AllocatePacket(Armsd_BufferSize);
719 if (packet == NULL) {
720 fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
725 Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
726 Adp_ChannelRead(CI_CLIB, &packet);
727 Adp_ChannelRegisterRead(CI_CLIB,
728 (ChannelCallback)HandleSysMessage,
730 buffhead = packet->pk_buffer;
731 unpack_message(BUFFERDATA(buffhead),"%w", &reason_code);
732 if (reason_code != (CL_ReadX|TtoH)) {
733 fprintf(stderr, "EXPECTING CL_ReadX GOT %u at line %d in %s\n",
734 reason_code, __LINE__, __FILE__);
735 DevSW_FreePacket(packet);
741 } while (TRUE); /* will return above on error or when done */
744 case CL_ReadX: /* If we're here something has probably gone wrong */
745 fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n");
750 unpack_message(buffp, "%w%w", &fh, &posn);
751 DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn));
752 DevSW_FreePacket(packet);
754 fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
758 err = fseek(fhreal, posn, SEEK_SET);
759 stateptr->last_errno = errno;
760 DebugCheckErr("fseek", TRUE, err, stateptr->last_errno);
763 return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT,
764 DebugID, OSInfo1, OSInfo2, err);
769 unpack_message(buffp, "%w", &fh);
770 DebugPrintF(("CL_Flen: fh %d ", fh));
771 DevSW_FreePacket(packet);
773 fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
777 posn = ftell(fhreal);
778 if (fseek(fhreal, 0L, SEEK_END) < 0) {
783 fseek(fhreal, posn, SEEK_SET);
785 stateptr->last_errno = errno;
787 DebugPrintF(("returning len %ld\n", fl));
788 return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1,
795 unpack_message(buffp, "%w", &fh);
796 DebugPrintF(("CL_IsTTY: fh %d ", fh));
797 DevSW_FreePacket(packet);
799 fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
803 ttyOrNot = isatty_(fhreal);
804 stateptr->last_errno = errno;
806 DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)"));
808 return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT,
809 DebugID, OSInfo1, OSInfo2, ttyOrNot);
815 unsigned int tnamelen, TargetID;
816 unpack_message(buffp, "%w%w", &tnamelen, &TargetID);
817 DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ",
818 tnamelen, TargetID));
819 DevSW_FreePacket(packet);
821 TargetID = TargetID & 0xFF;
822 if (stateptr->OSptr->TempNames[TargetID] == NULL) {
823 if ((stateptr->OSptr->TempNames[TargetID] =
824 (char *)malloc(L_tmpnam)) == NULL)
826 fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
830 tmpnam(stateptr->OSptr->TempNames[TargetID]);
832 name = stateptr->OSptr->TempNames[TargetID];
833 len = strlen(name) + 1;
834 packet = DevSW_AllocatePacket(Armsd_BufferSize);
837 fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
841 buffhead = packet->pk_buffer;
842 if (len > tnamelen) {
843 DebugPrintF(("TMPNAME TOO LONG!\n"));
844 count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w",
845 CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, -1);
848 DebugPrintF(("returning \"%s\"\n", name));
849 count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_TmpNam|HtoT,
850 DebugID, OSInfo1, OSInfo2, 0, len);
851 strcpy((char *)BUFFERDATA(buffhead)+count, name);
854 packet->pk_length = count;
855 Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
859 case CL_Unrecognised:
860 DebugPrintF(("CL_Unrecognised!!\n"));
864 fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code);
866 /* Need some sort of error handling here. */
867 /* A call to CL_Unrecognised should suffice */
869 return -1; /* Stop a potential compiler warning */
872 #ifdef COMPILING_ON_WINDOWS
876 extern HWND hwndParent;
878 void panic(const char *format, ...)
885 va_start(args, format);
886 vsprintf(buf, format, args);
888 MessageBox(hwndParent, (LPCTSTR)buf, (LPCTSTR)"Fatal Error:", MB_OK);
890 /* SJ - Not the proper way to shutdown the app */
894 if (hwndParent != NULL)
895 SendMessage(hwndParent, WM_QUIT, 0, 0);
903 void panic(const char *format, ...)
907 va_start(args, format);
908 fprintf(stderr, "Fatal error: ");
909 vfprintf(stderr, format, args);
910 fprintf(stderr,"\n");