Read a single byte from stdin

M

Martin Gregorie

I don't think it is required to be in any specific languages.
Agreed.
I would expect it to be coded in C (with possible a bit of C++) on all
platforms - both POSIX complaint and non POSIX compliant.
That would be my guess too, with as much POSIX compliance as possible.
But JVM's are very platform specific, so they do not have a problem with
platform specific code.
Sure, but it still pays for the major JVM suppliers to keep as much code
as possible platform independent. If they restrict themselves as far as
possible to portable functions and constructs they can minimize the size
of the #ifdef forest and/or the set of platform-specific source modules.
 
T

Tom Anderson

Earlier today I was wondering how possible it would be to do exactly that
via the KeyEvent mechanism.

It seems likely that I'll have to define an invisible AWT or Swing window
the same size as my screen in order to define the area where key presses
would generate KeyEvents. The idea is that this whole mess should run on
a headless server that's being accessed via ssh, so does anybody know if
a program that creates invisible AWT or Swing objects can start correctly
on a headless system that doesn't have either an X-server running locally
or access to a remote X-term via ssh X.11 forwarding?

Nope. And if it did, it wouldn't do what you want - those key events can
only come from X, so if there's no X, there are no key events.

I'd look for a java wrapper round curses/ncurses - you're talking about "a
headless machine" here, which suggests that there's a particular machine
in mind and portability isn't a requirement here. Alternatively, a C
driver program that reads a character at a time (perhaps using the POSIX
incantation someone posted already) and passes it to java.

Or, how about making your app use a socket, then connecting to it with
telnet? It's a bit Heath Robinson, but i think that should give you a
character at a time, provided your telnet is cooperative.

tom
 
R

Roedy Green

It's a bit Heath Robinson

Robinson was an English cartoonist and illustrator, best-known for the
complicated and outlandish inventions he portrayed.

The American equivalent would be Rube Goldberg.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"For reason that have a lot to do with US Government bureaucracy, we settled on the one issue everyone could agree on, which was weapons of mass destruction."
~ Paul Wolfowitz 2003-06, explaining how the Bush administration sold the Iraq war to a gullible public.
 
J

Joshua Cranmer

Martin said:
Sure, but it still pays for the major JVM suppliers to keep as much code
as possible platform independent. If they restrict themselves as far as
possible to portable functions and constructs they can minimize the size
of the #ifdef forest and/or the set of platform-specific source modules.

There are problems with some areas of platform-independence. Any JVM
likely to be used in realistic conditions would have some form of JIT,
which is obviously rather processor-dependent. Also, many
high-performance JVMs will be in the stage of über-optimization--there's
some code for swapping bytes in assembly in Sun's JDK.

Finally, any native code calling will have to have some form reflective
access, so one has to differentiate different function call schemes on
various processors.

Now, granted, a good JVM would isolate all of the processor or
platform-dependent code into a few classes or modules (depending on C++
or C implementation). But there is still a large remnant of dependence;
in some cases, JVMs might eschew portability in favor of speed.
 
A

Arne Vajhøj

Martin said:
That would be my guess too, with as much POSIX compliance as possible.

Sure, but it still pays for the major JVM suppliers to keep as much code
as possible platform independent. If they restrict themselves as far as
possible to portable functions and constructs they can minimize the size
of the #ifdef forest and/or the set of platform-specific source modules.

They should.

But some JVM suppliers only support a single platform. Others may
support multiple platforms but are so divisionalized that it is in
reality like two suppliers.

Arne
 
A

Arne Vajhøj

Martin said:
That's true for all full-duplex physical terminals I've used, e.g. Wyse
120, and the X-term console. AFAIK it was only the old half-duplex
terminals (or half-duplex compatibility mode on newer ones) that don't
require a software echo from the host.

Yep. I have not run half-duplex since NOS on CDC Cyber.
There's a useful little OS/9 utility, codes, that shows what byte(s) a
terminal keystroke generates that I've re-implemented for DOS and *nixen
without any problem. Here's what it does:

Keystroke Output
========= ======
a a = 97 0x61
^A . = 1 0x01 (ctrl-a)
right arrow . = 27 0x1b (Esc)
[ = 91 0x5b
C = 67 0x43

'Right arrow' is the '->' key with an X-term console running. 'codes' is
a good test case for this stuff, since to work correctly it needs
unbuffered terminal input with echoing suppressed. Non-printable
characters are output as '.' to avoid messing up the display so echo must
be off.

You can look up those in any VT100/VT200 manual.
Implementing this has involved three C dialects: K&R under OS/9, Borland
C for DOS/Windows and the Gnu ANSI/POSIX C for Linux. All have methods
for suppressing line buffering and echo though the system calls to do it
differ. I haven't tried compiling it with the DJGPP DOS/Windows port of
the Gnu C compiler, but the Linux version should 'just work' there too.

Cygwin on Windows would work like *nix, MinGW on Windows would work
like Borland.

It is a long time since I have last used DJGPP, but let me
check. Hm - it seems to have conio.

Arne
 
T

Tom Anderson

Arne said:
I would put it another way.

If System.in is line buffered on one or more systems, then
a portable program can not not assume it is not line buffered.

Implementation specific does not solve hos problem. He need
something that is documented to work in all compliant
implementations.

Right. In other words, if the JRE doesn't provide this (which to the
best of my knowledge, it does not), the only solution is
system-specific JNI. In fact, JRE support for this feature amounts to
a requirement that JRE implementors provide the system-specific JNI
for us.

Having said that, suppose for the sake of argument that you'd
constructed seperate JNI for Windows, Mac, and Linux [1], and were happy
that you'd now solved the problem for all of your likely users. What's
the best way to package your application? Do you need three different
versions, or is there some magic that will allow the app to locate and
load the proper version of the JNI library at runtime?

There's no chance that Java will load the wrong library in this case, as
those three platforms have different naming conventions for libraries (not
to mention different formats): you'd have SCHILLING.DLL,
libschilling.dylib, and libschilling.so, respectively. You might have a
problem if you wanted to support multiple unices, especially if they all
used the same binary format - i don't know how you'd disambiguate two ELFs
called libschilling.so where one was for linux and one for FreeBSD.

However, there is a bigger problem, which i think renders the name clash
moot: how do you get the JVM to find your library. You can't just put it
somewhere on disk and hope. Unless the JVM has some particular mechanism
i'm not aware of for finding libraries (which is more than possible),
you'll have to use the local OS's method, eg setting LD_LIBRARY_PATH on
linux - in which case you can sidestep the ambiguity problem by putting
the different versions of your library in different places.

tom
 
M

Martin Gregorie

You can look up those [terminal-specific control sequences] in any
VT100/VT200 manual.
If you're using a VT100/200. Or just read /etc/termcap

Granted, its reduced to a nice-to-have on most modern OSen, but it was
really useful on OS/9, a small, fast real time OS initially implemented
on MC6809 and rapidly ported to the MC 68xxx chipset. It was always multi-
user (yes, even on a 64KB 6809. Really.) and could and usually did run
with a fearsome collection of incompatible terminals connected to its box
- say VT-100, Wyse-60, and a TVI925.
It is a long time since I have last used DJGPP, but let me check. Hm -
it seems to have conio.
Code written on Linux ports pretty easily to Win95 with DJGPP. Almost the
only denizens of the #ifdef forest are differing include names and code
needed to deal with the DOS's drive letters and separate filing systems.
As you'd expect is a much cleaner port than a move to the Borland family
of compilers.
 
M

Martin Gregorie

Nope. And if it did, it wouldn't do what you want - those key events can
only come from X, so if there's no X, there are no key events.
OK, sounds like it may have to be JINI then, and the POSIX incantation
from my 'codes' utility.
You're talking about
"a headless machine" here, which suggests that there's a particular
machine in mind and portability isn't a requirement here.
No particular machine in mind, just one with either no graphical X
libraries or running at init level 3 though I don't see a need to handle
serial terminals - just the console and ssh or telnet sessions. ssh could
include PuTTY, which has no graphical capability.
Or, how about making your app use a socket, then connecting to it with
telnet? It's a bit Heath Robinson, but i think that should give you a
character at a time, provided your telnet is cooperative.
Ideally it would work from a command line in a normal login session,
which rather negates the socket idea.
 
T

Tom Anderson

OK, sounds like it may have to be JINI then, and the POSIX incantation
from my 'codes' utility.

Yup.

I'd suggest using JNI instead of Jini, though. :)
No particular machine in mind, just one with either no graphical X
libraries or running at init level 3 though I don't see a need to handle
serial terminals - just the console and ssh or telnet sessions. ssh
could include PuTTY, which has no graphical capability.

Still, if you know it's always going to be a POSIX machine, then the JNI/C
approach doesn't lose you any real value here.
Ideally it would work from a command line in a normal login session,
which rather negates the socket idea.

Sorry, i didn't explain myself very well (ie at all) there. I was thinking
of a wrapper script which looks like:

#! /bin/bash
MARTIN_PORT=${MARTIN_PORT:-4141}
java MartinApp -Dtelnet.port=$MARTIN_PORT &
APP_PID=$!
sleep 5 # wait for server socket to come up
telnet localhost $MARTIN_PORT # user interacts with this
kill $APP_PID # ask for graceful shutdown ...
wait # ... and wait for it to happen

tom
 
A

Arne Vajhøj

Martin said:
You can look up those [terminal-specific control sequences] in any
VT100/VT200 manual.
If you're using a VT100/200.

It looked a lot like VT100/VT200.

Besides outside the mainframe world I would expect non-VT-compatible
terminals to be rare today.
Granted, its reduced to a nice-to-have on most modern OSen, but it was
really useful on OS/9, a small, fast real time OS initially implemented
on MC6809 and rapidly ported to the MC 68xxx chipset. It was always multi-
user (yes, even on a 64KB 6809. Really.) and could and usually did run
with a fearsome collection of incompatible terminals connected to its box

I believe you.

Arne
 
A

Arne Vajhøj

Mike said:
Having said that, suppose for the sake of argument that you'd
constructed seperate JNI for Windows, Mac, and Linux [1], and were
happy that you'd now solved the problem for all of your likely users.
What's the best way to package your application? Do you need three
different versions, or is there some magic that will allow the app to
locate and load the proper version of the JNI library at runtime?

I would go for an installer generator that know all 3 OS'es.

No simple packaging solution.

Arne
 
M

Martin Gregorie

Sorry, i didn't explain myself very well (ie at all) there. I was
thinking of a wrapper script which looks like:
... and, because I've been thinking 'ssh session', I was thinking you
meant that the client would be run remotely to the target program.
#! /bin/bash
MARTIN_PORT=${MARTIN_PORT:-4141}
java MartinApp -Dtelnet.port=$MARTIN_PORT & APP_PID=$!
sleep 5 # wait for server socket to come up telnet localhost
$MARTIN_PORT # user interacts with this kill $APP_PID # ask for graceful
shutdown ... wait # ... and wait for it to happen
Cute. I'll have a play with that.
 
M

Mike Schilling

Arne said:
Mike said:
Having said that, suppose for the sake of argument that you'd
constructed seperate JNI for Windows, Mac, and Linux [1], and were
happy that you'd now solved the problem for all of your likely
users.
What's the best way to package your application? Do you need three
different versions, or is there some magic that will allow the app
to
locate and load the proper version of the JNI library at runtime?

I would go for an installer generator that know all 3 OS'es.

No simple packaging solution.

Yeah, that's what I thouight. That's one of the reasons I try as
hard as I can to avoid JNI. Imagine if you could do the following:

1. Put a JNI-path entry in a jar file's manifest
2. This would point to a JNI library, indexed by os.name, os.arch, and
os.version

Developing JNI would still be a bit onerous, but shipping JNI-using
apps would be a breeze. And adding new platforms would be
straightforward for either the developer or the end-user.
 
A

Arne Vajhøj

Mike said:
Arne said:
Mike said:
Having said that, suppose for the sake of argument that you'd
constructed seperate JNI for Windows, Mac, and Linux [1], and were
happy that you'd now solved the problem for all of your likely
users.
What's the best way to package your application? Do you need three
different versions, or is there some magic that will allow the app
to
locate and load the proper version of the JNI library at runtime?
I would go for an installer generator that know all 3 OS'es.

No simple packaging solution.

Yeah, that's what I thouight. That's one of the reasons I try as
hard as I can to avoid JNI. Imagine if you could do the following:

1. Put a JNI-path entry in a jar file's manifest
2. This would point to a JNI library, indexed by os.name, os.arch, and
os.version

Developing JNI would still be a bit onerous, but shipping JNI-using
apps would be a breeze. And adding new platforms would be
straightforward for either the developer or the end-user.

The problem would be that the library is not loaded by JVM code
but by OS code - there may be OS'es where it would be impossible
to let the JVM specify the path to the OS.

Arne
 
M

Mike Schilling

Arne said:
Mike said:
Arne said:
Mike Schilling wrote:
Having said that, suppose for the sake of argument that you'd
constructed seperate JNI for Windows, Mac, and Linux [1], and
were
happy that you'd now solved the problem for all of your likely
users.
What's the best way to package your application? Do you need
three
different versions, or is there some magic that will allow the
app
to
locate and load the proper version of the JNI library at runtime?
I would go for an installer generator that know all 3 OS'es.

No simple packaging solution.

Yeah, that's what I thouight. That's one of the reasons I try as
hard as I can to avoid JNI. Imagine if you could do the
following:

1. Put a JNI-path entry in a jar file's manifest
2. This would point to a JNI library, indexed by os.name, os.arch,
and os.version

Developing JNI would still be a bit onerous, but shipping JNI-using
apps would be a breeze. And adding new platforms would be
straightforward for either the developer or the end-user.

The problem would be that the library is not loaded by JVM code
but by OS code - there may be OS'es where it would be impossible
to let the JVM specify the path to the OS.

But that's Sun's problem, not mine.

Less silly response: if the JVM has to copy the library from the
classpath to the OS-required location, that's fine with me. Anyway,
while I know of OS's which specify the *default* location for shared
libraries/shareable images/DLLs, all have system calls that allow them
to be loaded from a location given by the caller.
 
T

Tom Anderson

Arne said:
Mike said:
Arne Vajh?j wrote:
Mike Schilling wrote:
Having said that, suppose for the sake of argument that you'd
constructed seperate JNI for Windows, Mac, and Linux [1], and
were
happy that you'd now solved the problem for all of your likely
users.
What's the best way to package your application? Do you need
three
different versions, or is there some magic that will allow the
app
to
locate and load the proper version of the JNI library at runtime?
I would go for an installer generator that know all 3 OS'es.

No simple packaging solution.

Yeah, that's what I thouight. That's one of the reasons I try as
hard as I can to avoid JNI. Imagine if you could do the
following:

1. Put a JNI-path entry in a jar file's manifest 2. This would point
to a JNI library, indexed by os.name, os.arch, and os.version

It would probably have to point to a directory holding libraries, rather
than a library, because library names can vary wildly.

Inspired by a thing i work with, it could just let you do system property
substitution in the path, so:

JNI-Path: lib/native/{os.name}/libs_{os.arch}
But that's Sun's problem, not mine.

Less silly response: if the JVM has to copy the library from the
classpath to the OS-required location, that's fine with me. Anyway,
while I know of OS's which specify the *default* location for shared
libraries/shareable images/DLLs, all have system calls that allow them
to be loaded from a location given by the caller.

Since the JVM manages to link code that it's made up itself, this should
be a fairly minor challenge.

tom
 
A

Arne Vajhøj

Tom said:
Since the JVM manages to link code that it's made up itself, this should
be a fairly minor challenge.

No guarantee that JVM use DLL's itself or that the process has write
permission where the DLL's reside.

Arne
 
T

Tom Anderson

No guarantee that JVM use DLL's itself or that the process has write
permission where the DLL's reside.

No, and it doesn't need either of those things. If it can read the DLL
file, it can read it into memory, and then link it as if it was code that
it had compiled itself. The JVM needs to understand the library format,
but that's a matter of code, not one of capabilities. Even if the JVM
isn't a JIT, because it's a C program in the end (or rather, assuming it
is a C program or similar), it should be possible for it to read in a
library as a file, make it executable, then find and jump to the relevant
point in it.

I'm not suggesting this as a sensible thing to do, mind. Using the OS's
own linker is almost certainly a much better idea.

tom
 
A

Arne Vajhøj

Tom said:
No, and it doesn't need either of those things. If it can read the DLL
file, it can read it into memory, and then link it as if it was code
that it had compiled itself. The JVM needs to understand the library
format, but that's a matter of code, not one of capabilities. Even if
the JVM isn't a JIT, because it's a C program in the end (or rather,
assuming it is a C program or similar), it should be possible for it to
read in a library as a file, make it executable, then find and jump to
the relevant point in it.

I was assuming Mikes method "if the JVM has to copy the library
from the classpath to the OS-required location".

That requires write permission.

If you don't do that, then you don't need write permission. But
will have other problems to resolve.

Arne
 

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

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top