"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "filepopen.cpp" between
blassic-0.10.3.tgz and blassic-0.11.0.tgz

About: Blassic is a classic Basic interpreter.

filepopen.cpp  (blassic-0.10.3.tgz):filepopen.cpp  (blassic-0.11.0.tgz)
// filepopen.cpp // filepopen.cpp
// Revision 6-feb-2005 // Revision 25-apr-2006
#include "file.h" #include "file.h"
#include "blassic.h" #include "blassic.h"
#include "error.h" #include "error.h"
#include "showerror.h" #include "showerror.h"
#include "sysvar.h" #include "sysvar.h"
#include "util.h" #include "util.h"
using util::to_string; using util::to_string;
#include "trace.h" #include "trace.h"
#include <iostream> #include <iostream>
using std::cerr; using std::cerr;
using std::endl; using std::endl;
#include "config_win.h"
#include "config_unistd.h"
#include "config_wait.h"
#ifndef BLASSIC_USE_WINDOWS #ifndef BLASSIC_USE_WINDOWS
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
// Suggested in autoconf manual. #if ! HAVE_PID_T
#ifdef HAVE_SYS_WAIT_H typedef int pid_t;
#include <sys/wait.h>
#endif
#ifndef WEXITSTATUS
#define WEXITSTATUS(star_val) ((unsigned) (stat_val) >> 8)
#endif
#ifndef WIFEXITED
#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif #endif
#include <fcntl.h> #include <fcntl.h>
#include <sys/poll.h> #include <sys/poll.h>
#else #else
#include <windows.h> #include <windows.h>
#undef min #undef min
#undef max #undef max
#endif #endif
// para strerror (errno) // para strerror (errno)
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#define ASSERT assert
namespace blassic { namespace blassic {
namespace file { namespace file {
//*********************************************** //***********************************************
// BlFilePopen // BlFilePopen
//*********************************************** //***********************************************
class BlFilePopen : public BlFile { class BlFilePopen : public BlFile {
protected: protected:
skipping to change at line 206 skipping to change at line 198
showlasterror ("Error creating /dev/null handle"); showlasterror ("Error creating /dev/null handle");
throw ErrOperatingSystem; throw ErrOperatingSystem;
} }
return hnull; return hnull;
} }
void launchchild (const std::string & str, void launchchild (const std::string & str,
bool forread, bool forwrite, bool witherr, bool forread, bool forwrite, bool witherr,
HANDLE & hreadpipe, HANDLE & hwritepipe, HANDLE & childprocess) HANDLE & hreadpipe, HANDLE & hwritepipe, HANDLE & childprocess)
{ {
TRACEFUNC (tr, "launchchild"); TRF;
const std::string command= makecommand (str); const std::string command= makecommand (str);
HANDLE current= GetCurrentProcess (); HANDLE current= GetCurrentProcess ();
const HANDLE hnull= createnull (); const HANDLE hnull= createnull ();
ProtectHandle prnull (hnull); ProtectHandle prnull (hnull);
STARTUPINFO start; STARTUPINFO start;
start.cb= sizeof start; start.cb= sizeof start;
GetStartupInfo (& start); GetStartupInfo (& start);
skipping to change at line 464 skipping to change at line 456
popen.hasread.set (); popen.hasread.set ();
} }
return 0; return 0;
} }
BlFilePopenWindows::BlFilePopenWindows BlFilePopenWindows::BlFilePopenWindows
(const std::string & str, OpenMode nmode) : (const std::string & str, OpenMode nmode) :
BlFilePopen (nmode) BlFilePopen (nmode)
{ {
TRACEFUNC (tr, "BlFilePopenWindows::BlFilePopenWindows"); TRF;
hprocess= INVALID_HANDLE_VALUE; hprocess= INVALID_HANDLE_VALUE;
hreadpipe= INVALID_HANDLE_VALUE; hreadpipe= INVALID_HANDLE_VALUE;
hwritepipe= INVALID_HANDLE_VALUE; hwritepipe= INVALID_HANDLE_VALUE;
hreadthread= NULL; hreadthread= NULL;
nowreading= false; nowreading= false;
finishthread= false; finishthread= false;
error_reading= false; error_reading= false;
eof_found= false; eof_found= false;
skipping to change at line 501 skipping to change at line 493
{ {
ResumeThread (hreadthread); ResumeThread (hreadthread);
nowreading= true; nowreading= true;
canread.set (); canread.set ();
} }
protect.release (); protect.release ();
} }
BlFilePopenWindows::~BlFilePopenWindows () BlFilePopenWindows::~BlFilePopenWindows ()
{ {
TRACEFUNC (tr, "BlFilePopenWindows::~BlFilePopenWindows"); TRF;
// This is to workaround errors in C++ Builder. // This is to workaround errors in C++ Builder.
if (hprocess == INVALID_HANDLE_VALUE) if (hprocess == INVALID_HANDLE_VALUE)
return; return;
if (hreadthread != NULL) if (hreadthread != NULL)
{ {
finishthread= true; finishthread= true;
CloseHandle (hreadthread); CloseHandle (hreadthread);
hreadthread= NULL; hreadthread= NULL;
skipping to change at line 568 skipping to change at line 560
if (error_reading) if (error_reading)
throw ErrOperatingSystem; throw ErrOperatingSystem;
if (eof_found) if (eof_found)
return 0; return 0;
return buffer [bufpos++]; return buffer [bufpos++];
} }
void BlFilePopenWindows::closein () void BlFilePopenWindows::closein ()
{ {
TRACEFUNC (tr, "BlFilePopenWindows::closein"); TRF;
if (! getmode () & Input) if (! getmode () & Input)
throw ErrFileMode; throw ErrFileMode;
finishthread= true; finishthread= true;
CloseHandle (hreadpipe); CloseHandle (hreadpipe);
hreadpipe= INVALID_HANDLE_VALUE; hreadpipe= INVALID_HANDLE_VALUE;
critical.enter (); critical.enter ();
nowreading= true; nowreading= true;
hasread.reset (); hasread.reset ();
canread.set (); canread.set ();
critical.leave (); critical.leave ();
CloseHandle (hreadthread); CloseHandle (hreadthread);
hreadthread= INVALID_HANDLE_VALUE; hreadthread= INVALID_HANDLE_VALUE;
} }
void BlFilePopenWindows::closeout () void BlFilePopenWindows::closeout ()
{ {
TRACEFUNC (tr, "BlFilePopenWindows::closeout"); TRF;
if (! getmode () & Output) if (! getmode () & Output)
throw ErrFileMode; throw ErrFileMode;
CloseHandle (hwritepipe); CloseHandle (hwritepipe);
hwritepipe= INVALID_HANDLE_VALUE; hwritepipe= INVALID_HANDLE_VALUE;
} }
bool BlFilePopenWindows::eof () bool BlFilePopenWindows::eof ()
{ {
TRACEFUNC (tr, "BlFilePopenWindows::eof"); TRF;
if (! getmode () & Input) if (! getmode () & Input)
throw ErrFileMode; throw ErrFileMode;
{ {
CriticalLock lock (critical); CriticalLock lock (critical);
if (bufpos < bufread) if (bufpos < bufread)
return false; return false;
} }
skipping to change at line 644 skipping to change at line 636
char c= getcharfrombuffer (); char c= getcharfrombuffer ();
if (c == 0 && eof_found) if (c == 0 && eof_found)
break; break;
str+= c; str+= c;
} }
return str; return str;
} }
void BlFilePopenWindows::getline (std::string & str, bool) void BlFilePopenWindows::getline (std::string & str, bool)
{ {
TRACEFUNC (tr, "BlFilePopenWindows::getline"); TRF;
if (! getmode () & Input) if (! getmode () & Input)
throw ErrFileMode; throw ErrFileMode;
str= std::string (); str= std::string ();
char c; char c;
while ( (c= getcharfrombuffer () ) != '\r' && c != '\n') while ( (c= getcharfrombuffer () ) != '\r' && c != '\n')
{ {
if (c == 0) if (c == 0)
{ {
skipping to change at line 727 skipping to change at line 719
bufpos= 0; bufpos= 0;
bufread= bytesread; bufread= bytesread;
nowreading= false; nowreading= false;
} }
hasread.set (); hasread.set ();
} while (! error_reading & ! eof_found & ! finishthread); } while (! error_reading & ! eof_found & ! finishthread);
} }
void BlFilePopenWindows::outstring (const std::string & str) void BlFilePopenWindows::outstring (const std::string & str)
{ {
TRACEFUNC (tr, "BlFilePopenWindows::outstring"); TRF;
if (! getmode () & Output) if (! getmode () & Output)
throw ErrFileMode; throw ErrFileMode;
const char * to= str.data (); const char * to= str.data ();
std::string::size_type l= str.size (); std::string::size_type l= str.size ();
DWORD written; DWORD written;
//WriteFile (hpipe, to, l, & written, NULL); //WriteFile (hpipe, to, l, & written, NULL);
if (WriteFile (hwritepipe, to, l, & written, NULL) == 0) if (WriteFile (hwritepipe, to, l, & written, NULL) == 0)
{ {
skipping to change at line 853 skipping to change at line 845
duporfail (newstd, STDIN_FILENO); duporfail (newstd, STDIN_FILENO);
duporfail (newstd, STDOUT_FILENO); duporfail (newstd, STDOUT_FILENO);
duporfail (newstd, STDERR_FILENO); duporfail (newstd, STDERR_FILENO);
close (newstd); close (newstd);
} }
void launchchild (const std::string & str, void launchchild (const std::string & str,
bool forread, bool forwrite, bool witherr, bool forread, bool forwrite, bool witherr,
int & readhandle, int & writehandle, pid_t & childpid) int & readhandle, int & writehandle, pid_t & childpid)
{ {
TRACEFUNC (tr, "launchchild"); TRF;
if (! forread && ! forwrite) if (! forread && ! forwrite)
{ {
ASSERT (false); ASSERT (false);
throw ErrBlassicInternal; throw ErrBlassicInternal;
} }
int writechild= -1; int writechild= -1;
if (forread) if (forread)
createpipe (readhandle, writechild); createpipe (readhandle, writechild);
skipping to change at line 955 skipping to change at line 947
int readhandle; int readhandle;
int writehandle; int writehandle;
pid_t childpid; pid_t childpid;
}; };
BlFilePopenUnix::BlFilePopenUnix BlFilePopenUnix::BlFilePopenUnix
(const std::string & str, OpenMode nmode) : (const std::string & str, OpenMode nmode) :
BlFilePopen (nmode) BlFilePopen (nmode)
{ {
TRACEFUNC (tr, "BlFilePopenUnix::BlFilePopenUnix"); TRFDEB (str);
TRMESSAGE (tr, str);
readhandle= -1; readhandle= -1;
writehandle= -1; writehandle= -1;
childpid= -1; childpid= -1;
launchchild (str, forread, forwrite, witherr, launchchild (str, forread, forwrite, witherr,
readhandle, writehandle, childpid); readhandle, writehandle, childpid);
} }
BlFilePopenUnix::~BlFilePopenUnix () BlFilePopenUnix::~BlFilePopenUnix ()
{ {
TRACEFUNC (tr, "BlFilePopenUnix::~BlFilePopenUnix"); TRF;
// First close the pipes, the child can be waiting for input. // First close the pipes, the child can be waiting for input.
closeread (); closeread ();
closewrite (); closewrite ();
int status; int status;
if (waitpid (childpid, & status, 0) == -1 || ! WIFEXITED (status) ) if (waitpid (childpid, & status, 0) == -1 || ! WIFEXITED (status) )
{ {
showlasterror (); showlasterror ();
throw ErrOperatingSystem; throw ErrOperatingSystem;
} }
TRMESSAGE (tr, "Exit code: " + to_string (WEXITSTATUS (status) ) ); TRDEBS ("Exit code: " << WEXITSTATUS (status) );
sysvar::set (sysvar::ShellResult, WEXITSTATUS (status) ); sysvar::set (sysvar::ShellResult, WEXITSTATUS (status) );
} }
char BlFilePopenUnix::getcharfrombuffer () char BlFilePopenUnix::getcharfrombuffer ()
{ {
if (bufpos >= bufread) if (bufpos >= bufread)
{ {
readbuffer (); readbuffer ();
if (bufread == 0) if (bufread == 0)
return '\0'; return '\0';
} }
return buffer [bufpos++]; return buffer [bufpos++];
} }
void BlFilePopenUnix::closein () void BlFilePopenUnix::closein ()
{ {
TRACEFUNC (tr, "BlFilePopenUnix::closein"); TRF;
if (! getmode () & Input) if (! getmode () & Input)
throw ErrFileMode; throw ErrFileMode;
closeread (); closeread ();
} }
void BlFilePopenUnix::closeout () void BlFilePopenUnix::closeout ()
{ {
TRACEFUNC (tr, "BlFilePopenUnix::closeout"); TRF;
if (! getmode () & Output) if (! getmode () & Output)
throw ErrFileMode; throw ErrFileMode;
closewrite (); closewrite ();
} }
bool BlFilePopenUnix::eof () bool BlFilePopenUnix::eof ()
{ {
TRACEFUNC (tr, "BlFilePopenUnix::eof"); TRF;
if (! getmode () & Input) if (! getmode () & Input)
throw ErrFileMode; throw ErrFileMode;
if (bufpos < bufread) if (bufpos < bufread)
return false; return false;
readbuffer (); readbuffer ();
return bufread == 0; return bufread == 0;
} }
skipping to change at line 1057 skipping to change at line 1048
str+= c; str+= c;
} }
else else
str+= c; str+= c;
} }
return str; return str;
} }
void BlFilePopenUnix::getline (std::string & str, bool) void BlFilePopenUnix::getline (std::string & str, bool)
{ {
TRACEFUNC (tr, "BlFilePopenUnix::getline"); TRF;
if (! getmode () & Input) if (! getmode () & Input)
throw ErrFileMode; throw ErrFileMode;
str= std::string (); str= std::string ();
char c; char c;
while ( (c= getcharfrombuffer () ) != '\r' && c != '\n') while ( (c= getcharfrombuffer () ) != '\r' && c != '\n')
{ {
if (c == '\0') if (c == '\0')
{ {
skipping to change at line 1109 skipping to change at line 1100
} }
void BlFilePopenUnix::readbuffer () void BlFilePopenUnix::readbuffer ()
{ {
bufpos= 0; bufpos= 0;
bufread= do_readbuffer (buffer, bufsize); bufread= do_readbuffer (buffer, bufsize);
} }
size_t BlFilePopenUnix::do_readbuffer (char * buffer, size_t bytes) size_t BlFilePopenUnix::do_readbuffer (char * buffer, size_t bytes)
{ {
TRACEFUNC (tr, "BlFilePopenUnix::do_readbuffer"); TRF;
size_t bytesread= ::read (readhandle, buffer, bytes); size_t bytesread= ::read (readhandle, buffer, bytes);
if (bytesread == size_t (-1) ) if (bytesread == size_t (-1) )
bytesread= 0; bytesread= 0;
return bytesread; return bytesread;
} }
void BlFilePopenUnix::outstring (const std::string & str) void BlFilePopenUnix::outstring (const std::string & str)
{ {
TRACEFUNC (tr, "BlFilePopenUnix::outstring"); TRF;
if (! getmode () & Output) if (! getmode () & Output)
throw ErrFileMode; throw ErrFileMode;
const char * to= str.data (); const char * to= str.data ();
std::string::size_type l= str.size (); std::string::size_type l= str.size ();
if (write (writehandle, to, l) == -1) if (write (writehandle, to, l) == -1)
{ {
showlasterror (); showlasterror ();
throw ErrOperatingSystem; throw ErrOperatingSystem;
skipping to change at line 1147 skipping to change at line 1138
if (write (writehandle, & c, 1) == -1) if (write (writehandle, & c, 1) == -1)
{ {
showlasterror (); showlasterror ();
throw ErrOperatingSystem; throw ErrOperatingSystem;
} }
} }
bool BlFilePopenUnix::poll () bool BlFilePopenUnix::poll ()
{ {
TRACEFUNC (tr, "BlFilePopenUnix::poll"); TRF;
if (! getmode () & Input) if (! getmode () & Input)
throw ErrFileMode; throw ErrFileMode;
struct pollfd data [1]; struct pollfd data [1];
data [0].fd= readhandle; data [0].fd= readhandle;
data [0].events= POLLIN | POLLPRI; data [0].events= POLLIN | POLLPRI;
switch (::poll (data, 1, 0) ) switch (::poll (data, 1, 0) )
{ {
case 0: case 0:
return false; return false;
 End of changes. 24 change blocks. 
35 lines changed or deleted 26 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)