xref: /dflybsd-src/contrib/gdb-7/gdb/inf-child.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Default child (native) target interface, for GDB when running under
25796c8dcSSimon Schubert    Unix.
35796c8dcSSimon Schubert 
4*ef5ccd6cSJohn Marino    Copyright (C) 1988-2013 Free Software Foundation, Inc.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This file is part of GDB.
75796c8dcSSimon Schubert 
85796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
115796c8dcSSimon Schubert    (at your option) any later version.
125796c8dcSSimon Schubert 
135796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
145796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
155796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
165796c8dcSSimon Schubert    GNU General Public License for more details.
175796c8dcSSimon Schubert 
185796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
195796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
205796c8dcSSimon Schubert 
215796c8dcSSimon Schubert #include "defs.h"
225796c8dcSSimon Schubert #include "regcache.h"
235796c8dcSSimon Schubert #include "memattr.h"
245796c8dcSSimon Schubert #include "symtab.h"
255796c8dcSSimon Schubert #include "target.h"
265796c8dcSSimon Schubert #include "inferior.h"
275796c8dcSSimon Schubert #include "gdb_string.h"
28*ef5ccd6cSJohn Marino #include "gdb_stat.h"
295796c8dcSSimon Schubert #include "inf-child.h"
30*ef5ccd6cSJohn Marino #include "gdb/fileio.h"
31*ef5ccd6cSJohn Marino #include "agent.h"
32*ef5ccd6cSJohn Marino #include "gdb_wait.h"
33*ef5ccd6cSJohn Marino 
34*ef5ccd6cSJohn Marino #ifdef HAVE_SYS_PARAM_H
35*ef5ccd6cSJohn Marino #include <sys/param.h>		/* for MAXPATHLEN */
36*ef5ccd6cSJohn Marino #endif
37*ef5ccd6cSJohn Marino #include <sys/types.h>
38*ef5ccd6cSJohn Marino #include <fcntl.h>
39*ef5ccd6cSJohn Marino #include <unistd.h>
40*ef5ccd6cSJohn Marino 
41*ef5ccd6cSJohn Marino /* Helper function for child_wait and the derivatives of child_wait.
42*ef5ccd6cSJohn Marino    HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
43*ef5ccd6cSJohn Marino    translation of that in OURSTATUS.  */
44*ef5ccd6cSJohn Marino void
store_waitstatus(struct target_waitstatus * ourstatus,int hoststatus)45*ef5ccd6cSJohn Marino store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
46*ef5ccd6cSJohn Marino {
47*ef5ccd6cSJohn Marino   if (WIFEXITED (hoststatus))
48*ef5ccd6cSJohn Marino     {
49*ef5ccd6cSJohn Marino       ourstatus->kind = TARGET_WAITKIND_EXITED;
50*ef5ccd6cSJohn Marino       ourstatus->value.integer = WEXITSTATUS (hoststatus);
51*ef5ccd6cSJohn Marino     }
52*ef5ccd6cSJohn Marino   else if (!WIFSTOPPED (hoststatus))
53*ef5ccd6cSJohn Marino     {
54*ef5ccd6cSJohn Marino       ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
55*ef5ccd6cSJohn Marino       ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (hoststatus));
56*ef5ccd6cSJohn Marino     }
57*ef5ccd6cSJohn Marino   else
58*ef5ccd6cSJohn Marino     {
59*ef5ccd6cSJohn Marino       ourstatus->kind = TARGET_WAITKIND_STOPPED;
60*ef5ccd6cSJohn Marino       ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (hoststatus));
61*ef5ccd6cSJohn Marino     }
62*ef5ccd6cSJohn Marino }
635796c8dcSSimon Schubert 
645796c8dcSSimon Schubert /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
655796c8dcSSimon Schubert    for all registers.  */
665796c8dcSSimon Schubert 
675796c8dcSSimon Schubert static void
inf_child_fetch_inferior_registers(struct target_ops * ops,struct regcache * regcache,int regnum)685796c8dcSSimon Schubert inf_child_fetch_inferior_registers (struct target_ops *ops,
695796c8dcSSimon Schubert 				    struct regcache *regcache, int regnum)
705796c8dcSSimon Schubert {
715796c8dcSSimon Schubert   if (regnum == -1)
725796c8dcSSimon Schubert     {
735796c8dcSSimon Schubert       for (regnum = 0;
745796c8dcSSimon Schubert 	   regnum < gdbarch_num_regs (get_regcache_arch (regcache));
755796c8dcSSimon Schubert 	   regnum++)
765796c8dcSSimon Schubert 	regcache_raw_supply (regcache, regnum, NULL);
775796c8dcSSimon Schubert     }
785796c8dcSSimon Schubert   else
795796c8dcSSimon Schubert     regcache_raw_supply (regcache, regnum, NULL);
805796c8dcSSimon Schubert }
815796c8dcSSimon Schubert 
825796c8dcSSimon Schubert /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
835796c8dcSSimon Schubert    this for all registers (including the floating point registers).  */
845796c8dcSSimon Schubert 
855796c8dcSSimon Schubert static void
inf_child_store_inferior_registers(struct target_ops * ops,struct regcache * regcache,int regnum)865796c8dcSSimon Schubert inf_child_store_inferior_registers (struct target_ops *ops,
875796c8dcSSimon Schubert 				    struct regcache *regcache, int regnum)
885796c8dcSSimon Schubert {
895796c8dcSSimon Schubert }
905796c8dcSSimon Schubert 
915796c8dcSSimon Schubert static void
inf_child_post_attach(int pid)925796c8dcSSimon Schubert inf_child_post_attach (int pid)
935796c8dcSSimon Schubert {
945796c8dcSSimon Schubert   /* This version of Unix doesn't require a meaningful "post attach"
955796c8dcSSimon Schubert      operation by a debugger.  */
965796c8dcSSimon Schubert }
975796c8dcSSimon Schubert 
985796c8dcSSimon Schubert /* Get ready to modify the registers array.  On machines which store
995796c8dcSSimon Schubert    individual registers, this doesn't need to do anything.  On
1005796c8dcSSimon Schubert    machines which store all the registers in one fell swoop, this
1015796c8dcSSimon Schubert    makes sure that registers contains all the registers from the
1025796c8dcSSimon Schubert    program being debugged.  */
1035796c8dcSSimon Schubert 
1045796c8dcSSimon Schubert static void
inf_child_prepare_to_store(struct regcache * regcache)1055796c8dcSSimon Schubert inf_child_prepare_to_store (struct regcache *regcache)
1065796c8dcSSimon Schubert {
1075796c8dcSSimon Schubert }
1085796c8dcSSimon Schubert 
1095796c8dcSSimon Schubert static void
inf_child_open(char * arg,int from_tty)1105796c8dcSSimon Schubert inf_child_open (char *arg, int from_tty)
1115796c8dcSSimon Schubert {
1125796c8dcSSimon Schubert   error (_("Use the \"run\" command to start a Unix child process."));
1135796c8dcSSimon Schubert }
1145796c8dcSSimon Schubert 
1155796c8dcSSimon Schubert static void
inf_child_post_startup_inferior(ptid_t ptid)1165796c8dcSSimon Schubert inf_child_post_startup_inferior (ptid_t ptid)
1175796c8dcSSimon Schubert {
1185796c8dcSSimon Schubert   /* This version of Unix doesn't require a meaningful "post startup
1195796c8dcSSimon Schubert      inferior" operation by a debugger.  */
1205796c8dcSSimon Schubert }
1215796c8dcSSimon Schubert 
1225796c8dcSSimon Schubert static int
inf_child_follow_fork(struct target_ops * ops,int follow_child)1235796c8dcSSimon Schubert inf_child_follow_fork (struct target_ops *ops, int follow_child)
1245796c8dcSSimon Schubert {
1255796c8dcSSimon Schubert   /* This version of Unix doesn't support following fork or vfork
1265796c8dcSSimon Schubert      events.  */
1275796c8dcSSimon Schubert   return 0;
1285796c8dcSSimon Schubert }
1295796c8dcSSimon Schubert 
1305796c8dcSSimon Schubert static int
inf_child_can_run(void)1315796c8dcSSimon Schubert inf_child_can_run (void)
1325796c8dcSSimon Schubert {
1335796c8dcSSimon Schubert   return 1;
1345796c8dcSSimon Schubert }
1355796c8dcSSimon Schubert 
1365796c8dcSSimon Schubert static char *
inf_child_pid_to_exec_file(int pid)1375796c8dcSSimon Schubert inf_child_pid_to_exec_file (int pid)
1385796c8dcSSimon Schubert {
1395796c8dcSSimon Schubert   /* This version of Unix doesn't support translation of a process ID
1405796c8dcSSimon Schubert      to the filename of the executable file.  */
1415796c8dcSSimon Schubert   return NULL;
1425796c8dcSSimon Schubert }
1435796c8dcSSimon Schubert 
144*ef5ccd6cSJohn Marino 
145*ef5ccd6cSJohn Marino /* Target file operations.  */
146*ef5ccd6cSJohn Marino 
147*ef5ccd6cSJohn Marino static int
inf_child_fileio_open_flags_to_host(int fileio_open_flags,int * open_flags_p)148*ef5ccd6cSJohn Marino inf_child_fileio_open_flags_to_host (int fileio_open_flags, int *open_flags_p)
149*ef5ccd6cSJohn Marino {
150*ef5ccd6cSJohn Marino   int open_flags = 0;
151*ef5ccd6cSJohn Marino 
152*ef5ccd6cSJohn Marino   if (fileio_open_flags & ~FILEIO_O_SUPPORTED)
153*ef5ccd6cSJohn Marino     return -1;
154*ef5ccd6cSJohn Marino 
155*ef5ccd6cSJohn Marino   if (fileio_open_flags & FILEIO_O_CREAT)
156*ef5ccd6cSJohn Marino     open_flags |= O_CREAT;
157*ef5ccd6cSJohn Marino   if (fileio_open_flags & FILEIO_O_EXCL)
158*ef5ccd6cSJohn Marino     open_flags |= O_EXCL;
159*ef5ccd6cSJohn Marino   if (fileio_open_flags & FILEIO_O_TRUNC)
160*ef5ccd6cSJohn Marino     open_flags |= O_TRUNC;
161*ef5ccd6cSJohn Marino   if (fileio_open_flags & FILEIO_O_APPEND)
162*ef5ccd6cSJohn Marino     open_flags |= O_APPEND;
163*ef5ccd6cSJohn Marino   if (fileio_open_flags & FILEIO_O_RDONLY)
164*ef5ccd6cSJohn Marino     open_flags |= O_RDONLY;
165*ef5ccd6cSJohn Marino   if (fileio_open_flags & FILEIO_O_WRONLY)
166*ef5ccd6cSJohn Marino     open_flags |= O_WRONLY;
167*ef5ccd6cSJohn Marino   if (fileio_open_flags & FILEIO_O_RDWR)
168*ef5ccd6cSJohn Marino     open_flags |= O_RDWR;
169*ef5ccd6cSJohn Marino /* On systems supporting binary and text mode, always open files in
170*ef5ccd6cSJohn Marino    binary mode. */
171*ef5ccd6cSJohn Marino #ifdef O_BINARY
172*ef5ccd6cSJohn Marino   open_flags |= O_BINARY;
173*ef5ccd6cSJohn Marino #endif
174*ef5ccd6cSJohn Marino 
175*ef5ccd6cSJohn Marino   *open_flags_p = open_flags;
176*ef5ccd6cSJohn Marino   return 0;
177*ef5ccd6cSJohn Marino }
178*ef5ccd6cSJohn Marino 
179*ef5ccd6cSJohn Marino static int
inf_child_errno_to_fileio_error(int errnum)180*ef5ccd6cSJohn Marino inf_child_errno_to_fileio_error (int errnum)
181*ef5ccd6cSJohn Marino {
182*ef5ccd6cSJohn Marino   switch (errnum)
183*ef5ccd6cSJohn Marino     {
184*ef5ccd6cSJohn Marino       case EPERM:
185*ef5ccd6cSJohn Marino         return FILEIO_EPERM;
186*ef5ccd6cSJohn Marino       case ENOENT:
187*ef5ccd6cSJohn Marino         return FILEIO_ENOENT;
188*ef5ccd6cSJohn Marino       case EINTR:
189*ef5ccd6cSJohn Marino         return FILEIO_EINTR;
190*ef5ccd6cSJohn Marino       case EIO:
191*ef5ccd6cSJohn Marino         return FILEIO_EIO;
192*ef5ccd6cSJohn Marino       case EBADF:
193*ef5ccd6cSJohn Marino         return FILEIO_EBADF;
194*ef5ccd6cSJohn Marino       case EACCES:
195*ef5ccd6cSJohn Marino         return FILEIO_EACCES;
196*ef5ccd6cSJohn Marino       case EFAULT:
197*ef5ccd6cSJohn Marino         return FILEIO_EFAULT;
198*ef5ccd6cSJohn Marino       case EBUSY:
199*ef5ccd6cSJohn Marino         return FILEIO_EBUSY;
200*ef5ccd6cSJohn Marino       case EEXIST:
201*ef5ccd6cSJohn Marino         return FILEIO_EEXIST;
202*ef5ccd6cSJohn Marino       case ENODEV:
203*ef5ccd6cSJohn Marino         return FILEIO_ENODEV;
204*ef5ccd6cSJohn Marino       case ENOTDIR:
205*ef5ccd6cSJohn Marino         return FILEIO_ENOTDIR;
206*ef5ccd6cSJohn Marino       case EISDIR:
207*ef5ccd6cSJohn Marino         return FILEIO_EISDIR;
208*ef5ccd6cSJohn Marino       case EINVAL:
209*ef5ccd6cSJohn Marino         return FILEIO_EINVAL;
210*ef5ccd6cSJohn Marino       case ENFILE:
211*ef5ccd6cSJohn Marino         return FILEIO_ENFILE;
212*ef5ccd6cSJohn Marino       case EMFILE:
213*ef5ccd6cSJohn Marino         return FILEIO_EMFILE;
214*ef5ccd6cSJohn Marino       case EFBIG:
215*ef5ccd6cSJohn Marino         return FILEIO_EFBIG;
216*ef5ccd6cSJohn Marino       case ENOSPC:
217*ef5ccd6cSJohn Marino         return FILEIO_ENOSPC;
218*ef5ccd6cSJohn Marino       case ESPIPE:
219*ef5ccd6cSJohn Marino         return FILEIO_ESPIPE;
220*ef5ccd6cSJohn Marino       case EROFS:
221*ef5ccd6cSJohn Marino         return FILEIO_EROFS;
222*ef5ccd6cSJohn Marino       case ENOSYS:
223*ef5ccd6cSJohn Marino         return FILEIO_ENOSYS;
224*ef5ccd6cSJohn Marino       case ENAMETOOLONG:
225*ef5ccd6cSJohn Marino         return FILEIO_ENAMETOOLONG;
226*ef5ccd6cSJohn Marino     }
227*ef5ccd6cSJohn Marino   return FILEIO_EUNKNOWN;
228*ef5ccd6cSJohn Marino }
229*ef5ccd6cSJohn Marino 
230*ef5ccd6cSJohn Marino /* Open FILENAME on the target, using FLAGS and MODE.  Return a
231*ef5ccd6cSJohn Marino    target file descriptor, or -1 if an error occurs (and set
232*ef5ccd6cSJohn Marino    *TARGET_ERRNO).  */
233*ef5ccd6cSJohn Marino static int
inf_child_fileio_open(const char * filename,int flags,int mode,int * target_errno)234*ef5ccd6cSJohn Marino inf_child_fileio_open (const char *filename, int flags, int mode,
235*ef5ccd6cSJohn Marino 		       int *target_errno)
236*ef5ccd6cSJohn Marino {
237*ef5ccd6cSJohn Marino   int nat_flags;
238*ef5ccd6cSJohn Marino   int fd;
239*ef5ccd6cSJohn Marino 
240*ef5ccd6cSJohn Marino   if (inf_child_fileio_open_flags_to_host (flags, &nat_flags) == -1)
241*ef5ccd6cSJohn Marino     {
242*ef5ccd6cSJohn Marino       *target_errno = FILEIO_EINVAL;
243*ef5ccd6cSJohn Marino       return -1;
244*ef5ccd6cSJohn Marino     }
245*ef5ccd6cSJohn Marino 
246*ef5ccd6cSJohn Marino   /* We do not need to convert MODE, since the fileio protocol uses
247*ef5ccd6cSJohn Marino      the standard values.  */
248*ef5ccd6cSJohn Marino   fd = open (filename, nat_flags, mode);
249*ef5ccd6cSJohn Marino   if (fd == -1)
250*ef5ccd6cSJohn Marino     *target_errno = inf_child_errno_to_fileio_error (errno);
251*ef5ccd6cSJohn Marino 
252*ef5ccd6cSJohn Marino   return fd;
253*ef5ccd6cSJohn Marino }
254*ef5ccd6cSJohn Marino 
255*ef5ccd6cSJohn Marino /* Write up to LEN bytes from WRITE_BUF to FD on the target.
256*ef5ccd6cSJohn Marino    Return the number of bytes written, or -1 if an error occurs
257*ef5ccd6cSJohn Marino    (and set *TARGET_ERRNO).  */
258*ef5ccd6cSJohn Marino static int
inf_child_fileio_pwrite(int fd,const gdb_byte * write_buf,int len,ULONGEST offset,int * target_errno)259*ef5ccd6cSJohn Marino inf_child_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
260*ef5ccd6cSJohn Marino 			 ULONGEST offset, int *target_errno)
261*ef5ccd6cSJohn Marino {
262*ef5ccd6cSJohn Marino   int ret;
263*ef5ccd6cSJohn Marino 
264*ef5ccd6cSJohn Marino #ifdef HAVE_PWRITE
265*ef5ccd6cSJohn Marino   ret = pwrite (fd, write_buf, len, (long) offset);
266*ef5ccd6cSJohn Marino #else
267*ef5ccd6cSJohn Marino   ret = -1;
268*ef5ccd6cSJohn Marino #endif
269*ef5ccd6cSJohn Marino   /* If we have no pwrite or it failed for this file, use lseek/write.  */
270*ef5ccd6cSJohn Marino   if (ret == -1)
271*ef5ccd6cSJohn Marino     {
272*ef5ccd6cSJohn Marino       ret = lseek (fd, (long) offset, SEEK_SET);
273*ef5ccd6cSJohn Marino       if (ret != -1)
274*ef5ccd6cSJohn Marino 	ret = write (fd, write_buf, len);
275*ef5ccd6cSJohn Marino     }
276*ef5ccd6cSJohn Marino 
277*ef5ccd6cSJohn Marino   if (ret == -1)
278*ef5ccd6cSJohn Marino     *target_errno = inf_child_errno_to_fileio_error (errno);
279*ef5ccd6cSJohn Marino 
280*ef5ccd6cSJohn Marino   return ret;
281*ef5ccd6cSJohn Marino }
282*ef5ccd6cSJohn Marino 
283*ef5ccd6cSJohn Marino /* Read up to LEN bytes FD on the target into READ_BUF.
284*ef5ccd6cSJohn Marino    Return the number of bytes read, or -1 if an error occurs
285*ef5ccd6cSJohn Marino    (and set *TARGET_ERRNO).  */
286*ef5ccd6cSJohn Marino static int
inf_child_fileio_pread(int fd,gdb_byte * read_buf,int len,ULONGEST offset,int * target_errno)287*ef5ccd6cSJohn Marino inf_child_fileio_pread (int fd, gdb_byte *read_buf, int len,
288*ef5ccd6cSJohn Marino 			ULONGEST offset, int *target_errno)
289*ef5ccd6cSJohn Marino {
290*ef5ccd6cSJohn Marino   int ret;
291*ef5ccd6cSJohn Marino 
292*ef5ccd6cSJohn Marino #ifdef HAVE_PREAD
293*ef5ccd6cSJohn Marino   ret = pread (fd, read_buf, len, (long) offset);
294*ef5ccd6cSJohn Marino #else
295*ef5ccd6cSJohn Marino   ret = -1;
296*ef5ccd6cSJohn Marino #endif
297*ef5ccd6cSJohn Marino   /* If we have no pread or it failed for this file, use lseek/read.  */
298*ef5ccd6cSJohn Marino   if (ret == -1)
299*ef5ccd6cSJohn Marino     {
300*ef5ccd6cSJohn Marino       ret = lseek (fd, (long) offset, SEEK_SET);
301*ef5ccd6cSJohn Marino       if (ret != -1)
302*ef5ccd6cSJohn Marino 	ret = read (fd, read_buf, len);
303*ef5ccd6cSJohn Marino     }
304*ef5ccd6cSJohn Marino 
305*ef5ccd6cSJohn Marino   if (ret == -1)
306*ef5ccd6cSJohn Marino     *target_errno = inf_child_errno_to_fileio_error (errno);
307*ef5ccd6cSJohn Marino 
308*ef5ccd6cSJohn Marino   return ret;
309*ef5ccd6cSJohn Marino }
310*ef5ccd6cSJohn Marino 
311*ef5ccd6cSJohn Marino /* Close FD on the target.  Return 0, or -1 if an error occurs
312*ef5ccd6cSJohn Marino    (and set *TARGET_ERRNO).  */
313*ef5ccd6cSJohn Marino static int
inf_child_fileio_close(int fd,int * target_errno)314*ef5ccd6cSJohn Marino inf_child_fileio_close (int fd, int *target_errno)
315*ef5ccd6cSJohn Marino {
316*ef5ccd6cSJohn Marino   int ret;
317*ef5ccd6cSJohn Marino 
318*ef5ccd6cSJohn Marino   ret = close (fd);
319*ef5ccd6cSJohn Marino   if (ret == -1)
320*ef5ccd6cSJohn Marino     *target_errno = inf_child_errno_to_fileio_error (errno);
321*ef5ccd6cSJohn Marino 
322*ef5ccd6cSJohn Marino   return ret;
323*ef5ccd6cSJohn Marino }
324*ef5ccd6cSJohn Marino 
325*ef5ccd6cSJohn Marino /* Unlink FILENAME on the target.  Return 0, or -1 if an error
326*ef5ccd6cSJohn Marino    occurs (and set *TARGET_ERRNO).  */
327*ef5ccd6cSJohn Marino static int
inf_child_fileio_unlink(const char * filename,int * target_errno)328*ef5ccd6cSJohn Marino inf_child_fileio_unlink (const char *filename, int *target_errno)
329*ef5ccd6cSJohn Marino {
330*ef5ccd6cSJohn Marino   int ret;
331*ef5ccd6cSJohn Marino 
332*ef5ccd6cSJohn Marino   ret = unlink (filename);
333*ef5ccd6cSJohn Marino   if (ret == -1)
334*ef5ccd6cSJohn Marino     *target_errno = inf_child_errno_to_fileio_error (errno);
335*ef5ccd6cSJohn Marino 
336*ef5ccd6cSJohn Marino   return ret;
337*ef5ccd6cSJohn Marino }
338*ef5ccd6cSJohn Marino 
339*ef5ccd6cSJohn Marino /* Read value of symbolic link FILENAME on the target.  Return a
340*ef5ccd6cSJohn Marino    null-terminated string allocated via xmalloc, or NULL if an error
341*ef5ccd6cSJohn Marino    occurs (and set *TARGET_ERRNO).  */
342*ef5ccd6cSJohn Marino static char *
inf_child_fileio_readlink(const char * filename,int * target_errno)343*ef5ccd6cSJohn Marino inf_child_fileio_readlink (const char *filename, int *target_errno)
344*ef5ccd6cSJohn Marino {
345*ef5ccd6cSJohn Marino   /* We support readlink only on systems that also provide a compile-time
346*ef5ccd6cSJohn Marino      maximum path length (MAXPATHLEN), at least for now.  */
347*ef5ccd6cSJohn Marino #if defined (HAVE_READLINK) && defined (MAXPATHLEN)
348*ef5ccd6cSJohn Marino   char buf[MAXPATHLEN - 1];
349*ef5ccd6cSJohn Marino   int len;
350*ef5ccd6cSJohn Marino   char *ret;
351*ef5ccd6cSJohn Marino 
352*ef5ccd6cSJohn Marino   len = readlink (filename, buf, sizeof buf);
353*ef5ccd6cSJohn Marino   if (len < 0)
354*ef5ccd6cSJohn Marino     {
355*ef5ccd6cSJohn Marino       *target_errno = inf_child_errno_to_fileio_error (errno);
356*ef5ccd6cSJohn Marino       return NULL;
357*ef5ccd6cSJohn Marino     }
358*ef5ccd6cSJohn Marino 
359*ef5ccd6cSJohn Marino   ret = xmalloc (len + 1);
360*ef5ccd6cSJohn Marino   memcpy (ret, buf, len);
361*ef5ccd6cSJohn Marino   ret[len] = '\0';
362*ef5ccd6cSJohn Marino   return ret;
363*ef5ccd6cSJohn Marino #else
364*ef5ccd6cSJohn Marino   *target_errno = FILEIO_ENOSYS;
365*ef5ccd6cSJohn Marino   return NULL;
366*ef5ccd6cSJohn Marino #endif
367*ef5ccd6cSJohn Marino }
368*ef5ccd6cSJohn Marino 
369*ef5ccd6cSJohn Marino static int
inf_child_use_agent(int use)370*ef5ccd6cSJohn Marino inf_child_use_agent (int use)
371*ef5ccd6cSJohn Marino {
372*ef5ccd6cSJohn Marino   if (agent_loaded_p ())
373*ef5ccd6cSJohn Marino     {
374*ef5ccd6cSJohn Marino       use_agent = use;
375*ef5ccd6cSJohn Marino       return 1;
376*ef5ccd6cSJohn Marino     }
377*ef5ccd6cSJohn Marino   else
378*ef5ccd6cSJohn Marino     return 0;
379*ef5ccd6cSJohn Marino }
380*ef5ccd6cSJohn Marino 
381*ef5ccd6cSJohn Marino static int
inf_child_can_use_agent(void)382*ef5ccd6cSJohn Marino inf_child_can_use_agent (void)
383*ef5ccd6cSJohn Marino {
384*ef5ccd6cSJohn Marino   return agent_loaded_p ();
385*ef5ccd6cSJohn Marino }
386*ef5ccd6cSJohn Marino 
3875796c8dcSSimon Schubert struct target_ops *
inf_child_target(void)3885796c8dcSSimon Schubert inf_child_target (void)
3895796c8dcSSimon Schubert {
3905796c8dcSSimon Schubert   struct target_ops *t = XZALLOC (struct target_ops);
391cf7f2e2dSJohn Marino 
3925796c8dcSSimon Schubert   t->to_shortname = "child";
3935796c8dcSSimon Schubert   t->to_longname = "Unix child process";
3945796c8dcSSimon Schubert   t->to_doc = "Unix child process (started by the \"run\" command).";
3955796c8dcSSimon Schubert   t->to_open = inf_child_open;
3965796c8dcSSimon Schubert   t->to_post_attach = inf_child_post_attach;
3975796c8dcSSimon Schubert   t->to_fetch_registers = inf_child_fetch_inferior_registers;
3985796c8dcSSimon Schubert   t->to_store_registers = inf_child_store_inferior_registers;
3995796c8dcSSimon Schubert   t->to_prepare_to_store = inf_child_prepare_to_store;
4005796c8dcSSimon Schubert   t->to_insert_breakpoint = memory_insert_breakpoint;
4015796c8dcSSimon Schubert   t->to_remove_breakpoint = memory_remove_breakpoint;
4025796c8dcSSimon Schubert   t->to_terminal_init = terminal_init_inferior;
4035796c8dcSSimon Schubert   t->to_terminal_inferior = terminal_inferior;
4045796c8dcSSimon Schubert   t->to_terminal_ours_for_output = terminal_ours_for_output;
4055796c8dcSSimon Schubert   t->to_terminal_save_ours = terminal_save_ours;
4065796c8dcSSimon Schubert   t->to_terminal_ours = terminal_ours;
4075796c8dcSSimon Schubert   t->to_terminal_info = child_terminal_info;
4085796c8dcSSimon Schubert   t->to_post_startup_inferior = inf_child_post_startup_inferior;
4095796c8dcSSimon Schubert   t->to_follow_fork = inf_child_follow_fork;
4105796c8dcSSimon Schubert   t->to_can_run = inf_child_can_run;
4115796c8dcSSimon Schubert   t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
4125796c8dcSSimon Schubert   t->to_stratum = process_stratum;
4135796c8dcSSimon Schubert   t->to_has_all_memory = default_child_has_all_memory;
4145796c8dcSSimon Schubert   t->to_has_memory = default_child_has_memory;
4155796c8dcSSimon Schubert   t->to_has_stack = default_child_has_stack;
4165796c8dcSSimon Schubert   t->to_has_registers = default_child_has_registers;
4175796c8dcSSimon Schubert   t->to_has_execution = default_child_has_execution;
418*ef5ccd6cSJohn Marino   t->to_fileio_open = inf_child_fileio_open;
419*ef5ccd6cSJohn Marino   t->to_fileio_pwrite = inf_child_fileio_pwrite;
420*ef5ccd6cSJohn Marino   t->to_fileio_pread = inf_child_fileio_pread;
421*ef5ccd6cSJohn Marino   t->to_fileio_close = inf_child_fileio_close;
422*ef5ccd6cSJohn Marino   t->to_fileio_unlink = inf_child_fileio_unlink;
423*ef5ccd6cSJohn Marino   t->to_fileio_readlink = inf_child_fileio_readlink;
4245796c8dcSSimon Schubert   t->to_magic = OPS_MAGIC;
425*ef5ccd6cSJohn Marino   t->to_use_agent = inf_child_use_agent;
426*ef5ccd6cSJohn Marino   t->to_can_use_agent = inf_child_can_use_agent;
4275796c8dcSSimon Schubert   return t;
4285796c8dcSSimon Schubert }
429