Runtime: Enhance API to work with temporary files and directories

Created on 13 Sep 2017  路  10Comments  路  Source: dotnet/runtime

Rationale

In PowerShell repo we have a feature request to create temporary files with custom extension (not ".tmp").
Also we internally have to implement a function to create a directory for temporary files. Windows has GPO option to create session-based temporary directories.
Creating temporary files/directories is security-related (specially on Unix) so it would be right to implement this in .Net Core.
Unix has very power mkstemps fuction. It makes sense to give users its full functionality.

Proposed API

```c#
// if NewSubDir==true create new temporary directory as subdirectory in default temporary directory
public static string GetTempPath(bool newSubDir);

// Create new temp directory in 'InDirectory' directory
public static string GetTempPath(string inDirectory);

// Create a temp file with 'Suffix' extention
public static string GetTempFileName(string suffix);

// Create a temp file in 'InTempDirectory' directory
public static string GetTempFileName(string inTempDirectory);

// Optionally expose Unix 'mkstemps' function features and etc.
public static string GetTempFileName(string prefix);
public static string GetTempFileName(string prefix, string suffix);
public static string GetTempFileName(string prefix, string suffix, int variableLength);
public static string GetTempFileName(string prefix, string suffix, int variableLength, string inTempDirectory);
```

api-needs-work area-System.IO

Most helpful comment

@iSazonov, it is unlikely to be in 2.1 as time is almost up for that release. The enumeration updates are eating up all of my remaining bandwidth. Rest assured that better temporary file handling is something I'm _very_ interested in.

All 10 comments

c# public static string GetTempFileName(string Suffix) public static string GetTempFileName(string InTempDirectory) public static string GetTempFileName(string Prefix)

These three can't exist at the same time, since they have the same signature.

(Also, parameters should be named in camelCase, not PascalCase.)

Thanks for feedback. Case is fixed.
I list all API options for discussiononly - currently I don't know which options is best.

Creating temporary files/directories is security-related (specially on Unix)

If this is the case, I think you need to go into more detail about what you expect the behavior to be, and what aspects of the created files you expect to be secure. Do you want the guarantees of mkstemps, e.g. only the current user and process can access the file?

Without security concerns, I think the current API is sufficient -- you could easily build something that creates regular temporary files matching some specified filename pattern.

@eerhardt for the unix angle

About security. From link above http://man7.org/linux/man-pages/man3/mkstemp.3.html:

In glibc versions 2.06 and earlier, the file is created with
permissions 0666, that is, read and write for all users. This old
behavior may be a security risk, especially since other UNIX flavors
use 0600, and somebody might overlook this detail when porting
programs. POSIX.1-2008 adds a requirement that the file be created
with mode 0600.

We see two important requirements:

  1. File must be open.
  2. File must have 0600 access mask.

It's not that critical important for Windows but it is best practice too. If we want to create temporary files in an arbitrary directory, it also becomes critical important.

About workarounds. In addition to security, there are technical problems.
If we create a temporary file by standard way and then move it to an arbitrary directory and/or change the extension, we need to resolve the name conflicts: this utility makes millions of attempts in a loop to overcome such conflicts ("File already exists"). This is justified because all processes use a single general directory /tmp. (On Windows the limit is 65535 files)

I guess not all consumers care about these nuances.
We could offer them simple and secure API in .Net Core.

Unix has very power mkstemps fuction. It makes sense to give users its full functionality.

The Mono.Posix.NETStandard library exposes this function and its corresponding overloads, giving users its full functionality. Of course, it is lower level than the .NET I/O APIs, but you can do anything you'd like.

Can we expect this unified API to appear in 2.1 version?

@iSazonov, it is unlikely to be in 2.1 as time is almost up for that release. The enumeration updates are eating up all of my remaining bandwidth. Rest assured that better temporary file handling is something I'm _very_ interested in.

Another important point is that on Windows it calls an old Windows API for that. This API has not only a limit of around 65.000 files but has also bad performance (especially when getting closer to that limit). Therefore just for the sake of performance and file limit problem a new overload is needed.

Closing as we intend to cover this request in dotnet/runtime/issues/2048.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aggieben picture aggieben  路  3Comments

matty-hall picture matty-hall  路  3Comments

btecu picture btecu  路  3Comments

jkotas picture jkotas  路  3Comments

noahfalk picture noahfalk  路  3Comments