[Windows] Any way to distinguish ^C Induced EOF from ^Z EOF?

J

Jan Burse

Arne said:
All his suggestions were for using well defined
and supported behavior.

Arne

Didn't you read my note: People who are
not used to work on solutions, please
refrain from posting?

You are just wasting bandwidth.
 
S

Steven Simpson

Its a custom made wrapper for Signal & SignalHandler.
In version 1 of the above class I used the package
sun.misc.*. In version 2 of the above class I
used reflection i.e. Proxy class etc.. It will
noop when sun.misc.Signal is not present.

I was going to suggest using Runtime.addShutdownHook(Thread) as a
portable alternative. You don't find out which signal was raised, but
it gives your program a chance to shut down gracefully instead of abruptly.

import java.io.*;

public class TestInput {
public static void main(String[] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException ex) {
}
}
});

FileInputStream fs = new FileInputStream(FileDescriptor.in);
byte[] buf = new byte[256];
for (;;) {
System.out.print("test: ");
int len = fs.read(buf);
String str = new String(buf,0,Math.max(0,len));
System.out.println("len = "+len+", buf = "+str+", buf[0]="+buf[0]);
if ("exit".equals(str.trim())) break;
}
}
}

Unfortunately, you still get the same read()==-1 on Windows, while the
read call doesn't return on Linux. Of course, this loop doesn't
terminate on EOF, and while the shutdown hook is still running, you can
continue to type on both Windows and Linux, and have the results printed.

However, this could be a way to distinguish the 'fake' EOF from a real
one. Having received -1, read again. A real one will produce -1 again,
but the fake one will block or yield more input. For a real EOF, the
behaviour seems the same on Windows and Linux, so stop when you get two
'-1's. Can't speak for Mac, or anything else, of course.

Is a read() call's behaviour well defined after a previous call returned
-1? I couldn't tell from a quick scan of the docs.
 
A

Arne Vajhøj

Didn't you read my note: People who are
not used to work on solutions, please
refrain from posting?

I would hope that well defined and supported
behavior is a strong preference among people
used to work on solutions.

There are many places where software being
reliable and easy to upgrade and platform
independent is considered a good thing.

Arne
 
J

Jan Burse

Steven said:
I was going to suggest using Runtime.addShutdownHook(Thread) as a portable

In the final application the SIGINT should enter a monitor,
and the end-user can then choose among other things whether
he would like to abort the application or not.

But the effect is of course also seen with ordinary shut down
hooks.

When one overrides the SIGINT with the help of Signal/SignalHandler
the shutdown sequence is not anymore called. But the handler
is free to call System.exit() which will initiate the shut
down sequence.
Unfortunately, you still get the same read()==-1 on Windows, while
the read call doesn't return on Linux.

Yes, on Linux, it is as it should be.
The read call is blocking.
However, this could be a way to distinguish the 'fake' EOF
from a real one. Having received -1, read again. A real
one will produce -1 again, but the fake one will block or
yield more input. For a real EOF, the behaviour seems the
same

Actually the standard input stream is special. It can return
-1 but will not close. And then after returning -1 it will
return normal user input. This works for Linux, Mac and
Windows.

So one can enter:

abc
<EOF>
def
<EOF>

Where <EOF> depends on the platform (^D on Mac and Linux,
^Z + Enter on Windows). When doing Buffered str = readLine().
One gets:

str = "abc"
str = null
str = "def"
str = null

The above is perfectly fine and intended. And one can write
applications that use recursive stream input.

The only issue on Windows is now that SIGINT injects a EOF.
I don't think that in my Monitor case a continued reading
might detect the SIGINT EOF. Since the SIGINT will not
perform a System.exit().

I guess that eventually in the non-Monitor case after a
System.exit() or so, the continued reading might show something,
IOException or so. Not sure.

But getting two EOF in general might be just the user
interaction, and not a SIGINT EOF. Getting two EOF is actually
a legal user interaction in my application. For example
on can recursively open a REPL, and then exit form it:

?- break.
[1] ?- break.
[2] ?- <EOF>
[1] ?- <EOF>
?-

Bye
 
J

Jan Burse

Leif said:
I think you're confusing the terms "solution" and "hack" here,
actually, but that's just me.

Conceptually Signal/SignalHandler is a solution for
providing a SIGINT hook. When I wrap this in my
own class without other visible classes than from
java.lang.* I am not anymore dependent on sun.misc.*.

For platforms that don't have sun.misc.* I can
bundle a different implementation of my class.
This is programming by contract. My class defines
a contract, and I can deliver what ever realization
I want.

So its only in as far a hack, because I have not yet
done a wide range realization of the contract. But
sun.misc.* is already pretty wide range. For example
I am not that dependent on Sun/Oracle, since OpenJDK
on Linux has also sun.misc.* at the moment.

But I am open to suggestions that would provide:
- Their own contract
- Their own set of realizations

What would Joshua do?

Bye
 
A

Arne Vajhøj

Conceptually Signal/SignalHandler is a solution for
providing a SIGINT hook. When I wrap this in my
own class without other visible classes than from
java.lang.* I am not anymore dependent on sun.misc.*.

For platforms that don't have sun.misc.* I can
bundle a different implementation of my class.
This is programming by contract. My class defines
a contract, and I can deliver what ever realization
I want.

So its only in as far a hack, because I have not yet
done a wide range realization of the contract. But
sun.misc.* is already pretty wide range. For example
I am not that dependent on Sun/Oracle, since OpenJDK
on Linux has also sun.misc.* at the moment.

But I am open to suggestions that would provide:
- Their own contract
- Their own set of realizations

I believe the JNI solution is more clean.

If you use sun.* and hit a platform where it is not
available or work differently, then it is a hard problem
to solve. It basically means back to square one.

If you use JNI and define a C API with certain semantics, then
it should be a relative simple task to implement that on a new
platform (assuming that there are expertise about the platform
available).

Arne
 
J

Jan Burse

Arne said:
If you use JNI and define a C API with certain semantics, then
it should be a relative simple task to implement that on a new
platform (assuming that there are expertise about the platform
available).

In the present case JNI would be more expensive.
I would need to create and bundle a .dll, a
..so and a .dyln. And need 3 different platforms
to develop them. (When I want to support Windows,
Linux and Mac)

Using sun.misc.* takes about 1 hour to implement
the Ctrl-C handler. If someone comes up with
a platform where there is no sun.misc.*, it might
be that there is already some other Java class.

"personally" using JNI to make something CPU/OS independent
is most of the time last resort and NOT a good advice.
There are bigger entities which have most likely already
faced the problem. One has only to search.

For example I found the following just now:

http://rxr.whitequark.org/jruby/source/src/org/jruby/util/SunSignalFacade.java
org.jruby.util.SunSignalFacade

But did not dig further. But for example the
good news are the IBM J9 has also sun.misc.*.

BTW: It was you guys who slapped this into my
face a dozen times, that I have a "personal" program-
ming problem, i.e. that it is my fault. But "personal"
programming problems that are CPU/OS independent
should never call for JNI. Just look around whether
the problem is not so "personal".

But currently I don't waste some time on sun.misc.*,
what interests me is:

FileInputStreamFix

Which fixes the superflous <EOF>. This is also the
title of the thread, and not where do I find a portable
sun.misc.*.

But the same principle does not apply,
that JNI is last resort. Since it is Windows specific,
thats why I put [Windows] in the thread title. Here
you are right a JNI solutions is feasible.

So please forget about sun.misc.* and focus on
the <EOF> issue.

Bye
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top