End of input in XTerm usnig keyboard - xterm

How can I signal XTerm terminal to end of input. In my case, I run a C++ program in XTerm console and I want to signal the program the end of input by pressing some combination of keyboard buttons.(I tried Ctrl+D Ctrl+Z ).My program goes like this :
map<int,string>info;
string name;
int age;
cin>>name;
while( **?????????** ){ //Input till EOF , missing logic
cin>>age;
info.insert( pair<int,string>(age,name) );
cin>>name;
}
The program proceeds upon receiving the end of input signal from terminal.

You always need to check the input after reading, i.e., your program should look something like this:
while (std::cin >> name >> age) {
// do something with name and age
}
This will read from std::cin until something fails. You can check if std::cin.eof() is set to determine if having reached the end of the of the input is the cause of the error or there was some other failure, e.g., an attempt to enter something which isn't a number for the age.

Related

Ctrl+Z behaviour in terminal

string s;
while(getline(cin,s)){
cout << "---" << endl
for(auto c: s) cout << int(c) << endl;
}
cout << "Exiting";
If my input is Ctrl+Z, then I press enter once, and my program exits immediately.
^Z
Exiting
If I enter a character before pressing Ctrl+Z, then I have to press enter twice, and my program does not exit.
s^Z
---
115
26
I had always interpreted Ctrl+Z as the EOF character. getline would continue until it reaches this character, at which point getline tests false and my program would exit. I'm curious why my program interprets Ctrl+Z as the substitute character 26, depending on whether there is a preceding character or not, and why it was necessary for me to press Enter twice in the second example?
26 is code of ^Z on your platform , and ^Z is a EOF marker for terminal, that's true. Characters with codes less than 32 are control characters for ASCII -compatible platform, I hope you know that. 26 isn't a substitute character, it's actual control code, ^Z or some "bug" character are substitutes. getline reads input until EOL (end-of-line, designated as CR by ASCII) or EOF (end of file, end of stream, designated as SUB) is encountered in stream, so ^Z is read with the second call of getline. That behavior is absolutely correct.
It is defined by platform (or, more precisely, by terminal type) if characters are sent to input buffer immediately or after some flush command occurred. Usual cause of buffer flush is EOL character, that's your ENTER (CR - Carriage return). Tat's why program receives EOF after Enter in your case. Note that some platform use LF (line feed) as EOL, and some - a pair of LF+CR. C literal '\n' is to be correctly translated into particular EOL marker.
Note, that you can use different delimiter:
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline(
std::basic_istream<CharT,Traits>& input,
std::basic_string<CharT,Traits,Allocator>& str,
CharT delim );
ASCII table with substitute Control+ :

D: executeShell on Windows to run another program not returning immediately

I'm using D as a scripting language for Windows 7 console stuff to automate boring tasks. One of my scripts (open.exe) is supposed to allow me to open stuff from the command line without me having to specify which program I use (I have a configuration file with this stuff). Now, I use executeShell to do this, and call something like start [name of program I want to use] [name of input file]. If I do this directly from the shell, it returns immediately, but if I do it using my D script, it doesn't return until the program that it opens is closed. What should I do to allow it to return immediately?
For reference purposes, this is the business logic of my script (the main method just does some argument parsing for piping purposes):
immutable path = "some//path//going//to//config//file.conf";
void process(string input) {
string extension = split(input,".")[1]; //get file extension from input
auto config = File(path,"r"); auto found = false;
while (!config.eof()){
auto line = chomp(config.readln());
if (line[0]!='#') { //skip comment lines
auto divided = split(line, ":");
if (divided[0] == extension) {
found = true;
auto command = "start " ~ divided[1] ~ " " ~ input;
auto result = executeShell(command);
//test for error code and output if necessary
writeln(result.output);
}
}
}
if (!found)
writeln("ERROR: Don't know how to open " ~ input);
}
From the top of the std.process documentation:
Execute and wait for completion, collect output - executeShell
The Windows start program spawns a process and exits immediately. D's executeShell does something else. If you'd like to spawn another program, use the appropriate functions: spawnProcess or spawnShell.

C - passing an unknown command into execvp()

I'm writing a fake shell, where I create a child process and then call execvp(). In the normal shell, when I enter an unknown command such as 'hello' it returns 'hello: Command not found.' However, when I pass hello into execvp(), it doesn't return any error by default and just continues running the rest of my program like nothing happened. What's the easiest way to find out if nothing was actually run? here's my code:
if(fork() == 0)
{
execvp(cmd, args);
}
else
{
int status = 0;
int corpse = wait(&status);
printf(Child %d exited with a status of %d\n", corpse, status);
}
I know that if corpse < 0, then it's an unknown command, but there are other conditions in my code not listed where I don't want to wait (such as if & is entered at the end of a command). Any suggestions?
All of the exec methods can return -1 if there was an error (errno is set appropriately). You aren't checking the result of execvp so if it fails, the rest of your program will continue executing. You could have something like this to prevent the rest of your program from executing:
if (execvp(cmd, args) == -1)
exit(EXIT_FAILURE);
You also want to check the result of fork() for <0.
You have two independent concerns.
1) is the return value of execvp. It shouldn't return. If it does there is a problem. Here's what I get execvp'ing a bad command. You don't want to wait if execvp fails. Always check the return values.
int res = execvp(argv[1], argv);
printf ("res is %i %s\n", res, strerror(errno));
// => res is -1 No such file or directory
2) The other concern is background processes and such. That's the job of a shell and you're going to need to figure out when your program should wait immediately and when you want to save the pid from fork and wait on it later.

Get_user running at kernel mode returns error

I have a problem with get_user() macro. What I did is as follows:
I run the following program
int main()
{
int a = 20;
printf("address of a: %p", &a);
sleep(200);
return 0;
}
When the program runs, it outputs the address of a, say, 0xbff91914.
Then I pass this address to a module running in Kernel Mode that retrieves the contents at this address (at the time when I did this, I also made sure the process didn't terminate, because I put it to sleep for 200 seconds... ):
The address is firstly sent as a string, and I cast them into pointer type.
int * ptr = (int*)simple_strtol(buffer, NULL,16);
printk("address: %p",ptr); // I use this line to make sure the cast is correct. When running, it outputs bff91914, as expected.
int val = 0;
int res;
res= get_user(val, (int*) ptr);
However, res is always not 0, meaning that get_user returns error. I am wondering what is the problem....
Thank you!!
-- Fangkai
That is probably because you're trying to get value from a different user space. That address you got is from your simple program's address space, while you're probably using another program for passing the value to the module, aren't you?
The call to get_user must be made in the context of the user process.
Since you write "I also made sure the process didn't terminate, because I put it to sleep for 200 seconds..." I have a feeling you are not abiding by that rule. For the call to get_user to be in the context of the user process, you would have had to make a system call from that process and there would not have been a need to sleep the process.
So, you need to have your user process make a system call (an ioctl would be fine) and from that system call make the call to get_user.

How to trace a program from its very beginning without running it as root

I'm writing a tool that calls through to DTrace to trace the program that the user specifies.
If my tool uses dtrace -c to run the program as a subprocess of DTrace, not only can I not pass any arguments to the program, but the program runs with all the privileges of DTrace—that is, as root (I'm on Mac OS X). This makes certain things that should work break, and obviously makes a great many things that shouldn't work possible.
The other solution I know of is to start the program myself, pause it by sending it SIGSTOP, pass its PID to dtrace -p, then continue it by sending it SIGCONT. The problem is that either the program runs for a few seconds without being traced while DTrace gathers the symbol information or, if I sleep for a few seconds before continuing the process, DTrace complains that objc<pid>:<class>:<method>:entry matches no probes.
Is there a way that I can run the program under the user's account, not as root, but still have DTrace able to trace it from the beginning?
Something like sudo dtruss -f sudo -u <original username> <command> has worked for me, but I felt bad about it afterwards.
I filed a Radar bug about it and had it closed as a duplicate of #5108629.
Well, this is a bit old, but why not :-)..
I don't think there is a way to do this simply from command line, but as suggested, a simple launcher application, such as the following, would do it. The manual attaching could of course also be replaced with a few calls to libdtrace.
int main(int argc, char *argv[]) {
pid_t pid = fork();
if(pid == 0) {
setuid(123);
seteuid(123);
ptrace(PT_TRACE_ME, 0, NULL, 0);
execl("/bin/ls", "/bin/ls", NULL);
} else if(pid > 0) {
int status;
wait(&status);
printf("Process %d started. Attach now, and click enter.\n", pid);
getchar();
ptrace(PT_CONTINUE, pid, (caddr_t) 1, 0);
}
return 0;
}
This script takes the name of the executable (for an app this is the info.plist's CFBundleExecutable) you want to monitor to DTrace as a parameter (you can then launch the target app after this script is running):
string gTarget; /* the name of the target executable */
dtrace:::BEGIN
{
gTarget = $$1; /* get the target execname from 1st DTrace parameter */
/*
* Note: DTrace's execname is limited to 15 characters so if $$1 has more
* than 15 characters the simple string comparison "($$1 == execname)"
* will fail. We work around this by copying the parameter passed in $$1
* to gTarget and truncating that to 15 characters.
*/
gTarget[15] = 0; /* truncate to 15 bytes */
gTargetPID = -1; /* invalidate target pid */
}
/*
* capture target launch (success)
*/
proc:::exec-success
/
gTarget == execname
/
{
gTargetPID = pid;
}
/*
* detect when our target exits
*/
syscall::*exit:entry
/
pid == gTargetPID
/
{
gTargetPID = -1; /* invalidate target pid */
}
/*
* capture open arguments
*/
syscall::open*:entry
/
((pid == gTargetPID) || progenyof(gTargetPID))
/
{
self->arg0 = arg0;
self->arg1 = arg1;
}
/*
* track opens
*/
syscall::open*:return
/
((pid == gTargetPID) || progenyof(gTargetPID))
/
{
this->op_kind = ((self->arg1 & O_ACCMODE) == O_RDONLY) ? "READ" : "WRITE";
this->path0 = self->arg0 ? copyinstr(self->arg0) : "<nil>";
printf("open for %s: <%s> #%d",
this->op_kind,
this->path0,
arg0);
}
If the other answer doesn't work for you, can you run the program in gdb, break in main (or even earlier), get the pid, and start the script? I've tried that in the past and it seemed to work.
Create a launcher program that will wait for a signal of some sort (not necessarily a literal signal, just an indication that it's ready), then exec() your target. Now dtrace -p the launcher program, and once dtrace is up, let the launcher go.
dtruss has the -n option where you can specify name of process you want to trace, without starting it (Credit to latter part of #kenorb's answer at https://stackoverflow.com/a/11706251/970301). So something like the following should do it:
sudo dtruss -n "$program"
$program
There exists a tool darwin-debug that ships in Apple's CLT LLDB.framework which will spawn your program and pause it before it does anything. You then read the pid out of the unix socket you pass as an argument, and after attaching the debugger/dtrace you continue the process.
darwin-debug will exec itself into a child process <PROGRAM> that is
halted for debugging. It does this by using posix_spawn() along with
darwin specific posix_spawn flags that allows exec only (no fork), and
stop at the program entry point. Any program arguments <PROGRAM-ARG> are
passed on to the exec as the arguments for the new process. The current
environment will be passed to the new process unless the "--no-env"
option is used. A unix socket must be supplied using the
--unix-socket=<SOCKET> option so the calling program can handshake with
this process and get its process id.
See my answer on related question "How can get dtrace to run the traced command with non-root priviledges?" [sic].
Essentially, you can start a (non-root) background process which waits 1sec for DTrace to start up (sorry for race condition), and snoops the PID of that process.
sudo true && \
(sleep 1; cat /etc/hosts) &; \
sudo dtrace -n 'syscall:::entry /pid == $1/ {#[probefunc] = count();}' $! \
&& kill $!
Full explanation in linked answer.

Resources