C++ Learning Community Forum
August 01, 2010, 03:14:08 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Hello. Smiley
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Strange output when dealing with csh/bash from pseudo-terminals  (Read 1030 times)
ih8censorship
Megalomaniac!!!
Administrator
C++ guru
*****
Posts: 1236



View Profile
« on: April 20, 2008, 09:13:43 PM »

For some reason, i am getting output that i am not expecting and i don't know why. It's almost like the terminals I'm used to filter out some of the output and only display certain things to the user or something. Its pretty strange, i've included the code I've been using and the output of the code for both csh and bash. I know i could parse the data i need easily, but im wondering if anyone has a better way or at least an explanation of why the output I'm getting isn't what I'm seeing when i use csh and bash from the commandline.

This code is messy, but i wanted it all to compile with one call to g++ for testing.
Code
GeSHi (cpp):
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
 
#include <sys/time.h>
 
#include <fcntl.h>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
#include <fstream>
 
 
class liniocontroller
{
public:
 liniocontroller();
 void run();
 int write(std::string);
 void read();
 virtual void readhandler(std::string);
 
 
private:
 int master;
 int slave;
 std::string slavename;
 
};
 
liniocontroller::liniocontroller()
{
//open pseudo-terminal "master" multiplexer device, and save the file descriptor in master
master=open("/dev/ptmx",O_RDWR);
 //open the pseudo-terminal "master"
 if(grantpt(master)==0)
 {
  //unlock a pseudo-terminal master/slave pair
  slave=unlockpt(master);
  //save the "slave" end of the terminals device file name as slavename
  slavename=ptsname(master);
 }
}
 
void liniocontroller::run()
{
//create a commandline where shell program receives input from and outputs to slave end of terminal
std::string cmdline="bash >"+slavename+" <"+slavename;
//run that commandline, in a new thread so we still have control here
boost::thread runthread(boost::bind(system,cmdline.c_str()));
//start up a thread to read data that is sent back to the master end
boost::thread readthread(boost::bind(&liniocontroller::read,this));
}
 
void liniocontroller::read()
{
char buffer='\0';
std::string indata;
 //read one charachter at a time and append it to a string while on the same line.
 
fd_set rdfs;
FD_ZERO(&rdfs);
FD_SET(master,&rdfs);
struct timeval tv;
 
//Wait up to 1 second.
   tv.tv_sec = 0;
   tv.tv_usec = 0;
 
 while(/*select(master,&rdfs,NULL,NULL,&tv) && */buffer != '\n')
 {
  ::read(master,&buffer,1);
  indata+=buffer;
 }
//send data to the handler to be further processed
readhandler(indata);
//start over.
read();
}
 
void liniocontroller::readhandler(std::string indata)
{
std::ofstream fout("output2.txt",std::ios::app);
fout<<indata;
fout.close();
}
 
int liniocontroller::write(std::string outdata)
{
 
outdata+='\n';//stdin is line buffered, so add this so it knows to act on what you wrote.
return ::write(master,outdata.c_str(),outdata.size());
}
 
int main()
{
   liniocontroller control;
   control.run();
   control.write("fortune");
   std::cin.get();
   return 0;
}
 
 
Created by GeSHI 1.0.7.18

output from csh - http://www.fileupyours.com/view/172153/output.txt
output from bash- http://www.fileupyours.com/view/172153/output2.txt
Logged

PC==perfect_companion

Knowledge cannot come packaged and predigested; it must be chewed over carefully before swallowed.

What have you tried?
kruncher
N00b!!1
*
Posts: 4


View Profile
« Reply #1 on: April 21, 2008, 04:16:17 AM »

Almost looks like an array (C terminology?) which has not been "zeroed" out. I've gotten weird things like that in buffers where I've not nulled the array before usage or when using the string again.

Do you even have a file or directory located in /media/XTV_STR_DSK or reference that anywhere in your source code?

Also, the structure of the output.txt file is out of wack. Why is the fortune command first, shouldn't it be your prompt (klyons on somewhere:) first, then the command?

Or is it possible that your input and output to this virtual terminal are overlapping (thread issues?) and introducing oddness?

The reason I say this is because you have weird content after your prompt (stdout, "klyons on somewhere") and before the command (stdin first then read back from stdout, "fortune").

Just my 2 cents...
Logged
ih8censorship
Megalomaniac!!!
Administrator
C++ guru
*****
Posts: 1236



View Profile
« Reply #2 on: April 21, 2008, 05:29:56 AM »

I was thinking it could be a buffer overflow issue as well at first, now I'm kindof not thinking so as there is something of a pattern in the output of both shells-

0x1b 0x5d 0x32 0x3b  /*stuff*/ 0x1b 0x5d 0x31 0x3b /*hostname*/ 0x07 or '\a'  /* data i would want to use*/

Also the 0x07 character or '\a' being there before what is output after the shell prompt seems almost like it would be a flag of some sort.

The executable is in "/media/XTV_STR_DSK/virtual terminal", it's my usb hard disk. It has the funny volume name because i took the drive out of a dead tivo and just stuck it in an enclosure haha.

My theory as to why fortune is there on top, is that those shells dont automatically give you a text prompt, maybe they need a newline sent to them first and you just get an illusion of the way it works through your terminal emulator window. I dunno i'd have to look into it further. that first line would have been filtered out in my "real" code anyway (as the same thing happens in Windows... gotta love inheritance) , so i'm not worried about that.
Logged

PC==perfect_companion

Knowledge cannot come packaged and predigested; it must be chewed over carefully before swallowed.

What have you tried?
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!