Rename gdbarch_update() to gdbarch_update_p()
[deliverable/binutils-gdb.git] / gdb / go32-nat.c
CommitLineData
e49d4fa6
SS
1/* Native debugging support for Intel x86 running DJGPP.
2 Copyright 1997, 1999 Free Software Foundation, Inc.
3 Written by Robert Hoehne.
4
c5aa993b 5 This file is part of GDB.
e49d4fa6 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
e49d4fa6 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
e49d4fa6 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
e49d4fa6
SS
21
22#include <fcntl.h>
23
24#include "defs.h"
e49d4fa6 25#include "inferior.h"
03f2053f 26#include "gdb_wait.h"
e49d4fa6
SS
27#include "gdbcore.h"
28#include "command.h"
29#include "floatformat.h"
0fff5247 30#include "buildsym.h"
e49d4fa6 31
c5aa993b 32#include <stdio.h> /* required for __DJGPP_MINOR__ */
e49d4fa6
SS
33#include <stdlib.h>
34#include <string.h>
53a5351d 35#include <errno.h>
c2c6d25f 36#include <unistd.h>
53a5351d
JM
37#include <io.h>
38#include <dpmi.h>
e49d4fa6
SS
39#include <debug/v2load.h>
40#include <debug/dbgcom.h>
53a5351d
JM
41#if __DJGPP_MINOR__ > 2
42#include <debug/redir.h>
43#endif
e49d4fa6 44
b83266a0
SS
45#if __DJGPP_MINOR__ < 3
46/* This code will be provided from DJGPP 2.03 on. Until then I code it
47 here */
c5aa993b
JM
48typedef struct
49 {
50 unsigned short sig0;
51 unsigned short sig1;
52 unsigned short sig2;
53 unsigned short sig3;
54 unsigned short exponent:15;
55 unsigned short sign:1;
56 }
57NPXREG;
58
59typedef struct
60 {
61 unsigned int control;
62 unsigned int status;
63 unsigned int tag;
64 unsigned int eip;
65 unsigned int cs;
66 unsigned int dataptr;
67 unsigned int datasel;
68 NPXREG reg[8];
69 }
70NPX;
b83266a0
SS
71
72static NPX npx;
73
c5aa993b
JM
74static void save_npx (void); /* Save the FPU of the debugged program */
75static void load_npx (void); /* Restore the FPU of the debugged program */
b83266a0
SS
76
77/* ------------------------------------------------------------------------- */
78/* Store the contents of the NPX in the global variable `npx'. */
c5aa993b 79/* *INDENT-OFF* */
b83266a0
SS
80
81static void
82save_npx (void)
83{
84 asm ("inb $0xa0, %%al
c5aa993b
JM
85 testb $0x20, %%al
86 jz 1f
87 xorb %% al, %%al
88 outb %% al, $0xf0
89 movb $0x20, %%al
90 outb %% al, $0xa0
91 outb %% al, $0x20
b83266a0 921:
c5aa993b
JM
93 fnsave % 0
94 fwait "
95: "=m" (npx)
96: /* No input */
97: "%eax");
b83266a0 98}
c5aa993b
JM
99
100/* *INDENT-ON* */
101
102
103
104
105
b83266a0
SS
106/* ------------------------------------------------------------------------- */
107/* Reload the contents of the NPX from the global variable `npx'. */
108
109static void
110load_npx (void)
111{
c5aa993b 112asm ("frstor %0":"=m" (npx));
b83266a0 113}
53a5351d
JM
114/* ------------------------------------------------------------------------- */
115/* Stubs for the missing redirection functions. */
116typedef struct {
117 char *command;
118 int redirected;
119} cmdline_t;
120
121void redir_cmdline_delete (cmdline_t *ptr) {ptr->redirected = 0;}
122int redir_cmdline_parse (const char *args, cmdline_t *ptr)
123{
124 return -1;
125}
126int redir_to_child (cmdline_t *ptr)
127{
128 return 1;
129}
130int redir_to_debugger (cmdline_t *ptr)
131{
132 return 1;
133}
134int redir_debug_init (cmdline_t *ptr) { return 0; }
b83266a0
SS
135#endif /* __DJGPP_MINOR < 3 */
136
e49d4fa6
SS
137extern void _initialize_go32_nat (void);
138
53a5351d
JM
139typedef enum { wp_insert, wp_remove, wp_count } wp_op;
140
141/* This holds the current reference counts for each debug register. */
142static int dr_ref_count[4];
143
e49d4fa6
SS
144extern char **environ;
145
146#define SOME_PID 42
147
e49d4fa6 148static int prog_has_started = 0;
c5aa993b
JM
149static void go32_open (char *name, int from_tty);
150static void go32_close (int quitting);
151static void go32_attach (char *args, int from_tty);
152static void go32_detach (char *args, int from_tty);
153static void go32_resume (int pid, int step, enum target_signal siggnal);
154static int go32_wait (int pid, struct target_waitstatus *status);
155static void go32_fetch_registers (int regno);
156static void store_register (int regno);
157static void go32_store_registers (int regno);
158static void go32_prepare_to_store (void);
159static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
160 int write, struct target_ops *target);
161static void go32_files_info (struct target_ops *target);
162static void go32_stop (void);
163static void go32_kill_inferior (void);
164static void go32_create_inferior (char *exec_file, char *args, char **env);
53a5351d 165static void cleanup_dregs (void);
c5aa993b
JM
166static void go32_mourn_inferior (void);
167static int go32_can_run (void);
53a5351d
JM
168static int go32_insert_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
169 int len, int rw);
170static int go32_remove_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
171 int len, int rw);
172static int go32_handle_nonaligned_watchpoint (wp_op what, CORE_ADDR waddr,
173 CORE_ADDR addr, int len, int rw);
b83266a0
SS
174
175static struct target_ops go32_ops;
c5aa993b
JM
176static void go32_terminal_init (void);
177static void go32_terminal_inferior (void);
178static void go32_terminal_ours (void);
e49d4fa6 179
53a5351d 180#define r_ofs(x) (offsetof(TSS,x))
e49d4fa6
SS
181
182static struct
183{
53a5351d
JM
184 size_t tss_ofs;
185 size_t size;
e49d4fa6
SS
186}
187regno_mapping[] =
188{
0fff5247
EZ
189 {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */
190 {r_ofs (tss_ecx), 4},
191 {r_ofs (tss_edx), 4},
192 {r_ofs (tss_ebx), 4},
193 {r_ofs (tss_esp), 4},
194 {r_ofs (tss_ebp), 4},
195 {r_ofs (tss_esi), 4},
196 {r_ofs (tss_edi), 4},
197 {r_ofs (tss_eip), 4},
198 {r_ofs (tss_eflags), 4},
199 {r_ofs (tss_cs), 2},
200 {r_ofs (tss_ss), 2},
201 {r_ofs (tss_ds), 2},
202 {r_ofs (tss_es), 2},
203 {r_ofs (tss_fs), 2},
204 {r_ofs (tss_gs), 2},
205 {0, 10}, /* 8 FP registers, from npx.reg[] */
206 {1, 10},
207 {2, 10},
208 {3, 10},
209 {4, 10},
210 {5, 10},
211 {6, 10},
212 {7, 10},
53a5351d 213 /* The order of the next 7 registers must be consistent
0fff5247
EZ
214 with their numbering in config/i386/tm-i386.h, which see. */
215 {0, 2}, /* control word, from npx */
216 {4, 2}, /* status word, from npx */
217 {8, 2}, /* tag word, from npx */
218 {16, 2}, /* last FP exception CS from npx */
219 {12, 4}, /* last FP exception EIP from npx */
220 {24, 2}, /* last FP exception operand selector from npx */
221 {20, 4}, /* last FP exception operand offset from npx */
222 {18, 2} /* last FP opcode from npx */
e49d4fa6
SS
223};
224
225static struct
226 {
227 int go32_sig;
0fff5247 228 enum target_signal gdb_sig;
e49d4fa6
SS
229 }
230sig_map[] =
231{
0fff5247
EZ
232 {0, TARGET_SIGNAL_FPE},
233 {1, TARGET_SIGNAL_TRAP},
53a5351d
JM
234 /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL,
235 but I think SIGBUS is better, since the NMI is usually activated
236 as a result of a memory parity check failure. */
0fff5247
EZ
237 {2, TARGET_SIGNAL_BUS},
238 {3, TARGET_SIGNAL_TRAP},
239 {4, TARGET_SIGNAL_FPE},
240 {5, TARGET_SIGNAL_SEGV},
241 {6, TARGET_SIGNAL_ILL},
242 {7, TARGET_SIGNAL_EMT}, /* no-coprocessor exception */
243 {8, TARGET_SIGNAL_SEGV},
244 {9, TARGET_SIGNAL_SEGV},
245 {10, TARGET_SIGNAL_BUS},
246 {11, TARGET_SIGNAL_SEGV},
247 {12, TARGET_SIGNAL_SEGV},
248 {13, TARGET_SIGNAL_SEGV},
249 {14, TARGET_SIGNAL_SEGV},
250 {16, TARGET_SIGNAL_FPE},
251 {17, TARGET_SIGNAL_BUS},
252 {31, TARGET_SIGNAL_ILL},
253 {0x1b, TARGET_SIGNAL_INT},
254 {0x75, TARGET_SIGNAL_FPE},
255 {0x78, TARGET_SIGNAL_ALRM},
256 {0x79, TARGET_SIGNAL_INT},
257 {0x7a, TARGET_SIGNAL_QUIT},
258 {-1, TARGET_SIGNAL_LAST}
e49d4fa6
SS
259};
260
53a5351d
JM
261static struct {
262 enum target_signal gdb_sig;
263 int djgpp_excepno;
264} excepn_map[] = {
0fff5247
EZ
265 {TARGET_SIGNAL_0, -1},
266 {TARGET_SIGNAL_ILL, 6}, /* Invalid Opcode */
267 {TARGET_SIGNAL_EMT, 7}, /* triggers SIGNOFP */
268 {TARGET_SIGNAL_SEGV, 13}, /* GPF */
269 {TARGET_SIGNAL_BUS, 17}, /* Alignment Check */
53a5351d
JM
270 /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
271 details. */
0fff5247
EZ
272 {TARGET_SIGNAL_TERM, 0x1b}, /* triggers Ctrl-Break type of SIGINT */
273 {TARGET_SIGNAL_FPE, 0x75},
274 {TARGET_SIGNAL_INT, 0x79},
275 {TARGET_SIGNAL_QUIT, 0x7a},
276 {TARGET_SIGNAL_ALRM, 0x78}, /* triggers SIGTIMR */
277 {TARGET_SIGNAL_PROF, 0x78},
278 {TARGET_SIGNAL_LAST, -1}
53a5351d
JM
279};
280
e49d4fa6 281static void
0fff5247 282go32_open (char *name ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
e49d4fa6 283{
53a5351d 284 printf_unfiltered ("Done. Use the \"run\" command to run the program.\n");
e49d4fa6
SS
285}
286
287static void
0fff5247 288go32_close (int quitting ATTRIBUTE_UNUSED)
e49d4fa6
SS
289{
290}
291
292static void
0fff5247 293go32_attach (char *args ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
e49d4fa6 294{
53a5351d
JM
295 error ("\
296You cannot attach to a running program on this platform.\n\
297Use the `run' command to run DJGPP programs.");
e49d4fa6
SS
298}
299
300static void
0fff5247 301go32_detach (char *args ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
e49d4fa6
SS
302{
303}
304
305static int resume_is_step;
53a5351d 306static int resume_signal = -1;
e49d4fa6
SS
307
308static void
0fff5247 309go32_resume (int pid ATTRIBUTE_UNUSED, int step, enum target_signal siggnal)
c5aa993b 310{
53a5351d
JM
311 int i;
312
c5aa993b 313 resume_is_step = step;
53a5351d
JM
314
315 if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
316 {
0fff5247
EZ
317 for (i = 0, resume_signal = -1;
318 excepn_map[i].gdb_sig != TARGET_SIGNAL_LAST; i++)
53a5351d
JM
319 if (excepn_map[i].gdb_sig == siggnal)
320 {
321 resume_signal = excepn_map[i].djgpp_excepno;
322 break;
323 }
324 if (resume_signal == -1)
325 printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
326 target_signal_to_name (siggnal));
327 }
c5aa993b 328}
e49d4fa6 329
53a5351d
JM
330static char child_cwd[FILENAME_MAX];
331
e49d4fa6 332static int
0fff5247 333go32_wait (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *status)
e49d4fa6
SS
334{
335 int i;
53a5351d 336 unsigned char saved_opcode;
0fff5247 337 unsigned long INT3_addr = 0;
53a5351d 338 int stepping_over_INT = 0;
e49d4fa6 339
53a5351d 340 a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */
e49d4fa6 341 if (resume_is_step)
53a5351d
JM
342 {
343 /* If the next instruction is INT xx or INTO, we need to handle
344 them specially. Intel manuals say that these instructions
345 reset the single-step flag (a.k.a. TF). However, it seems
346 that, at least in the DPMI environment, and at least when
347 stepping over the DPMI interrupt 31h, the problem is having
348 TF set at all when INT 31h is executed: the debuggee either
349 crashes (and takes the system with it) or is killed by a
350 SIGTRAP.
351
352 So we need to emulate single-step mode: we put an INT3 opcode
353 right after the INT xx instruction, let the debuggee run
354 until it hits INT3 and stops, then restore the original
355 instruction which we overwrote with the INT3 opcode, and back
356 up the debuggee's EIP to that instruction. */
357 read_child (a_tss.tss_eip, &saved_opcode, 1);
358 if (saved_opcode == 0xCD || saved_opcode == 0xCE)
359 {
360 unsigned char INT3_opcode = 0xCC;
361
362 INT3_addr
363 = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
364 stepping_over_INT = 1;
365 read_child (INT3_addr, &saved_opcode, 1);
366 write_child (INT3_addr, &INT3_opcode, 1);
367 }
368 else
369 a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
370 }
371
372 /* The special value FFFFh in tss_trap indicates to run_child that
373 tss_irqn holds a signal to be delivered to the debuggee. */
374 if (resume_signal <= -1)
375 {
376 a_tss.tss_trap = 0;
377 a_tss.tss_irqn = 0xff;
378 }
e49d4fa6 379 else
53a5351d
JM
380 {
381 a_tss.tss_trap = 0xffff; /* run_child looks for this */
382 a_tss.tss_irqn = resume_signal;
383 }
384
385 /* The child might change working directory behind our back. The
386 GDB users won't like the side effects of that when they work with
387 relative file names, and GDB might be confused by its current
388 directory not being in sync with the truth. So we always make a
389 point of changing back to where GDB thinks is its cwd, when we
390 return control to the debugger, but restore child's cwd before we
391 run it. */
3a45aed8
EZ
392 /* Initialize child_cwd, before the first call to run_child and not
393 in the initialization, so the child get also the changed directory
394 set with the gdb-command "cd ..." */
395 if (!*child_cwd)
396 /* Initialize child's cwd with the current one. */
397 getcwd (child_cwd, sizeof (child_cwd));
398
53a5351d 399 chdir (child_cwd);
e49d4fa6 400
b83266a0 401#if __DJGPP_MINOR__ < 3
53a5351d 402 load_npx ();
b83266a0 403#endif
e49d4fa6 404 run_child ();
b83266a0 405#if __DJGPP_MINOR__ < 3
53a5351d 406 save_npx ();
b83266a0 407#endif
e49d4fa6 408
53a5351d
JM
409 /* Did we step over an INT xx instruction? */
410 if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
411 {
412 /* Restore the original opcode. */
413 a_tss.tss_eip--; /* EIP points *after* the INT3 instruction */
414 write_child (a_tss.tss_eip, &saved_opcode, 1);
415 /* Simulate a TRAP exception. */
416 a_tss.tss_irqn = 1;
417 a_tss.tss_eflags |= 0x0100;
418 }
419
420 getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
421 chdir (current_directory);
422
e49d4fa6
SS
423 if (a_tss.tss_irqn == 0x21)
424 {
425 status->kind = TARGET_WAITKIND_EXITED;
426 status->value.integer = a_tss.tss_eax & 0xff;
427 }
428 else
429 {
430 status->value.sig = TARGET_SIGNAL_UNKNOWN;
431 status->kind = TARGET_WAITKIND_STOPPED;
432 for (i = 0; sig_map[i].go32_sig != -1; i++)
433 {
434 if (a_tss.tss_irqn == sig_map[i].go32_sig)
435 {
53a5351d 436#if __DJGPP_MINOR__ < 3
e49d4fa6
SS
437 if ((status->value.sig = sig_map[i].gdb_sig) !=
438 TARGET_SIGNAL_TRAP)
439 status->kind = TARGET_WAITKIND_SIGNALLED;
53a5351d
JM
440#else
441 status->value.sig = sig_map[i].gdb_sig;
442#endif
e49d4fa6
SS
443 break;
444 }
445 }
446 }
447 return SOME_PID;
448}
449
450static void
451go32_fetch_registers (int regno)
452{
c5aa993b 453 /*JHW */
e49d4fa6
SS
454 int end_reg = regno + 1; /* just one reg initially */
455
456 if (regno < 0) /* do the all registers */
457 {
458 regno = 0; /* start at first register */
459 /* # regs in table */
460 end_reg = sizeof (regno_mapping) / sizeof (regno_mapping[0]);
461 }
462
463 for (; regno < end_reg; regno++)
464 {
465 if (regno < 16)
466 supply_register (regno,
467 (char *) &a_tss + regno_mapping[regno].tss_ofs);
468 else if (regno < 24)
469 supply_register (regno,
470 (char *) &npx.reg[regno_mapping[regno].tss_ofs]);
0fff5247
EZ
471 else if (regno < 32)
472 {
473 unsigned regval;
474
475 switch (regno_mapping[regno].size)
476 {
477 case 2:
478 regval = *(unsigned short *)
479 ((char *) &npx + regno_mapping[regno].tss_ofs);
480 regval &= 0xffff;
481 if (regno == FOP_REGNUM && regval)
482 /* Feature: restore the 5 bits of the opcode
483 stripped by FSAVE/FNSAVE. */
484 regval |= 0xd800;
485 break;
486 case 4:
487 regval = *(unsigned *)
488 ((char *) &npx + regno_mapping[regno].tss_ofs);
489 break;
490 default:
491 internal_error ("\
492Invalid native size for register no. %d in go32_fetch_register.", regno);
493 }
494 supply_register (regno, (char *) &regval);
495 }
e49d4fa6 496 else
4ce44c66
JM
497 internal_error ("Invalid register no. %d in go32_fetch_register.",
498 regno);
e49d4fa6
SS
499 }
500}
501
502static void
503store_register (int regno)
504{
505 void *rp;
506 void *v = (void *) &registers[REGISTER_BYTE (regno)];
507
508 if (regno < 16)
509 rp = (char *) &a_tss + regno_mapping[regno].tss_ofs;
510 else if (regno < 24)
511 rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs];
0fff5247 512 else if (regno < 32)
e49d4fa6
SS
513 rp = (char *) &npx + regno_mapping[regno].tss_ofs;
514 else
4ce44c66 515 internal_error ("Invalid register no. %d in store_register.", regno);
e49d4fa6 516 memcpy (rp, v, regno_mapping[regno].size);
0fff5247
EZ
517 if (regno == FOP_REGNUM)
518 *(short *)rp &= 0x07ff; /* strip high 5 bits, in case they added them */
e49d4fa6
SS
519}
520
521static void
522go32_store_registers (int regno)
523{
0fff5247 524 unsigned r;
e49d4fa6
SS
525
526 if (regno >= 0)
527 store_register (regno);
528 else
529 {
530 for (r = 0; r < sizeof (regno_mapping) / sizeof (regno_mapping[0]); r++)
531 store_register (r);
532 }
533}
534
535static void
536go32_prepare_to_store (void)
537{
538}
539
540static int
541go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
0fff5247 542 struct target_ops *target ATTRIBUTE_UNUSED)
e49d4fa6
SS
543{
544 if (write)
545 {
546 if (write_child (memaddr, myaddr, len))
547 {
548 return 0;
549 }
550 else
551 {
552 return len;
553 }
554 }
555 else
556 {
557 if (read_child (memaddr, myaddr, len))
558 {
559 return 0;
560 }
561 else
562 {
563 return len;
564 }
565 }
566}
567
53a5351d
JM
568static cmdline_t child_cmd; /* parsed child's command line kept here */
569
e49d4fa6 570static void
0fff5247 571go32_files_info (struct target_ops *target ATTRIBUTE_UNUSED)
e49d4fa6 572{
53a5351d 573 printf_unfiltered ("You are running a DJGPP V2 program.\n");
e49d4fa6
SS
574}
575
576static void
577go32_stop (void)
578{
579 normal_stop ();
580 cleanup_client ();
581 inferior_pid = 0;
582 prog_has_started = 0;
583}
584
585static void
586go32_kill_inferior (void)
587{
53a5351d
JM
588 redir_cmdline_delete (&child_cmd);
589 resume_signal = -1;
590 resume_is_step = 0;
e49d4fa6
SS
591 unpush_target (&go32_ops);
592}
593
594static void
595go32_create_inferior (char *exec_file, char *args, char **env)
596{
597 jmp_buf start_state;
598 char *cmdline;
599 char **env_save = environ;
600
0fff5247
EZ
601 /* If no exec file handed to us, get it from the exec-file command -- with
602 a good, common error message if none is specified. */
603 if (exec_file == 0)
604 exec_file = get_exec_file (1);
605
e49d4fa6
SS
606 if (prog_has_started)
607 {
b83266a0 608 go32_stop ();
e49d4fa6
SS
609 go32_kill_inferior ();
610 }
53a5351d
JM
611 resume_signal = -1;
612 resume_is_step = 0;
3a45aed8
EZ
613
614 /* Initialize child's cwd as empty to be initialized when starting
615 the child. */
616 *child_cwd = 0;
617
53a5351d
JM
618 /* Init command line storage. */
619 if (redir_debug_init (&child_cmd) == -1)
4ce44c66 620 internal_error ("Cannot allocate redirection storage: not enough memory.\n");
53a5351d
JM
621
622 /* Parse the command line and create redirections. */
623 if (strpbrk (args, "<>"))
624 {
625 if (redir_cmdline_parse (args, &child_cmd) == 0)
626 args = child_cmd.command;
627 else
628 error ("Syntax error in command line.");
629 }
630 else
c2d11a7d 631 child_cmd.command = xstrdup (args);
e49d4fa6
SS
632
633 cmdline = (char *) alloca (strlen (args) + 4);
634 cmdline[0] = strlen (args);
635 strcpy (cmdline + 1, args);
636 cmdline[strlen (args) + 1] = 13;
637
638 environ = env;
639
640 if (v2loadimage (exec_file, cmdline, start_state))
641 {
642 environ = env_save;
643 printf_unfiltered ("Load failed for image %s\n", exec_file);
644 exit (1);
645 }
646 environ = env_save;
647
648 edi_init (start_state);
53a5351d
JM
649#if __DJGPP_MINOR__ < 3
650 save_npx ();
651#endif
e49d4fa6
SS
652
653 inferior_pid = SOME_PID;
654 push_target (&go32_ops);
655 clear_proceed_status ();
656 insert_breakpoints ();
2acceee2 657 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
b83266a0 658 prog_has_started = 1;
e49d4fa6
SS
659}
660
661static void
662go32_mourn_inferior (void)
663{
53a5351d
JM
664 /* We need to make sure all the breakpoint enable bits in the DR7
665 register are reset when the inferior exits. Otherwise, if they
666 rerun the inferior, the uncleared bits may cause random SIGTRAPs,
667 failure to set more watchpoints, and other calamities. It would
668 be nice if GDB itself would take care to remove all breakpoints
669 at all times, but it doesn't, probably under an assumption that
670 the OS cleans up when the debuggee exits. */
671 cleanup_dregs ();
e49d4fa6
SS
672 go32_kill_inferior ();
673 generic_mourn_inferior ();
674}
675
676static int
677go32_can_run (void)
678{
679 return 1;
680}
681
e49d4fa6
SS
682/* Hardware watchpoint support. */
683
684#define DR_STATUS 6
685#define DR_CONTROL 7
686#define DR_ENABLE_SIZE 2
687#define DR_LOCAL_ENABLE_SHIFT 0
688#define DR_GLOBAL_ENABLE_SHIFT 1
689#define DR_LOCAL_SLOWDOWN 0x100
690#define DR_GLOBAL_SLOWDOWN 0x200
691#define DR_CONTROL_SHIFT 16
692#define DR_CONTROL_SIZE 4
53a5351d 693#define DR_RW_READWRITE 0x3
e49d4fa6
SS
694#define DR_RW_WRITE 0x1
695#define DR_CONTROL_MASK 0xf
696#define DR_ENABLE_MASK 0x3
697#define DR_LEN_1 0x0
698#define DR_LEN_2 0x4
699#define DR_LEN_4 0xc
700
701#define D_REGS edi.dr
702#define CONTROL D_REGS[DR_CONTROL]
703#define STATUS D_REGS[DR_STATUS]
704
705#define IS_REG_FREE(index) \
53a5351d 706 (!(CONTROL & (3 << (DR_ENABLE_SIZE * (index)))))
e49d4fa6
SS
707
708#define LOCAL_ENABLE_REG(index) \
53a5351d 709 (CONTROL |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
710
711#define GLOBAL_ENABLE_REG(index) \
53a5351d 712 (CONTROL |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
713
714#define DISABLE_REG(index) \
53a5351d 715 (CONTROL &= ~(3 << (DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
716
717#define SET_LOCAL_EXACT() \
718 (CONTROL |= DR_LOCAL_SLOWDOWN)
719
720#define SET_GLOBAL_EXACT() \
721 (CONTROL |= DR_GLOBAL_SLOWDOWN)
722
53a5351d
JM
723#define RESET_LOCAL_EXACT() \
724 (CONTROL &= ~(DR_LOCAL_SLOWDOWN))
725
726#define RESET_GLOBAL_EXACT() \
727 (CONTROL &= ~(DR_GLOBAL_SLOWDOWN))
728
e49d4fa6
SS
729#define SET_BREAK(index,address) \
730 do {\
53a5351d 731 CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index)));\
e49d4fa6 732 D_REGS[index] = address;\
c2c6d25f 733 dr_ref_count[index]++;\
e49d4fa6
SS
734 } while(0)
735
736#define SET_WATCH(index,address,rw,len) \
737 do {\
738 SET_BREAK(index,address);\
53a5351d 739 CONTROL |= ((len)|(rw)) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index));\
e49d4fa6
SS
740 } while (0)
741
53a5351d
JM
742#define IS_WATCH(index) \
743 (CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE*(index))))
744
c2c6d25f 745#define WATCH_HIT(index) ((STATUS & (1 << (index))) && IS_WATCH(index))
e49d4fa6 746
53a5351d
JM
747#define DR_DEF(index) \
748 ((CONTROL >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index))) & 0x0f)
749
750
751#if 0 /* use debugging macro */
752#define SHOW_DR(text,len) \
e49d4fa6 753do { \
53a5351d 754 if (!getenv ("GDB_SHOW_DR")) break; \
e49d4fa6 755 fprintf(stderr,"%08x %08x ",edi.dr[7],edi.dr[6]); \
53a5351d
JM
756 fprintf(stderr,"%08x %d %08x %d ", \
757 edi.dr[0],dr_ref_count[0],edi.dr[1],dr_ref_count[1]); \
758 fprintf(stderr,"%08x %d %08x %d ", \
759 edi.dr[2],dr_ref_count[2],edi.dr[3],dr_ref_count[3]); \
760 fprintf(stderr,(len)?"(%s:%d)\n":"(%s)\n",#text,len); \
e49d4fa6
SS
761} while (0)
762#else
53a5351d 763#define SHOW_DR(text,len) do {} while (0)
e49d4fa6
SS
764#endif
765
53a5351d
JM
766static void
767cleanup_dregs (void)
768{
769 int i;
770
771 CONTROL = 0;
772 STATUS = 0;
773 for (i = 0; i < 4; i++)
774 {
775 D_REGS[i] = 0;
776 dr_ref_count[i] = 0;
777 }
778}
779
e49d4fa6
SS
780/* Insert a watchpoint. */
781
782int
0fff5247
EZ
783go32_insert_watchpoint (int pid ATTRIBUTE_UNUSED, CORE_ADDR addr,
784 int len, int rw)
e49d4fa6 785{
53a5351d 786 int ret = go32_insert_aligned_watchpoint (addr, addr, len, rw);
e49d4fa6 787
53a5351d 788 SHOW_DR (insert_watch, len);
e49d4fa6
SS
789 return ret;
790}
791
792static int
53a5351d 793go32_insert_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
e49d4fa6
SS
794 int len, int rw)
795{
796 int i;
797 int read_write_bits, len_bits;
798
53a5351d
JM
799 /* Values of rw: 0 - write, 1 - read, 2 - access (read and write).
800 However, x86 doesn't support read-only data breakpoints. */
801 read_write_bits = rw ? DR_RW_READWRITE : DR_RW_WRITE;
802
803 switch (len)
804 {
805 case 4:
806 len_bits = DR_LEN_4;
807 break;
808 case 2:
809 len_bits = DR_LEN_2;
810 break;
811 case 1:
812 len_bits = DR_LEN_1;
813 break;
814 default:
815 /* The debug registers only have 2 bits for the length, so
816 so this value will always fail the loop below. */
817 len_bits = 0x10;
818 }
819
820 /* Look for an occupied debug register with the same address and the
821 same RW and LEN definitions. If we find one, we can use it for
822 this watchpoint as well (and save a register). */
823 for (i = 0; i < 4; i++)
824 {
825 if (!IS_REG_FREE (i) && D_REGS[i] == addr
0fff5247 826 && DR_DEF (i) == (unsigned)(len_bits | read_write_bits))
e49d4fa6 827 {
53a5351d
JM
828 dr_ref_count[i]++;
829 return 0;
e49d4fa6 830 }
53a5351d
JM
831 }
832
833 /* Look for a free debug register. */
834 for (i = 0; i <= 3; i++)
835 {
836 if (IS_REG_FREE (i))
837 break;
838 }
e49d4fa6
SS
839
840 /* No more debug registers! */
841 if (i > 3)
842 return -1;
843
53a5351d
JM
844 if (len == 2)
845 {
846 if (addr % 2)
847 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr,
848 len, rw);
849 }
e49d4fa6 850 else if (len == 4)
53a5351d
JM
851 {
852 if (addr % 4)
853 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr,
854 len, rw);
855 }
856 else if (len != 1)
857 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr, len, rw);
e49d4fa6
SS
858
859 SET_WATCH (i, addr, read_write_bits, len_bits);
860 LOCAL_ENABLE_REG (i);
861 SET_LOCAL_EXACT ();
53a5351d
JM
862 SET_GLOBAL_EXACT ();
863 return 0;
e49d4fa6
SS
864}
865
866static int
53a5351d 867go32_handle_nonaligned_watchpoint (wp_op what, CORE_ADDR waddr, CORE_ADDR addr,
e49d4fa6
SS
868 int len, int rw)
869{
870 int align;
871 int size;
53a5351d 872 int rv = 0, status = 0;
e49d4fa6 873
184a103e 874 static int size_try_array[4][4] =
e49d4fa6 875 {
184a103e
EZ
876 { 1, 1, 1, 1 }, /* trying size one */
877 { 2, 1, 2, 1 }, /* trying size two */
878 { 2, 1, 2, 1 }, /* trying size three */
879 { 4, 1, 2, 1 } /* trying size four */
e49d4fa6
SS
880 };
881
882 while (len > 0)
883 {
884 align = addr % 4;
184a103e
EZ
885 /* Four is the maximum length a 386 debug register can watch. */
886 size = size_try_array[len > 4 ? 3 : len - 1][align];
53a5351d
JM
887 if (what == wp_insert)
888 status = go32_insert_aligned_watchpoint (waddr, addr, size, rw);
889 else if (what == wp_remove)
890 status = go32_remove_aligned_watchpoint (waddr, addr, size, rw);
891 else if (what == wp_count)
892 rv++;
893 else
d03cef9d 894 status = EINVAL;
53a5351d
JM
895 /* We keep the loop going even after a failure, because some of
896 the other aligned watchpoints might still succeed, e.g. if
897 they watch addresses that are already watched, and thus just
898 increment the reference counts of occupied debug registers.
899 If we break out of the loop too early, we could cause those
900 addresses watched by other watchpoints to be disabled when
901 GDB reacts to our failure to insert this watchpoint and tries
902 to remove it. */
903 if (status)
904 rv = status;
e49d4fa6
SS
905 addr += size;
906 len -= size;
907 }
908 return rv;
909}
910
911/* Remove a watchpoint. */
912
913int
0fff5247
EZ
914go32_remove_watchpoint (int pid ATTRIBUTE_UNUSED, CORE_ADDR addr,
915 int len, int rw)
53a5351d
JM
916{
917 int ret = go32_remove_aligned_watchpoint (addr, addr, len, rw);
918
919 SHOW_DR (remove_watch, len);
920 return ret;
921}
922
923static int
924go32_remove_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
925 int len, int rw)
e49d4fa6
SS
926{
927 int i;
53a5351d
JM
928 int read_write_bits, len_bits;
929
930 /* Values of rw: 0 - write, 1 - read, 2 - access (read and write).
931 However, x86 doesn't support read-only data breakpoints. */
932 read_write_bits = rw ? DR_RW_READWRITE : DR_RW_WRITE;
933
934 switch (len)
935 {
936 case 4:
937 len_bits = DR_LEN_4;
938 break;
939 case 2:
940 len_bits = DR_LEN_2;
941 break;
942 case 1:
943 len_bits = DR_LEN_1;
944 break;
945 default:
946 /* The debug registers only have 2 bits for the length, so
947 so this value will always fail the loop below. */
948 len_bits = 0x10;
949 }
950
951 if (len == 2)
952 {
953 if (addr % 2)
954 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr,
955 len, rw);
956 }
957 else if (len == 4)
958 {
959 if (addr % 4)
960 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr,
961 len, rw);
962 }
963 else if (len != 1)
964 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr, len, rw);
e49d4fa6
SS
965
966 for (i = 0; i <= 3; i++)
967 {
53a5351d 968 if (!IS_REG_FREE (i) && D_REGS[i] == addr
0fff5247 969 && DR_DEF (i) == (unsigned)(len_bits | read_write_bits))
e49d4fa6 970 {
53a5351d
JM
971 dr_ref_count[i]--;
972 if (dr_ref_count[i] == 0)
973 DISABLE_REG (i);
e49d4fa6
SS
974 }
975 }
53a5351d
JM
976 RESET_LOCAL_EXACT ();
977 RESET_GLOBAL_EXACT ();
e49d4fa6
SS
978
979 return 0;
980}
981
53a5351d
JM
982/* Can we use debug registers to watch a region whose address is ADDR
983 and whose length is LEN bytes? */
984
985int
986go32_region_ok_for_watchpoint (CORE_ADDR addr, int len)
987{
988 /* Compute how many aligned watchpoints we would need to cover this
989 region. */
990 int nregs = go32_handle_nonaligned_watchpoint (wp_count, addr, addr, len, 0);
991
992 return nregs <= 4 ? 1 : 0;
993}
994
995/* Check if stopped by a data watchpoint. If so, return the address
996 whose access triggered the watchpoint. */
e49d4fa6
SS
997
998CORE_ADDR
0fff5247 999go32_stopped_by_watchpoint (int pid ATTRIBUTE_UNUSED, int data_watchpoint)
e49d4fa6
SS
1000{
1001 int i, ret = 0;
1002 int status;
1003
1004 status = edi.dr[DR_STATUS];
53a5351d 1005 SHOW_DR (stopped_by, 0);
e49d4fa6
SS
1006 for (i = 0; i <= 3; i++)
1007 {
53a5351d 1008 if (WATCH_HIT (i) && data_watchpoint)
e49d4fa6 1009 {
53a5351d 1010 SHOW_DR (WP_HIT, 0);
e49d4fa6
SS
1011 ret = D_REGS[i];
1012 }
1013 }
e49d4fa6
SS
1014
1015 return ret;
1016}
1017
1018/* Remove a breakpoint. */
1019
1020int
0fff5247 1021go32_remove_hw_breakpoint (CORE_ADDR addr, void *shadow ATTRIBUTE_UNUSED)
e49d4fa6
SS
1022{
1023 int i;
1024 for (i = 0; i <= 3; i++)
1025 {
53a5351d 1026 if (!IS_REG_FREE (i) && D_REGS[i] == addr && DR_DEF (i) == 0)
e49d4fa6 1027 {
53a5351d
JM
1028 dr_ref_count[i]--;
1029 if (dr_ref_count[i] == 0)
1030 DISABLE_REG (i);
e49d4fa6
SS
1031 }
1032 }
53a5351d 1033 SHOW_DR (remove_hw, 0);
e49d4fa6
SS
1034 return 0;
1035}
1036
1037int
0fff5247 1038go32_insert_hw_breakpoint (CORE_ADDR addr, void *shadow ATTRIBUTE_UNUSED)
e49d4fa6
SS
1039{
1040 int i;
e49d4fa6 1041
53a5351d
JM
1042 /* Look for an occupied debug register with the same address and the
1043 same RW and LEN definitions. If we find one, we can use it for
1044 this breakpoint as well (and save a register). */
1045 for (i = 0; i < 4; i++)
1046 {
1047 if (!IS_REG_FREE (i) && D_REGS[i] == addr && DR_DEF (i) == 0)
1048 {
1049 dr_ref_count[i]++;
1050 SHOW_DR (insert_hw, 0);
1051 return 0;
1052 }
1053 }
1054
e49d4fa6
SS
1055 /* Look for a free debug register. */
1056 for (i = 0; i <= 3; i++)
1057 {
1058 if (IS_REG_FREE (i))
1059 break;
1060 }
1061
53a5351d
JM
1062 /* No more debug registers? */
1063 if (i < 4)
1064 {
1065 SET_BREAK (i, addr);
1066 LOCAL_ENABLE_REG (i);
1067 }
1068 SHOW_DR (insert_hw, 0);
e49d4fa6 1069
d03cef9d 1070 return i < 4 ? 0 : EBUSY;
e49d4fa6
SS
1071}
1072
53a5351d
JM
1073/* Put the device open on handle FD into either raw or cooked
1074 mode, return 1 if it was in raw mode, zero otherwise. */
1075
1076static int
1077device_mode (int fd, int raw_p)
1078{
1079 int oldmode, newmode;
1080 __dpmi_regs regs;
1081
1082 regs.x.ax = 0x4400;
1083 regs.x.bx = fd;
1084 __dpmi_int (0x21, &regs);
1085 if (regs.x.flags & 1)
1086 return -1;
1087 newmode = oldmode = regs.x.dx;
1088
1089 if (raw_p)
1090 newmode |= 0x20;
1091 else
1092 newmode &= ~0x20;
1093
1094 if (oldmode & 0x80) /* Only for character dev */
1095 {
1096 regs.x.ax = 0x4401;
1097 regs.x.bx = fd;
1098 regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
1099 __dpmi_int (0x21, &regs);
1100 if (regs.x.flags & 1)
1101 return -1;
1102 }
1103 return (oldmode & 0x20) == 0x20;
1104}
1105
1106
1107static int inf_mode_valid = 0;
1108static int inf_terminal_mode;
1109
1110/* This semaphore is needed because, amazingly enough, GDB calls
1111 target.to_terminal_ours more than once after the inferior stops.
1112 But we need the information from the first call only, since the
1113 second call will always see GDB's own cooked terminal. */
1114static int terminal_is_ours = 1;
1115
cce74817
JM
1116static void
1117go32_terminal_init (void)
1118{
53a5351d
JM
1119 inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
1120 terminal_is_ours = 1;
cce74817
JM
1121}
1122
1123static void
0fff5247 1124go32_terminal_info (char *args ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
cce74817 1125{
53a5351d
JM
1126 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
1127 !inf_mode_valid
1128 ? "default" : inf_terminal_mode ? "raw" : "cooked");
1129
1130#if __DJGPP_MINOR__ > 2
1131 if (child_cmd.redirection)
1132 {
1133 int i;
1134
1135 for (i = 0; i < DBG_HANDLES; i++)
c5aa993b 1136 {
53a5351d
JM
1137 if (child_cmd.redirection[i]->file_name)
1138 printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
1139 i, child_cmd.redirection[i]->file_name);
1140 else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
1141 printf_unfiltered
1142 ("\tFile handle %d appears to be closed by inferior.\n", i);
1143 /* Mask off the raw/cooked bit when comparing device info words. */
1144 else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
1145 != (_get_dev_info (i) & 0xdf))
1146 printf_unfiltered
1147 ("\tFile handle %d appears to be redirected by inferior.\n", i);
c5aa993b 1148 }
53a5351d
JM
1149 }
1150#endif
1151}
1152
1153static void
1154go32_terminal_inferior (void)
1155{
1156 /* Redirect standard handles as child wants them. */
1157 errno = 0;
1158 if (redir_to_child (&child_cmd) == -1)
1159 {
1160 redir_to_debugger (&child_cmd);
1161 error ("Cannot redirect standard handles for program: %s.",
1162 strerror (errno));
1163 }
1164 /* set the console device of the inferior to whatever mode
1165 (raw or cooked) we found it last time */
1166 if (terminal_is_ours)
1167 {
1168 if (inf_mode_valid)
1169 device_mode (0, inf_terminal_mode);
1170 terminal_is_ours = 0;
1171 }
cce74817
JM
1172}
1173
1174static void
1175go32_terminal_ours (void)
1176{
53a5351d
JM
1177 /* Switch to cooked mode on the gdb terminal and save the inferior
1178 terminal mode to be restored when it is resumed */
1179 if (!terminal_is_ours)
1180 {
1181 inf_terminal_mode = device_mode (0, 0);
1182 if (inf_terminal_mode != -1)
1183 inf_mode_valid = 1;
1184 else
1185 /* If device_mode returned -1, we don't know what happens with
1186 handle 0 anymore, so make the info invalid. */
1187 inf_mode_valid = 0;
1188 terminal_is_ours = 1;
1189
1190 /* Restore debugger's standard handles. */
1191 errno = 0;
1192 if (redir_to_debugger (&child_cmd) == -1)
1193 {
1194 redir_to_child (&child_cmd);
1195 error ("Cannot redirect standard handles for debugger: %s.",
1196 strerror (errno));
1197 }
1198 }
cce74817
JM
1199}
1200
e49d4fa6
SS
1201static void
1202init_go32_ops (void)
1203{
1204 go32_ops.to_shortname = "djgpp";
1205 go32_ops.to_longname = "djgpp target process";
1206 go32_ops.to_doc =
1207 "Program loaded by djgpp, when gdb is used as an external debugger";
1208 go32_ops.to_open = go32_open;
1209 go32_ops.to_close = go32_close;
53a5351d 1210 go32_ops.to_attach = go32_attach;
e49d4fa6
SS
1211 go32_ops.to_detach = go32_detach;
1212 go32_ops.to_resume = go32_resume;
1213 go32_ops.to_wait = go32_wait;
1214 go32_ops.to_fetch_registers = go32_fetch_registers;
1215 go32_ops.to_store_registers = go32_store_registers;
1216 go32_ops.to_prepare_to_store = go32_prepare_to_store;
1217 go32_ops.to_xfer_memory = go32_xfer_memory;
1218 go32_ops.to_files_info = go32_files_info;
1219 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
1220 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
cce74817
JM
1221 go32_ops.to_terminal_init = go32_terminal_init;
1222 go32_ops.to_terminal_inferior = go32_terminal_inferior;
53a5351d 1223 go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
cce74817 1224 go32_ops.to_terminal_ours = go32_terminal_ours;
53a5351d 1225 go32_ops.to_terminal_info = go32_terminal_info;
e49d4fa6
SS
1226 go32_ops.to_kill = go32_kill_inferior;
1227 go32_ops.to_create_inferior = go32_create_inferior;
1228 go32_ops.to_mourn_inferior = go32_mourn_inferior;
1229 go32_ops.to_can_run = go32_can_run;
1230 go32_ops.to_stop = go32_stop;
1231 go32_ops.to_stratum = process_stratum;
1232 go32_ops.to_has_all_memory = 1;
1233 go32_ops.to_has_memory = 1;
1234 go32_ops.to_has_stack = 1;
1235 go32_ops.to_has_registers = 1;
1236 go32_ops.to_has_execution = 1;
1237 go32_ops.to_magic = OPS_MAGIC;
53a5351d 1238
3a45aed8
EZ
1239 /* Initialize child's cwd as empty to be initialized when starting
1240 the child. */
1241 *child_cwd = 0;
53a5351d
JM
1242
1243 /* Initialize child's command line storage. */
1244 if (redir_debug_init (&child_cmd) == -1)
4ce44c66 1245 internal_error ("Cannot allocate redirection storage: not enough memory.\n");
0fff5247
EZ
1246
1247 /* We are always processing GCC-compiled programs. */
1248 processing_gcc_compilation = 2;
e49d4fa6
SS
1249}
1250
1251void
1252_initialize_go32_nat (void)
1253{
1254 init_go32_ops ();
1255 add_target (&go32_ops);
1256}
53a5351d
JM
1257
1258pid_t
1259tcgetpgrp (int fd)
1260{
1261 if (isatty (fd))
1262 return SOME_PID;
1263 errno = ENOTTY;
1264 return -1;
1265}
1266
1267int
1268tcsetpgrp (int fd, pid_t pgid)
1269{
1270 if (isatty (fd) && pgid == SOME_PID)
1271 return 0;
1272 errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
1273 return -1;
1274}
This page took 0.122271 seconds and 4 git commands to generate.