- 
                Notifications
    You must be signed in to change notification settings 
- Fork 3.4k
When opening broken symlink with O_CREAT, create file at target #23002
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When opening broken symlink with O_CREAT, create file at target #23002
Conversation
      
        
              This comment was marked as resolved.
        
        
      
    
  This comment was marked as resolved.
Instead of raising an EEXIST error
55152ce    to
    5bd422e      
    Compare
  
    | if (!current.node_ops.readlink) { | ||
| throw new FS.ErrnoError({{{ cDefs.ENOSYS }}}); | ||
| } | ||
| var link = current.node_ops.readlink(current); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before this change, FS.readlink calls lookupPath again which repeats exactly the same work we've done up to this point in this function except with opts.follow false. Rather than doing that, we already have the node here so I figure it's better just to call node_ops.readlink.
| I think this one is ready to merge? | 
| Looks like there is an asan failure with this test: https://logs.chromium.org/logs/emscripten-releases/buildbucket/cr-buildbucket/8728915358824971169/+/u/Emscripten_testsuite__ASan_/stdout  | 
…ripten-core#23002) If we open a broken symlink with `O_CREAT` we should create a new file as the target of the symlink. Fixes: emscripten-core#23001.
If we open a broken symlink with
O_CREATwe should create a new file as the target of the symlink.This resolves #23001.
To fix the problem, I added an extra
handleBrokenLinkoption tolookupPath. When this option is passed, if the input path is a broken symlink, instead of raisingEEXIST, it returns{ path: theTarget, node: undefined}. Then inopenwe updatepathbased on the returned path, so if the node doesn't exist we attempt create it at the resolved target path of the symlink rather than trying to create it on the source of the symlink which raisesEEXISTagain.