Bug 224989 - [terminal][api] Support contributed services over Terminal connections
Summary: [terminal][api] Support contributed services over Terminal connections
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: terminal (show other bugs)
Version: Next   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords: api
Depends on:
Blocks: 259271
  Show dependency tree
 
Reported: 2008-03-31 16:35 EDT by Alex Chapiro CLA
Modified: 2020-09-04 15:11 EDT (History)
2 users (show)

See Also:


Attachments
Patch to add requested feature (14.70 KB, patch)
2008-04-01 11:20 EDT, Alex Chapiro CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Chapiro CLA 2008-03-31 16:35:52 EDT
This is a change request.
I'm using TerminalView and trying to add some functionality that I need for our product. One feature I'm implementing is file transfer using different protocol based on serial connection. In order to not repeat RXTX wrapper code I'd like to get access to ITerminalConnection to us its service. How to do it? 

Typical use case for that:
User needs action to be added to the terminal instance. This action causes transfer IPL or OS image to remote target. It would be nice to use terminal transport services (e.g. InputStream and OutputStream for serial connection) and for setting session parameters to use standard UI that terminal view already  provides.
Comment 1 Alex Chapiro CLA 2008-04-01 11:20:50 EDT
Created attachment 94374 [details]
Patch to add requested feature

What's done in this patch:
- created notification interface to inform registred listeners about change of connection state. I added this functionality to ITerminalViewControl interface and ITerminalView interface (this one works just as a client of ITerminalViewControl notification mechanism. I'd prefer instead of that add this notification feature to ITerminalConnector interface, however it would cause more changes that I dare to present in this patch.
- exposed instance of ITerminalConnectorInfo associated with terminal view. I'd prefer to expose ITerminalConnector instead of that, but two obstacles prevented me of doing that: 
     a) cannot get connection protocol ID
     b) no method to check current state (for ITerminalConnectorInfo I at least can use isInitialized() which is not enough but better than nothing.
- exposed InputStream instance for ITerminalConnector in order to support bi-directional transfer protocol 

This changes let me implement data transfer framework which use terminal communication servises to implement various data transmit protocols based on serial communication layer.
Comment 2 Michael Scharf CLA 2008-04-01 12:40:38 EDT
Why does ITerminalView extends IViewPart?

I think adding ITerminalConnector.getInputStream is dangerous, because there is typically a thread in th connector that reads the input stream and writes the bytes to the terminal. I wonder how you use this in your extension... There are probably two threads trying to read from this input stream, this sounds like causing trouble....
Comment 3 Alex Chapiro CLA 2008-04-01 14:02:59 EDT
(In reply to comment #2)
> Why does ITerminalView extends IViewPart?
I could live without that, it happened historically. As for now the reason I would keep it on this way is that it is more convenient in ...ActionDelegate implementation: it lets me to avoid either casting in hacker's manner or implementation of an adapter method in TerminalView. On the other hand it seemed to me harmless, taking in account that the only implementation of it extends ViewPart. However, I'm ready to revoke this change as not principal one. 

> 
> I think adding ITerminalConnector.getInputStream is dangerous, because there is
> typically a thread in th connector that reads the input stream and writes the
> bytes to the terminal. I wonder how you use this in your extension... There are
> probably two threads trying to read from this input stream, this sounds like
> causing trouble....
> 
Actually I use inputstream in implementation of transfer protocol in order to get flow control packets from the target. In this case client (i.e. transfer protocol implementation) has to completely control input, and terminal itself is not expected to receive this data and output them to display. Maybe, to guarantee full control over the input stream it would be better to synchronize its usage It is easy to do on the server side, terminal transport service. It should be commented in the interface definition  that InputStream must be synchronized during the period when client expects receiving data.
Comment 4 Michael Scharf CLA 2008-04-01 19:08:16 EDT
I think what you need for the input stream is described in  bug 165893 comment #19
Comment 5 Martin Oberhuber CLA 2008-04-02 04:01:10 EDT
I fully agree: It's not sufficient to just hijack a terminal's InputStream. What we need is a Decorator to intercept both InputStream and OutputStream. If that's not done, a user could destroy an ongoing file transmission by typing some random characters in the terminal while the transmission is ongoing, right?

However the use-case on this bug is slightly simpler than bug 165893 because here, we're not concerned of contributing arbitrary decorators by extension point; we rather use contributed menus/actions which use API to operate on the current connector of the current Terminal. That simplifies the Ordering problem, because via API we're not concerned about the order of a decorator stack (first come first serve).

We might also not be concerned about stacking multiple stream decorators yet, although this looks like a nice generalization if we can do it.

I also checked the console framework, but it doesn't seem to support decorators; however they have IOConsole with  IOConsoleInputStream and IOConsoleOutputStream, supporting multiple outputs and a single input on one console. The special streams basically add some buffering but I think that our PipedInputStream is actually better.

http://help.eclipse.org/help33/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/console/IOConsole.html
Comment 6 Martin Oberhuber CLA 2008-04-02 04:06:45 EDT
Actually, looking at the proposed use case from bug 185348 / attachment 94254 [details] again: it seems to me that you're really only interested in getting your own channel connected for transmission, independent of a Terminal.

Would it help if you instantiated your own (serial) connector? And reuse the TerminalSettingsDlg to configure your connection?

Along the lines of bug 185348 comment 5 and
http://dev.eclipse.org/newslists/news.eclipse.dsdp.tm/msg00229.html
Comment 7 Alex Chapiro CLA 2008-04-02 07:07:19 EDT
(In reply to comment #6)
> Actually, looking at the proposed use case from bug 185348 / attachment 94254 [details]
> again: it seems to me that you're really only interested in getting your own
> channel connected for transmission, independent of a Terminal.
> 
> Would it help if you instantiated your own (serial) connector? And reuse the
> TerminalSettingsDlg to configure your connection?
> 
> Along the lines of bug 185348 comment 5 and
> http://dev.eclipse.org/newslists/news.eclipse.dsdp.tm/msg00229.html

Not at all. The process of loading  image could be multi-step and includes several times interaction with target via terminal. And these operations are never overlapped with data flow. 

What do you think if we add just releaseInputStream() together with getInputStream(). If client gets ownership over input stream, terminal cannot use it any more until client does not release it. I think that the same is valid for outputStream. This is a sort of a simple synchronization, and it doesn't seem to require a big changes. 


Comment 8 Alex Chapiro CLA 2008-04-02 07:12:25 EDT
(In reply to comment #6)
> Actually, looking at the proposed use case from bug 185348 / attachment 94254 [details]
> again: it seems to me that you're really only interested in getting your own
> channel connected for transmission, independent of a Terminal.
> 
> Would it help if you instantiated your own (serial) connector? And reuse the
> TerminalSettingsDlg to configure your connection?
> 
> Along the lines of bug 185348 comment 5 and
> http://dev.eclipse.org/newslists/news.eclipse.dsdp.tm/msg00229.html
> 

Moreover, during the overall process terminal and client share one and the same physical channel, so each of them must get ultimate access to this resource.

Comment 9 Michael Scharf CLA 2008-04-02 09:51:48 EDT
...that is why a decorator is a good approach: your decorator (FilterOutputStream) would see all the communication and it could then grab the data it needs and write it to a file.

There are two directions of communication: remoteToTerminal and terminalToRemote. Both are represented by an output stream:
* remoteToTerminal is used to write to the terminal (when the remote site wants to display a string in the terminal, this channel is used):
  ITerminalControl.getRemoteToTerminalOutputStream()
* terminalToRemote is used to write to the remote site (if a key is pressed the key is sent to the remote site on this channel:
  ITerminalConnector.getOutputStream()

I assume there are two scenarios for a file transfer: 1. the remote site sends a file to the terminal and 2. the terminal sends a file to the remote site. I also assume that there is a special maker in the stream (escape sequence) to signal the beginning and the end of a file transfer.

Let's look at both cases (for simplicity, let's assume the special marker is a single char MARKER_CHAR):

1. remote to terminal: the remote site wants to send a file. it sends the begin file marker. Your write method in your FilterOutputStream would look like this:
public class RemoteToTerminalFilterOutputStream extends FilterOutputStream {
	private static final int MARKER_CHAR = 1;
	public RemoteToTerminalFilterOutputStream(OutputStream out) {
		super(out);
	}
    boolean inFileTransfer;
    OutputStream fileStream;
    public void write(int b) throws IOException {
    	// the marker begins and ends th file transfer.
    	// in real life, the marker would be a multi-byte
    	// sequence (plus a way to "escape" the marker)). 
    	// And there might be some more markers in the transfer
    	// mode to denote the filename etc.
    	if(b==MARKER_CHAR) {
    		inFileTransfer=!inFileTransfer;
    		if(inFileTransfer) {
    			// begin the transfer
    			fileStream=askUserForOutputFile();
    		} else {
    			// transfer is done
    			fileStream.close();
    		}
    	} else {
    		if(inFileTransfer)
    			// write to the file if we are in the transfer mode
       			fileStream.write(b);
    		else 
    			super.write(b);
     	}
    }
	private OutputStream askUserForOutputFile() {
		return ...
	}
}


2. terminal to remote (you send a file):
public class TerminalToRemoteFilterOutputStream extends FilterOutputStream {
	private static final byte MARKER_CHAR = 1;
	public TerminalToRemoteFilterOutputStream(OutputStream out) {
		super(out);
	}
    private boolean inFileTransfer;
    public void sendFile(InputStream in) throws IOException {
    	// during the transfer do not allow writing to the stream
    	synchronized(this) {
    		inFileTransfer=true;
    	}
    	try {
        	// use the decorated output stream directly
    		// In real life, the marker would be more than
    		// one char and there should be an escape sequence
    		// to "quote" the marker....
        	out.write(MARKER_CHAR);
    		copyStream(in,out);
        	out.write(MARKER_CHAR);			
		} finally {
	    	// make sure to end the transfer mode
	    	synchronized(this) {
	    		inFileTransfer=false;
	    	}
		}
    }
	private void copyStream(InputStream is, OutputStream os) throws IOException {
		byte bytes[]=new byte[1024];
		int n;
		// read until the thread gets interrupted....
		while( (n=is.read(bytes))!=-1) {
			os.write(bytes,0,n);
		}
	}
    synchronized public void write(int b) throws IOException {
    	// ignore input from the terminal during file transfer
    	// it could also be buffered and sent to the terminal
    	// after the file transfer had finished
    	if(inFileTransfer)
    		return;
    	super.write(b);
    }
}


The remaining question is, how to decorate the two streams. Alex, before I go into this, I want to know if this is what you  are trying to do.....
Comment 10 Michael Scharf CLA 2008-04-02 09:57:42 EDT
Here the two files with better formatting:

public class RemoteToTerminalFilterOutputStream extends FilterOutputStream {
    private static final int MARKER_CHAR = 1;
    public RemoteToTerminalFilterOutputStream(OutputStream out) {
        super(out);
    }
    boolean inFileTransfer;
    OutputStream fileStream;
    public void write(int b) throws IOException {
        // the marker begins and ends th file transfer.
        // in real life, the marker would be a multi-byte
        // sequence (plus a way to "escape" the marker)). 
        // And there might be some more markers in the transfer
        // mode to denote the filename etc.
        if(b==MARKER_CHAR) {
            inFileTransfer=!inFileTransfer;
            if(inFileTransfer) {
                // begin the transfer
                fileStream=askUserForOutputFile();
            } else {
                // transfer is done
                fileStream.close();
            }
        } else {
            if(inFileTransfer)
                // write to the file if we are in the transfer mode
                fileStream.write(b);
            else 
                super.write(b);
        }
    }
    private OutputStream askUserForOutputFile() {
        return ...;
    }
}



public class TerminalToRemoteFilterOutputStream extends FilterOutputStream {
    private static final byte MARKER_CHAR = 1;
    public TerminalToRemoteFilterOutputStream(OutputStream out) {
        super(out);
    }
    private boolean inFileTransfer;
    public void sendFile(InputStream in) throws IOException {
        // during the transfer do not allow writing to the stream
        synchronized(this) {
            inFileTransfer=true;
        }
        try {
            // use the decorated output stream directly
            // In real life, the marker would be more than
            // one char and there should be an escape sequence
            // to "quote" the marker....
            out.write(MARKER_CHAR);
            copyStream(in,out);
            out.write(MARKER_CHAR);         
        } finally {
            // make sure to end the transfer mode
            synchronized(this) {
                inFileTransfer=false;
            }
        }
    }
    private void copyStream(InputStream is, OutputStream os) throws IOException {
        byte bytes[]=new byte[1024];
        int n;
        // read until the thread gets interrupted....
        while( (n=is.read(bytes))!=-1) {
            os.write(bytes,0,n);
        }
    }
    synchronized public void write(int b) throws IOException {
        // ignore input from the terminal during file transfer
        // it could also be buffered and sent to the terminal
        // after the file transfer had finished
        if(inFileTransfer)
            return;
        super.write(b);
    }
}
Comment 11 Alex Chapiro CLA 2008-04-02 10:41:18 EDT
I'd concentrate on the second case (terminal to remote) because the first one is out of my scope. If you ask me to specify my task in a couple of phrases, it would be sound like that:
- Client gets full control on the input channel receiving ALL remote target->terminal traffic, target itself can or cannot send escaped control data (such as ACK/NAK for example or whatever ) like it takes place in simple "copy file comN" case.
- Client  gets full control on the output channel
- terminal "thinks" that it still controls input and output channel, but these are just proxy i/o streams that client provides as a replacement.  Client can decide which part of incoming  trafic should be displayed on the terminal. Client should be able to disable/enable user's keyboard input (maybe by sending ESC sequences). It can also generate some extra stuff on the terminal such as  user request about error processing.


What do you think about that approach? Is it flexible, too flexible, just silly  or what?

Sorry, it is not direct answer to you question, I just would like to find common ground before switching to implementation issues.
Comment 12 Michael Scharf CLA 2008-04-02 12:09:51 EDT
What do you mean by "client". Is the (ab)using the terminal connection for the file transfer?

You also have to understand that there is no InputStream in the current design. There are two output streams. One from the remote site to the target and one from the target to the remote site. 

If the ITerminalConnector would provide an InputStream, then the terminal would be responsible to create a thread that reads from the input stream. This might cause some problems with some connectors, because only the connector knows which thread(s) can use the input stream. In addition, the connector knows better how to handle errors on the input stream. If the terminal would read from the input stream, it would be very hard to deal with errors (e.g, closing the connection and opening a new one). 

Therefore each connector (often in a class called Connection) has something like a loop that reads from the input stream and writes it to the ITerminalControl.getRemoteToTerminalOutputStream():
       private void readDataForever(InputStream in) throws IOException {
        // read the data
        byte bytes[]=new byte[8*1024];
        int n;
        while( (n=in.read(bytes))!=-1) {
            fControl.getRemoteToTerminalOutputStream().write(bytes,0,n);
        }
    }

I also don't understand how you want to replace the streams. I think it is quite difficult to replace a stream while the communication is already going on. That's why I propose the decorator approach. But maybe you can explain to me how you would replace the stream while the communication is going on....
Comment 13 Michael Scharf CLA 2008-04-02 12:11:37 EDT
 > What do you mean by "client". Is the (ab)using the terminal connection for the file transfer?

I meant: Is the "cleint" (ab)using the terminal connection for the file transfer?
 
Comment 14 Alex Chapiro CLA 2008-04-02 12:34:34 EDT
This is a component which communicates on some way with remote target using terminal communication ad user interaction abilities. It's the client of terminal service.
Comment 15 Alex Chapiro CLA 2008-04-02 13:47:46 EDT
(In reply to comment #12)
> You also have to understand that there is no InputStream in the current design.
> There are two output streams. One from the remote site to the target and one
> from the target to the remote site. 
> 
OK, I understand that. This is a connector who has input stream. That's good as well :-)

> I also don't understand how you want to replace the streams. I think it is
> quite difficult to replace a stream while the communication is already going
> on. That's why I propose the decorator approach. But maybe you can explain to
> me how you would replace the stream while the communication is going on....
> 
Maybe I don't understand something, but is it a problem? For terminal it is just switching a buffer, isn't it? The most important thing is to control which data goes to terminal, and which doesn't, doesn't matter how it is implemented. Please correct me if I'm wrong.

Anyway, let it be decorated stream. The purpose of my previous message was to explain what features I need to have. If you think it is feasible (I mean that at the end of the story I'll get what I need) , go ahead with this implementation. If you need any help, I'd be happy to participate in this work.

Comment 16 Alex Chapiro CLA 2008-04-03 15:13:51 EDT
(In reply to comment #12)
I would like to  to give an illustration of my verbal description. It is just a raw not polished fragments of code. I'm talking now only about seriall connection.

I add two methods to ITerminalConnector interface:
  /**
     * Depends on the connector implementation. Should be invoked 
     * each time user does not need to grab input from the remote
     * target. 
     */
    void releaseInputStream();
    
    /**
     * @return a stream used to write to the terminal. Any bytes written to this
	 * stream appear in the terminal or are interpreted by the emulator as
	 * control sequences. Returns null if input is not grabbed.
     */
    OutputStream getTerminalOutputStream();    

Small changes in TerminalConnectorExtension:

		public OutputStream getTerminalOutputStream() {
			return getConnector().getTerminalOutputStream();
		}
		public void releaseInputStream() {
			getConnector().releaseInputStream();
			
		}

Their implementation in SerialConnector:
        
        private boolean fInputGrabbed = false;

	public InputStream getInputStream() {
		fInputGrabbed = true;
 		return fInputStream;
 	}
	
	public void releaseInputStream() {
		fInputGrabbed = false;
	}
	
/* this method is not a part of public interface  */
	boolean isInputGrabbed() {
		return fInputGrabbed;
	}
	
	public OutputStream getTerminalOutputStream() {
		if(isInputGrabbed())
			return fControl.getRemoteToTerminalOutputStream();
		return null;
			
	}
	

Change a bit serialEvent method in SerialPortHandler

 	public void serialEvent(SerialPortEvent event) {
 		switch (event.getEventType()) {
 		case SerialPortEvent.DATA_AVAILABLE:
			if(!fConn.isInputGrabbed())
				onSerialDataAvailable(null);
 			break;
 		}
 	}

Now what program that use this service does:

	public void setTransport(ITerminalConnector transport) {
		ostream = transport.getOutputStream();
		controlData = transport.getInputStream();
	}
Comment 17 Alex Chapiro CLA 2008-04-03 15:41:25 EDT
Sorry, my message was interrupted accidentally. Below is the end of the message.

Now what program that use this service does:
        private OutputStream ostream; // To remote target
        private InputStream controlFlow; // From remote target
        private OutputStream termOutputStream;

        public void setTransport(ITerminalConnector transport) {
                ostream = transport.getOutputStream();
                controlFlow  = transport.getInputStream();
                termOutputStream = transport.getTerminalOutputStream();

       }
       ......
       void processBlock(byte[] buffer) {
            writeControlDataPerBlock(buffer);
            ostream.write(buffer, 0, buffer.length);
            .....
            for(int code = controlFlow.read(); code >= 0; ) {
            switch (code) {
		case ABORT_CKSUM :
                     // Process error
		      break;
		case ABORT_SEQ :
                     // Process error
		      break;
		case ABORT_PROTOCOL :
                     // Process error
		      break;
                 default:

                     
                         // This is not a part of protocol exchange - 
                         // send it to the terminal                                                                 
                           termOutputString.write(code);
                 }
        }        


         ... 
         // Don't forget to release input stream:
          
           } finally {
               ...
               transport.releaseInputStream();
               ...
            }

Admittedly, I didn't try it yet, but it seems to me that at least for serial connection it should work ok. I'd like to know your opinion.
Comment 18 Michael Scharf CLA 2008-04-04 00:46:57 EDT
Alex, I think I know what you need and I am working on a solution.....
Comment 19 Michael Scharf CLA 2008-04-07 21:13:15 EDT
Alex, there are many ways a file transfer could work on a shared connection. Lets assume the file we want to send has "0123456789" as content. And the user is typing "abcdefgh".  And let's assume the transfer starts after the user has typed 'b' and during the transfer he's typing "cde" and after the transfer "fgh". Here are different solutions I can think of:

1.    The file is send in one big junk use '[' to begin the transfer and ']' to end the transfer (it could also be a begin marker with a size).
1.a. The bytes sent during the trensfer are dropped: "ab[0123456789]fgh"
1.b. The bytes sent during the transfer are delayed: "ab[0123456789]cdefgh"
2.    The file is sent in chunks and the bytes send during the transfer are send in between: "ab[0123]cd[4567]e[89]fgh"
2.a  The intercepting bytes ("cde") are sent as soon as they arrive. If there are no intercepting bytes the file is send as one long string.
2.b  The transfer is always chunked [0123][4567][89]

In a more complex world, there could be multiple file transfers going on in parallel, where each chunk has a header telling which file it belongs to. Which leads to the most general design, where multiple streams are multiplexed in chunks over one channel...

And for the controlFlow: there could be other characters coming on the control flow stream. So you's have to filter out your specific control characters and the other characters have to flow to the receiver. It is essentially the same design but this time you remove the chunks that belong to you from the stream....

Does this somehow describe what you need?
Comment 20 Alex Chapiro CLA 2008-04-08 18:03:20 EDT
(In reply to comment #19)
> Alex, there are many ways a file transfer could work on a shared connection.
> Lets assume the file we want to send has "0123456789" as content. And the user
> is typing "abcdefgh".  And let's assume the transfer starts after the user has
> typed 'b' and during the transfer he's typing "cde" and after the transfer
> "fgh". Here are different solutions I can think of:
> 
> 1.    The file is send in one big junk use '[' to begin the transfer and ']' to
> end the transfer (it could also be a begin marker with a size).
> 1.a. The bytes sent during the trensfer are dropped: "ab[0123456789]fgh"
> 1.b. The bytes sent during the transfer are delayed: "ab[0123456789]cdefgh"
> 2.    The file is sent in chunks and the bytes send during the transfer are
> send in between: "ab[0123]cd[4567]e[89]fgh"
> 2.a  The intercepting bytes ("cde") are sent as soon as they arrive. If there
> are no intercepting bytes the file is send as one long string.
> 2.b  The transfer is always chunked [0123][4567][89]
> 
> In a more complex world, there could be multiple file transfers going on in
> parallel, where each chunk has a header telling which file it belongs to. Which
> leads to the most general design, where multiple streams are multiplexed in
> chunks over one channel...
> 
> And for the controlFlow: there could be other characters coming on the control
> flow stream. So you's have to filter out your specific control characters and
> the other characters have to flow to the receiver. It is essentially the same
> design but this time you remove the chunks that belong to you from the
> stream....
> 
> Does this somehow describe what you need?
> 

I follow standard multi-tier level. Each tier knows what belongs to it, then all the rest follows to upper level (if control data that tier received doesnt say other). Next level does the same. So on each level control flow contains only not stripped on the lower tiers stuff. For example, your application that controls serial port doesn't receive control bytes that serial drivers exchange to each other. I think that to say that there is a great variety of transfer protocols based on RS232 would be a bit exagerration because this is very old and stable communication environment, and one could call barely more than half a dozen of different transfer methods.
So I agree with your last paragraph: this is what I'm talking about.
Comment 21 Alex Chapiro CLA 2008-04-14 10:57:25 EDT
Michael, Martin,

I just finished testing together with our tester my patch. (I updated the previous one after the discussion in this bug and fixed synchronization issues for Remote-to-local stream), and it looks like it works fine now (admittedly, we tested it on Windows platform only so far).  I just was wondering about your plans  on this issue. Would you are still planning to fix it soon, I appreciate it and can wait for the generic solution. If this is not in your closest plans and you are somehow curious to look at this solution, I could once again to create a patch and send it to you. I just wouldn't do this work if it is against your plans or interests, because you have been changing terminal stuff quite intensively last week, and it would takes a wile to create new patch. "No" is also OK:-)
Comment 22 Martin Oberhuber CLA 2008-04-15 16:27:49 EDT
We definitely want to bring the "contributed services over terminal connections" idea into TM 3.0. In fact, some work-in-progress has just been checked into the org.eclipse.tm.terminal.tests plugin.

The difference between our work and your patch is, that while 

* In your case, it's totally up to the clients who writes on the stream and 
  when, so the resulting stream is timing dependent (which may be fine in most
  cases).

* In our case, we're trying to make the process of merking two streams into
  one, or splitting one stream up into two, configurable. That is, our 
  StreamInterceptor class allows the contributor to provide an algorithm 
  which selects who's writing to the stream and when. Some example trivial
  implementations of the Interceptor are:

  - SerializingInterceptor: Write from Stream A until it's closed, then
         append everything from Stream B (essentiall B is blocked while 
         A is busy writing).
  - ImmediateInterceptor: Write bytes from Stream A or Stream B onto the
         output as they come along. That's essentially what you are doing.

  It's similar for the other way round, demultiplexing a single Stream onto
  two outputs. Here, the trivial implementatio is

  - DuplicatingInterceptor: Every byte from IN is copied onto both A and B.

Some implementation is still missing, and we'll happily accept your feedback about the idea, as well as what we currently have. One part of the work in progress is rationalizing the synchronization / threading story behind the multiplexers.
Comment 23 Alex Chapiro CLA 2008-04-16 09:29:43 EDT
Thank you Martin, sounds good for me. It looks more generic and shouldn't add much overhead. I'm waiting for implementation.
Comment 24 Martin Oberhuber CLA 2008-12-18 11:54:08 EST
tentatively planned for M5 to allow some API review.
Comment 25 Martin Oberhuber CLA 2011-05-31 17:41:37 EDT
Moving deferred 3.3 api items to 3.4
Comment 26 Missing name Mising name CLA 2011-12-20 05:58:57 EST
Hi Michael,
I want to upload a binary file to the device connect through serial port.
When the data is sent, the device will send success/failure message for every packet. I have to interrupt with the data received.

Is there any work around/patch before 3.4 release? It is very urgent requirement.

I have also rised a Topic in the forum. http://www.eclipse.org/forums/index.php/m/768501/#msg_768501
Comment 27 Martin Oberhuber CLA 2011-12-20 10:41:15 EST
If it's urgent I'm afraid you'll have to work on the feature yourself, or use an external terminal program that supports xyzmodem.

As of today the assignment to 3.4 is tentative and we can't guarantee getting this in.
Comment 28 Jonah Graham CLA 2020-05-01 10:09:04 EDT
The Terminal component of the Eclipse Ecosystem has a new home. The Terminal is now part of the Eclipse CDT project[1].

This change means a new Git repo[2], P2 site[3] and Bugzilla component. The terminal will continue to be delivered as part of the quarterly Simultaneous Release of Eclipse as well.

The marketplace entry[4] had not been updated in a few years. It will once again install the latest release of the terminal on the latest release of the whole IDE (currently 2020-03).

If this bug is no longer relevant, please feel free to comment or close the bug. If you can confirm if this issues still occurs in the latest release please do let me know in a comment.

[1] https://wiki.eclipse.org/CDT/User/NewIn911
[2] https://git.eclipse.org/c/cdt/org.eclipse.cdt.git (in the terminal directory)
[3] current release is 9.11 - P2 site https://download.eclipse.org/tools/cdt/releases/9.11/
[4] https://marketplace.eclipse.org/content/tm-terminal

(This comment was added to all open terminal bugs along with changing the Product/component pair to CDT/terminal.)