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");
129 extern char *sys_errlist
[];
131 static char *DebugStrError(int last_errno
)
133 if (last_errno
< sys_nerr
)
134 return sys_errlist
[last_errno
];
136 return "NO MSG (errno>sys_nerr)";
139 static void DebugCheckErr(char *prefix
, bool nl
, int err
, int last_errno
)
141 printf("\t%s: returned ", prefix
);
145 printf("%d, errno = %d \"%s\"", err
, last_errno
,
146 DebugStrError(last_errno
));
156 static void DebugCheckNonNull(char *prefix
, bool nl
,
157 void *handle
, int last_errno
)
159 printf("\t%s: returned ", prefix
);
161 printf("okay [%08x]", (unsigned int)handle
);
163 printf("NULL, errno = %d \"%s\"", last_errno
,
164 DebugStrError(last_errno
));
174 #define DebugPrintF(c) printf c;
178 #define DebugCheckNullTermString(p, n, l, s) ((void)(0))
179 #define DebugCheckErr(p, n, e, l) ((void)(0))
180 #define DebugCheckNonNull(p, n, h, l) ((void)(0))
181 #define DebugPrintF(c) ((void)(0))
183 #endif /* ifdef DEBUG ... else */
185 static FILE *hsysGetRealFileHandle(hsys_state
*stateptr
, int fh
, char *flags
)
189 if (fh
< 0 || fh
>= HSYS_FOPEN_MAX
)
191 stateptr
->last_errno
= EBADF
;
192 DebugPrintF(("\tfh %d out-of-bounds!\n", fh
));
197 file_p
= stateptr
->OSptr
->FileTable
[fh
];
198 if (file_p
!= NULL
) {
200 *flags
= stateptr
->OSptr
->FileFlags
[fh
];
203 stateptr
->last_errno
= EBADF
;
204 DebugPrintF(("\tFileTable[%d] is NULL\n", fh
));
211 int HandleSysMessage(Packet
*packet
, hsys_state
*stateptr
)
213 unsigned int reason_code
, mode
, len
, c
, nbytes
, nbtotal
, nbtogo
= 0;
218 /* Note: We must not free the buffer passed in as the callback handler */
219 /* expects to do this. Freeing any other buffers we have malloced */
220 /* ourselves is acceptable */
222 unsigned char *buffp
= ((unsigned char *)BUFFERDATA(packet
->pk_buffer
))+16;
223 /* buffp points to the parameters*/
224 /* the invidual messages, excluding*/
225 /* standard SYS fields (debugID, */
226 /* osinfo and reasoncode) */
227 unsigned char *buffhead
= (unsigned char *)(packet
->pk_buffer
);
229 int DebugID
, OSInfo1
, OSInfo2
, count
;
231 const char* fmode
[] = {"r","rb","r+","r+b",
234 "r","r","r","r"} /* last 4 are illegal */ ;
236 FILEHANDLE fh
; /* fh is used as an index to the real file handle
239 unpack_message(BUFFERDATA(buffhead
), "%w%w%w%w", &reason_code
,
240 &DebugID
, &OSInfo1
, &OSInfo2
);
241 /* Extract reason code from buffer. */
242 reason_code
&= 0xFFFF; /* Strip away direction bit, OSInfo and */
243 /* DebugInfo fields. Will want to do some */
244 /* sort of validation on this later. */
249 case CL_WriteC
: /* Write a character to the terminal. */
250 /* byte data -> word status */
253 int c
= (int)(*buffp
);
254 printf("CL_WriteC: [%02x]>%c<", c
, isprint(c
) ? c
: '.');
256 stateptr
->hostif
->writec(stateptr
->hostif
->hostosarg
, (int)(*buffp
));
257 DevSW_FreePacket(packet
);
258 return msgsend(CI_CLIB
,"%w%w%w%w%w", CL_WriteC
|HtoT
,
259 DebugID
, OSInfo1
, OSInfo2
, NoError
);
262 case CL_Write0
: /* Write a null terminated string to the terminal. */
264 unpack_message(buffp
, "%w", &len
);
265 DebugCheckNullTermString("CL_Write0", TRUE
, len
, buffp
+4);
266 stateptr
->hostif
->write(stateptr
->hostif
->hostosarg
,
267 (char *) buffp
+4, len
);
268 DevSW_FreePacket(packet
);
269 return msgsend(CI_CLIB
, "%w%w%w%w%w", CL_Write0
|HtoT
, DebugID
,
270 OSInfo1
, OSInfo2
, NoError
);
273 case CL_ReadC
: /* Read a byte from the terminal */
275 DebugPrintF(("CL_ReadC: "));
276 DevSW_FreePacket(packet
);
278 character
= stateptr
->hostif
->readc(stateptr
->hostif
->hostosarg
);
279 DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character
,
280 isprint(character
) ? character
: '.'));
282 return msgsend(CI_CLIB
, "%w%w%w%w%w%b", CL_ReadC
|HtoT
,
283 DebugID
, OSInfo1
, OSInfo2
, NoError
, character
);
286 case CL_System
: /* Pass NULL terminated string to the hosts command
287 * interpreter. As it is nULL terminated we dont need
291 unpack_message(buffp
, "%w", &len
);
292 DebugCheckNullTermString("CL_System", TRUE
, len
, buffp
+4);
294 err
= system((char *)buffp
+4); /* Use the string in the buffer */
295 stateptr
->last_errno
= errno
;
296 DebugCheckErr("system", TRUE
, err
, stateptr
->last_errno
);
298 err
= msgsend(CI_CLIB
, "%w%w%w%w%w%w", CL_System
|HtoT
,
299 DebugID
, OSInfo1
, OSInfo2
, NoError
, err
);
300 DevSW_FreePacket(packet
);
304 case CL_GetCmdLine
: /* Returns the command line used to call the program */
306 /* Note: we reuse the packet here, this may not always be desirable */
307 /* /* TODO: Use long buffers if possible */
308 DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr
->CommandLine
)));
310 if (buffhead
!=NULL
) {
311 len
= strlen(*(stateptr
->CommandLine
));
312 if (len
> Armsd_BufferSize
-24) len
= Armsd_BufferSize
-24;
313 packet
->pk_length
= len
+ msgbuild(BUFFERDATA(buffhead
),
314 "%w%w%w%w%w%w", CL_GetCmdLine
|HtoT
,
315 DebugID
, OSInfo1
, OSInfo2
,
317 strncpy((char *) BUFFERDATA(buffhead
)+24,*(stateptr
->CommandLine
),
320 Adp_ChannelWrite(CI_CLIB
, packet
);/* Send message. */
326 case CL_Clock
: /* Return the number of centiseconds since the support */
327 /* code started executing */
329 time_t retTime
= time(NULL
);
330 if (retTime
== (time_t)-1)
331 stateptr
->last_errno
= errno
;
335 DebugPrintF(("CL_Clock: %lu\n", retTime
));
336 DebugCheckErr("time", TRUE
, (retTime
== (time_t)-1),
337 stateptr
->last_errno
);
339 DevSW_FreePacket(packet
);
340 return msgsend(CI_CLIB
, "%w%w%w%w%w%w",CL_Clock
|HtoT
,
341 DebugID
, OSInfo1
, OSInfo2
, NoError
, retTime
);
344 case CL_Time
: /* return time, in seconds since the start of 1970 */
346 time_t retTime
= time(NULL
);
347 if (retTime
== (time_t)-1)
348 stateptr
->last_errno
= errno
;
350 DebugPrintF(("CL_Time: %lu\n", retTime
));
351 DebugCheckErr("time", TRUE
, (retTime
== (time_t)-1),
352 stateptr
->last_errno
);
354 DevSW_FreePacket(packet
);
355 return msgsend(CI_CLIB
,"%w%w%w%w%w%w",CL_Time
|HtoT
,
356 DebugID
, OSInfo1
, OSInfo2
, NoError
, retTime
);
359 case CL_Remove
: /* delete named in the null terminated string */
361 /* Removing an open file will cause problems but once again
362 * its not our problem, likely result is a tangled FileTable */
363 /* As the filename is passed with a null terminator we can use it
364 * straight out of the buffer without copying it.*/
366 unpack_message(buffp
, "%w", &len
);
367 DebugCheckNullTermString("CL_Remove", TRUE
, len
, buffp
+4);
369 err
=remove((char *)buffp
+4);
370 stateptr
->last_errno
= errno
;
371 DevSW_FreePacket(packet
);
372 DebugCheckErr("remove", TRUE
, err
, stateptr
->last_errno
);
374 return msgsend(CI_CLIB
, "%w%w%w%w%w", CL_Remove
|HtoT
,
375 DebugID
, OSInfo1
, OSInfo2
, err
?-1:NoError
);
378 case CL_Rename
: /* rename file */
380 /* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
381 * return(byte status)
385 unpack_message(buffp
, "%w", &len
);
386 DebugCheckNullTermString("CL_Rename", FALSE
, len
, buffp
+4);
387 unpack_message(buffp
+5+len
, "%w", &len2
);
388 DebugCheckNullTermString("to", TRUE
, len2
, buffp
+9+len
);
390 /* Both names are passed with null terminators so we can use them
391 * directly from the buffer. */
392 err
= rename((char *)buffp
+4, (char *)buffp
+9+len
);
393 stateptr
->last_errno
= errno
;
394 DebugCheckErr("rename", TRUE
, err
, stateptr
->last_errno
);
395 DevSW_FreePacket(packet
);
397 return msgsend(CI_CLIB
, "%w%w%w%w%w", CL_Rename
|HtoT
,
398 DebugID
, OSInfo1
, OSInfo2
, (err
==0)? NoError
: -1);
401 case CL_Open
: /* open the file */
403 /* Open(word nbytes, bytes name, byte mode)
404 * return(word handle)
406 unpack_message(buffp
, "%w", &len
);
407 /* get the open mode */
408 unpack_message((buffp
)+4+len
+1, "%w", &mode
);
409 DebugCheckNullTermString("CL_Open", FALSE
, len
, buffp
+4);
410 DebugPrintF(("mode: %d\n", mode
));
412 /* do some checking on the file first? */
413 /* check if its a tty */
414 if (strcmp((char *)buffp
+4, ":tt")==0 && (mode
==0||mode
==1)) {
415 /* opening tty "r" */
417 stateptr
->last_errno
= errno
;
418 DebugPrintF(("\tstdin "));
420 else if (strcmp((char *)buffp
+4, ":tt")== 0 && (mode
==4||mode
==5)) {
421 /* opening tty "w" */
423 stateptr
->last_errno
= errno
;
424 DebugPrintF(("\tstdout "));
428 fhreal
= fopen((char *)buffp
+4, fmode
[mode
&0xFF]);
429 stateptr
->last_errno
= errno
;
430 DebugCheckNonNull("fopen", FALSE
, fhreal
, stateptr
->last_errno
);
432 DevSW_FreePacket(packet
);
435 if (fhreal
!= NULL
) {
436 /* update filetable */
437 for (c
=3; c
< HSYS_FOPEN_MAX
; c
++) {
438 /* allow for stdin, stdout, stderr (!!! WHY? MJG) */
439 if (stateptr
->OSptr
->FileTable
[c
] == NULL
) {
440 stateptr
->OSptr
->FileTable
[c
]= fhreal
;
441 stateptr
->OSptr
->FileFlags
[c
]= mode
& 1;
442 DebugPrintF(("fh: %d\n", c
));
445 else if (c
== HSYS_FOPEN_MAX
) {
446 /* no filehandles free */
447 DebugPrintF(("no free fh: %d\n", c
));
448 stateptr
->last_errno
= EMFILE
;
454 DebugPrintF(("error fh: %d\n", c
));
456 (void) msgsend(CI_CLIB
, "%w%w%w%w%w", CL_Open
|HtoT
,
457 DebugID
, OSInfo1
, OSInfo2
, c
);
461 case CL_Close
: /* close the file pointed to by the filehandle */
463 unpack_message(buffp
, "%w", &fh
);
464 DebugPrintF(("CL_Close: fh %d\n", fh
));
465 DevSW_FreePacket(packet
);
467 fhreal
= hsysGetRealFileHandle(stateptr
, fh
, NULL
);
471 if (fhreal
== stdin
|| fhreal
== stdout
|| fhreal
== stderr
) {
472 stateptr
->last_errno
= errno
;
473 DebugPrintF(("\tskipping close of std*\n"));
477 err
= fclose(fhreal
);
479 stateptr
->OSptr
->FileTable
[fh
]=NULL
;
480 stateptr
->last_errno
= errno
;
481 DebugCheckErr("fclose", TRUE
, err
, stateptr
->last_errno
);
484 return msgsend(CI_CLIB
,"%w%w%w%w%w", CL_Close
|HtoT
, DebugID
,
485 OSInfo1
, OSInfo2
, err
);
490 /* Write(word handle, word nbtotal, word nbytes, bytes data)
491 * return(word nbytes)
492 * WriteX(word nbytes, bytes data)
493 * return(word nbytes)
495 unsigned char *rwdata
= NULL
, *rwhead
= NULL
;
496 unsigned char *write_source
= NULL
;
499 unsigned int ack_reason
= CL_Write
; /* first ack is for CL_Write */
501 err
= -1; /* err == 0 is fwrite() error indication */
502 unpack_message(buffp
, "%w%w%w", &fh
, &nbtotal
, &nbytes
);
503 DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n",
504 fh
, nbtotal
, nbytes
));
506 fhreal
= hsysGetRealFileHandle(stateptr
, fh
, &flags
);
509 /* deal with the file handle */
514 fseek(fhreal
,0,SEEK_CUR
);
515 stateptr
->OSptr
->FileFlags
[fh
] = (flags
& BINARY
) | WRITEOP
;
520 write_source
= rwdata
= rwhead
= (unsigned char *)malloc(nbtotal
);
521 if (rwhead
== NULL
) {
522 fprintf(stderr
, "OUT OF MEMORY at line %d in %s\n",
526 memcpy(rwdata
, buffp
+12, nbytes
);
530 write_source
= buffp
+12;
534 /* at least once!! */
536 if (nbtogo
== 0 && err
!= 0) {
537 /* Do the actual write! */
538 if (fhreal
== stdout
|| fhreal
== stderr
) {
539 stateptr
->hostif
->write(stateptr
->hostif
->hostosarg
,
540 (char *)write_source
, nbtotal
);
543 err
= fwrite(write_source
, 1, nbtotal
, fhreal
);
544 stateptr
->last_errno
= errno
;
545 DebugCheckErr("fwrite", TRUE
, (err
== 0), stateptr
->last_errno
);
548 DevSW_FreePacket(packet
);
549 if (msgsend(CI_CLIB
,"%w%w%w%w%w%w", ack_reason
|HtoT
,
550 DebugID
, OSInfo1
, OSInfo2
, (err
== 0), nbtogo
))
552 fprintf(stderr
, "COULD NOT REPLY at line %d in %s\n",
559 if (nbtogo
== 0 || err
== 0) {
560 DebugPrintF(("\twrite complete - returning\n"));
566 /* await extension */
567 ack_reason
= CL_WriteX
;
569 packet
= DevSW_AllocatePacket(Armsd_BufferSize
);
572 fprintf(stderr
, "COULD NOT ALLOC PACKET at line %d in %s\n",
578 Adp_ChannelRegisterRead(CI_CLIB
, NULL
, NULL
);
579 Adp_ChannelRead(CI_CLIB
, &packet
);
580 Adp_ChannelRegisterRead(CI_CLIB
,
581 (ChannelCallback
)HandleSysMessage
,
584 buffhead
= packet
->pk_buffer
;
585 unpack_message(BUFFERDATA(buffhead
), "%w%w%w%w%w", &reason_code
,
586 &DebugID
, &OSInfo1
, &OSInfo2
, &nbytes
);
587 if (reason_code
!= (CL_WriteX
|TtoH
)) {
588 DevSW_FreePacket(packet
);
590 fprintf(stderr
, "EXPECTING CL_WriteX GOT %u at line %d in %s\n",
591 reason_code
, __LINE__
, __FILE__
);
595 DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes
));
596 memcpy(rwdata
, BUFFERDATA(buffhead
)+20, nbytes
);
601 } while (TRUE
); /* will return when done */
605 * NOTE: if we've got here something has gone wrong
606 * CL_WriteX's should all be picked up within the
607 * CL_Write loop, probably best to return an error here
608 * do this for the moment just so we do actually return
610 fprintf(stderr
, "ERROR: unexpected CL_WriteX message received\n");
615 /* Read(word handle, word nbtotal)
616 * return(word nbytes, word nbmore, bytes data)
619 * return(word nbytes, word nbmore, bytes data) */
620 unsigned char *rwdata
, *rwhead
;
622 unsigned int max_data_in_buffer
=Armsd_BufferSize
-28;
625 unsigned int nbleft
= 0, reason
= CL_Read
;
629 unpack_message(buffp
, "%w%w", &fh
, &nbtotal
);
630 DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh
, nbtotal
));
632 rwdata
= rwhead
= (unsigned char *)malloc(nbtotal
);
633 if (rwdata
== NULL
) {
634 fprintf(stderr
, "OUT OF MEMORY at line %d in %s\n",
636 DevSW_FreePacket(packet
);
640 /* perform the actual read */
641 fhreal
= hsysGetRealFileHandle(stateptr
, fh
, &flags
);
644 /* bad file handle */
652 fseek(fhreal
,0,SEEK_CUR
);
653 stateptr
->OSptr
->FileFlags
[fh
] = (flags
& BINARY
) | WRITEOP
;
654 if (isatty_(fhreal
)) {
655 /* reading from a tty, so do some nasty stuff, reading into rwdata */
656 if (angel_hostif
->gets(stateptr
->hostif
->hostosarg
, (char *)rwdata
,
658 gotlen
= strlen((char *)rwdata
);
661 stateptr
->last_errno
= errno
;
662 DebugPrintF(("ttyread %d\n", gotlen
));
665 /* not a tty, reading from a real file */
666 gotlen
= fread(rwdata
, 1, nbtotal
, fhreal
);
667 stateptr
->last_errno
= errno
;
668 DebugCheckErr("fread", FALSE
, (gotlen
== 0), stateptr
->last_errno
);
669 DebugPrintF(("(%d)\n", gotlen
));
678 if ((unsigned int) nbtogo
<= max_data_in_buffer
)
681 nbytes
= max_data_in_buffer
;
684 /* last ReadX needs subtle adjustment to returned nbtogo */
685 if (nbtogo
== 0 && err
== NoError
&& reason
== CL_ReadX
)
686 nbleft
= nbtotal
- gotlen
;
690 count
= msgbuild(BUFFERDATA(buffhead
), "%w%w%w%w%w%w%w",
691 reason
|HtoT
, 0, ADP_HandleUnknown
,
692 ADP_HandleUnknown
, err
, nbytes
, nbleft
);
694 if (err
== NoError
) {
695 /* copy data into buffptr */
696 memcpy(BUFFERDATA(buffhead
)+28, rwdata
, nbytes
);
701 DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n",
702 err
, nbytes
, nbtogo
));
704 packet
->pk_length
= count
;
705 Adp_ChannelWrite(CI_CLIB
, packet
);
707 if (nbtogo
== 0 || err
!= NoError
) {
713 /* await extension */
716 packet
= DevSW_AllocatePacket(Armsd_BufferSize
);
717 if (packet
== NULL
) {
718 fprintf(stderr
, "COULD NOT ALLOC PACKET at line %d in %s\n",
723 Adp_ChannelRegisterRead(CI_CLIB
, NULL
, NULL
);
724 Adp_ChannelRead(CI_CLIB
, &packet
);
725 Adp_ChannelRegisterRead(CI_CLIB
,
726 (ChannelCallback
)HandleSysMessage
,
728 buffhead
= packet
->pk_buffer
;
729 unpack_message(BUFFERDATA(buffhead
),"%w", &reason_code
);
730 if (reason_code
!= (CL_ReadX
|TtoH
)) {
731 fprintf(stderr
, "EXPECTING CL_ReadX GOT %u at line %d in %s\n",
732 reason_code
, __LINE__
, __FILE__
);
733 DevSW_FreePacket(packet
);
739 } while (TRUE
); /* will return above on error or when done */
742 case CL_ReadX
: /* If we're here something has probably gone wrong */
743 fprintf(stderr
, "ERROR: Got unexpected CL_ReadX message\n");
748 unpack_message(buffp
, "%w%w", &fh
, &posn
);
749 DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh
, posn
));
750 DevSW_FreePacket(packet
);
752 fhreal
= hsysGetRealFileHandle(stateptr
, fh
, NULL
);
756 err
= fseek(fhreal
, posn
, SEEK_SET
);
757 stateptr
->last_errno
= errno
;
758 DebugCheckErr("fseek", TRUE
, err
, stateptr
->last_errno
);
761 return msgsend(CI_CLIB
, "%w%w%w%w%w", CL_Seek
|HtoT
,
762 DebugID
, OSInfo1
, OSInfo2
, err
);
767 unpack_message(buffp
, "%w", &fh
);
768 DebugPrintF(("CL_Flen: fh %d ", fh
));
769 DevSW_FreePacket(packet
);
771 fhreal
= hsysGetRealFileHandle(stateptr
, fh
, NULL
);
775 posn
= ftell(fhreal
);
776 if (fseek(fhreal
, 0L, SEEK_END
) < 0) {
781 fseek(fhreal
, posn
, SEEK_SET
);
783 stateptr
->last_errno
= errno
;
785 DebugPrintF(("returning len %ld\n", fl
));
786 return msgsend(CI_CLIB
, "%w%w%w%w%w", CL_Flen
|HtoT
, DebugID
, OSInfo1
,
793 unpack_message(buffp
, "%w", &fh
);
794 DebugPrintF(("CL_IsTTY: fh %d ", fh
));
795 DevSW_FreePacket(packet
);
797 fhreal
= hsysGetRealFileHandle(stateptr
, fh
, NULL
);
801 ttyOrNot
= isatty_(fhreal
);
802 stateptr
->last_errno
= errno
;
804 DebugPrintF(("returning %s\n", ttyOrNot
? "tty (1)" : "not (0)"));
806 return msgsend(CI_CLIB
, "%w%w%w%w%w",CL_IsTTY
|HtoT
,
807 DebugID
, OSInfo1
, OSInfo2
, ttyOrNot
);
813 unsigned int tnamelen
, TargetID
;
814 unpack_message(buffp
, "%w%w", &tnamelen
, &TargetID
);
815 DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ",
816 tnamelen
, TargetID
));
817 DevSW_FreePacket(packet
);
819 TargetID
= TargetID
& 0xFF;
820 if (stateptr
->OSptr
->TempNames
[TargetID
] == NULL
) {
821 if ((stateptr
->OSptr
->TempNames
[TargetID
] =
822 (char *)malloc(L_tmpnam
)) == NULL
)
824 fprintf(stderr
, "OUT OF MEMORY at line %d in %s\n",
828 tmpnam(stateptr
->OSptr
->TempNames
[TargetID
]);
830 name
= stateptr
->OSptr
->TempNames
[TargetID
];
831 len
= strlen(name
) + 1;
832 packet
= DevSW_AllocatePacket(Armsd_BufferSize
);
835 fprintf(stderr
, "COULD NOT ALLOC PACKET at line %d in %s\n",
839 buffhead
= packet
->pk_buffer
;
840 if (len
> tnamelen
) {
841 DebugPrintF(("TMPNAME TOO LONG!\n"));
842 count
= msgbuild(BUFFERDATA(buffhead
), "%w%w%w%w%w",
843 CL_TmpNam
|HtoT
, DebugID
, OSInfo1
, OSInfo2
, -1);
846 DebugPrintF(("returning \"%s\"\n", name
));
847 count
= msgbuild(BUFFERDATA(buffhead
), "%w%w%w%w%w%w", CL_TmpNam
|HtoT
,
848 DebugID
, OSInfo1
, OSInfo2
, 0, len
);
849 strcpy((char *)BUFFERDATA(buffhead
)+count
, name
);
852 packet
->pk_length
= count
;
853 Adp_ChannelWrite(CI_CLIB
, packet
);/* Send message. */
857 case CL_Unrecognised
:
858 DebugPrintF(("CL_Unrecognised!!\n"));
862 fprintf(stderr
, "UNRECOGNISED CL code %08x\n", reason_code
);
864 /* Need some sort of error handling here. */
865 /* A call to CL_Unrecognised should suffice */
867 return -1; /* Stop a potential compiler warning */
870 #ifdef COMPILING_ON_WINDOWS
874 extern HWND hwndParent
;
876 void panic(const char *format
, ...)
883 va_start(args
, format
);
884 vsprintf(buf
, format
, args
);
886 MessageBox(hwndParent
, (LPCTSTR
)buf
, (LPCTSTR
)"Fatal Error:", MB_OK
);
888 /* SJ - Not the proper way to shutdown the app */
892 if (hwndParent != NULL)
893 SendMessage(hwndParent, WM_QUIT, 0, 0);
901 void panic(const char *format
, ...)
905 va_start(args
, format
);
906 fprintf(stderr
, "Fatal error: ");
907 vfprintf(stderr
, format
, args
);
908 fprintf(stderr
,"\n");