OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [rdi-share/] [hsys.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3
 *
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
6
 * software.
7
 */
8
 
9
/*
10
 * Host C Library support functions.
11
 *
12
 * $Revision: 1.1.1.1 $
13
 *     $Date: 2002-01-16 10:24:33 $
14
 */
15
 
16
#ifdef DEBUG
17
#  include <ctype.h>
18
#endif
19
 
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <string.h>
23
#include <stdarg.h>
24
#include <errno.h>
25
#include <time.h>
26
 
27
#include "adp.h"
28
#include "host.h"
29
#include "ardi.h"
30
#include "buffers.h"
31
#include "channels.h"        /* Channel interface. */
32
#include "angel_endian.h"
33
#include "logging.h"         /* Angel support functions. */
34
#include "msgbuild.h"
35
#include "sys.h"    
36
#include "hsys.h"      /* Function and structure declarations. */
37
#include "hostchan.h"
38
 
39
#define FILEHANDLE int
40
 
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.   */
50
 
51
 
52
/* taken staight from armulator source */
53
#ifdef __riscos
54
  extern int _fisatty(FILE *);
55
# define isatty_(f) _fisatty(f)
56
# define EMFILE -1
57
# define EBADF -1
58
  int _kernel_escape_seen(void) { return 0 ;}
59
#else
60
# if defined(_WINDOWS) || defined(_CONSOLE)
61
#   define isatty_(f) (f == stdin || f == stdout)
62
# else
63
#   ifdef __ZTC__
64
#     include <io.h>
65
#     define isatty_(f) isatty((f)->_file)
66
#   else
67
#     ifdef macintosh
68
#       include <ioctl.h>
69
#       define isatty_(f) (~ioctl((f)->_file,FIOINTERACTIVE,NULL))
70
#     else
71
#       define isatty_(f) isatty(fileno(f))
72
#     endif
73
#   endif
74
# endif
75
#endif
76
 
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)
80
{
81
  ChannelCallback HandleMessageFPtr = (ChannelCallback) HandleSysMessage;
82
  int i;
83
  *stateptr = (hsys_state *)malloc(sizeof(hsys_state));
84
 
85
  if (*stateptr == NULL) return RDIError_OutOfStore;
86
 
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;
95
  }
96
  (*stateptr)->CommandLine=cmdline;
97
 
98
  return Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleMessageFPtr,
99
                                 *stateptr);
100
}
101
 
102
/* Shut down the Clib support, this will probably never get called though */
103
int HostSysExit(hsys_state *stateptr)
104
{
105
  free(stateptr->OSptr);
106
  free(stateptr);
107
  return RDIError_NoError;
108
}
109
 
110
#ifdef DEBUG
111
static void DebugCheckNullTermString(char *prefix, bool nl,
112
                                     unsigned int len, unsigned char *strp)
113
{
114
    printf("%s: %d: ", prefix, len);
115
    if (strp[len]=='\0')
116
       printf("\"%s\"", strp);
117
    else
118
       printf("NOT NULL TERMINATED");
119
    if (nl)
120
       printf("\n");
121
    else
122
    {
123
        printf(" ");
124
        fflush(stdout);
125
    }
126
}
127
 
128
#ifdef NEED_SYSERRLIST
129
extern int sys_nerr;
130
extern char *sys_errlist[];
131
#endif
132
 
133
static char *DebugStrError(int last_errno)
134
{
135
    if (last_errno < sys_nerr)
136
       return sys_errlist[last_errno];
137
    else
138
       return "NO MSG (errno>sys_nerr)";
139
}
140
 
141
static void DebugCheckErr(char *prefix, bool nl, int err, int last_errno)
142
{
143
    printf("\t%s: returned ", prefix);
144
    if (err == 0)
145
       printf("okay");
146
    else
147
       printf("%d, errno = %d \"%s\"", err, last_errno,
148
              DebugStrError(last_errno));
149
    if (nl)
150
       printf("\n");
151
    else
152
    {
153
        printf(" ");
154
        fflush(stdout);
155
    }
156
}
157
 
158
static void DebugCheckNonNull(char *prefix, bool nl,
159
                              void *handle, int last_errno)
160
{
161
    printf("\t%s: returned ", prefix);
162
    if (handle != NULL)
163
       printf("okay [%08x]", (unsigned int)handle);
164
    else
165
       printf("NULL, errno = %d \"%s\"", last_errno,
166
              DebugStrError(last_errno));
167
    if (nl)
168
       printf("\n");
169
    else
170
    {
171
        printf(" ");
172
        fflush(stdout);
173
    }
174
}
175
 
176
#define DebugPrintF(c) printf c;
177
 
178
#else
179
 
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))
184
 
185
#endif /* ifdef DEBUG ... else */
186
 
187
static FILE *hsysGetRealFileHandle(hsys_state *stateptr, int fh, char *flags)
188
{
189
    FILE *file_p = NULL;
190
 
191
    if (fh < 0 || fh >= HSYS_FOPEN_MAX)
192
    {
193
        stateptr->last_errno = EBADF;
194
        DebugPrintF(("\tfh %d out-of-bounds!\n", fh));
195
        return NULL;
196
    }
197
    else
198
    {
199
        file_p = stateptr->OSptr->FileTable[fh];
200
        if (file_p != NULL) {
201
            if (flags != NULL)
202
               *flags = stateptr->OSptr->FileFlags[fh];
203
        }
204
        else {
205
          stateptr->last_errno = EBADF;
206
          DebugPrintF(("\tFileTable[%d] is NULL\n", fh));
207
        }
208
 
209
        return file_p;
210
    }
211
}
212
 
213
int HandleSysMessage(Packet *packet, hsys_state *stateptr)
214
{
215
  unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0;
216
  long posn, fl;
217
  char character;
218
  int err;
219
 
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 */
223
 
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);
230
 
231
  int DebugID, OSInfo1, OSInfo2, count;
232
 
233
  const char* fmode[] = {"r","rb","r+","r+b",
234
                               "w","wb","w+","w+b",
235
                               "a","ab","a+","a+b",
236
                               "r","r","r","r"} /* last 4 are illegal */ ;
237
 
238
  FILEHANDLE fh;  /* fh is used as an index to the real file handle
239
                         * in OSptr */
240
  FILE *fhreal;
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.        */
247
 
248
  switch(reason_code)
249
  {
250
 
251
  case CL_WriteC:   /* Write a character to the terminal. */
252
                    /* byte data -> word status           */
253
    {
254
#ifdef DEBUG
255
      int c = (int)(*buffp);
256
      printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.');
257
#endif
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);
262
    }
263
 
264
  case CL_Write0:  /* Write a null terminated string to the terminal. */
265
    {
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);
273
    }
274
 
275
  case CL_ReadC:   /* Read a byte from the terminal */
276
    {
277
      DebugPrintF(("CL_ReadC: "));
278
      DevSW_FreePacket(packet);
279
 
280
      character = stateptr->hostif->readc(stateptr->hostif->hostosarg);
281
      DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character,
282
                   isprint(character) ? character : '.'));
283
 
284
      return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT,
285
                    DebugID, OSInfo1, OSInfo2, NoError, character);
286
    }
287
 
288
  case CL_System:  /* Pass NULL terminated string to the hosts command
289
                    * interpreter. As it is nULL terminated we dont need
290
                    * the length
291
                    */
292
    {
293
      unpack_message(buffp, "%w", &len);
294
      DebugCheckNullTermString("CL_System", TRUE, len, buffp+4);
295
 
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);
299
 
300
      err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT,
301
                    DebugID, OSInfo1, OSInfo2, NoError, err);
302
      DevSW_FreePacket(packet);
303
      return err;
304
    }
305
 
306
  case CL_GetCmdLine:  /* Returns the command line used to call the program */
307
    {
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)));
311
 
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,
318
                                           NoError, len);
319
        strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine),
320
                len);
321
 
322
        Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
323
        return 0;
324
      }
325
      else return -1;
326
    }
327
 
328
  case CL_Clock:   /* Return the number of centiseconds since the support */
329
                   /* code started executing */
330
    {
331
      time_t retTime = time(NULL);
332
      if (retTime == (time_t)-1)
333
             stateptr->last_errno = errno;
334
      else
335
             retTime *=100;
336
 
337
      DebugPrintF(("CL_Clock: %lu\n", retTime));
338
      DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
339
                    stateptr->last_errno);
340
 
341
      DevSW_FreePacket(packet);
342
      return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT,
343
                         DebugID, OSInfo1, OSInfo2, NoError, retTime);
344
    }
345
 
346
  case CL_Time:    /* return time, in seconds since the start of 1970 */
347
    {
348
      time_t retTime = time(NULL);
349
      if (retTime == (time_t)-1)
350
              stateptr->last_errno = errno;
351
 
352
      DebugPrintF(("CL_Time: %lu\n", retTime));
353
      DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
354
                    stateptr->last_errno);
355
 
356
      DevSW_FreePacket(packet);
357
      return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT,
358
                         DebugID, OSInfo1, OSInfo2, NoError, retTime);
359
    }
360
 
361
  case CL_Remove:  /* delete named in the null terminated string */
362
    {
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.*/
367
 
368
      unpack_message(buffp, "%w", &len);
369
      DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4);
370
 
371
      err=remove((char *)buffp+4);
372
      stateptr->last_errno = errno;
373
      DevSW_FreePacket(packet);
374
      DebugCheckErr("remove", TRUE, err, stateptr->last_errno);
375
 
376
      return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT,
377
                     DebugID, OSInfo1, OSInfo2, err?-1:NoError);
378
    }
379
 
380
  case CL_Rename:  /* rename file */
381
    {
382
      /* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
383
      * return(byte status)
384
      */
385
      unsigned int len2;
386
 
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);
391
 
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);
398
 
399
      return msgsend(CI_CLIB, "%w%w%w%w%w",  CL_Rename|HtoT,
400
                     DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1);
401
    }
402
 
403
  case CL_Open:    /* open the file */
404
    {
405
      /* Open(word nbytes, bytes name, byte mode)
406
      * return(word handle)
407
      */
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));
413
 
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" */
418
        fhreal = stdin;
419
        stateptr->last_errno = errno;
420
        DebugPrintF(("\tstdin "));
421
      }
422
      else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) {
423
        /* opening tty "w" */
424
        fhreal = stdout;
425
        stateptr->last_errno = errno;
426
        DebugPrintF(("\tstdout "));
427
      }
428
      else
429
      {
430
        fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]);
431
        stateptr->last_errno = errno;
432
        DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno);
433
      }
434
      DevSW_FreePacket(packet);
435
 
436
      c = NONHANDLE;
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));
445
            break;
446
          }
447
          else if (c == HSYS_FOPEN_MAX) {
448
          /* no filehandles free */
449
          DebugPrintF(("no free fh: %d\n", c));
450
          stateptr->last_errno = EMFILE;
451
          }
452
        }
453
      }
454
      else {
455
        /*        c = NULL;*/
456
        DebugPrintF(("error fh: %d\n", c));
457
      }
458
      (void) msgsend(CI_CLIB, "%w%w%w%w%w",  CL_Open|HtoT,
459
                     DebugID, OSInfo1, OSInfo2, c);
460
      return 0;
461
    }
462
 
463
  case CL_Close:   /* close the file pointed to by the filehandle */
464
    {
465
      unpack_message(buffp, "%w", &fh);
466
      DebugPrintF(("CL_Close: fh %d\n", fh));
467
      DevSW_FreePacket(packet);
468
 
469
      fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
470
      if (fhreal == NULL)
471
         err = -1;
472
      else {
473
          if (fhreal == stdin || fhreal == stdout || fhreal == stderr) {
474
              stateptr->last_errno = errno;
475
              DebugPrintF(("\tskipping close of std*\n"));
476
              err = 0;
477
          }
478
          else {
479
              err = fclose(fhreal);
480
              if (err == 0)
481
                 stateptr->OSptr->FileTable[fh]=NULL;
482
              stateptr->last_errno = errno;
483
              DebugCheckErr("fclose", TRUE, err, stateptr->last_errno);
484
          }
485
      }
486
      return msgsend(CI_CLIB,"%w%w%w%w%w",  CL_Close|HtoT, DebugID,
487
                     OSInfo1, OSInfo2, err);
488
    }
489
 
490
  case CL_Write:
491
    {
492
        /* Write(word handle, word nbtotal, word nbytes, bytes data)
493
         * return(word nbytes)
494
         * WriteX(word nbytes, bytes data)
495
         * return(word nbytes)
496
         */
497
      unsigned char *rwdata = NULL, *rwhead = NULL;
498
      unsigned char *write_source = NULL;
499
      char flags;
500
      FILE *fhreal;
501
      unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */
502
 
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));
507
 
508
      fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
509
      nbtogo = nbtotal;
510
 
511
      /* deal with the file handle */
512
      if (fhreal == NULL)
513
         err = 0;
514
      else {
515
        if (flags & READOP)
516
           fseek(fhreal,0,SEEK_CUR);
517
        stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
518
 
519
        nbtogo -= nbytes;
520
 
521
        if (nbtogo > 0) {
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",
525
                    __LINE__, __FILE__);
526
            return -1;
527
          }
528
          memcpy(rwdata, buffp+12, nbytes);
529
          rwdata += nbytes;
530
        }
531
        else
532
           write_source = buffp+12;
533
      }
534
 
535
      do {
536
        /* at least once!! */
537
 
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);
543
          }
544
          else
545
             err = fwrite(write_source, 1, nbtotal, fhreal);
546
          stateptr->last_errno = errno;
547
          DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno);
548
        }
549
 
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))
553
        {
554
            fprintf(stderr, "COULD NOT REPLY at line %d in %s\n",
555
                    __LINE__, __FILE__);
556
            if (rwhead != NULL)
557
               free(rwhead);
558
            return -1;
559
        }
560
 
561
        if (nbtogo == 0 || err == 0) {
562
          DebugPrintF(("\twrite complete - returning\n"));
563
          if (rwhead != NULL)
564
             free(rwhead);
565
          return 0;
566
        }
567
        else {
568
          /* await extension */
569
          ack_reason = CL_WriteX;
570
 
571
          packet = DevSW_AllocatePacket(Armsd_BufferSize);
572
          if (packet == NULL)
573
          {
574
            fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
575
                    __LINE__, __FILE__);
576
            if (rwhead != NULL)
577
               free(rwhead);
578
            return -1;
579
          }
580
          Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
581
          Adp_ChannelRead(CI_CLIB, &packet);
582
          Adp_ChannelRegisterRead(CI_CLIB,
583
                                  (ChannelCallback)HandleSysMessage,
584
                                  stateptr);
585
 
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);
591
            free(rwhead);
592
            fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n",
593
                    reason_code, __LINE__, __FILE__);
594
            return -1;
595
          }
596
 
597
          DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes));
598
          memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes);
599
          rwdata += nbytes;
600
          nbtogo -= nbytes;
601
        }
602
 
603
      } while (TRUE);           /* will return when done */
604
    }
605
 
606
  case CL_WriteX:     /*
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
611
                       */
612
    fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n");
613
    return -1;
614
 
615
  case CL_Read:
616
    {
617
                   /* Read(word handle, word nbtotal)
618
                    * return(word nbytes, word nbmore, bytes data)
619
                    */
620
                   /* ReadX()
621
                    * return(word nbytes, word nbmore, bytes data) */
622
      unsigned char *rwdata, *rwhead;
623
      int gotlen;
624
      unsigned int max_data_in_buffer=Armsd_BufferSize-28;
625
      char flags;
626
      FILE *fhreal;
627
      unsigned int nbleft = 0, reason = CL_Read;
628
 
629
      err = NoError;
630
 
631
      unpack_message(buffp, "%w%w", &fh, &nbtotal);
632
      DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal));
633
 
634
      rwdata = rwhead = (unsigned char *)malloc(nbtotal);
635
      if (rwdata == NULL) {
636
        fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
637
                __LINE__, __FILE__);
638
        DevSW_FreePacket(packet);
639
        return -1;
640
      }
641
 
642
      /* perform the actual read */
643
      fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
644
      if (fhreal == NULL)
645
      {
646
        /* bad file handle */
647
        err = -1;
648
        nbytes = 0;
649
        gotlen = 0;
650
      }
651
      else
652
      {
653
        if (flags & WRITEOP)
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,
659
                                 nbtotal) != 0)
660
             gotlen = strlen((char *)rwdata);
661
          else
662
             gotlen = 0;
663
          stateptr->last_errno = errno;
664
          DebugPrintF(("ttyread %d\n", gotlen));
665
        }
666
        else {
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));
672
        }
673
      }
674
 
675
      nbtogo = gotlen;
676
 
677
      do {
678
        /* at least once */
679
 
680
        if ((unsigned int) nbtogo <= max_data_in_buffer)
681
           nbytes = nbtogo;
682
        else
683
           nbytes = max_data_in_buffer;
684
        nbtogo -= nbytes;
685
 
686
        /* last ReadX needs subtle adjustment to returned nbtogo */
687
        if (nbtogo == 0 && err == NoError && reason == CL_ReadX)
688
           nbleft = nbtotal - gotlen;
689
        else
690
           nbleft = nbtogo;
691
 
692
        count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w",
693
                         reason|HtoT, 0, ADP_HandleUnknown,
694
                         ADP_HandleUnknown, err, nbytes, nbleft);
695
 
696
        if (err == NoError) {
697
          /* copy data into buffptr */
698
          memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes);
699
          rwdata += nbytes;
700
          count += nbytes;
701
        }
702
 
703
        DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n",
704
                     err, nbytes, nbtogo));
705
 
706
        packet->pk_length = count;
707
        Adp_ChannelWrite(CI_CLIB, packet);
708
 
709
        if (nbtogo == 0 || err != NoError) {
710
          /* done */
711
          free(rwhead);
712
          return 0;
713
        }
714
        else {
715
          /* await extension */
716
          reason = CL_ReadX;
717
 
718
          packet = DevSW_AllocatePacket(Armsd_BufferSize);
719
          if (packet == NULL) {
720
            fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
721
                    __LINE__, __FILE__);
722
            free(rwhead);
723
            return -1;
724
          }
725
          Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
726
          Adp_ChannelRead(CI_CLIB, &packet);
727
          Adp_ChannelRegisterRead(CI_CLIB,
728
                                  (ChannelCallback)HandleSysMessage,
729
                                  stateptr);
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);
736
            free(rwdata);
737
            return -1;
738
          }
739
        }
740
 
741
      } while (TRUE);           /* will return above on error or when done */
742
    }
743
 
744
  case CL_ReadX:      /* If we're here something has probably gone wrong */
745
    fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n");
746
    return -1;
747
 
748
  case CL_Seek:
749
    {
750
      unpack_message(buffp, "%w%w", &fh, &posn);
751
      DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn));
752
      DevSW_FreePacket(packet);
753
 
754
      fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
755
      if (fhreal == NULL)
756
         err = -1;
757
      else {
758
        err = fseek(fhreal, posn, SEEK_SET);
759
        stateptr->last_errno = errno;
760
        DebugCheckErr("fseek", TRUE, err, stateptr->last_errno);
761
      }
762
 
763
      return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT,
764
                         DebugID, OSInfo1, OSInfo2, err);
765
    }
766
 
767
  case CL_Flen:
768
    {
769
      unpack_message(buffp, "%w", &fh);
770
      DebugPrintF(("CL_Flen: fh %d ", fh));
771
      DevSW_FreePacket(packet);
772
 
773
      fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
774
      if (fhreal == NULL)
775
        fl = -1;
776
      else {
777
        posn = ftell(fhreal);
778
        if (fseek(fhreal, 0L, SEEK_END) < 0) {
779
          fl=-1;
780
        }
781
        else {
782
          fl = ftell(fhreal);
783
          fseek(fhreal, posn, SEEK_SET);
784
        }
785
        stateptr->last_errno = errno;
786
      }
787
      DebugPrintF(("returning len %ld\n", fl));
788
      return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1,
789
                     OSInfo2, fl);
790
    }
791
 
792
  case CL_IsTTY:
793
    {
794
      int  ttyOrNot;
795
      unpack_message(buffp, "%w", &fh);
796
      DebugPrintF(("CL_IsTTY: fh %d ", fh));
797
      DevSW_FreePacket(packet);
798
 
799
      fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
800
      if (fhreal == NULL)
801
         ttyOrNot = FALSE;
802
      else {
803
        ttyOrNot = isatty_(fhreal);
804
        stateptr->last_errno = errno;
805
      }
806
      DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)"));
807
 
808
      return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT,
809
                         DebugID, OSInfo1, OSInfo2, ttyOrNot);
810
    }
811
 
812
  case CL_TmpNam:
813
    {
814
      char *name;
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);
820
 
821
      TargetID = TargetID & 0xFF;
822
      if (stateptr->OSptr->TempNames[TargetID] == NULL) {
823
        if ((stateptr->OSptr->TempNames[TargetID] =
824
             (char *)malloc(L_tmpnam)) == NULL)
825
        {
826
          fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
827
                  __LINE__, __FILE__);
828
          return -1;
829
        }
830
        tmpnam(stateptr->OSptr->TempNames[TargetID]);
831
      }
832
      name = stateptr->OSptr->TempNames[TargetID];
833
      len = strlen(name) + 1;
834
      packet = DevSW_AllocatePacket(Armsd_BufferSize);
835
      if (packet == NULL)
836
      {
837
          fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
838
                  __LINE__, __FILE__);
839
          return -1;
840
      }
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);
846
      }
847
      else {
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);
852
        count +=len+1;
853
      }
854
      packet->pk_length = count;
855
      Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
856
      return 0;
857
    }
858
 
859
  case CL_Unrecognised:
860
    DebugPrintF(("CL_Unrecognised!!\n"));
861
    return 0;
862
 
863
  default:
864
    fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code);
865
    break;
866
/* Need some sort of error handling here. */
867
/* A call to CL_Unrecognised should suffice */
868
  }
869
  return -1;  /* Stop a potential compiler warning */
870
}
871
 
872
#ifdef COMPILING_ON_WINDOWS
873
 
874
#include <windows.h>
875
 
876
extern HWND hwndParent;
877
 
878
void panic(const char *format, ...)
879
{
880
    char buf[2048];
881
    va_list args;
882
 
883
    Adp_CloseDevice();
884
 
885
    va_start(args, format);
886
    vsprintf(buf, format, args);
887
 
888
    MessageBox(hwndParent, (LPCTSTR)buf, (LPCTSTR)"Fatal Error:", MB_OK);
889
 
890
    /* SJ - Not the proper way to shutdown the app */
891
    exit(EXIT_FAILURE);
892
 
893
/*
894
    if (hwndParent != NULL)
895
        SendMessage(hwndParent, WM_QUIT, 0, 0);
896
*/
897
 
898
    va_end(args);
899
}
900
 
901
#else
902
 
903
void panic(const char *format, ...)
904
{
905
    va_list args;
906
 
907
    va_start(args, format);
908
    fprintf(stderr, "Fatal error: ");
909
    vfprintf(stderr, format, args);
910
    fprintf(stderr,"\n");
911
 
912
    exit(EXIT_FAILURE);
913
}
914
 
915
#endif
916
 
917
/* EOF hsys.c */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.