upstream revision 3887 released 2014-03-25
Also known as 2014 C++ Update 1 and WorkbenchUpdate20140325rev3887.
diff --git a/aos/externals/WPILib/WPILib.a b/aos/externals/WPILib/WPILib.a
index 57584f3..e0261cc 100644
--- a/aos/externals/WPILib/WPILib.a
+++ b/aos/externals/WPILib/WPILib.a
Binary files differ
diff --git a/aos/externals/WPILib/WPILib/DriverStation.cpp b/aos/externals/WPILib/WPILib/DriverStation.cpp
index 676ce77..134fe98 100644
--- a/aos/externals/WPILib/WPILib/DriverStation.cpp
+++ b/aos/externals/WPILib/WPILib/DriverStation.cpp
@@ -162,11 +162,11 @@
getCommonControlData(m_controlData, WAIT_FOREVER);
if (!lastEnabled && IsEnabled())
{
- // If starting teleop, assume that autonomous just took up 15 seconds
+ // If starting teleop, assume that autonomous just took up 10 seconds
if (IsAutonomous())
m_approxMatchTimeOffset = Timer::GetFPGATimestamp();
else
- m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 15.0;
+ m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 10.0;
}
else if (lastEnabled && !IsEnabled())
{
diff --git a/aos/externals/WPILib/WPILib/RobotBase.cpp b/aos/externals/WPILib/WPILib/RobotBase.cpp
index a9ec2ee..9127fb9 100644
--- a/aos/externals/WPILib/WPILib/RobotBase.cpp
+++ b/aos/externals/WPILib/WPILib/RobotBase.cpp
@@ -19,7 +19,7 @@
RobotBase* RobotBase::m_instance = NULL;
const char *FILE_NAME = "/c/FRC_Lib_Version.ini";
-const char *VERSION_STRING = "C++ 2014 Update 0";
+const char *VERSION_STRING = "C++ 2014 Update 1";
void RobotBase::setInstance(RobotBase* robot)
diff --git a/aos/externals/WPILib/WPILib/Scripts/CopyWPILibToUpdateDirectory.cmd b/aos/externals/WPILib/WPILib/Scripts/CopyWPILibToUpdateDirectory.cmd
index 2445cce..26ecc83 100644
--- a/aos/externals/WPILib/WPILib/Scripts/CopyWPILibToUpdateDirectory.cmd
+++ b/aos/externals/WPILib/WPILib/Scripts/CopyWPILibToUpdateDirectory.cmd
@@ -6,7 +6,7 @@
mkdir vxworks-6.3\target\h\WPILib\CAN
mkdir vxworks-6.3\target\h\WPILib\ChipObject
mkdir vxworks-6.3\target\h\WPILib\ChipObject\fpgainterfacecapi
-mkdir vxworks-6.3\target\h\WPILib\CInterfaces
+mkdir vxworks-6.3\target\h\WPILib\Interfaces
mkdir vxworks-6.3\target\h\WPILib\Commands
mkdir vxworks-6.3\target\h\WPILib\NetworkCommunication
mkdir vxworks-6.3\target\h\WPILib\SmartDashboard
@@ -32,7 +32,7 @@
del vxworks-6.3\target\h\WPIlib\Buttons\*.h
del vxworks-6.3\target\h\WPIlib\CAN\*.h
del vxworks-6.3\target\h\WPIlib\ChipObject\*.h
-del vxworks-6.3\target\h\WPIlib\CInterfaces\*.h
+del vxworks-6.3\target\h\WPIlib\Interfaces\*.h
del vxworks-6.3\target\h\WPIlib\Commands\*.h
del vxworks-6.3\target\h\WPIlib\NetworkCommunication\*.h
del vxworks-6.3\target\h\WPIlib\SmartDashboard\*.h
@@ -61,7 +61,7 @@
copy C:\WindRiver\workspace\WPILib\CAN\*.h vxworks-6.3\target\h\WPILib\CAN
copy C:\WindRiver\workspace\WPILib\ChipObject\*.h vxworks-6.3\target\h\WPILib\ChipObject
copy C:\WindRiver\workspace\WPILib\ChipObject\fpgainterfacecapi\*.h vxworks-6.3\target\h\WPILib\ChipObject\fpgainterfacecapi
-copy C:\WindRiver\workspace\WPILib\CInterfaces\*.h vxworks-6.3\target\h\WPILib\CInterfaces
+copy C:\WindRiver\workspace\WPILib\Interfaces\*.h vxworks-6.3\target\h\WPILib\Interfaces
copy C:\WindRiver\workspace\WPILib\Commands\*.h vxworks-6.3\target\h\WPILib\Commands
copy C:\WindRiver\workspace\WPILib\NetworkCommunication\*.h vxworks-6.3\target\h\WPILib\NetworkCommunication
copy C:\WindRiver\workspace\WPILib\SmartDashboard\*.h vxworks-6.3\target\h\WPILib\SmartDashboard
diff --git a/aos/externals/WPILib/WPILib/SerialPort.cpp b/aos/externals/WPILib/WPILib/SerialPort.cpp
index 7a1047e..f948f0a 100644
--- a/aos/externals/WPILib/WPILib/SerialPort.cpp
+++ b/aos/externals/WPILib/WPILib/SerialPort.cpp
@@ -183,13 +183,18 @@
uint32_t retCount = 0;
if (!m_consoleModeEnabled)
{
- ViStatus localStatus = viBufRead(m_portHandle, (ViPBuf)buffer, count, (ViPUInt32)&retCount);
+ ViStatus localStatus = viRead(m_portHandle, (ViPBuf)buffer, count, (ViPUInt32)&retCount);
switch (localStatus)
{
case VI_SUCCESS_TERM_CHAR:
case VI_SUCCESS_MAX_CNT:
case VI_ERROR_TMO: // Timeout
break;
+ case VI_ERROR_IO:
+ case VI_ERROR_ASRL_OVERRUN:
+ wpi_setError(localStatus);
+ Reset();
+ break;
default:
wpi_setError(localStatus);
}
@@ -209,7 +214,7 @@
uint32_t retCount = 0;
if (!m_consoleModeEnabled)
{
- ViStatus localStatus = viBufWrite(m_portHandle, (ViPBuf)buffer, count, (ViPUInt32)&retCount);
+ ViStatus localStatus = viWrite(m_portHandle, (ViPBuf)buffer, count, (ViPUInt32)&retCount);
wpi_setError(localStatus);
}
return retCount;
diff --git a/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.cpp b/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.cpp
index 00829a0..8d268b2 100644
--- a/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.cpp
@@ -32,7 +32,7 @@
*/
NetworkTableEntry* AbstractNetworkTableEntryStore::GetEntry(std::string& name){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
std::map<std::string, NetworkTableEntry*>::iterator value_itr = namedEntries.find(name);
if(value_itr != namedEntries.end()) {
return value_itr->second;
@@ -43,7 +43,7 @@
NetworkTableEntry* AbstractNetworkTableEntryStore::GetEntry(EntryId entryId){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
std::map<EntryId, NetworkTableEntry*>::iterator value_itr = idEntries.find(entryId);
if(value_itr != idEntries.end()) {
@@ -55,7 +55,7 @@
std::vector<std::string>* AbstractNetworkTableEntryStore::keys(){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
std::vector<std::string>* keys = new std::vector<std::string>();
std::map<std::string, NetworkTableEntry*>::iterator itr;
@@ -77,7 +77,7 @@
*/
void AbstractNetworkTableEntryStore::clearEntries(){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
namedEntries.clear();
idEntries.clear();
}
@@ -88,7 +88,7 @@
*/
void AbstractNetworkTableEntryStore::clearIds(){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
std::map<std::string, NetworkTableEntry*>::iterator itr;
idEntries.clear();
@@ -119,7 +119,7 @@
*/
void AbstractNetworkTableEntryStore::PutOutgoing(std::string& name, NetworkTableEntryType* type, EntryValue value){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
std::map<std::string, NetworkTableEntry*>::iterator index = namedEntries.find(name);
NetworkTableEntry* tableEntry;
if(index == namedEntries.end())//if the name does not exist in the current entries
@@ -167,7 +167,7 @@
void AbstractNetworkTableEntryStore::offerIncomingAssignment(NetworkTableEntry* entry){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
std::map<std::string, NetworkTableEntry*>::iterator itr = namedEntries.find(entry->name);
NetworkTableEntry* tableEntry;
if(addEntry(entry)){
@@ -203,7 +203,7 @@
*/
void AbstractNetworkTableEntryStore::notifyEntries(ITable* table, ITableListener* listener){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
std::map<std::string, NetworkTableEntry*>::iterator itr;
for(itr = namedEntries.begin(); itr != namedEntries.end(); itr++)
{
diff --git a/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.h b/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.h
index b394cfb..7d6903f 100644
--- a/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.h
+++ b/aos/externals/WPILib/WPILib/networktables2/AbstractNetworkTableEntryStore.h
@@ -36,6 +36,7 @@
class AbstractNetworkTableEntryStore : public IncomingEntryReceiver{
protected:
std::map<EntryId,NetworkTableEntry*> idEntries;
+ NTReentrantSemaphore block_namedEntries;
std::map<std::string,NetworkTableEntry*> namedEntries;
TableListenerManager& listenerManager;
diff --git a/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.cpp b/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.cpp
index 9538c91..658c7c7 100644
--- a/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.cpp
@@ -20,6 +20,17 @@
m_isDirty = false;
}
+NetworkTableEntry::NetworkTableEntry(const NetworkTableEntry &other) :
+ name(other.name),
+ id(other.id),
+ sequenceNumber(other.sequenceNumber),
+ type(other.type),
+ m_isNew(other.m_isNew),
+ m_isDirty(other.m_isDirty)
+{
+ value = type->copyValue(other.value);
+}
+
NetworkTableEntry::~NetworkTableEntry(){
type->deleteValue(value);
}
diff --git a/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.h b/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.h
index 2a29004..27223e4 100644
--- a/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.h
+++ b/aos/externals/WPILib/WPILib/networktables2/NetworkTableEntry.h
@@ -42,6 +42,7 @@
NetworkTableEntry(std::string& name, NetworkTableEntryType* type, EntryValue value);
NetworkTableEntry(EntryId id, std::string& name, SequenceNumber sequenceNumber, NetworkTableEntryType* type, EntryValue value);
+ NetworkTableEntry(const NetworkTableEntry &);
virtual ~NetworkTableEntry();
EntryId GetId();
diff --git a/aos/externals/WPILib/WPILib/networktables2/WriteManager.cpp b/aos/externals/WPILib/WPILib/networktables2/WriteManager.cpp
index bbe08f5..64688e3 100644
--- a/aos/externals/WPILib/WPILib/networktables2/WriteManager.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/WriteManager.cpp
@@ -54,10 +54,15 @@
void WriteManager::offerOutgoingAssignment(NetworkTableEntry* entry) {
{
- NTSynchronized sync(transactionsLock);
- ((std::queue<NetworkTableEntry*>*)incomingAssignmentQueue)->push(entry);
-
- if(((std::queue<NetworkTableEntry*>*)incomingAssignmentQueue)->size()>=queueSize){
+ bool test_queue_overflow=false;
+ {
+ NTSynchronized sync(transactionsLock);
+ ((std::queue<NetworkTableEntry*>*)incomingAssignmentQueue)->push(entry);
+
+ test_queue_overflow=(((std::queue<NetworkTableEntry*>*)incomingAssignmentQueue)->size()>=queueSize);
+ }
+ if (test_queue_overflow)
+ {
run();
writeWarning("assignment queue overflowed. decrease the rate at which you create new entries or increase the write buffer size");
}
@@ -67,9 +72,15 @@
void WriteManager::offerOutgoingUpdate(NetworkTableEntry* entry) {
{
- NTSynchronized sync(transactionsLock);
- ((std::queue<NetworkTableEntry*>*)incomingUpdateQueue)->push(entry);
- if(((std::queue<NetworkTableEntry*>*)incomingUpdateQueue)->size()>=queueSize){
+ bool test_queue_overflow=false;
+ {
+ NTSynchronized sync(transactionsLock);
+ ((std::queue<NetworkTableEntry*>*)incomingUpdateQueue)->push(entry);
+ test_queue_overflow=(((std::queue<NetworkTableEntry*>*)incomingUpdateQueue)->size()>=queueSize);
+
+ }
+ if (test_queue_overflow)
+ {
run();
writeWarning("update queue overflowed. decrease the rate at which you update entries or increase the write buffer size");
}
@@ -97,10 +108,17 @@
entry = ((std::queue<NetworkTableEntry*>*)outgoingAssignmentQueue)->front();
((std::queue<NetworkTableEntry*>*)outgoingAssignmentQueue)->pop();
{
- NTSynchronized sync(entryStore.LOCK);
- entry->MakeClean();
- wrote = true;
- receiver.offerOutgoingAssignment(entry);
+ NetworkTableEntry * entryCopy;
+
+ {
+ NTSynchronized sync(entryStore.LOCK);
+ entry->MakeClean();
+ wrote = true;
+ entryCopy = new NetworkTableEntry(*entry);
+ }
+
+ receiver.offerOutgoingAssignment(entryCopy);
+ delete entryCopy;
}
}
@@ -108,10 +126,17 @@
entry = ((std::queue<NetworkTableEntry*>*)outgoingUpdateQueue)->front();
((std::queue<NetworkTableEntry*>*)outgoingUpdateQueue)->pop();
{
- NTSynchronized sync(entryStore.LOCK);
- entry->MakeClean();
- wrote = true;
- receiver.offerOutgoingUpdate(entry);
+ NetworkTableEntry * entryCopy;
+
+ {
+ NTSynchronized sync(entryStore.LOCK);
+ entry->MakeClean();
+ wrote = true;
+ entryCopy = new NetworkTableEntry(*entry);
+ }
+
+ receiver.offerOutgoingUpdate(entryCopy);
+ delete entryCopy;
}
}
diff --git a/aos/externals/WPILib/WPILib/networktables2/client/ClientNetworkTableEntryStore.cpp b/aos/externals/WPILib/WPILib/networktables2/client/ClientNetworkTableEntryStore.cpp
index d2fc19d..15c0e1f 100644
--- a/aos/externals/WPILib/WPILib/networktables2/client/ClientNetworkTableEntryStore.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/client/ClientNetworkTableEntryStore.cpp
@@ -17,7 +17,7 @@
bool ClientNetworkTableEntryStore::addEntry(NetworkTableEntry* newEntry){
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
NetworkTableEntry* entry = (NetworkTableEntry*)namedEntries[newEntry->name];
if(entry!=NULL){
diff --git a/aos/externals/WPILib/WPILib/networktables2/connection/NetworkTableConnection.cpp b/aos/externals/WPILib/WPILib/networktables2/connection/NetworkTableConnection.cpp
index 6f675b0..13c61fc 100644
--- a/aos/externals/WPILib/WPILib/networktables2/connection/NetworkTableConnection.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/connection/NetworkTableConnection.cpp
@@ -19,6 +19,7 @@
void NetworkTableConnection::SetIOStream(IOStream* stream)
{
+ isValid=(stream!=NULL);
ioStream->SetIOStream(stream); //just passing through
}
@@ -102,7 +103,7 @@
}
void NetworkTableConnection::read(ConnectionAdapter& adapter) {
- int messageType = ioStream->readByte();
+ int messageType = (isValid)?ioStream->readByte():KEEP_ALIVE;
switch (messageType) {
case KEEP_ALIVE:
adapter.keepAlive();
diff --git a/aos/externals/WPILib/WPILib/networktables2/server/NetworkTableServer.cpp b/aos/externals/WPILib/WPILib/networktables2/server/NetworkTableServer.cpp
index ea85356..a0f3677 100644
--- a/aos/externals/WPILib/WPILib/networktables2/server/NetworkTableServer.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/server/NetworkTableServer.cpp
@@ -35,6 +35,9 @@
void NetworkTableServer::Close(){
try{
+ //Note: streamProvider must come before the incomingStreamMonitor so the that task can complete first for the thread to close
+ // [9/1/2013 Terminator]
+ streamProvider.close();
incomingStreamMonitor.stop();
writeManager.stop();
connectionList.closeAll();
diff --git a/aos/externals/WPILib/WPILib/networktables2/server/ServerConnectionAdapter.cpp b/aos/externals/WPILib/WPILib/networktables2/server/ServerConnectionAdapter.cpp
index 195f6e7..62323d8 100644
--- a/aos/externals/WPILib/WPILib/networktables2/server/ServerConnectionAdapter.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/server/ServerConnectionAdapter.cpp
@@ -36,6 +36,9 @@
gotoState(new ServerConnectionState_Error(e));
adapterListener.close(*this, true);
m_IsAdapterListenerClosed=true;
+ if (readThread) {
+ readThread->stop();
+ }
}
void ServerConnectionAdapter::ioException(IOException& e) {
@@ -47,6 +50,9 @@
gotoState(new ServerConnectionState_Error(e));
adapterListener.close(*this, false);
m_IsAdapterListenerClosed=true;
+ if (readThread) {
+ readThread->stop();
+ }
}
diff --git a/aos/externals/WPILib/WPILib/networktables2/server/ServerIncomingStreamMonitor.cpp b/aos/externals/WPILib/WPILib/networktables2/server/ServerIncomingStreamMonitor.cpp
index 51c5733..44bf367 100644
--- a/aos/externals/WPILib/WPILib/networktables2/server/ServerIncomingStreamMonitor.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/server/ServerIncomingStreamMonitor.cpp
@@ -7,6 +7,7 @@
#include "networktables2/server/ServerIncomingStreamMonitor.h"
#include "networktables2/stream/IOStream.h"
+#include "networktables2/util/System.h"
ServerIncomingStreamMonitor::ServerIncomingStreamMonitor(IOStreamProvider& _streamProvider, ServerNetworkTableEntryStore& _entryStore,
ServerIncomingConnectionListener& _incomingListener, ServerAdapterManager& _adapterListener, NetworkTableEntryTypeManager& _typeManager,
@@ -69,6 +70,7 @@
ServerConnectionAdapter* connectionAdapter = new ServerConnectionAdapter(newStream, entryStore, entryStore, adapterListener, typeManager, threadManager);
incomingListener.OnNewConnection(*connectionAdapter);
}
+ sleep_ms(100); //avoid busy wait
}
}
catch (IOException& e)
diff --git a/aos/externals/WPILib/WPILib/networktables2/server/ServerNetworkTableEntryStore.cpp b/aos/externals/WPILib/WPILib/networktables2/server/ServerNetworkTableEntryStore.cpp
index b1d86c9..b49bbf5 100644
--- a/aos/externals/WPILib/WPILib/networktables2/server/ServerNetworkTableEntryStore.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/server/ServerNetworkTableEntryStore.cpp
@@ -18,7 +18,7 @@
bool ServerNetworkTableEntryStore::addEntry(NetworkTableEntry* newEntry)
{
- NTSynchronized sync(LOCK);
+ NTSynchronized sync(block_namedEntries);
NetworkTableEntry* entry = namedEntries[newEntry->name];
if (entry == NULL)
@@ -44,13 +44,20 @@
*/
void ServerNetworkTableEntryStore::sendServerHello(NetworkTableConnection& connection)
{
- NTSynchronized sync(LOCK);
- std::map<std::string, NetworkTableEntry*>::iterator itr;
- for (itr = namedEntries.begin(); itr != namedEntries.end(); itr++)
+ std::vector<NetworkTableEntry *> entry_list;
{
- NetworkTableEntry* entry = itr->second;
- connection.sendEntryAssignment(*entry);
+ NTSynchronized sync(block_namedEntries);
+ std::map<std::string, NetworkTableEntry*>::iterator itr;
+ for (itr = namedEntries.begin(); itr != namedEntries.end(); itr++)
+ {
+ NetworkTableEntry* entry = itr->second;
+ entry_list.push_back(entry);
+ }
}
+
+ for (size_t i=0;i<entry_list.size();i++)
+ connection.sendEntryAssignment(*(entry_list[i]));
+
connection.sendServerHelloComplete();
connection.flush();
}
diff --git a/aos/externals/WPILib/WPILib/networktables2/stream/FDIOStream.cpp b/aos/externals/WPILib/WPILib/networktables2/stream/FDIOStream.cpp
index d0dd657..55e2ac2 100644
--- a/aos/externals/WPILib/WPILib/networktables2/stream/FDIOStream.cpp
+++ b/aos/externals/WPILib/WPILib/networktables2/stream/FDIOStream.cpp
@@ -11,7 +11,7 @@
#include <errno.h>
#include <stdlib.h>
-#include <iolib.h>
+#include <ioLib.h>
#include <selectLib.h>
#include <string.h>
#include <stdio.h>
@@ -22,6 +22,13 @@
// f = fdopen(_fd, "rbwb");
// if(f==NULL)
// throw IOException("Could not open stream from file descriptor", errno);
+ // Set the TCP socket to be non-blocking
+ int on = 1;
+ if (ioctl(fd, FIONBIO, (int)&on) < 0)
+ {
+ ::close(fd);
+ throw IOException("Could not set socket to non-blocking mode");
+ }
}
FDIOStream::~FDIOStream(){
close();
@@ -64,14 +71,35 @@
return totalRead;
}
int FDIOStream::write(const void* ptr, int numbytes){
- int numWrote = ::write(fd, (char*)ptr, numbytes);//TODO: this is bad
- //int numWrote = fwrite(ptr, 1, numbytes, f);
- if(numWrote==numbytes)
- return numWrote;
- perror("write error: ");
- fflush(stderr);
- throw IOException("Could not write all bytes to fd stream");
-
+ int numWrote = ::write(fd, (char*)ptr, numbytes);
+ if(numWrote==numbytes)
+ return numWrote;
+
+ if (numWrote == -1 && (errno == EWOULDBLOCK || errno == EAGAIN))
+ {
+ // see if write timeout expires
+ struct timeval timeout;
+ fd_set fdSet;
+
+ FD_ZERO(&fdSet);
+ FD_SET(fd, &fdSet);
+ timeout.tv_sec = 1; // wait 1 second for the other side to connect
+ timeout.tv_usec = 0;
+
+ int select_result = select(FD_SETSIZE, NULL, &fdSet, NULL, &timeout);
+ if ( select_result < 0)
+ throw IOException("Select returned an error on write");
+
+ if (FD_ISSET(fd, &fdSet)) {
+ numWrote = ::write(fd, (char*)ptr, numbytes);
+ if(numWrote==numbytes)
+ return numWrote;
+ }
+ }
+
+ perror("write error: ");
+ fflush(stderr);
+ throw IOException("Could not write all bytes to fd stream");
}
void FDIOStream::flush(){
//if(fflush(f)==EOF)