mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Add support to create a pseudo master terminal for the debugger.
This commit is contained in:
parent
fe4c884ab4
commit
7edb51d4cc
13 changed files with 402 additions and 19 deletions
1
core/org.eclipse.cdt.core.linux/library/.cvsignore
Normal file
1
core/org.eclipse.cdt.core.linux/library/.cvsignore
Normal file
|
@ -0,0 +1 @@
|
|||
*.o
|
|
@ -5,14 +5,27 @@ JDK_INCLUDES=/usr/local/jdk/include
|
|||
JDK_OS_INCLUDES=/usr/local/jdk/include/linux
|
||||
|
||||
CC=gcc
|
||||
LIB_NAME = libspawner.so
|
||||
LIB_NAME_FULL = ../os/linux/x86/libspawner.so
|
||||
OBJS=spawner.o io.o exec_unix.o pfind.o
|
||||
CPPFLAGS = -I. -I$(JDK_INCLUDES) -I$(JDK_OS_INCLUDES)
|
||||
CFLAGS +=-fpic -D_REENTRANT
|
||||
|
||||
spawner : $(OBJS)
|
||||
$(CC) -g -shared -Wl,-soname,$(LIB_NAME) -o $(LIB_NAME_FULL) $(OBJS) -lc
|
||||
LIB_NAME_SPAWNER = libspawner.so
|
||||
LIB_NAME_FULL_SPAWNER = ../os/linux/x86/libspawner.so
|
||||
OBJS_SPAWNER=spawner.o io.o exec_unix.o pfind.o
|
||||
|
||||
LIB_NAME_PTY = libpty.so
|
||||
LIB_NAME_FULL_PTY = ../os/linux/x86/libpty.so
|
||||
OBJS_PTY= openpty.o pty.o ptyio.o
|
||||
|
||||
OBJS = $(OBJS_SPAWNER) $(OBJS_PTY)
|
||||
|
||||
all: $(LIB_NAME_FULL_SPAWNER) $(LIB_NAME_FULL_PTY)
|
||||
|
||||
$(LIB NAME_FULL_SPAWNER) : $(OBJS_SPAWNER)
|
||||
$(CC) -g -shared -Wl,-soname,$(LIB_NAME_SPAWNER) -o $(LIB_NAME_FULL_SPAWNER) $(OBJS_SPAWNER) -lc
|
||||
|
||||
$(LIB_NAME_FULL_PTY): $(OBJS_PTY)
|
||||
$(CC) -g -shared -Wl,-soname,$(LIB_NAME_PTY) -o $(LIB_NAME_FULL_PTY) $(OBJS_PTY)
|
||||
|
||||
clean :
|
||||
rm $(OBJS)
|
||||
echo -rm $(OBJS_SPAWNER) $(LIB_NAME_FULL_SPAWNER)
|
||||
-rm $(OBJS_PTY) $(LIB_NAME_FULL_PTY)
|
||||
|
|
21
core/org.eclipse.cdt.core.linux/library/PTY.h
Normal file
21
core/org.eclipse.cdt.core.linux/library/PTY.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class org_eclipse_cdt_utils_pty_PTY */
|
||||
|
||||
#ifndef _Included_org_eclipse_cdt_utils_pty_PTY
|
||||
#define _Included_org_eclipse_cdt_utils_pty_PTY
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTY
|
||||
* Method: forkpty
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_forkpty
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
32
core/org.eclipse.cdt.core.linux/library/PTYInputStream.h
Normal file
32
core/org.eclipse.cdt.core.linux/library/PTYInputStream.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class org_eclipse_cdt_utils_pty_PTYInputStream */
|
||||
|
||||
#ifndef _Included_org_eclipse_cdt_utils_pty_PTYInputStream
|
||||
#define _Included_org_eclipse_cdt_utils_pty_PTYInputStream
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#undef org_eclipse_cdt_utils_pty_PTYInputStream_SKIP_BUFFER_SIZE
|
||||
#define org_eclipse_cdt_utils_pty_PTYInputStream_SKIP_BUFFER_SIZE 2048L
|
||||
/* Inaccessible static: skipBuffer */
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTYInputStream
|
||||
* Method: read0
|
||||
* Signature: (I[BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_read0
|
||||
(JNIEnv *, jobject, jint, jbyteArray, jint);
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTYInputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_close0
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
29
core/org.eclipse.cdt.core.linux/library/PTYOutputStream.h
Normal file
29
core/org.eclipse.cdt.core.linux/library/PTYOutputStream.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class org_eclipse_cdt_utils_pty_PTYOutputStream */
|
||||
|
||||
#ifndef _Included_org_eclipse_cdt_utils_pty_PTYOutputStream
|
||||
#define _Included_org_eclipse_cdt_utils_pty_PTYOutputStream
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTYOutputStream
|
||||
* Method: write0
|
||||
* Signature: (I[BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_write0
|
||||
(JNIEnv *, jobject, jint, jbyteArray, jint);
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTYOutputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_close0
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
105
core/org.eclipse.cdt.core.linux/library/openpty.c
Normal file
105
core/org.eclipse.cdt.core.linux/library/openpty.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* (c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stropts.h>
|
||||
|
||||
/**
|
||||
* This is taken from R. W. Stevens book.
|
||||
* Alain Magloire.
|
||||
*/
|
||||
|
||||
int ptym_open (char *pts_name);
|
||||
int ptys_open (int fdm, char * pts_name);
|
||||
|
||||
int
|
||||
openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp)
|
||||
{
|
||||
char line[20];
|
||||
line[0]=0;
|
||||
*amaster = ptym_open(line);
|
||||
if (*amaster < 0)
|
||||
return -1;
|
||||
*aslave = ptys_open(*amaster, line);
|
||||
if (*aslave < 0) {
|
||||
close(*amaster);
|
||||
return -1;
|
||||
}
|
||||
if (name)
|
||||
strcpy(name, line);
|
||||
#ifndef TCSAFLUSH
|
||||
#define TCSAFLUSH TCSETAF
|
||||
#endif
|
||||
if (termp)
|
||||
(void) tcsetattr(*aslave, TCSAFLUSH, termp);
|
||||
#ifdef TIOCSWINSZ
|
||||
if (winp)
|
||||
(void) ioctl(*aslave, TIOCSWINSZ, (char *)winp);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ptym_open(char * pts_name)
|
||||
{
|
||||
int fdm;
|
||||
char *ptr;
|
||||
|
||||
strcpy(pts_name, "/dev/ptmx");
|
||||
fdm = getpt();
|
||||
if (fdm < 0)
|
||||
return -1;
|
||||
if (grantpt(fdm) < 0) { /* grant access to slave */
|
||||
close(fdm);
|
||||
return -2;
|
||||
}
|
||||
if (unlockpt(fdm) < 0) { /* clear slave's lock flag */
|
||||
close(fdm);
|
||||
return -3;
|
||||
}
|
||||
ptr = ptsname(fdm);
|
||||
if (ptr == NULL) { /* get slave's name */
|
||||
close (fdm);
|
||||
return -4;
|
||||
}
|
||||
strcpy(pts_name, ptr); /* return name of slave */
|
||||
return fdm; /* return fd of master */
|
||||
}
|
||||
|
||||
int
|
||||
ptys_open(int fdm, char * pts_name)
|
||||
{
|
||||
int fds;
|
||||
/* following should allocate controlling terminal */
|
||||
fds = open(pts_name, O_RDWR);
|
||||
if (fds < 0) {
|
||||
close(fdm);
|
||||
return -5;
|
||||
}
|
||||
if (ioctl(fds, I_PUSH, "ptem") < 0) {
|
||||
printf("pterm:%s\n", strerror(errno));
|
||||
close(fdm);
|
||||
close(fds);
|
||||
return -6;
|
||||
}
|
||||
if (ioctl(fds, I_PUSH, "ldterm") < 0) {
|
||||
printf("ldterm %s\n", strerror(errno));
|
||||
close(fdm);
|
||||
close(fds);
|
||||
return -7;
|
||||
}
|
||||
return fds;
|
||||
}
|
10
core/org.eclipse.cdt.core.linux/library/openpty.h
Normal file
10
core/org.eclipse.cdt.core.linux/library/openpty.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* (c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
*/
|
||||
#ifndef _OPENPTY_H
|
||||
#define _OPENPTY_H
|
||||
int ptym_open (char *pts_name);
|
||||
int ptys_open (int fdm, char * pts_name);
|
||||
#endif
|
36
core/org.eclipse.cdt.core.linux/library/pty.c
Normal file
36
core/org.eclipse.cdt.core.linux/library/pty.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include "PTY.h"
|
||||
#include "openpty.h"
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTY
|
||||
* Method: forkpty
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
|
||||
jfieldID fid; /* Store the field ID */
|
||||
jstring jstr = NULL;
|
||||
int master = -1;
|
||||
char line[1024]; /* FIXME: Should be enough */
|
||||
int err;
|
||||
jclass cls;
|
||||
|
||||
line[0] = '\0';
|
||||
|
||||
master = ptym_open(line);
|
||||
if (err >= 0) {
|
||||
/* Get a reference to the obj's class */
|
||||
cls = (*env)->GetObjectClass(env, jobj);
|
||||
|
||||
/* Set the master fd. */
|
||||
fid = (*env)->GetFieldID(env, cls, "master", "I");
|
||||
if (fid == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetIntField(env, jobj, fid, (jint)master);
|
||||
|
||||
/* Create a new String for the slave. */
|
||||
jstr = (*env)->NewStringUTF(env, line);
|
||||
}
|
||||
return jstr;
|
||||
}
|
103
core/org.eclipse.cdt.core.linux/library/ptyio.c
Normal file
103
core/org.eclipse.cdt.core.linux/library/ptyio.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include <jni.h>
|
||||
#include <stdio.h>
|
||||
#include <PTYInputStream.h>
|
||||
#include <PTYOutputStream.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Header for class _org_eclipse_cdt_utils_pty_PTYInputStream */
|
||||
/* Header for class _org_eclipse_cdt_utils_pty_PTYOutputStream */
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTYInputStream
|
||||
* Method: read0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_pty_PTYInputStream_read0(JNIEnv * env,
|
||||
jobject jobj,
|
||||
jint jfd,
|
||||
jbyteArray buf,
|
||||
jint buf_len)
|
||||
{
|
||||
int fd;
|
||||
int status;
|
||||
jbyte *data;
|
||||
int data_len;
|
||||
|
||||
data = (*env)->GetByteArrayElements(env, buf, 0);
|
||||
data_len = buf_len;
|
||||
fd = jfd;
|
||||
|
||||
status = read( fd, data, data_len );
|
||||
(*env)->ReleaseByteArrayElements(env, buf, data, 0);
|
||||
|
||||
if (status == 0) {
|
||||
/* EOF. */
|
||||
status = -1;
|
||||
} else if (status == -1) {
|
||||
/* Error, toss an exception */
|
||||
jclass exception = (*env)->FindClass(env, "java/io/IOException");
|
||||
if (exception == NULL) {
|
||||
/* Give up. */
|
||||
return -1;
|
||||
}
|
||||
(*env)->ThrowNew(env, exception, "read error");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTYInputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_pty_PTYInputStream_close0(JNIEnv * env,
|
||||
jobject jobj,
|
||||
jint fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTYOutputStream
|
||||
* Method: write0
|
||||
* Signature: (II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_pty_PTYOutputStream_write0(JNIEnv * env,
|
||||
jobject jobj,
|
||||
jint jfd,
|
||||
jbyteArray buf,
|
||||
jint buf_len)
|
||||
{
|
||||
int status;
|
||||
int fd;
|
||||
jbyte *data;
|
||||
int data_len;
|
||||
|
||||
data = (*env)->GetByteArrayElements(env, buf, 0);
|
||||
data_len = buf_len;
|
||||
fd = jfd;
|
||||
|
||||
status = write(fd, data, data_len);
|
||||
(*env)->ReleaseByteArrayElements(env, buf, data, 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTYOutputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_pty_PTYOutputStream_close0(JNIEnv * env,
|
||||
jobject jobj,
|
||||
jint fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
BIN
core/org.eclipse.cdt.core.linux/os/linux/x86/libpty.so
Normal file
BIN
core/org.eclipse.cdt.core.linux/os/linux/x86/libpty.so
Normal file
Binary file not shown.
|
@ -18,6 +18,7 @@ import org.eclipse.cdt.debug.mi.core.command.MIGDBShowExitCode;
|
|||
import org.eclipse.cdt.debug.mi.core.event.MIInferiorExitEvent;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIGDBShowExitCodeInfo;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
|
||||
import org.eclipse.cdt.utils.pty.PTY;
|
||||
import org.eclipse.cdt.utils.spawner.Spawner;
|
||||
|
||||
/**
|
||||
|
@ -35,15 +36,19 @@ public class MIInferior extends Process {
|
|||
MISession session;
|
||||
|
||||
OutputStream out;
|
||||
InputStream in;
|
||||
|
||||
PipedInputStream in;
|
||||
PipedOutputStream inPiped;
|
||||
|
||||
PipedInputStream err;
|
||||
PipedOutputStream errPiped;
|
||||
|
||||
MIInferior(MISession mi) {
|
||||
MIInferior(MISession mi, PTY pty) {
|
||||
session = mi;
|
||||
if (pty != null) {
|
||||
out = pty.getOutputStream();
|
||||
in = pty.getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,15 +5,13 @@
|
|||
package org.eclipse.cdt.debug.mi.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.cdt.debug.core.cdi.ICDISession;
|
||||
import org.eclipse.cdt.debug.mi.core.cdi.CSession;
|
||||
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIBreakInsert;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MITargetAttach;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
|
||||
import org.eclipse.cdt.utils.pty.PTY;
|
||||
import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
||||
import org.eclipse.core.runtime.IPluginDescriptor;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
|
@ -44,14 +42,23 @@ public class MIPlugin extends Plugin {
|
|||
|
||||
/**
|
||||
* Method createMISession.
|
||||
* @param in
|
||||
* @param out
|
||||
* @param Process
|
||||
* @return MISession
|
||||
*/
|
||||
public MISession createMISession(Process process) throws MIException {
|
||||
return new MISession(process);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method createMISession.
|
||||
* @param Process
|
||||
* @param PTY
|
||||
* @return MISession
|
||||
*/
|
||||
public MISession createMISession(Process process, PTY pty) throws MIException {
|
||||
return new MISession(process, pty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method createCSession.
|
||||
* @param program
|
||||
|
@ -59,9 +66,20 @@ public class MIPlugin extends Plugin {
|
|||
* @throws IOException
|
||||
*/
|
||||
public ICDISession createCSession(String program) throws IOException, MIException {
|
||||
String[]args = new String[]{"gdb", "-q", "-nw", "-i", "mi", program};
|
||||
String[] args;
|
||||
PTY pty = null;
|
||||
try {
|
||||
pty = new PTY();
|
||||
String ttyName = pty.getSlaveName();
|
||||
args = new String[]{"gdb", "-q", "-nw", "-tty", ttyName, "-i", "mi", program};
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
pty = null;
|
||||
args = new String[]{"gdb", "-q", "-nw", "-i", "mi", program};
|
||||
}
|
||||
|
||||
Process gdb = ProcessFactory.getFactory().exec(args);
|
||||
MISession session = createMISession(gdb);
|
||||
MISession session = createMISession(gdb, pty);
|
||||
/*
|
||||
try {
|
||||
CommandFactory factory = session.getCommandFactory();
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.cdt.debug.mi.core.event.MIGDBExitEvent;
|
|||
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIOutput;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIParser;
|
||||
import org.eclipse.cdt.utils.pty.PTY;
|
||||
|
||||
/**
|
||||
* Represents a GDB/MI session.
|
||||
|
@ -56,10 +57,19 @@ public class MISession extends Observable {
|
|||
/**
|
||||
* Create the gdb session.
|
||||
*
|
||||
* @param i the gdb input channel.
|
||||
* @param o gdb output channel.
|
||||
* @param Process gdb Process.
|
||||
*/
|
||||
public MISession(Process process) throws MIException {
|
||||
this(process, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the gdb session.
|
||||
*
|
||||
* @param Process gdb Process.
|
||||
* @param pty Terminal to use for the inferior.
|
||||
*/
|
||||
public MISession(Process process, PTY pty) throws MIException {
|
||||
miProcess = process;
|
||||
inChannel = process.getInputStream();
|
||||
outChannel = process.getOutputStream();
|
||||
|
@ -69,7 +79,7 @@ public class MISession extends Observable {
|
|||
parser = new MIParser();
|
||||
|
||||
// Do this first.
|
||||
inferior = new MIInferior(this);
|
||||
inferior = new MIInferior(this, pty);
|
||||
|
||||
txQueue = new CommandQueue();
|
||||
rxQueue = new CommandQueue();
|
||||
|
|
Loading…
Add table
Reference in a new issue