2012-09-09 3 views
0

제목에서 이진 쓰기 용 파일을 열려고 할 때이 오류가 표시됨을 알 수 있습니다 (모드는 중요하지 않음).디스크에 파일 생성/열기가 반환됩니다. EAGAIN

내 응용 프로그램은 libek를 사용하여 소켓 (비 차단/epoll 백엔드)을 처리하고 클라이언트 패킷을 구문 분석하는 동안 파일 업로드 메시지를받는 지점에서 서버로부터받는 디스크 데이터를 쓰기 시작합니다. 사용

  1. 는 fopen (...) 반환 EAGAIN
  2. :

    내가 EAGAIN(Resource temporarily unavailable) 메시지 및 파일 열기에 대해 아무것도 구글 없습니다 ..

    이 내가 해봤 방법이 있습니다 ofstream/fstream의 열기 (...)을 힙에 작성하여 (new) EAGAIN

  3. ofstream/fstre를 사용하십시오. (ofstream m_ofFile;)로 정적으로 컴파일하지만, 이상하게도 컴파일러는 ofstream 소멸자를 호출하는 코드를 생성하고 클래스 메소드를 종료하기 전에 파일을 닫습니다. .open에서부터 호출합니다.

    @Joachim

    당신은, 내가 바로 '있어 : 이제 클래스 유형이다 반원, 소멸자가 바로 클래스 사용하기 전에 호출 내 C++ 지식 ..

편집과 모순 이 오류가 발생하는 것은 아닙니다. (방법 # 1. 곧 방법 # 2를 다시 시험 할 것입니다.) 파일은 regulary를 열어서 나는 정규 FILE *을 얻는다. 내 클래스의 Init (...) 함수에서 발생하지만, 나중에 OnFileChunk를 호출하면 m_hFile이 0이되어서 쓸 수 없습니다.

   class CFileTransferCS 
       { 
        wstring m_wszfile; 
        wstring m_wszLocalUserFolderPath; 
        int  m_nChunkIndex; 
        int  m_nWrittenBytes; 
        int  m_nFileSize; 
        FILE* m_hFile; 

        CFileTransferCS(const CFileTransferCS& c){} 
        CFileTransferCS& operator=(const CFileTransferCS& c){} 

       public: 

        CFileTransferCS(); 
        CFileTransferCS(wstring file, uint32_t size); 

        void OnFileChunk(char* FileChunk, int size); 
        void Init(wstring file, uint32_t size); 
        void SetLocalUserLocalPath(wstring path); 

       }; 

       CFileTransferCS::CFileTransferCS() 
       { 
        m_hFile = NULL; 
        m_wszLocalUserFolderPath = L""; 
        m_nChunkIndex = 0; 
        m_nWrittenBytes = 0; 
       } 

       CFileTransferCS::CFileTransferCS(wstring file, uint32_t size) 
       { 
        m_nChunkIndex = 0; 
        m_nWrittenBytes = 0; 

        m_wszfile = file; 
        m_nFileSize = size; 

        wstring wszFullFilePath = m_wszLocalUserFolderPath + m_wszfile.substr(m_wszfile.find_last_of(L"\\") + 1); 

        // string fp = string(file.begin(),file.end()); 
        string fp ="test.bin"; //for testing purposes 

        this->m_hFile = fopen(fp.c_str(),"wb"); 

        printf("fp: %s hFile %d\n",fp.c_str(),this->m_hFile); //everything's fine here... 

        if(!this->m_hFile) 
        { 
         perror ("cant open file "); 
        } 

       } 

       void CFileTransferCS::SetLocalUserLocalPath(wstring path) 
       { 
        m_wszLocalUserFolderPath = path; 

       } 

       void CFileTransferCS::Init(wstring file, uint32_t size) 
       { 

        // If previous transfer session got interrupted for whatever reason 
        // close and delete old file and open new one 

        if(this->m_hFile) 
        { 
         printf("init CS transfer: deleting old file///\n"); 
         fclose(this->m_hFile); 

         string fp = string(file.begin(),file.end()); 

         if(remove(fp.c_str())) 
         { 
          //cant delete file... 
         } 

        } 

        CFileTransferCS(file, size); 

       } 


       void CFileTransferCS::OnFileChunk(char* FileChunk, int size) 
       { 

        for (;;) 
        { 

         printf("ofc: hFile %d\n",this->m_hFile); //m_hFile is 0 here... 
         if(!this->m_hFile) 
         { 
          //   m_pofFile->open("kurac.txt",fstream::out); 
          printf("file not opened!\n"); 
          break; 
         } 


         int nBytesWritten = fwrite(FileChunk, 1, size, this->m_hFile); 

         if(!nBytesWritten) 
         { 
          perror("file write!!\n"); 
          break; 
         } 

         m_nWrittenBytes+=size; 

         if(m_nWrittenBytes == m_nFileSize) 
         { 
          fclose(m_hFile); 
          printf("file uplaod transfer finished!!!\n"); 
         } 


         break; 
        } 

        printf("CFileTransferCS::OnFileChunk size: %d m_nWrittenBytes: %d m_nFileSize: %d\n",size,m_nWrittenBytes,m_nFileSize); 
       } 

최종 편집 : 여기에 완전한 클래스 코드는

나는 그것이 .. 이런 생성자를 호출 .. 생성자가 문제를 만든 (uint32_t 크기, 파일을 wstring을) 명시 적으로 CFileTransferCS를 호출있어 명시 적으로 원인이이 포인터에서 그것은 원래 하나 (그 Init 함수를 사용했다) 그래서 내가 그것에서 파일을 열고 m_hFile에 대한 핸들을 저장, 난 다른 일부 개체 (CFileTransferCS (..) CFileTransferCS 개체 또는 메모리의 다른 부분을 무작위로 손상 시켰습니다. 나중에 IDA에서 확인해 보겠습니다.)

모두와 사과에 감사드립니다.

감사합니다, 마이크 -

+1

실제로 오류일까요? 함수가 성공하면'errno'는 유효하지 않다는 것을 기억하십시오. 예 : 경우 1,'fopen' _did_는'NULL'을 리턴합니까? 또한 파일을 열고 오류를 확인하는 데 사용하는 코드를 표시 할 수 있습니까? –

+0

어떤 운영 체제입니까? 컴파일러? 기존 파일/새 파일? 문제를 나타내는 작은 컴파일 가능한 코드를 만들 수 있습니까? – Bill

+0

컴파일 중 C++ 0x 스위치를 사용하여 Debian (amd64)의 @Bill im. fopen/open을 호출 할 때 항상 새 파일을 만듭니다. –

답변

0

@MikeJacksons 대답 :

생성자가 문제를 만든 (uint32_t 크기, 파일을 wstring을) 명시 적으로 CFileTransferCS를 호출. 이와 같은 생성자를 명시 적으로 호출하면이 포인터가 원래의 포인터 (Init 함수가 사용하고있는 함수)가 아니 었습니다. 그래서 파일을 열고 m_hFile에 핸들을 저장하면 다른 객체에서 처리하고있었습니다 (현재는 확실하지 않습니다). CFileTransferCS (..) 호출 CFileTransferCS 개체에 대한 메모리를 할당하거나 메모리의 다른 부분을 무작위로 손상 .. IDA 나중에 확인해) 감사합니다 모두와 사과.

는 제거 : CFileTransferCS(file, size);

(당신이 훌륭한 일이 버그를 사냥처럼 마이크를 appologize 할 필요는 보지 않는다).

관련 문제