diff options
Diffstat (limited to 'setedit/libmigdb/src/get_free_pty.c')
-rw-r--r-- | setedit/libmigdb/src/get_free_pty.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/setedit/libmigdb/src/get_free_pty.c b/setedit/libmigdb/src/get_free_pty.c new file mode 100644 index 0000000..8c145d0 --- /dev/null +++ b/setedit/libmigdb/src/get_free_pty.c @@ -0,0 +1,132 @@ +/**[txh]******************************************************************** + + Copyright (c) 2004 by Salvador E. Tropea. + Covered by the GPL license. + + Module: pseudo terminal + Comments: + Helper to find a free pseudo terminal. Use this if you need to manage + input *and* output to the target process. If you just need output then + define a handler for target output stream records (assuming that this + is working for your particular version of gdb). + Usage: + + mi_pty *pty = gmi_look_for_free_pty(); + if (pty) gmi_target_terminal(mih, pty->slave); + ... + * reading from pty->master will get stdout from target * + * writing to pty->master will send to target stdin * + + Note: Contributed by Greg Watson (gwatson lanl gov) + +***************************************************************************/ + +#define _GNU_SOURCE +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> + +#include "mi_gdb.h" + +/**[txh]******************************************************************** + + Description: + Look for a free and usable pseudo terminal. Low level, use +@x{gmi_look_for_free_pty}. + + Return: A file descriptor connected to the master pty and the name of the slave device, or <0 on error. + +***************************************************************************/ + +#ifdef __APPLE__ + +#include <util.h> + +int mi_look_for_free_pty(int *master, char **slave) +{ + int fdmaster; + int fdslave; + static char name[BUFSIZ]; + + if (openpty(&fdmaster,&fdslave,name,NULL,NULL)<0) + return -1; + + (void)close(fdslave); /* this will be reopened by gdb */ + *master=fdmaster; + *slave =name; + + return 0; +} + +#elif defined(__linux__) + +int mi_look_for_free_pty(int *master, char **slave) +{ + if ((*master=open("/dev/ptmx",O_RDWR))<0) + return -1; + if (grantpt(*master)<0 || unlockpt(*master)<0) + return -1; + *slave = ptsname(*master); + + return 0; +} + +#else /* undefined o/s */ + +int mi_look_for_free_pty(int *master, char **slave) +{ + return -1; +} +#endif + +/**[txh]******************************************************************** + + Description: + Look for a free and usable pseudo terminal to be used by the child. + + Return: A new mi_pty structure, you can use @x{gmi_end_pty} to +release it. + +***************************************************************************/ + +mi_pty *gmi_look_for_free_pty() +{ + int master; + char *slave; + int pty=mi_look_for_free_pty(&master,&slave); + mi_pty *res; + + if (pty<0) + return NULL; + res=(mi_pty *)malloc(sizeof(mi_pty)); + if (!res) + return NULL; + res->slave=strdup(slave); + res->master=master; + return res; +} + +void mi_free_pty(mi_pty *p) +{ + if (!p) + return; + free(p->slave); + free(p); +} + +/**[txh]******************************************************************** + + Description: + Closes the pseudo termial master and releases the allocated memory. + +***************************************************************************/ + +void gmi_end_pty(mi_pty *p) +{ + if (!p) + return; + close(p->master); + mi_free_pty(p); +} |