1
0
Fork 0
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:
Alain Magloire 2002-09-06 03:39:19 +00:00
parent fe4c884ab4
commit 7edb51d4cc
13 changed files with 402 additions and 19 deletions

View file

@ -0,0 +1 @@
*.o

View file

@ -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)

View 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

View 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

View 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

View 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;
}

View 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

View 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;
}

View 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);
}

Binary file not shown.

View file

@ -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;
PipedInputStream in;
InputStream 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();
}
}
/**

View file

@ -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();

View file

@ -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();