1130812Smarcel/* A client to make GDB return to command level in Mach 3.
2130812Smarcel   Copyright 1992, 1993, 1994, 2000 Free Software Foundation, Inc.
3130812Smarcel
4130812Smarcel   This file is part of GDB.
5130812Smarcel
6130812Smarcel   This program is free software; you can redistribute it and/or modify
7130812Smarcel   it under the terms of the GNU General Public License as published by
8130812Smarcel   the Free Software Foundation; either version 2 of the License, or
9130812Smarcel   (at your option) any later version.
10130812Smarcel
11130812Smarcel   This program is distributed in the hope that it will be useful,
12130812Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
13130812Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14130812Smarcel   GNU General Public License for more details.
15130812Smarcel
16130812Smarcel   You should have received a copy of the GNU General Public License
17130812Smarcel   along with this program; if not, write to the Free Software
18130812Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
19130812Smarcel   Boston, MA 02111-1307, USA.  */
20130812Smarcel
21130812Smarcel/* Authors: Jukka Virtanen <jtv@hut.fi> and Peter Stout <pds@cs.cmu.edu>.
22130812Smarcel
23130812Smarcel   A simple client to make GDB (versions 4.4 and later) on Mach 3 return
24130812Smarcel   to the command level when it is waiting for the inferior to stop.
25130812Smarcel
26130812Smarcel   Actions: Lookup the send right to the GDB message port from the
27130812Smarcel   NetMsgServer.
28130812Smarcel
29130812Smarcel   Send an asynchronous message with msgh_id
30130812Smarcel   GDB_MESSAGE_ID_STOP to that port.
31130812Smarcel */
32130812Smarcel
33130812Smarcel#include <stdio.h>
34130812Smarcel
35130812Smarcel#include "defs.h"
36130812Smarcel
37130812Smarcel#include <mach.h>
38130812Smarcel#include <mach/message.h>
39130812Smarcel#include <mach_error.h>
40130812Smarcel#include <servers/netname.h>
41130812Smarcel#include <servers/netname_defs.h>
42130812Smarcel
43130812Smarcelvoid
44130812Smarcelmain (int argc, char **argv)
45130812Smarcel{
46130812Smarcel  kern_return_t kr;
47130812Smarcel  mach_msg_header_t msg;
48130812Smarcel  mach_port_t gdb_port;
49130812Smarcel  char *host;
50130812Smarcel  char *name;
51130812Smarcel
52130812Smarcel  if (argc == 1)
53130812Smarcel    argv[argc++] = GDB_DEF_NAME;
54130812Smarcel
55130812Smarcel  if (argc != 2)
56130812Smarcel    {
57130812Smarcel      fprintf (stderr, "Usage : %s <GDB name>\n", argv[0]);
58130812Smarcel      exit (1);
59130812Smarcel    }
60130812Smarcel
61130812Smarcel  /* Allow the user to specify a remote host.  */
62130812Smarcel  host = strchr (argv[1], '@');
63130812Smarcel  if (host)
64130812Smarcel    *(host++) = '\0';
65130812Smarcel  else
66130812Smarcel    host = (char *) "";
67130812Smarcel
68130812Smarcel  name = malloc (strlen (argv[1]) + sizeof (GDB_NAME_PREFIX));
69130812Smarcel  if (name == NULL)
70130812Smarcel    {
71130812Smarcel      fprintf (stderr, "Unable to allocate memory for name.");
72130812Smarcel      exit (1);
73130812Smarcel    }
74130812Smarcel
75130812Smarcel  strcpy (name, GDB_NAME_PREFIX);
76130812Smarcel  strcat (name, argv[1]);
77130812Smarcel
78130812Smarcel  /* Look up the GDB service port.  For convenience, add the
79130812Smarcel     GDB_NAME_PREFIX the argument before looking up the name.
80130812Smarcel     For backwards compatibility, do it without.  */
81130812Smarcel
82130812Smarcel  kr = netname_look_up (name_server_port, host, name, &gdb_port);
83130812Smarcel  if (kr == NETNAME_NOT_CHECKED_IN)
84130812Smarcel    kr = netname_look_up (name_server_port, host, argv[1], &gdb_port);
85130812Smarcel  if (kr != KERN_SUCCESS)
86130812Smarcel    {
87130812Smarcel      fprintf (stderr, "Unable to lookup the GDB service port: %s.\n",
88130812Smarcel	       mach_error_string (kr));
89130812Smarcel      exit (1);
90130812Smarcel    }
91130812Smarcel
92130812Smarcel  /* Code generated by mig stub generator, with minor cleanups :-)
93130812Smarcel
94130812Smarcel     simpleroutine stop_inferior(gdb_port : mach_port_t);  */
95130812Smarcel
96130812Smarcel  msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
97130812Smarcel  msg.msgh_remote_port = gdb_port;
98130812Smarcel  msg.msgh_local_port = MACH_PORT_NULL;
99130812Smarcel  msg.msgh_size = sizeof (msg);
100130812Smarcel  msg.msgh_seqno = 0;
101130812Smarcel  msg.msgh_id = GDB_MESSAGE_ID_STOP;
102130812Smarcel
103130812Smarcel  kr = mach_msg_send (&msg);
104130812Smarcel  if (kr != KERN_SUCCESS)
105130812Smarcel    fprintf (stderr, "Message not sent, return code %d : %s\n", kr,
106130812Smarcel	     mach_error_string (kr));
107130812Smarcel
108130812Smarcel  exit (kr != KERN_SUCCESS);
109130812Smarcel}
110