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

Subversion Repositories openrisc_me

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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