- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.7k
Clean revision of temporary file and directory functions #1440
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
Conversation
| Sorry to nitpick, but if we honor environment variables, I feel they should override even what  | 
| Ok. I can search environment variables in  | 
| Another revision made. See what you think of this. | 
| Looks good to me! Thanks for all your work on this. :) | 
        
          
                base/file.jl
              
                Outdated
          
        
      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.
We really need a better way to get the value of L_tmpnam rather than hardcoding 1024. This could lead to security and/or corruption issues at a later date. I don't know of a good way to do this though. :-(
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.
Yes, this is not a great long term strategy. It would be good to find a way to learn the true value of L_tmpnam.
But, for now, how about being a little wasteful and using 4096? Based on this list from Wikipedia (http://en.wikipedia.org/wiki/Comparison_of_file_systems), no existing filename should be longer than 4096. While this doesn't apply to full paths, it's at least a little safer at the expense of 4x as much memory.
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.
I would feel safer with 4096 in that case, even though that is not the greatest. I can't think of a way to get this except to compile a C program and have it print the value. Perhaps there are better ways.
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.
I agree that adding a C function that returns the value is the only surefire to do this. Should we go ahead with that?
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.
Just pass C_NULL to tmpnam, and copy the return string.
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.
Kudos to @nolta for actually reading the manpage. :P
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.
Change made.
        
          
                base/file.jl
              
                Outdated
          
        
      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.
We also need a check if the path already exists. So why don't we just go back to your original tempname, and move the tmpnam call into tempdir?
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.
Why not just use the looping approach from the previous tempname with this call to tmpnam? I might just be missing something, but it seems useful to have everything boil down to a call to tmpnam here.
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.
Do we even want to use tmpnam, since it doesn't work on windows?
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.
There's an equivalent implementation on Windows: http://msdn.microsoft.com/en-us/library/18x8h1bh(v=vs.80).aspx. (Why? Why are there parentheses in that URL?!) There's an insecure version as well, but Microsoft doesn't like you to use those.
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.
I'm not sure. There were some concerns about synchrony among RNG's corrupting the names produced by randstring, which is why I moved away from it. I don't really know what the right direction is for going forward. When some of the Windows developers last chimed in, I had the impression that  they would recommend using special calls on Windows, but I don't have the bandwidth or experience to implement that myself.
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.
GetTempPath and GetTempFileName are the functions to use on Windows. If you want to use tmpnam, I'm ok with you just marking it linux_only and making a windows_only version that raises a NotImplementedError. I''ll just open an issue against the windows version that it needs to be eventually implemented.
(@staticfloat to make matters worse, msdn is using that as a param string for the version, so the url works without it)
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.
Ok. I'll go ahead and do that then.
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.
Made changes. Didn't see a NotImplementedError type exception, so I'm just raising error("not yet implemented").
| Works on linux, freebsd, & darwin. | 
| @nolta that should work on windows too, with the addendum that the function is called as  | 
| @vtjnash So the final versions would be the following?  | 
| function tempname()
    d = get(ENV, "TMPDIR", C_NULL) # darwin workaround
    @windows_only p = ccall(:_tempnam, Ptr{Uint8}, (Ptr{Uint8},Ptr{Uint8}), d, "julia")
    @unix_only p = ccall(:tempnam, Ptr{Uint8}, (Ptr{Uint8},Ptr{Uint8}), d, "julia")
    s = bytestring(p)
    c_free(p)
    s
end? | 
|  | 
| Why do we need the  | 
| ccall is special. | 
| Ok. Changes made. | 
| Hmm, actually we don't. I added eval because this fails: But it works if tempnam is a global:  | 
| Ok. The eval's gone and tempnam is a global now. | 
| Thanks, @nolta and @johnmyleswhite, that's even better! | 
        
          
                base/file.jl
              
                Outdated
          
        
      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.
p = ccall(:mkstemp, Int32, (Ptr{Uint8},), b)
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.
Changed.
| ccall is special because it requires that the first three arguments be known (constant) at the compile time of the function. I was going to suggest Pao's code, to avoid the global and minimize duplication of code. But anything that accomplishes that is sufficient. | 
| mkdtemp and mkstemp do not exist on windows, so can you surround those functions with unix_only and then squash the history on this pull request so it is ready to merge? | 
Use tempname() in tempdir(); tempdir() in mktemp*() Environment variables take precendence for temporary directories Use C_NULL for arbitrary length filenames Insure that path doesn't exist Made candidate_tempname() a unix_only function tempname and tempdir for both Windows and UNIX Removed superfluous eval Revised tests Specify 32-bit ints Made mkstemp and mkdtemp wrappers UNIX only functions
| I corrupted my fork doing the squashing. I'm closing this one and opening one last pull request with the revised code. | 
) Stdlib: LinearAlgebra URL: https://github.com/JuliaLang/LinearAlgebra.jl.git Stdlib branch: master Julia branch: master Old commit: d568106 New commit: 7e11b5e Julia version: 1.13.0-DEV LinearAlgebra version: 1.13.0 Bump invoked by: @IanButterworth Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaLang/LinearAlgebra.jl@d568106...7e11b5e ``` $ git log --oneline d568106..7e11b5e 7e11b5e Add `AbstractArray` conversions for `AbstractQ` (#1470) 52c41f7 Add missing methods to `diagind` documentation (#1473) 28ee87e Overload array constructors for BunchKaufman (#1461) (#1466) 6f73f65 Add 'eigmin'/'eigmax' methods for 'Eigen' (#1468) 7b21cab Use `Iterators.rest` within `generic_norm` to simplify code (#1459) 57ac0eb Make `parentof_applytri` fully type-stable (#1243) 880a9fe Add `_sym_uplo` to skip validation (#1441) 8d6ca14 Public function to access the `uplo` for `Symmetric`/`Hermitian` (#1440) 7a4b27e Make `dot` with Bool-arrays type-stable (#1456) 6fe77f8 Make `dot` with Bool-arrays type-stable 5af75df Remove zeroing in `similar` for `Hermitian` (#1455) 5685390 Index into diag in `Tridigaonal` * `Diagonal` (#1454) 51923a5 Forward structure-preserving broadcasting to diag for `Diagonal` (#1423) 35a4427 Iterator norm in `isapprox` for `Array`s (#1378) 98723df Structured broadcasting for UpperHessenberg (#1325) ``` Co-authored-by: IanButterworth <1694067+IanButterworth@users.noreply.github.com>
Here is a clean pull request for working with temporary files and directories.
I've left the tests inactive until others confirm that they pass on other machines.