How to read only one character from stdin without waiting for pressing ENTER? - character

I have CLI implementation for my VisualWorks application.
There is "IOAccessor defaultClass stdin" and I want to read one character without waiting for user enter press.
It is possible?
in C language there is function like getCh ...

This is not a problem of the language: also the C-language getchar() will have to wait.
It is a matter of the underlying Operating System's tty-code. On UNIX (eg. Linux), you'd have to change the tty-characteristics to unbuffered, using an stty (old-style) or ioctl call.
Under other OSs, similar system calls do similar things.

Related

Real world examples of UNIX named pipes

I usually think of UNIX pipes as a quick and dirty way to interact with the console, doing things such as:
ls | grep '\.pdf$' #list all pdfs
I understand that it's possible to use create named pipes using mkfifo and mknod.
Are named pipes still used significantly today, or are they a relic of the past?
They are still used, although you might not notice. As a first-class file-system object provided by the operating system, a named pipe can be used by any program, regardless of what language it is written in, that can read and write to the file system for interprocess communication.
Specific to bash (and other shells), process substitution can be implemented using named pipes, and on some platforms that may be how it actually is implemented. The following
command < <( some_other_command )
is roughly identical to
mkfifo named_pipe
some_other_command > named_pipe &
command < named_pipe
and so is useful for things like POSIX-compliant shell code, which does not recognize process substitution.
And it works in the other direction: command > >( some_other_command ) is
mkfifo named_pipe
some_other_command < named_pipe &
command > named_pipe
pianobar, the command line Pandora Radio player, uses a named pipe to provide a mechanism for arbitrary control input. If you want to control Pianobar with another app, such as PianoKeys, you set it up to write command strings to the FIFO file, which piano bar watches for incoming commands.
I wrote a MAMP stack app in college that we used to manage users in an LDAP database on a file server. The PHP scripts would write commands to a FIFO that a shell script running in launchd would read from and interact with the LDAP database. I had no idea what I was doing, so I don’t know if there was a better or more correct way to do it, but it worked great at the time.
Named pipes are useful where a program would expect a path to a file as an argument as opposed to being willing to read/write with stdin and stdout, though very modern versions of bash can get around this with < ( foo ) it is still sometimes useful to have a file like object which is usable as a pipe.

TTY in perl, explaination and some examples

So I am trying run a perl debugger inside another perl debugger. I keep readin tty in perl is the solution. Can someone explain to me what tty means ( is it terminal type?) and how is it useful? This is where I read it:
http://search.cpan.org/~rjbs/perl-5.18.0/lib/perl5db.pl#$CreateTTY
The reason I am trying to use tty is because of this question I asked:
Pass argument to perl file in debugger and set breakpoint in file executed by system
Thanks to all the ones who answer, the more you guys tell me what it is, better the idea I get :)
TTY (short for teletype) is basically a special input or output filehandle that connects to the terminal - namely, user input. For nitty gritty details, see:
Unix.SE in-depth answer on TTYs
Text Terminal HOWTO
This is what you need to know for starters (hard to say more since you didn't explain what you need to do with a TTY):
On Unix, it typically maps to /dev/tty device or similar
You can test for it using -t in Perl
As far as debugger, 2 things need to be known at least (if you intend to play with the TTY, the last paragraph is the most important). All data is near-quoted from perldoc perldebug
p expr prints to $DB::OUT filehandle (NOT STDOUT), which in turn is open to /dev/tty.
I think this may be controlled by LineInfo option from PERLDB_OPTS but never played with it so not sure.
Can be affected by the following $ENV{PERLDB_OPTS} options:
TTY - The TTY to use for debugging I/O.
noTTY - If set, the debugger goes into NonStop mode and will not connect to a TTY. If interrupted (or if control goes to the debugger via explicit setting of $DB::signal or $DB::single from the Perl script), it connects to a TTY specified in the TTY option at startup, or to a tty found at runtime using the Term::Rendezvous module of your choice.
This module should implement a method named new that returns an object with two methods: IN and OUT . These should return filehandles to use for debugging input and output correspondingly. The new method should inspect an argument containing the value of $ENV{PERLDB_NOTTY} at startup, or "$ENV{HOME}/.perldbtty$$" otherwise. This file is not inspected for proper ownership, so security hazards are theoretically possible.

How interactive command line utilities actually work?

I grasp the basic concept of stdin, stdout, stderr and how programs work with a command line/terminal.
However, I've always wondered how utilities like less in Linux and git log work because they are interactive.
My current thought is that the program does not quit, writes to stdout, listens to key events and writes more to stdout until the user quits pressing q or sends the close signal.
Is my intuition right or is there more to it? Do they detect the amount of lines and characters per line to determine how much to output? And do they clear the screen always before output?
Very interesting question, even if it's a bit open ended.
As mentioned by #tripleee, ncurses is a foundational library for interactive CLI apps.
A bit of history ...
Terminal == "printer" ...
To understand POSIX "terminals", you have to consider their history ... more specifically, you need to think about what a "terminal" meant in the 70's where you'd have a keyboard+printer attached to a serial cable. As you type, a stream of bytes flows to the mainframe which echos them back to the printer causing the printer to echo the command as you type it. Then, typically after pressing ENTER, the mainframe would go off and do some work and then send output back to be printed. Since it basically a glorified dot-matrix printer, we are talking append-only here. There was no "painting the screen" or anything fancy like that.
Try this:
echo -e "Hi there\rBye"
and you'll see it print "Bye there". "\r" is a carriage return with no line feed. A carriage is that printer part that moves back and forth in an old dot-matrix printer and actually does the printing. So if you return the carriage back to the left side of the page and fail to advance the paper (ie, "line feed"), then you will start printing over the current line of text. "terminal" == "printer".
Monitors and software terminals ... still line-oriented
So flash forward a bit and a revolutionary tech called "monitors" comes about where you have a virtualized terminal display that can be rewritten. So like all good tech, we innovated incrementally by adding more and more special escape codes. For example, check out the ANSI color codes. If you are on a terminal that doesn't recognize those escape codes, you'll see a bunch of gibberish in the output from those uninterpreted codes:
"methodName": ESC[32m"newInstance"ESC[39m,
"fileName": ESC[32m"NativeConstructorAccessorImpl.java"ESC[39m,
"className": ESC[32m"sun.reflect.NativeConstructorAccessorImpl"ESC[39m,
"nativeMethod": ESC[33mfalseESC[39m,
When your terminal sees '\033' (ESC), '[', ..., 'm', it interprets it as a command to change the color. Try this:
echo -e "\033[32mgreen\033[39m"
So anyways, that's the history/legacy of the Unix terminal system which was then inherited by Linux and BSD (eg, macs), and semi-standardized as POSIX. Check out termio.h which defines the kernel interface for interacting with terminals. Almost certainly, Linux/BSD have a bunch of more advanced functions that aren't fully standardized into POSIX. While talking about "standards", there's also a bunch of de-facto terminal device protocol standards like the venerable VT100. Software "terminal emulators" like SSH or PuTTY know how to speak VT100 and usually a bunch of more advanced dialects as well.
Shoe-horning "interactive" onto a "line-oriented" interface ...
So ... interactive ... that doesn't really fit well with a line-printer view of the world. It's layered on top. Input is easy; instead of automatically echoing each keystroke typed and waiting for ENTER (ala "readline"), we have the program consume keystrokes as they come in from the TTY. Output is more complex. Even though the fundamental abstraction is a stream of output, with enough escape codes you can repaint the screen by positioning the "caret" and writing new text on top of old text (just like with my "\r" example). None of this is fun to implement yourself, especially when you want to support multiple environments with different escape codes. .... thus the libraries, of which ncurses is one of the most well known. To get an idea of the funky magic done to efficiently render a dynamic screen into a line-oriented TTY, check out Output and Screen Updating from "A Hacker's Guide to NCURSES".

how to perl for bi-directional communication with dsmadmc.exe?

I have simple web-form with a little js script that sends form values to a text box. This combined value becomes a database query.
This will be sendt to dsmadmc (TSM administrative command line).
How can I use perl to keep the dsmadmc process open for consecutive input/output without the dsmadmc process closing between each input command sent?
And how can I capture the output - this is to be sent back to the same web page, in a separate div.
Any thought, anyone?
Probably IPC::Open2 could help. It allows to read/write to/from both input and output of an external process.
Beware of deadlocks though (i.e. situations where both your code and the app wait for their counterpart). You might want to use IO::Select to handle that.
P.S. I don't know how these modules behave on windows (.exe?..), but from a quick google search it looks like they are compatible.

How can I check if a file is open by another program in Perl?

In Perl, how do I test if a file of open by another Perl program? I need the first program to be done before the second program can start.
alt text http://musicritics.com/wp/wp-content/uploads/2009/05/20061129morbo.gif
FILES DO NOT WORK THAT WAY!
But seriously, folks, advisory locks with flock are generally the best you can do. There's no way to guarantee that no other program wants to read or write a file at the same time as you.
You may be able to coordinate the two programs using flock: The first program would lock the file, and the second program would also try to acquire a lock on it, and it would block until the first program releases the lock.
Is flock() available on your system ? Otherwise, the two programs have be be synchronized, they can communicate thru a pipe or a socket, or via the presence/absence of a file.
Another direction if you are on a Unix-like system, could be use lsof output.
I assume having the first program starting the second one is not feasible.
In my experience, flock works fine on local systems on both Windows and Linux.
You could also, presumably, have the first program exec the second program when it's done processing the file.
If you are running on Windows, you could call CreateFile directly with a dwShareMode of 0.
According to MSDN:
Prevents other processes from opening a file or device if they request delete, read, or write access.
Win32API::File gives access to this call.
To specifically look for whether or not a file is open or in use, if you're on unix there is a wrapper to the lsof command to list open files: Unix::Lsof
If you're in Unix, you could also call fuser.
I might be misunderstanding the context and my comment may have limited usability in your case, but depending on what you are using the code for/on - Using serial queues to ensure that tasks to execute in a predictable order maybe an option. Your application (written in Perl) will need to explicitly create and manage the serial queues. For more details refer to the following link: GCD