int ACE_FILE_Connector::connect (ACE_FILE_IO &new_io, const ACE_FILE_Addr &remote_sap, ACE_Time_Value *timeout, const ACE_Addr &, int, int flags, int perms) { ACE_TRACE ("ACE_FILE_Connector::connect"); ACE_ASSERT (new_io.get_handle () == ACE_INVALID_HANDLE); ACE_HANDLE handle = ACE_INVALID_HANDLE; // Check to see if caller has requested that we create the filename. if(reinterpret_cast<const ACE_Addr &> ( const_cast<ACE_FILE_Addr &> (remote_sap)) == ACE_Addr::sap_any) { // Create a new temporary file. // Use ACE_OS::mkstemp() if it is available since it avoids a // race condition, and subsequently a security hole due to that // race condition (specifically, a denial-of-service attack). // // However, using mkstemp() prevents us from doing a timed open // since it opens the file for us. Better to avoid the race // condition. char filename[] = "ace-file-XXXXXX"; handle = ACE_OS::mkstemp (filename); // mkstemp() replaces "XXXXXX" if(handle == ACE_INVALID_HANDLE || new_io.addr_.set (ACE_TEXT_CHAR_TO_TCHAR (filename)) != 0) return -1; new_io.set_handle (handle); return 0; } else new_io.addr_ = remote_sap; // class copy. handle = ACE::handle_timed_open (timeout, new_io.addr_.get_path_name (), flags, perms); new_io.set_handle (handle); return handle == ACE_INVALID_HANDLE ? -1 : 0; }
int FileIOHandler::Connect() { int result = 0; // create an empty temporary file for the test if(connector_.connect(peer_, ACE_sap_any_cast (ACE_FILE_Addr &)) != 0) { ACE_ERROR((LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("FileIOHandler connect failed to create file"))); result = -1; } // close opened file but leave it where it is if (peer_.close () != 0) { ACE_ERROR((LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("FileIOHandler connect failed to close file"))); peer_.remove (); result = -1; } // get file address ACE_FILE_Addr tmp_addr; peer_.get_local_addr (tmp_addr); // reopen new file for asynch IO if(connector_.connect(peer_, tmp_addr, 0, //timeout ACE_Addr::sap_any, 0, //reuse O_RDWR |FILE_FLAG_OVERLAPPED) != 0) { ACE_ERROR((LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("FileIOHandler connect failed to open file"))); peer_.remove (); result = -1; } else // device connected successfully { // keep track of our writes for offset calculations (can't use O_APPEND since // this is not supported for the Win32_Asynch implementation) and data verifications this->block_count_ = 0; // start counting // Set our I/O handle to that of the peer_ object handling our connection handle(peer_.get_handle()); if (writer_.open(*this) != 0 || reader_.open(*this) != 0) { ACE_ERROR( (LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("FileIOHandler reader or writer open failed"))); result = -1; } else // reader and writer opened successfully { // Allocate a new message block and initiate a read operation on it // to prime the asynchronous read pipeline // The message block is sized for the largest message we expect ACE_Message_Block *mb; ACE_NEW_NORETURN(mb, ACE_Message_Block(FILE_FRAME_SIZE)); if (reader_.read(*mb, mb->space()) != 0) { int errnr = ACE_OS::last_error (); ACE_DEBUG( (LM_INFO, ACE_TEXT("%p [%d]\n"), ACE_TEXT("FileIOHandler begin read failed"), errnr)); mb->release(); #if defined (ACE_WIN32) // On older Win32 versions (WinXP, Win2003/2008) asynch IO with disk files is not // reliable and may perform sync IO in certain cases like when the read offset denotes // current end of file. Instead of scheduling a write operation the read will immediately // return with an EOF error. // We circumvent that situation here by not reporting an error and scheduling a read operation // later when we are sure data has been written at the offset in question (after the write finishes). if (errnr != ERROR_HANDLE_EOF) #endif result = -1; } #if defined (ACE_WIN32) else { this->read_pending_ = true; } #endif // If read worked, psMsg is now controlled by Proactor framework. } } return result; }