Skip to content

fix: guard Binstream write path against unopened files and failed fwrite - #8025

Open
mohanchen wants to merge 1 commit into
deepmodeling:developfrom
mohanchen:2026-09-25-line1-5
Open

mohanchen wants to merge 1 commit into
deepmodeling:developfrom
mohanchen:2026-09-25-line1-5

Conversation

@mohanchen

Copy link
Copy Markdown
Collaborator

Fixes #7562.

The binary wavefunction writers (wfc_nao_write2file and wfc_nao_write2file_complex) used to only print a warning when the output file could not be opened, then kept writing through a null FILE pointer, which could crash or produce corrupt files.

Binstream::operator<< and Binstream::write now check that the stream is open and verify the fwrite return value, matching the existing read-path behavior. The call sites in write_wfc_nao.cpp now terminate with WARNING_QUIT on open failure instead of continuing.

Tests added:

  • BinstreamTest.WriteToUnopenedFile
  • ModuleIOTest.WriteWfcNaoBinaryOpenFail
  • ModuleIOTest.WriteWfcNaoComplexBinaryOpenFail

Reminder

  • I have read AGENTS.md and docs/developers_guide/agent_governance.md.
  • I have linked an issue or explained why this PR does not need one.
  • I have added adequate unit tests and/or case tests, or explained why not.
  • I have listed the exact verification commands run and their results.
  • I have described user-visible behavior changes, including INPUT parameter changes.
  • I have explained core-module impact for ESolver, HSolver, ElecState, Hamilt, Operator, Psi, or other source/ changes.
  • I have requested any needed governance exception below.

Linked Issue

Fix #

Unit Tests and/or Case Tests for my changes

  • Commands run:
  • Result summary:
  • Checks not run, with reason:

What's changed?

  • Example: brief summary of the user-visible or developer-facing change.

Governance Notes

  • INPUT/docs changes:
  • Core module impact:
  • Exceptions requested:

Fixes deepmodeling#7562.

The binary wavefunction writers (wfc_nao_write2file and
wfc_nao_write2file_complex) used to only print a warning when the output
file could not be opened, then kept writing through a null FILE pointer,
which could crash or produce corrupt files.

Binstream::operator<< and Binstream::write now check that the stream is
open and verify the fwrite return value, matching the existing read-path
behavior. The call sites in write_wfc_nao.cpp now terminate with
WARNING_QUIT on open failure instead of continuing.

Tests added:
- BinstreamTest.WriteToUnopenedFile
- ModuleIOTest.WriteWfcNaoBinaryOpenFail
- ModuleIOTest.WriteWfcNaoComplexBinaryOpenFail
@mohanchen mohanchen added Bugs Bugs that only solvable with sufficient knowledge of DFT Input&Output Suitable for coders without knowing too many DFT details Refactor Refactor ABACUS codes labels Sep 25, 2026

@AsTonyshment AsTonyshment left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small suggestions.

std::cout<<"Error in Binstream: cannot write to an unopened file."<<std::endl;
exit(1);
}
size_t ch = fwrite(&data,size,1,this->fileptr);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwrite() can report success while data is still buffered, and both close() and the destructor ignore fclose() failures. With RLIMIT_FSIZE=1, both NAO binary writers return normally with only one byte written. Maybe also check the final close result and cover delayed write failures; the array overload has the same gap.

std::cout<<"Error in Binstream: cannot write to an unopened file."<<std::endl;
exit(1);
}
size_t ch = fwrite(data,size,n,this->fileptr);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as line 67.

size_t ch = fwrite(&data,size,1,this->fileptr);
if(ch<1)
{
std::cout<<"Error in Binstream: Some data didn't be written."<<std::endl;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some grammar errata: maybe "Some data wasn't written."?

size_t ch = fwrite(data,size,n,this->fileptr);
if(ch<static_cast<size_t>(n))
{
std::cout<<"Error in Binstream: Some dynamic memory didn't be written."<<std::endl;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Some dynamic memory wasn't written."?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bugs Bugs that only solvable with sufficient knowledge of DFT Input&Output Suitable for coders without knowing too many DFT details Refactor Refactor ABACUS codes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Code scan] Stop WFC_NAO binary writes after Binstream open failures

2 participants