|  | /* A client to make GDB return to command level in Mach 3. | 
|  | Copyright (C) 1992, 1993, 1994, 2000 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GDB. | 
|  |  | 
|  | This program is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 2 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program; if not, write to the Free Software | 
|  | Foundation, Inc., 51 Franklin Street, Fifth Floor, | 
|  | Boston, MA 02110-1301, USA.  */ | 
|  |  | 
|  | /* Authors: Jukka Virtanen <jtv@hut.fi> and Peter Stout <pds@cs.cmu.edu>. | 
|  |  | 
|  | A simple client to make GDB (versions 4.4 and later) on Mach 3 return | 
|  | to the command level when it is waiting for the inferior to stop. | 
|  |  | 
|  | Actions: Lookup the send right to the GDB message port from the | 
|  | NetMsgServer. | 
|  |  | 
|  | Send an asynchronous message with msgh_id | 
|  | GDB_MESSAGE_ID_STOP to that port. | 
|  | */ | 
|  |  | 
|  | #include <stdio.h> | 
|  |  | 
|  | #include "defs.h" | 
|  |  | 
|  | #include <mach.h> | 
|  | #include <mach/message.h> | 
|  | #include <mach_error.h> | 
|  | #include <servers/netname.h> | 
|  | #include <servers/netname_defs.h> | 
|  |  | 
|  | void | 
|  | main (int argc, char **argv) | 
|  | { | 
|  | kern_return_t kr; | 
|  | mach_msg_header_t msg; | 
|  | mach_port_t gdb_port; | 
|  | char *host; | 
|  | char *name; | 
|  |  | 
|  | if (argc == 1) | 
|  | argv[argc++] = GDB_DEF_NAME; | 
|  |  | 
|  | if (argc != 2) | 
|  | { | 
|  | fprintf (stderr, "Usage : %s <GDB name>\n", argv[0]); | 
|  | exit (1); | 
|  | } | 
|  |  | 
|  | /* Allow the user to specify a remote host.  */ | 
|  | host = strchr (argv[1], '@'); | 
|  | if (host) | 
|  | *(host++) = '\0'; | 
|  | else | 
|  | host = (char *) ""; | 
|  |  | 
|  | name = malloc (strlen (argv[1]) + sizeof (GDB_NAME_PREFIX)); | 
|  | if (name == NULL) | 
|  | { | 
|  | fprintf (stderr, "Unable to allocate memory for name."); | 
|  | exit (1); | 
|  | } | 
|  |  | 
|  | strcpy (name, GDB_NAME_PREFIX); | 
|  | strcat (name, argv[1]); | 
|  |  | 
|  | /* Look up the GDB service port.  For convenience, add the | 
|  | GDB_NAME_PREFIX the argument before looking up the name. | 
|  | For backwards compatibility, do it without.  */ | 
|  |  | 
|  | kr = netname_look_up (name_server_port, host, name, &gdb_port); | 
|  | if (kr == NETNAME_NOT_CHECKED_IN) | 
|  | kr = netname_look_up (name_server_port, host, argv[1], &gdb_port); | 
|  | if (kr != KERN_SUCCESS) | 
|  | { | 
|  | fprintf (stderr, "Unable to lookup the GDB service port: %s.\n", | 
|  | mach_error_string (kr)); | 
|  | exit (1); | 
|  | } | 
|  |  | 
|  | /* Code generated by mig stub generator, with minor cleanups :-) | 
|  |  | 
|  | simpleroutine stop_inferior(gdb_port : mach_port_t);  */ | 
|  |  | 
|  | msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); | 
|  | msg.msgh_remote_port = gdb_port; | 
|  | msg.msgh_local_port = MACH_PORT_NULL; | 
|  | msg.msgh_size = sizeof (msg); | 
|  | msg.msgh_seqno = 0; | 
|  | msg.msgh_id = GDB_MESSAGE_ID_STOP; | 
|  |  | 
|  | kr = mach_msg_send (&msg); | 
|  | if (kr != KERN_SUCCESS) | 
|  | fprintf (stderr, "Message not sent, return code %d : %s\n", kr, | 
|  | mach_error_string (kr)); | 
|  |  | 
|  | exit (kr != KERN_SUCCESS); | 
|  | } |