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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [remote-fileio.c] - Blame information for rev 318

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Remote File-I/O communications
2
 
3
   Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
/* See the GDB User Guide for details of the GDB remote protocol. */
22
 
23
#include "defs.h"
24
#include "gdb_string.h"
25
#include "gdbcmd.h"
26
#include "remote.h"
27
#include "gdb/fileio.h"
28
#include "gdb_wait.h"
29
#include "gdb_stat.h"
30
#include "exceptions.h"
31
#include "remote-fileio.h"
32
#include "event-loop.h"
33
 
34
#include <fcntl.h>
35
#include <sys/time.h>
36
#ifdef __CYGWIN__
37
#include <sys/cygwin.h>         /* For cygwin_conv_to_full_posix_path.  */
38
#endif
39
#include <signal.h>
40
 
41
static struct {
42
  int *fd_map;
43
  int fd_map_size;
44
} remote_fio_data;
45
 
46
#define FIO_FD_INVALID          -1
47
#define FIO_FD_CONSOLE_IN       -2
48
#define FIO_FD_CONSOLE_OUT      -3
49
 
50
static int remote_fio_system_call_allowed = 0;
51
 
52
static struct async_signal_handler *sigint_fileio_token;
53
 
54
static int
55
remote_fileio_init_fd_map (void)
56
{
57
  int i;
58
 
59
  if (!remote_fio_data.fd_map)
60
    {
61
      remote_fio_data.fd_map = (int *) xmalloc (10 * sizeof (int));
62
      remote_fio_data.fd_map_size = 10;
63
      remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
64
      remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
65
      remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
66
      for (i = 3; i < 10; ++i)
67
        remote_fio_data.fd_map[i] = FIO_FD_INVALID;
68
    }
69
  return 3;
70
}
71
 
72
static int
73
remote_fileio_resize_fd_map (void)
74
{
75
  int i = remote_fio_data.fd_map_size;
76
 
77
  if (!remote_fio_data.fd_map)
78
    return remote_fileio_init_fd_map ();
79
  remote_fio_data.fd_map_size += 10;
80
  remote_fio_data.fd_map =
81
    (int *) xrealloc (remote_fio_data.fd_map,
82
                      remote_fio_data.fd_map_size * sizeof (int));
83
  for (; i < remote_fio_data.fd_map_size; i++)
84
    remote_fio_data.fd_map[i] = FIO_FD_INVALID;
85
  return remote_fio_data.fd_map_size - 10;
86
}
87
 
88
static int
89
remote_fileio_next_free_fd (void)
90
{
91
  int i;
92
 
93
  for (i = 0; i < remote_fio_data.fd_map_size; ++i)
94
    if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
95
      return i;
96
  return remote_fileio_resize_fd_map ();
97
}
98
 
99
static int
100
remote_fileio_fd_to_targetfd (int fd)
101
{
102
  int target_fd = remote_fileio_next_free_fd ();
103
  remote_fio_data.fd_map[target_fd] = fd;
104
  return target_fd;
105
}
106
 
107
static int
108
remote_fileio_map_fd (int target_fd)
109
{
110
  remote_fileio_init_fd_map ();
111
  if (target_fd < 0 || target_fd >= remote_fio_data.fd_map_size)
112
    return FIO_FD_INVALID;
113
  return remote_fio_data.fd_map[target_fd];
114
}
115
 
116
static void
117
remote_fileio_close_target_fd (int target_fd)
118
{
119
  remote_fileio_init_fd_map ();
120
  if (target_fd >= 0 && target_fd < remote_fio_data.fd_map_size)
121
    remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID;
122
}
123
 
124
static int
125
remote_fileio_oflags_to_host (long flags)
126
{
127
  int hflags = 0;
128
 
129
  if (flags & FILEIO_O_CREAT)
130
    hflags |= O_CREAT;
131
  if (flags & FILEIO_O_EXCL)
132
    hflags |= O_EXCL;
133
  if (flags & FILEIO_O_TRUNC)
134
    hflags |= O_TRUNC;
135
  if (flags & FILEIO_O_APPEND)
136
    hflags |= O_APPEND;
137
  if (flags & FILEIO_O_RDONLY)
138
    hflags |= O_RDONLY;
139
  if (flags & FILEIO_O_WRONLY)
140
    hflags |= O_WRONLY;
141
  if (flags & FILEIO_O_RDWR)
142
    hflags |= O_RDWR;
143
/* On systems supporting binary and text mode, always open files in
144
   binary mode. */
145
#ifdef O_BINARY
146
  hflags |= O_BINARY;
147
#endif
148
  return hflags;
149
}
150
 
151
static mode_t
152
remote_fileio_mode_to_host (long mode, int open_call)
153
{
154
  mode_t hmode = 0;
155
 
156
  if (!open_call)
157
    {
158
      if (mode & FILEIO_S_IFREG)
159
        hmode |= S_IFREG;
160
      if (mode & FILEIO_S_IFDIR)
161
        hmode |= S_IFDIR;
162
      if (mode & FILEIO_S_IFCHR)
163
        hmode |= S_IFCHR;
164
    }
165
  if (mode & FILEIO_S_IRUSR)
166
    hmode |= S_IRUSR;
167
  if (mode & FILEIO_S_IWUSR)
168
    hmode |= S_IWUSR;
169
  if (mode & FILEIO_S_IXUSR)
170
    hmode |= S_IXUSR;
171
#ifdef S_IRGRP
172
  if (mode & FILEIO_S_IRGRP)
173
    hmode |= S_IRGRP;
174
#endif
175
#ifdef S_IWGRP
176
  if (mode & FILEIO_S_IWGRP)
177
    hmode |= S_IWGRP;
178
#endif
179
#ifdef S_IXGRP
180
  if (mode & FILEIO_S_IXGRP)
181
    hmode |= S_IXGRP;
182
#endif
183
  if (mode & FILEIO_S_IROTH)
184
    hmode |= S_IROTH;
185
#ifdef S_IWOTH
186
  if (mode & FILEIO_S_IWOTH)
187
    hmode |= S_IWOTH;
188
#endif
189
#ifdef S_IXOTH
190
  if (mode & FILEIO_S_IXOTH)
191
    hmode |= S_IXOTH;
192
#endif
193
  return hmode;
194
}
195
 
196
static LONGEST
197
remote_fileio_mode_to_target (mode_t mode)
198
{
199
  mode_t tmode = 0;
200
 
201
  if (S_ISREG(mode))
202
    tmode |= FILEIO_S_IFREG;
203
  if (S_ISDIR(mode))
204
    tmode |= FILEIO_S_IFDIR;
205
  if (S_ISCHR(mode))
206
    tmode |= FILEIO_S_IFCHR;
207
  if (mode & S_IRUSR)
208
    tmode |= FILEIO_S_IRUSR;
209
  if (mode & S_IWUSR)
210
    tmode |= FILEIO_S_IWUSR;
211
  if (mode & S_IXUSR)
212
    tmode |= FILEIO_S_IXUSR;
213
#ifdef S_IRGRP
214
  if (mode & S_IRGRP)
215
    tmode |= FILEIO_S_IRGRP;
216
#endif
217
#ifdef S_IWRGRP
218
  if (mode & S_IWGRP)
219
    tmode |= FILEIO_S_IWGRP;
220
#endif
221
#ifdef S_IXGRP
222
  if (mode & S_IXGRP)
223
    tmode |= FILEIO_S_IXGRP;
224
#endif
225
  if (mode & S_IROTH)
226
    tmode |= FILEIO_S_IROTH;
227
#ifdef S_IWOTH
228
  if (mode & S_IWOTH)
229
    tmode |= FILEIO_S_IWOTH;
230
#endif
231
#ifdef S_IXOTH
232
  if (mode & S_IXOTH)
233
    tmode |= FILEIO_S_IXOTH;
234
#endif
235
  return tmode;
236
}
237
 
238
static int
239
remote_fileio_errno_to_target (int error)
240
{
241
  switch (error)
242
    {
243
      case EPERM:
244
        return FILEIO_EPERM;
245
      case ENOENT:
246
        return FILEIO_ENOENT;
247
      case EINTR:
248
        return FILEIO_EINTR;
249
      case EIO:
250
        return FILEIO_EIO;
251
      case EBADF:
252
        return FILEIO_EBADF;
253
      case EACCES:
254
        return FILEIO_EACCES;
255
      case EFAULT:
256
        return FILEIO_EFAULT;
257
      case EBUSY:
258
        return FILEIO_EBUSY;
259
      case EEXIST:
260
        return FILEIO_EEXIST;
261
      case ENODEV:
262
        return FILEIO_ENODEV;
263
      case ENOTDIR:
264
        return FILEIO_ENOTDIR;
265
      case EISDIR:
266
        return FILEIO_EISDIR;
267
      case EINVAL:
268
        return FILEIO_EINVAL;
269
      case ENFILE:
270
        return FILEIO_ENFILE;
271
      case EMFILE:
272
        return FILEIO_EMFILE;
273
      case EFBIG:
274
        return FILEIO_EFBIG;
275
      case ENOSPC:
276
        return FILEIO_ENOSPC;
277
      case ESPIPE:
278
        return FILEIO_ESPIPE;
279
      case EROFS:
280
        return FILEIO_EROFS;
281
      case ENOSYS:
282
        return FILEIO_ENOSYS;
283
      case ENAMETOOLONG:
284
        return FILEIO_ENAMETOOLONG;
285
    }
286
  return FILEIO_EUNKNOWN;
287
}
288
 
289
static int
290
remote_fileio_seek_flag_to_host (long num, int *flag)
291
{
292
  if (!flag)
293
    return 0;
294
  switch (num)
295
    {
296
      case FILEIO_SEEK_SET:
297
        *flag = SEEK_SET;
298
        break;
299
      case FILEIO_SEEK_CUR:
300
        *flag =  SEEK_CUR;
301
        break;
302
      case FILEIO_SEEK_END:
303
        *flag =  SEEK_END;
304
        break;
305
      default:
306
        return -1;
307
    }
308
  return 0;
309
}
310
 
311
static int
312
remote_fileio_extract_long (char **buf, LONGEST *retlong)
313
{
314
  char *c;
315
  int sign = 1;
316
 
317
  if (!buf || !*buf || !**buf || !retlong)
318
    return -1;
319
  c = strchr (*buf, ',');
320
  if (c)
321
    *c++ = '\0';
322
  else
323
    c = strchr (*buf, '\0');
324
  while (strchr ("+-", **buf))
325
    {
326
      if (**buf == '-')
327
        sign = -sign;
328
      ++*buf;
329
    }
330
  for (*retlong = 0; **buf; ++*buf)
331
    {
332
      *retlong <<= 4;
333
      if (**buf >= '0' && **buf <= '9')
334
        *retlong += **buf - '0';
335
      else if (**buf >= 'a' && **buf <= 'f')
336
        *retlong += **buf - 'a' + 10;
337
      else if (**buf >= 'A' && **buf <= 'F')
338
        *retlong += **buf - 'A' + 10;
339
      else
340
        return -1;
341
    }
342
  *retlong *= sign;
343
  *buf = c;
344
  return 0;
345
}
346
 
347
static int
348
remote_fileio_extract_int (char **buf, long *retint)
349
{
350
  int ret;
351
  LONGEST retlong;
352
 
353
  if (!retint)
354
    return -1;
355
  ret = remote_fileio_extract_long (buf, &retlong);
356
  if (!ret)
357
    *retint = (long) retlong;
358
  return ret;
359
}
360
 
361
static int
362
remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
363
{
364
  char *c;
365
  LONGEST retlong;
366
 
367
  if (!buf || !*buf || !**buf || !ptrval || !length)
368
    return -1;
369
  c = strchr (*buf, '/');
370
  if (!c)
371
    return -1;
372
  *c++ = '\0';
373
  if (remote_fileio_extract_long (buf, &retlong))
374
    return -1;
375
  *ptrval = (CORE_ADDR) retlong;
376
  *buf = c;
377
  if (remote_fileio_extract_long (buf, &retlong))
378
    return -1;
379
  *length = (int) retlong;
380
  return 0;
381
}
382
 
383
/* Convert to big endian */
384
static void
385
remote_fileio_to_be (LONGEST num, char *buf, int bytes)
386
{
387
  int i;
388
 
389
  for (i = 0; i < bytes; ++i)
390
    buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff;
391
}
392
 
393
static void
394
remote_fileio_to_fio_uint (long num, fio_uint_t fnum)
395
{
396
  remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
397
}
398
 
399
static void
400
remote_fileio_to_fio_mode (mode_t num, fio_mode_t fnum)
401
{
402
  remote_fileio_to_be (remote_fileio_mode_to_target(num), (char *) fnum, 4);
403
}
404
 
405
static void
406
remote_fileio_to_fio_time (time_t num, fio_time_t fnum)
407
{
408
  remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
409
}
410
 
411
static void
412
remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
413
{
414
  remote_fileio_to_be (num, (char *) fnum, 8);
415
}
416
 
417
static void
418
remote_fileio_to_fio_ulong (LONGEST num, fio_ulong_t fnum)
419
{
420
  remote_fileio_to_be (num, (char *) fnum, 8);
421
}
422
 
423
static void
424
remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst)
425
{
426
  LONGEST blksize;
427
 
428
  /* `st_dev' is set in the calling function */
429
  remote_fileio_to_fio_uint ((long) st->st_ino, fst->fst_ino);
430
  remote_fileio_to_fio_mode (st->st_mode, fst->fst_mode);
431
  remote_fileio_to_fio_uint ((long) st->st_nlink, fst->fst_nlink);
432
  remote_fileio_to_fio_uint ((long) st->st_uid, fst->fst_uid);
433
  remote_fileio_to_fio_uint ((long) st->st_gid, fst->fst_gid);
434
  remote_fileio_to_fio_uint ((long) st->st_rdev, fst->fst_rdev);
435
  remote_fileio_to_fio_ulong ((LONGEST) st->st_size, fst->fst_size);
436
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
437
  blksize = st->st_blksize;
438
#else
439
  blksize = 512;
440
#endif
441
  remote_fileio_to_fio_ulong (blksize, fst->fst_blksize);
442
#if HAVE_STRUCT_STAT_ST_BLOCKS
443
  remote_fileio_to_fio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
444
#else
445
  /* FIXME: This is correct for DJGPP, but other systems that don't
446
     have st_blocks, if any, might prefer 512 instead of st_blksize.
447
     (eliz, 30-12-2003)  */
448
  remote_fileio_to_fio_ulong (((LONGEST) st->st_size + blksize - 1)
449
                              / blksize,
450
                              fst->fst_blocks);
451
#endif
452
  remote_fileio_to_fio_time (st->st_atime, fst->fst_atime);
453
  remote_fileio_to_fio_time (st->st_mtime, fst->fst_mtime);
454
  remote_fileio_to_fio_time (st->st_ctime, fst->fst_ctime);
455
}
456
 
457
static void
458
remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
459
{
460
  remote_fileio_to_fio_time (tv->tv_sec, ftv->ftv_sec);
461
  remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
462
}
463
 
464
static int remote_fio_ctrl_c_flag = 0;
465
static int remote_fio_no_longjmp = 0;
466
 
467
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
468
static struct sigaction remote_fio_sa;
469
static struct sigaction remote_fio_osa;
470
#else
471
static void (*remote_fio_ofunc)(int);
472
#endif
473
 
474
static void
475
remote_fileio_sig_init (void)
476
{
477
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
478
  remote_fio_sa.sa_handler = SIG_IGN;
479
  sigemptyset (&remote_fio_sa.sa_mask);
480
  remote_fio_sa.sa_flags = 0;
481
  sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa);
482
#else
483
  remote_fio_ofunc = signal (SIGINT, SIG_IGN);
484
#endif
485
}
486
 
487
static void
488
remote_fileio_sig_set (void (*sigint_func)(int))
489
{
490
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
491
  remote_fio_sa.sa_handler = sigint_func;
492
  sigemptyset (&remote_fio_sa.sa_mask);
493
  remote_fio_sa.sa_flags = 0;
494
  sigaction (SIGINT, &remote_fio_sa, NULL);
495
#else
496
  signal (SIGINT, sigint_func);
497
#endif
498
}
499
 
500
static void
501
remote_fileio_sig_exit (void)
502
{
503
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
504
  sigaction (SIGINT, &remote_fio_osa, NULL);
505
#else
506
  signal (SIGINT, remote_fio_ofunc);
507
#endif
508
}
509
 
510
static void
511
async_remote_fileio_interrupt (gdb_client_data arg)
512
{
513
  deprecated_throw_reason (RETURN_QUIT);
514
}
515
 
516
static void
517
remote_fileio_ctrl_c_signal_handler (int signo)
518
{
519
  remote_fileio_sig_set (SIG_IGN);
520
  remote_fio_ctrl_c_flag = 1;
521
  if (!remote_fio_no_longjmp)
522
    gdb_call_async_signal_handler (sigint_fileio_token, 1);
523
  remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
524
}
525
 
526
static void
527
remote_fileio_reply (int retcode, int error)
528
{
529
  char buf[32];
530
 
531
  remote_fileio_sig_set (SIG_IGN);
532
  strcpy (buf, "F");
533
  if (retcode < 0)
534
    {
535
      strcat (buf, "-");
536
      retcode = -retcode;
537
    }
538
  sprintf (buf + strlen (buf), "%x", retcode);
539
  if (error || remote_fio_ctrl_c_flag)
540
    {
541
      if (error && remote_fio_ctrl_c_flag)
542
        error = FILEIO_EINTR;
543
      if (error < 0)
544
        {
545
          strcat (buf, "-");
546
          error = -error;
547
        }
548
      sprintf (buf + strlen (buf), ",%x", error);
549
      if (remote_fio_ctrl_c_flag)
550
        strcat (buf, ",C");
551
    }
552
  remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
553
  putpkt (buf);
554
}
555
 
556
static void
557
remote_fileio_ioerror (void)
558
{
559
  remote_fileio_reply (-1, FILEIO_EIO);
560
}
561
 
562
static void
563
remote_fileio_badfd (void)
564
{
565
  remote_fileio_reply (-1, FILEIO_EBADF);
566
}
567
 
568
static void
569
remote_fileio_return_errno (int retcode)
570
{
571
  remote_fileio_reply (retcode,
572
                       retcode < 0 ? remote_fileio_errno_to_target (errno) : 0);
573
}
574
 
575
static void
576
remote_fileio_return_success (int retcode)
577
{
578
  remote_fileio_reply (retcode, 0);
579
}
580
 
581
/* Wrapper function for remote_write_bytes() which has the disadvantage to
582
   write only one packet, regardless of the requested number of bytes to
583
   transfer.  This wrapper calls remote_write_bytes() as often as needed. */
584
static int
585
remote_fileio_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
586
{
587
  int ret = 0, written;
588
 
589
  while (len > 0 && (written = remote_write_bytes (memaddr, myaddr, len)) > 0)
590
    {
591
      len -= written;
592
      memaddr += written;
593
      myaddr += written;
594
      ret += written;
595
    }
596
  return ret;
597
}
598
 
599
static void
600
remote_fileio_func_open (char *buf)
601
{
602
  CORE_ADDR ptrval;
603
  int length, retlength;
604
  long num;
605
  int flags, fd;
606
  mode_t mode;
607
  char *pathname;
608
  struct stat st;
609
 
610
  /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
611
  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
612
    {
613
      remote_fileio_ioerror ();
614
      return;
615
    }
616
  /* 2. Parameter: open flags */
617
  if (remote_fileio_extract_int (&buf, &num))
618
    {
619
      remote_fileio_ioerror ();
620
      return;
621
    }
622
  flags = remote_fileio_oflags_to_host (num);
623
  /* 3. Parameter: open mode */
624
  if (remote_fileio_extract_int (&buf, &num))
625
    {
626
      remote_fileio_ioerror ();
627
      return;
628
    }
629
  mode = remote_fileio_mode_to_host (num, 1);
630
 
631
  /* Request pathname using 'm' packet */
632
  pathname = alloca (length);
633
  retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
634
  if (retlength != length)
635
    {
636
      remote_fileio_ioerror ();
637
      return;
638
    }
639
 
640
  /* Check if pathname exists and is not a regular file or directory.  If so,
641
     return an appropriate error code.  Same for trying to open directories
642
     for writing. */
643
  if (!stat (pathname, &st))
644
    {
645
      if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
646
        {
647
          remote_fileio_reply (-1, FILEIO_ENODEV);
648
          return;
649
        }
650
      if (S_ISDIR (st.st_mode)
651
          && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
652
        {
653
          remote_fileio_reply (-1, FILEIO_EISDIR);
654
          return;
655
        }
656
    }
657
 
658
  remote_fio_no_longjmp = 1;
659
  fd = open (pathname, flags, mode);
660
  if (fd < 0)
661
    {
662
      remote_fileio_return_errno (-1);
663
      return;
664
    }
665
 
666
  fd = remote_fileio_fd_to_targetfd (fd);
667
  remote_fileio_return_success (fd);
668
}
669
 
670
static void
671
remote_fileio_func_close (char *buf)
672
{
673
  long num;
674
  int fd;
675
 
676
  /* Parameter: file descriptor */
677
  if (remote_fileio_extract_int (&buf, &num))
678
    {
679
      remote_fileio_ioerror ();
680
      return;
681
    }
682
  fd = remote_fileio_map_fd ((int) num);
683
  if (fd == FIO_FD_INVALID)
684
    {
685
      remote_fileio_badfd ();
686
      return;
687
    }
688
 
689
  remote_fio_no_longjmp = 1;
690
  if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
691
    remote_fileio_return_errno (-1);
692
  remote_fileio_close_target_fd ((int) num);
693
  remote_fileio_return_success (0);
694
}
695
 
696
static void
697
remote_fileio_func_read (char *buf)
698
{
699
  long target_fd, num;
700
  LONGEST lnum;
701
  CORE_ADDR ptrval;
702
  int fd, ret, retlength;
703
  gdb_byte *buffer;
704
  size_t length;
705
  off_t old_offset, new_offset;
706
 
707
  /* 1. Parameter: file descriptor */
708
  if (remote_fileio_extract_int (&buf, &target_fd))
709
    {
710
      remote_fileio_ioerror ();
711
      return;
712
    }
713
  fd = remote_fileio_map_fd ((int) target_fd);
714
  if (fd == FIO_FD_INVALID)
715
    {
716
      remote_fileio_badfd ();
717
      return;
718
    }
719
  /* 2. Parameter: buffer pointer */
720
  if (remote_fileio_extract_long (&buf, &lnum))
721
    {
722
      remote_fileio_ioerror ();
723
      return;
724
    }
725
  ptrval = (CORE_ADDR) lnum;
726
  /* 3. Parameter: buffer length */
727
  if (remote_fileio_extract_int (&buf, &num))
728
    {
729
      remote_fileio_ioerror ();
730
      return;
731
    }
732
  length = (size_t) num;
733
 
734
  switch (fd)
735
    {
736
      case FIO_FD_CONSOLE_OUT:
737
        remote_fileio_badfd ();
738
        return;
739
      case FIO_FD_CONSOLE_IN:
740
        {
741
          static char *remaining_buf = NULL;
742
          static int remaining_length = 0;
743
 
744
          buffer = (gdb_byte *) xmalloc (16384);
745
          if (remaining_buf)
746
            {
747
              remote_fio_no_longjmp = 1;
748
              if (remaining_length > length)
749
                {
750
                  memcpy (buffer, remaining_buf, length);
751
                  memmove (remaining_buf, remaining_buf + length,
752
                           remaining_length - length);
753
                  remaining_length -= length;
754
                  ret = length;
755
                }
756
              else
757
                {
758
                  memcpy (buffer, remaining_buf, remaining_length);
759
                  xfree (remaining_buf);
760
                  remaining_buf = NULL;
761
                  ret = remaining_length;
762
                }
763
            }
764
          else
765
            {
766
              /* Windows (at least XP and Server 2003) has difficulty
767
                 with large reads from consoles.  If a handle is
768
                 backed by a real console device, overly large reads
769
                 from the handle will fail and set errno == ENOMEM.
770
                 On a Windows Server 2003 system where I tested,
771
                 reading 26608 bytes from the console was OK, but
772
                 anything above 26609 bytes would fail.  The limit has
773
                 been observed to vary on different systems.  So, we
774
                 limit this read to something smaller than that - by a
775
                 safe margin, in case the limit depends on system
776
                 resources or version.  */
777
              ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
778
              remote_fio_no_longjmp = 1;
779
              if (ret > 0 && (size_t)ret > length)
780
                {
781
                  remaining_buf = (char *) xmalloc (ret - length);
782
                  remaining_length = ret - length;
783
                  memcpy (remaining_buf, buffer + length, remaining_length);
784
                  ret = length;
785
                }
786
            }
787
        }
788
        break;
789
      default:
790
        buffer = (gdb_byte *) xmalloc (length);
791
        /* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
792
           for read() to return -1 even if "some" bytes have been read.  It
793
           has been corrected in SUSv2 but that doesn't help us much...
794
           Therefore a complete solution must check how many bytes have been
795
           read on EINTR to return a more reliable value to the target */
796
        old_offset = lseek (fd, 0, SEEK_CUR);
797
        remote_fio_no_longjmp = 1;
798
        ret = read (fd, buffer, length);
799
        if (ret < 0 && errno == EINTR)
800
          {
801
            new_offset = lseek (fd, 0, SEEK_CUR);
802
            /* If some data has been read, return the number of bytes read.
803
               The Ctrl-C flag is set in remote_fileio_reply() anyway */
804
            if (old_offset != new_offset)
805
              ret = new_offset - old_offset;
806
          }
807
        break;
808
    }
809
 
810
  if (ret > 0)
811
    {
812
      retlength = remote_fileio_write_bytes (ptrval, buffer, ret);
813
      if (retlength != ret)
814
        ret = -1; /* errno has been set to EIO in remote_fileio_write_bytes() */
815
    }
816
 
817
  if (ret < 0)
818
    remote_fileio_return_errno (-1);
819
  else
820
    remote_fileio_return_success (ret);
821
 
822
  xfree (buffer);
823
}
824
 
825
static void
826
remote_fileio_func_write (char *buf)
827
{
828
  long target_fd, num;
829
  LONGEST lnum;
830
  CORE_ADDR ptrval;
831
  int fd, ret, retlength;
832
  gdb_byte *buffer;
833
  size_t length;
834
 
835
  /* 1. Parameter: file descriptor */
836
  if (remote_fileio_extract_int (&buf, &target_fd))
837
    {
838
      remote_fileio_ioerror ();
839
      return;
840
    }
841
  fd = remote_fileio_map_fd ((int) target_fd);
842
  if (fd == FIO_FD_INVALID)
843
    {
844
      remote_fileio_badfd ();
845
      return;
846
    }
847
  /* 2. Parameter: buffer pointer */
848
  if (remote_fileio_extract_long (&buf, &lnum))
849
    {
850
      remote_fileio_ioerror ();
851
      return;
852
    }
853
  ptrval = (CORE_ADDR) lnum;
854
  /* 3. Parameter: buffer length */
855
  if (remote_fileio_extract_int (&buf, &num))
856
    {
857
      remote_fileio_ioerror ();
858
      return;
859
    }
860
  length = (size_t) num;
861
 
862
  buffer = (gdb_byte *) xmalloc (length);
863
  retlength = remote_read_bytes (ptrval, buffer, length);
864
  if (retlength != length)
865
    {
866
      xfree (buffer);
867
      remote_fileio_ioerror ();
868
      return;
869
    }
870
 
871
  remote_fio_no_longjmp = 1;
872
  switch (fd)
873
    {
874
      case FIO_FD_CONSOLE_IN:
875
        remote_fileio_badfd ();
876
        xfree (buffer);
877
        return;
878
      case FIO_FD_CONSOLE_OUT:
879
        ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
880
                       (char *) buffer, length);
881
        gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
882
        ret = length;
883
        break;
884
      default:
885
        ret = write (fd, buffer, length);
886
        if (ret < 0 && errno == EACCES)
887
          errno = EBADF; /* Cygwin returns EACCESS when writing to a R/O file.*/
888
        break;
889
    }
890
 
891
  if (ret < 0)
892
    remote_fileio_return_errno (-1);
893
  else
894
    remote_fileio_return_success (ret);
895
 
896
  xfree (buffer);
897
}
898
 
899
static void
900
remote_fileio_func_lseek (char *buf)
901
{
902
  long num;
903
  LONGEST lnum;
904
  int fd, flag;
905
  off_t offset, ret;
906
 
907
  /* 1. Parameter: file descriptor */
908
  if (remote_fileio_extract_int (&buf, &num))
909
    {
910
      remote_fileio_ioerror ();
911
      return;
912
    }
913
  fd = remote_fileio_map_fd ((int) num);
914
  if (fd == FIO_FD_INVALID)
915
    {
916
      remote_fileio_badfd ();
917
      return;
918
    }
919
  else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
920
    {
921
      remote_fileio_reply (-1, FILEIO_ESPIPE);
922
      return;
923
    }
924
 
925
  /* 2. Parameter: offset */
926
  if (remote_fileio_extract_long (&buf, &lnum))
927
    {
928
      remote_fileio_ioerror ();
929
      return;
930
    }
931
  offset = (off_t) lnum;
932
  /* 3. Parameter: flag */
933
  if (remote_fileio_extract_int (&buf, &num))
934
    {
935
      remote_fileio_ioerror ();
936
      return;
937
    }
938
  if (remote_fileio_seek_flag_to_host (num, &flag))
939
    {
940
      remote_fileio_reply (-1, FILEIO_EINVAL);
941
      return;
942
    }
943
 
944
  remote_fio_no_longjmp = 1;
945
  ret = lseek (fd, offset, flag);
946
 
947
  if (ret == (off_t) -1)
948
    remote_fileio_return_errno (-1);
949
  else
950
    remote_fileio_return_success (ret);
951
}
952
 
953
static void
954
remote_fileio_func_rename (char *buf)
955
{
956
  CORE_ADDR old_ptr, new_ptr;
957
  int old_len, new_len, retlength;
958
  char *oldpath, *newpath;
959
  int ret, of, nf;
960
  struct stat ost, nst;
961
 
962
  /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
963
  if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
964
    {
965
      remote_fileio_ioerror ();
966
      return;
967
    }
968
 
969
  /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
970
  if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
971
    {
972
      remote_fileio_ioerror ();
973
      return;
974
    }
975
 
976
  /* Request oldpath using 'm' packet */
977
  oldpath = alloca (old_len);
978
  retlength = remote_read_bytes (old_ptr, (gdb_byte *) oldpath, old_len);
979
  if (retlength != old_len)
980
    {
981
      remote_fileio_ioerror ();
982
      return;
983
    }
984
 
985
  /* Request newpath using 'm' packet */
986
  newpath = alloca (new_len);
987
  retlength = remote_read_bytes (new_ptr, (gdb_byte *) newpath, new_len);
988
  if (retlength != new_len)
989
    {
990
      remote_fileio_ioerror ();
991
      return;
992
    }
993
 
994
  /* Only operate on regular files and directories */
995
  of = stat (oldpath, &ost);
996
  nf = stat (newpath, &nst);
997
  if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
998
      || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
999
    {
1000
      remote_fileio_reply (-1, FILEIO_EACCES);
1001
      return;
1002
    }
1003
 
1004
  remote_fio_no_longjmp = 1;
1005
  ret = rename (oldpath, newpath);
1006
 
1007
  if (ret == -1)
1008
    {
1009
      /* Special case: newpath is a non-empty directory.  Some systems
1010
         return ENOTEMPTY, some return EEXIST.  We coerce that to be
1011
         always EEXIST. */
1012
      if (errno == ENOTEMPTY)
1013
        errno = EEXIST;
1014
#ifdef __CYGWIN__
1015
      /* Workaround some Cygwin problems with correct errnos. */
1016
      if (errno == EACCES)
1017
        {
1018
          if (!of && !nf && S_ISDIR (nst.st_mode))
1019
            {
1020
              if (S_ISREG (ost.st_mode))
1021
                errno = EISDIR;
1022
              else
1023
                {
1024
                  char oldfullpath[PATH_MAX + 1];
1025
                  char newfullpath[PATH_MAX + 1];
1026
                  int len;
1027
 
1028
                  cygwin_conv_to_full_posix_path (oldpath, oldfullpath);
1029
                  cygwin_conv_to_full_posix_path (newpath, newfullpath);
1030
                  len = strlen (oldfullpath);
1031
                  if (newfullpath[len] == '/'
1032
                      && !strncmp (oldfullpath, newfullpath, len))
1033
                    errno = EINVAL;
1034
                  else
1035
                    errno = EEXIST;
1036
                }
1037
            }
1038
        }
1039
#endif
1040
 
1041
      remote_fileio_return_errno (-1);
1042
    }
1043
  else
1044
    remote_fileio_return_success (ret);
1045
}
1046
 
1047
static void
1048
remote_fileio_func_unlink (char *buf)
1049
{
1050
  CORE_ADDR ptrval;
1051
  int length, retlength;
1052
  char *pathname;
1053
  int ret;
1054
  struct stat st;
1055
 
1056
  /* Parameter: Ptr to pathname / length incl. trailing zero */
1057
  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1058
    {
1059
      remote_fileio_ioerror ();
1060
      return;
1061
    }
1062
  /* Request pathname using 'm' packet */
1063
  pathname = alloca (length);
1064
  retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
1065
  if (retlength != length)
1066
    {
1067
      remote_fileio_ioerror ();
1068
      return;
1069
    }
1070
 
1071
  /* Only operate on regular files (and directories, which allows to return
1072
     the correct return code) */
1073
  if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
1074
    {
1075
      remote_fileio_reply (-1, FILEIO_ENODEV);
1076
      return;
1077
    }
1078
 
1079
  remote_fio_no_longjmp = 1;
1080
  ret = unlink (pathname);
1081
 
1082
  if (ret == -1)
1083
    remote_fileio_return_errno (-1);
1084
  else
1085
    remote_fileio_return_success (ret);
1086
}
1087
 
1088
static void
1089
remote_fileio_func_stat (char *buf)
1090
{
1091
  CORE_ADDR statptr, nameptr;
1092
  int ret, namelength, retlength;
1093
  char *pathname;
1094
  LONGEST lnum;
1095
  struct stat st;
1096
  struct fio_stat fst;
1097
 
1098
  /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
1099
  if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
1100
    {
1101
      remote_fileio_ioerror ();
1102
      return;
1103
    }
1104
 
1105
  /* 2. Parameter: Ptr to struct stat */
1106
  if (remote_fileio_extract_long (&buf, &lnum))
1107
    {
1108
      remote_fileio_ioerror ();
1109
      return;
1110
    }
1111
  statptr = (CORE_ADDR) lnum;
1112
 
1113
  /* Request pathname using 'm' packet */
1114
  pathname = alloca (namelength);
1115
  retlength = remote_read_bytes (nameptr, (gdb_byte *) pathname, namelength);
1116
  if (retlength != namelength)
1117
    {
1118
      remote_fileio_ioerror ();
1119
      return;
1120
    }
1121
 
1122
  remote_fio_no_longjmp = 1;
1123
  ret = stat (pathname, &st);
1124
 
1125
  if (ret == -1)
1126
    {
1127
      remote_fileio_return_errno (-1);
1128
      return;
1129
    }
1130
  /* Only operate on regular files and directories */
1131
  if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
1132
    {
1133
      remote_fileio_reply (-1, FILEIO_EACCES);
1134
      return;
1135
    }
1136
  if (statptr)
1137
    {
1138
      remote_fileio_to_fio_stat (&st, &fst);
1139
      remote_fileio_to_fio_uint (0, fst.fst_dev);
1140
 
1141
      retlength = remote_fileio_write_bytes (statptr,
1142
                                             (gdb_byte *) &fst, sizeof fst);
1143
      if (retlength != sizeof fst)
1144
        {
1145
          remote_fileio_return_errno (-1);
1146
          return;
1147
        }
1148
    }
1149
  remote_fileio_return_success (ret);
1150
}
1151
 
1152
static void
1153
remote_fileio_func_fstat (char *buf)
1154
{
1155
  CORE_ADDR ptrval;
1156
  int fd, ret, retlength;
1157
  long target_fd;
1158
  LONGEST lnum;
1159
  struct stat st;
1160
  struct fio_stat fst;
1161
  struct timeval tv;
1162
 
1163
  /* 1. Parameter: file descriptor */
1164
  if (remote_fileio_extract_int (&buf, &target_fd))
1165
    {
1166
      remote_fileio_ioerror ();
1167
      return;
1168
    }
1169
  fd = remote_fileio_map_fd ((int) target_fd);
1170
  if (fd == FIO_FD_INVALID)
1171
    {
1172
      remote_fileio_badfd ();
1173
      return;
1174
    }
1175
  /* 2. Parameter: Ptr to struct stat */
1176
  if (remote_fileio_extract_long (&buf, &lnum))
1177
    {
1178
      remote_fileio_ioerror ();
1179
      return;
1180
    }
1181
  ptrval = (CORE_ADDR) lnum;
1182
 
1183
  remote_fio_no_longjmp = 1;
1184
  if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
1185
    {
1186
      remote_fileio_to_fio_uint (1, fst.fst_dev);
1187
      st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
1188
      st.st_nlink = 1;
1189
#ifdef HAVE_GETUID
1190
      st.st_uid = getuid ();
1191
#else
1192
      st.st_uid = 0;
1193
#endif
1194
#ifdef HAVE_GETGID
1195
      st.st_gid = getgid ();
1196
#else
1197
      st.st_gid = 0;
1198
#endif
1199
      st.st_rdev = 0;
1200
      st.st_size = 0;
1201
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1202
      st.st_blksize = 512;
1203
#endif
1204
#if HAVE_STRUCT_STAT_ST_BLOCKS
1205
      st.st_blocks = 0;
1206
#endif
1207
      if (!gettimeofday (&tv, NULL))
1208
        st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
1209
      else
1210
        st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
1211
      ret = 0;
1212
    }
1213
  else
1214
    ret = fstat (fd, &st);
1215
 
1216
  if (ret == -1)
1217
    {
1218
      remote_fileio_return_errno (-1);
1219
      return;
1220
    }
1221
  if (ptrval)
1222
    {
1223
      remote_fileio_to_fio_stat (&st, &fst);
1224
 
1225
      retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &fst, sizeof fst);
1226
      if (retlength != sizeof fst)
1227
        {
1228
          remote_fileio_return_errno (-1);
1229
          return;
1230
        }
1231
    }
1232
  remote_fileio_return_success (ret);
1233
}
1234
 
1235
static void
1236
remote_fileio_func_gettimeofday (char *buf)
1237
{
1238
  LONGEST lnum;
1239
  CORE_ADDR ptrval;
1240
  int ret, retlength;
1241
  struct timeval tv;
1242
  struct fio_timeval ftv;
1243
 
1244
  /* 1. Parameter: struct timeval pointer */
1245
  if (remote_fileio_extract_long (&buf, &lnum))
1246
    {
1247
      remote_fileio_ioerror ();
1248
      return;
1249
    }
1250
  ptrval = (CORE_ADDR) lnum;
1251
  /* 2. Parameter: some pointer value... */
1252
  if (remote_fileio_extract_long (&buf, &lnum))
1253
    {
1254
      remote_fileio_ioerror ();
1255
      return;
1256
    }
1257
  /* ...which has to be NULL */
1258
  if (lnum)
1259
    {
1260
      remote_fileio_reply (-1, FILEIO_EINVAL);
1261
      return;
1262
    }
1263
 
1264
  remote_fio_no_longjmp = 1;
1265
  ret = gettimeofday (&tv, NULL);
1266
 
1267
  if (ret == -1)
1268
    {
1269
      remote_fileio_return_errno (-1);
1270
      return;
1271
    }
1272
 
1273
  if (ptrval)
1274
    {
1275
      remote_fileio_to_fio_timeval (&tv, &ftv);
1276
 
1277
      retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1278
      if (retlength != sizeof ftv)
1279
        {
1280
          remote_fileio_return_errno (-1);
1281
          return;
1282
        }
1283
    }
1284
  remote_fileio_return_success (ret);
1285
}
1286
 
1287
static void
1288
remote_fileio_func_isatty (char *buf)
1289
{
1290
  long target_fd;
1291
  int fd;
1292
 
1293
  /* Parameter: file descriptor */
1294
  if (remote_fileio_extract_int (&buf, &target_fd))
1295
    {
1296
      remote_fileio_ioerror ();
1297
      return;
1298
    }
1299
  remote_fio_no_longjmp = 1;
1300
  fd = remote_fileio_map_fd ((int) target_fd);
1301
  remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
1302
                                fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
1303
}
1304
 
1305
static void
1306
remote_fileio_func_system (char *buf)
1307
{
1308
  CORE_ADDR ptrval;
1309
  int ret, length, retlength;
1310
  char *cmdline = NULL;
1311
 
1312
  /* Parameter: Ptr to commandline / length incl. trailing zero */
1313
  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1314
    {
1315
      remote_fileio_ioerror ();
1316
      return;
1317
    }
1318
 
1319
  if (length)
1320
    {
1321
      /* Request commandline using 'm' packet */
1322
      cmdline = alloca (length);
1323
      retlength = remote_read_bytes (ptrval, (gdb_byte *) cmdline, length);
1324
      if (retlength != length)
1325
        {
1326
          remote_fileio_ioerror ();
1327
          return;
1328
        }
1329
    }
1330
 
1331
  /* Check if system(3) has been explicitely allowed using the
1332
     `set remote system-call-allowed 1' command.  If length is 0,
1333
     indicating a NULL parameter to the system call, return zero to
1334
     indicate a shell is not available.  Otherwise fail with EPERM.  */
1335
  if (!remote_fio_system_call_allowed)
1336
    {
1337
      if (!length)
1338
        remote_fileio_return_success (0);
1339
      else
1340
        remote_fileio_reply (-1, FILEIO_EPERM);
1341
      return;
1342
    }
1343
 
1344
  remote_fio_no_longjmp = 1;
1345
  ret = system (cmdline);
1346
 
1347
  if (!length)
1348
    remote_fileio_return_success (ret);
1349
  else if (ret == -1)
1350
    remote_fileio_return_errno (-1);
1351
  else
1352
    remote_fileio_return_success (WEXITSTATUS (ret));
1353
}
1354
 
1355
static struct {
1356
  char *name;
1357
  void (*func)(char *);
1358
} remote_fio_func_map[] = {
1359
  { "open", remote_fileio_func_open },
1360
  { "close", remote_fileio_func_close },
1361
  { "read", remote_fileio_func_read },
1362
  { "write", remote_fileio_func_write },
1363
  { "lseek", remote_fileio_func_lseek },
1364
  { "rename", remote_fileio_func_rename },
1365
  { "unlink", remote_fileio_func_unlink },
1366
  { "stat", remote_fileio_func_stat },
1367
  { "fstat", remote_fileio_func_fstat },
1368
  { "gettimeofday", remote_fileio_func_gettimeofday },
1369
  { "isatty", remote_fileio_func_isatty },
1370
  { "system", remote_fileio_func_system },
1371
  { NULL, NULL }
1372
};
1373
 
1374
static int
1375
do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
1376
{
1377
  char *buf = buf_arg;
1378
  char *c;
1379
  int idx;
1380
 
1381
  remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
1382
 
1383
  c = strchr (++buf, ',');
1384
  if (c)
1385
    *c++ = '\0';
1386
  else
1387
    c = strchr (buf, '\0');
1388
  for (idx = 0; remote_fio_func_map[idx].name; ++idx)
1389
    if (!strcmp (remote_fio_func_map[idx].name, buf))
1390
      break;
1391
  if (!remote_fio_func_map[idx].name)   /* ERROR: No such function. */
1392
    return RETURN_ERROR;
1393
  remote_fio_func_map[idx].func (c);
1394
  return 0;
1395
}
1396
 
1397
/* Close any open descriptors, and reinitialize the file mapping.  */
1398
 
1399
void
1400
remote_fileio_reset (void)
1401
{
1402
  int ix;
1403
 
1404
  for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1405
    {
1406
      int fd = remote_fio_data.fd_map[ix];
1407
 
1408
      if (fd >= 0)
1409
        close (fd);
1410
    }
1411
  if (remote_fio_data.fd_map)
1412
    {
1413
      xfree (remote_fio_data.fd_map);
1414
      remote_fio_data.fd_map = NULL;
1415
      remote_fio_data.fd_map_size = 0;
1416
    }
1417
}
1418
 
1419
/* Handle a file I/O request. BUF points to the packet containing the
1420
   request. CTRLC_PENDING_P should be nonzero if the target has not
1421
   acknowledged the Ctrl-C sent asynchronously earlier.  */
1422
 
1423
void
1424
remote_fileio_request (char *buf, int ctrlc_pending_p)
1425
{
1426
  int ex;
1427
 
1428
  remote_fileio_sig_init ();
1429
 
1430
  if (ctrlc_pending_p)
1431
    {
1432
      /* If the target hasn't responded to the Ctrl-C sent
1433
         asynchronously earlier, take this opportunity to send the
1434
         Ctrl-C synchronously.  */
1435
      remote_fio_ctrl_c_flag = 1;
1436
      remote_fio_no_longjmp = 0;
1437
      remote_fileio_reply (-1, FILEIO_EINTR);
1438
    }
1439
  else
1440
    {
1441
      remote_fio_ctrl_c_flag = 0;
1442
      remote_fio_no_longjmp = 0;
1443
 
1444
      ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
1445
                             RETURN_MASK_ALL);
1446
      switch (ex)
1447
        {
1448
        case RETURN_ERROR:
1449
          remote_fileio_reply (-1, FILEIO_ENOSYS);
1450
          break;
1451
        case RETURN_QUIT:
1452
          remote_fileio_reply (-1, FILEIO_EINTR);
1453
          break;
1454
        default:
1455
          break;
1456
        }
1457
    }
1458
 
1459
  remote_fileio_sig_exit ();
1460
}
1461
 
1462
static void
1463
set_system_call_allowed (char *args, int from_tty)
1464
{
1465
  if (args)
1466
    {
1467
      char *arg_end;
1468
      int val = strtoul (args, &arg_end, 10);
1469
      if (*args && *arg_end == '\0')
1470
        {
1471
          remote_fio_system_call_allowed = !!val;
1472
          return;
1473
        }
1474
    }
1475
  error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1476
}
1477
 
1478
static void
1479
show_system_call_allowed (char *args, int from_tty)
1480
{
1481
  if (args)
1482
    error (_("Garbage after \"show remote system-call-allowed\" command: `%s'"), args);
1483
  printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1484
                     remote_fio_system_call_allowed ? "" : "not ");
1485
}
1486
 
1487
void
1488
initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
1489
                          struct cmd_list_element *remote_show_cmdlist)
1490
{
1491
  sigint_fileio_token =
1492
    create_async_signal_handler (async_remote_fileio_interrupt, NULL);
1493
 
1494
  add_cmd ("system-call-allowed", no_class,
1495
           set_system_call_allowed,
1496
           _("Set if the host system(3) call is allowed for the target."),
1497
           &remote_set_cmdlist);
1498
  add_cmd ("system-call-allowed", no_class,
1499
           show_system_call_allowed,
1500
           _("Show if the host system(3) call is allowed for the target."),
1501
           &remote_show_cmdlist);
1502
}

powered by: WebSVN 2.1.0

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