[filesystem] temp_dir_path()

The need for portably obtaining 'the' temporary-directory-path has been brought up a few times(but never addressed AFAICT), and I am now in the need for this as well. Windows has the GetTempPath, which follows a specific order of looking for a temporary directory path. If GetTempPath returns 0, GetLastError provides a system error. Posix relies on getEnv("TMPDIR"), which returns 0 if the environment variable does not exist. The following windows and posix implementation would be in the detail namespace: BOOST_FILESYSTEM_DECL path temp_dir_path(system::error_code* ec) { # ifdef BOOST_POSIX_API const char* val = getenv("TMPDIR"); return val? path(val) : path(); # else // Windows std::vector<Path::value_type> buf(GetTempPathW(0, NULL)); if(GetTempPathW(buf.size(), &buf[0])) return path(buf.begin(), buf.end()); int errval(::GetLastError()); if (ec) ec->assign(errval, system_category()); return path() # endif } Questions: - should Posix return an empty path or an error when empty? - should Windows provide a more 'temp-path' centric error? - should both verify the path exists? - if the path does not exist should one be created? Thanks, Jeff

On Sat, Oct 9, 2010 at 5:36 PM, Jeff Flinn <TriumphSprint2000@hotmail.com> wrote:
The need for portably obtaining 'the' temporary-directory-path has been brought up a few times(but never addressed AFAICT), and I am now in the need for this as well.
Windows has the GetTempPath, which follows a specific order of looking for a temporary directory path. If GetTempPath returns 0, GetLastError provides a system error.
Posix relies on getEnv("TMPDIR"), which returns 0 if the environment variable does not exist.
The following windows and posix implementation would be in the detail namespace:
BOOST_FILESYSTEM_DECL path temp_dir_path(system::error_code* ec) { # ifdef BOOST_POSIX_API const char* val = getenv("TMPDIR"); return val? path(val) : path();
# else // Windows
std::vector<Path::value_type> buf(GetTempPathW(0, NULL));
if(GetTempPathW(buf.size(), &buf[0])) return path(buf.begin(), buf.end());
int errval(::GetLastError()); if (ec) ec->assign(errval, system_category());
return path() # endif }
Questions: - should Posix return an empty path or an error when empty? - should Windows provide a more 'temp-path' centric error? - should both verify the path exists? - if the path does not exist should one be created?
Jeff, A temporary directory getter withing Boost.Filesystem would be a "nice to have". In my application, I created a function called GetValidatedTempDir() which does the get and validate, so my suggestions/comments would be as follows: - both flavours should verify the path exists. - a more 'temp-path' centric error might be good. I must confess to not knowing a great feal about the error codes. I usually have an outer catch for const std::exception& and expect that calling what() on that would give me something meaningful. If the temporary directory getter threw an exception if validation fails, and if calling what() on that gave me some idea about a problem with the temp path, then I'd be happy. - I don't think the path should be created. Regards, Pete

PB wrote:
On Sat, Oct 9, 2010 at 5:36 PM, Jeff Flinn <TriumphSprint2000@hotmail.com> wrote:
The need for portably obtaining 'the' temporary-directory-path has been brought up a few times(but never addressed AFAICT), and I am now in the need for this as well.
Windows has the GetTempPath, which follows a specific order of looking for a temporary directory path. If GetTempPath returns 0, GetLastError provides a system error.
Posix relies on getEnv("TMPDIR"), which returns 0 if the environment variable does not exist.
The following windows and posix implementation would be in the detail namespace:
BOOST_FILESYSTEM_DECL path temp_dir_path(system::error_code* ec) { # ifdef BOOST_POSIX_API const char* val = getenv("TMPDIR"); return val? path(val) : path();
# else // Windows
std::vector<Path::value_type> buf(GetTempPathW(0, NULL));
if(GetTempPathW(buf.size(), &buf[0])) return path(buf.begin(), buf.end());
int errval(::GetLastError()); if (ec) ec->assign(errval, system_category());
return path() # endif }
Questions: - should Posix return an empty path or an error when empty? - should Windows provide a more 'temp-path' centric error? - should both verify the path exists? - if the path does not exist should one be created?
Jeff,
A temporary directory getter withing Boost.Filesystem would be a "nice to have". In my application, I created a function called GetValidatedTempDir() which does the get and validate, so my suggestions/comments would be as follows:
- both flavours should verify the path exists. - a more 'temp-path' centric error might be good. I must confess to not knowing a great feal about the error codes. I usually have an outer catch for const std::exception& and expect that calling what() on that would give me something meaningful. If the temporary directory getter threw an exception if validation fails, and if calling what() on that gave me some idea about a problem with the temp path, then I'd be happy. - I don't think the path should be created.
Ok, the following uses filesystem's error facility to optionally throw or set errcode. It verfies the path is a directory, which IIUC, implies path existence. path temp_dir_path(system::error_code* ec) { # ifdef BOOST_POSIX_API const char* val = getenv("TMPDIR"); if (error(val==0, ec, "boost::filesystem::temp_dir_path")) return path(); path p(val); if (error(!fs::is_directory(p, ec), ec, "boost::filesystem::temp_dir_path")) return path(); return p; # else // Windows std::vector<Path::value_type> buf(GetTempPathW(0, NULL)); if (error(GetTempPathW(buf.size(), &buf[0])==0, ec, "boost::filesystem::temp_dir_path")) return path(); path p(buf.begin(), buf.end()); if (error(!fs::is_directory(p, ec), ec, "boost::filesystem::temp_dir_path")) return path(); return p; # endif } Jeff

Jeff Flinn wrote:
PB wrote:
On Sat, Oct 9, 2010 at 5:36 PM, Jeff Flinn <TriumphSprint2000@hotmail.com> wrote:
The need for portably obtaining 'the' temporary-directory-path has been brought up a few times(but never addressed AFAICT), and I am now in the need for this as well.
Windows has the GetTempPath, which follows a specific order of looking for a temporary directory path. If GetTempPath returns 0, GetLastError provides a system error.
Posix relies on getEnv("TMPDIR"), which returns 0 if the environment variable does not exist. ...
Questions: - should Posix return an empty path or an error when empty? - should Windows provide a more 'temp-path' centric error? - should both verify the path exists? - if the path does not exist should one be created?
A temporary directory getter withing Boost.Filesystem would be a "nice to have". In my application, I created a function called GetValidatedTempDir() which does the get and validate, so my suggestions/comments would be as follows:
- both flavours should verify the path exists. - a more 'temp-path' centric error might be good. I must confess to not knowing a great feal about the error codes. I usually have an outer catch for const std::exception& and expect that calling what() on that would give me something meaningful. If the temporary directory getter threw an exception if validation fails, and if calling what() on that gave me some idea about a problem with the temp path, then I'd be happy. - I don't think the path should be created.
Ok, the following uses filesystem's error facility to optionally throw or set errcode. It verfies the path is a directory, which IIUC, implies path existence.
Here's a version that actually compiles, at least on windows: path temp_dir_path(system::error_code* ec) { # ifdef BOOST_POSIX_API const char* val = std::getenv("TMPDIR"); if (error(val==0, ec, "boost::filesystem::temp_dir_path")) return path(); path p(val); if (error((ec && !is_directory(p, *ec)) || (!ec && !is_directory(p)), ec, "boost::filesystem::temp_dir_path")) return path(); return p; # else // Windows std::vector<path::value_type> buf(GetTempPathW(0, NULL)); if (error(GetTempPathW(buf.size(), &buf[0])==0, ec, "boost::filesystem::temp_dir_path")) return path(); path p(buf.begin(), buf.end()); if (error((ec && !is_directory(p, *ec)) || (!ec && !is_directory(p)), ec, "boost::filesystem::temp_dir_path")) return path(); return p; # endif } Jeff

On Saturday 09 October 2010 18:36:23 Jeff Flinn wrote:
Posix relies on getEnv("TMPDIR"), which returns 0 if the environment variable does not exist.
Question on that: Is it POSIX that actually mandates this very name anywhere? If it does, I'd like to hear chapter and verse, because then, lots of software doesn't conform to this and could be fixed. In my experience, there are actually four of these TMP, TEMP, TMPDIR and TEMPDIR. On my Debian system, I've redirected these to my homedir at ~/tmp/{tmp,temp,tmpdir,tempdir} and looking at ~/tmp I see this: uli@fruitbox:~/tmp$ du 24K ./tmp 4.0K ./tempdir 122M ./tmpdir 24M ./temp plus a bunch of files under /tmp bearing my ownership, probably from programs with a hard-coded path.
Questions: - should Posix return an empty path or an error when empty?
I'd say an error.
- should Windows provide a more 'temp-path' centric error?
I wouldn't bother. If someone needs this, they will probably file a bug ticket.
- should both verify the path exists?
Yes. Question remains what fallbacks should be tried, e.g. "/tmp" on POSIX systems or environment variables on non-embedded win32.
- if the path does not exist should one be created?
No, the application should define how to handle that, not the library. Uli

Ulrich Eckhardt wrote:
On Saturday 09 October 2010 18:36:23 Jeff Flinn wrote:
Posix relies on getEnv("TMPDIR"), which returns 0 if the environment variable does not exist.
Question on that: Is it POSIX that actually mandates this very name anywhere? If it does, I'd like to hear chapter and verse, because then, lots of software doesn't conform to this and could be fixed.
In my experience, there are actually four of these TMP, TEMP, TMPDIR and TEMPDIR. On my Debian system, I've redirected these to my homedir at ~/tmp/{tmp,temp,tmpdir,tempdir} and looking at ~/tmp I see this:
uli@fruitbox:~/tmp$ du 24K ./tmp 4.0K ./tempdir 122M ./tmpdir 24M ./temp
plus a bunch of files under /tmp bearing my ownership, probably from programs with a hard-coded path.
http://en.wikipedia.org/wiki/TMPDIR calls TMPDIR the "canonical Unix environment variable" and refers to the following for that justification: http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html#tag_0... On Mac OSX TMPDIR refers to the users temp folder.
Questions: - should Posix return an empty path or an error when empty?
I'd say an error.
Done. See the patch attached to ticket#4742. temp_dir_path() is now consistent with the error handling of the rest of filesystem.
- should Windows provide a more 'temp-path' centric error?
I wouldn't bother. If someone needs this, they will probably file a bug ticket.
- should both verify the path exists?
Yes. Question remains what fallbacks should be tried, e.g. "/tmp" on POSIX systems or environment variables on non-embedded win32.
Is the above reference sufficient to only rely on TMPDIR?
- if the path does not exist should one be created?
No, the application should define how to handle that, not the library.
agreed. Thanks, Jeff

On Sunday 10 October 2010 14:50:42 Jeff Flinn wrote:
Ulrich Eckhardt wrote:
On Saturday 09 October 2010 18:36:23 Jeff Flinn wrote: [...] http://en.wikipedia.org/wiki/TMPDIR calls TMPDIR the "canonical Unix environment variable" and refers to the following for that justification:
http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html#tag_ 08_03 [...]
- should both verify the path exists?
Yes. Question remains what fallbacks should be tried, e.g. "/tmp" on POSIX systems or environment variables on non-embedded win32.
Is the above reference sufficient to only rely on TMPDIR?
Yes, and thank you for that reference! Uli

Jeff Flinn wrote:
Ulrich Eckhardt wrote:
On Saturday 09 October 2010 18:36:23 Jeff Flinn wrote:
Posix relies on getEnv("TMPDIR"), which returns 0 if the environment variable does not exist.
Question on that: Is it POSIX that actually mandates this very name anywhere?
In my experience, there are actually four of these TMP, TEMP, TMPDIR and TEMPDIR.
http://en.wikipedia.org/wiki/TMPDIR calls TMPDIR the "canonical Unix environment variable" and refers to the following for that justification:
<http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html#tag_08_03>
On Mac OSX TMPDIR refers to the users temp folder.
This is curious. I've never set that variable, to my recollection, but have used TMP instead in my long years of using IRIX, Sun OS, Solaris, and Linux. It may well be that all of those OSes would have accepted both equally and, perhaps, even looked for TMPDIR first, but I've found TMP to work well and referencing only TMPDIR would break in my environment. I used set to verify my current environment and TMPDIR is not set by me or on my behalf. Granted, knowing the requirement or temp_dir_path(), I could readily correct my environment to fit, but it seems like trying the common e-vars would be a friendlier approach.
- should Windows provide a more 'temp-path' centric error?
I wouldn't bother. If someone needs this, they will probably file a bug ticket.
The two platforms should report the condition consistently, shouldn't they?
- should both verify the path exists?
Yes. Question remains what fallbacks should be tried, e.g. "/tmp" on POSIX systems or environment variables on non-embedded win32.
Is the above reference sufficient to only rely on TMPDIR?
I don't think so, but I'm inclined to say don't look for /tmp. That is, rely on the environment as the sole means to find the correct directory and if that is deficient, declare an error.
- if the path does not exist should one be created?
No, the application should define how to handle that, not the library.
agreed.
+1 An accessor should not have the side effect of creating a directory. Leave that for higher level code. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Stewart, Robert wrote:
Jeff Flinn wrote:
Ulrich Eckhardt wrote:
On Saturday 09 October 2010 18:36:23 Jeff Flinn wrote:
Posix relies on getEnv("TMPDIR"), which returns 0 if the environment variable does not exist. Question on that: Is it POSIX that actually mandates this very name anywhere?
In my experience, there are actually four of these TMP, TEMP, TMPDIR and TEMPDIR. http://en.wikipedia.org/wiki/TMPDIR calls TMPDIR the "canonical Unix environment variable" and refers to the following for that justification:
<http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html#tag_08_03>
On Mac OSX TMPDIR refers to the users temp folder.
This is curious. I've never set that variable, to my recollection, but have used TMP instead in my long years of using IRIX, Sun OS, Solaris, and Linux. It may well be that all of those OSes would have accepted both equally and, perhaps, even looked for TMPDIR first, but I've found TMP to work well and referencing only TMPDIR would break in my environment. I used set to verify my current environment and TMPDIR is not set by me or on my behalf.
Granted, knowing the requirement or temp_dir_path(), I could readily correct my environment to fit, but it seems like trying the common e-vars would be a friendlier approach.
Is there any consensus on this? What order should they be checked? Given the above links, I'd say TMPDIR should be first. How about: TMPDIR, TMP, TEMP, TEMPDIR?
- should Windows provide a more 'temp-path' centric error? I wouldn't bother. If someone needs this, they will probably file a bug ticket.
The two platforms should report the condition consistently, shouldn't they?
- should both verify the path exists? Yes. Question remains what fallbacks should be tried, e.g. "/tmp" on POSIX systems or environment variables on non-embedded win32. Is the above reference sufficient to only rely on TMPDIR?
I don't think so, but I'm inclined to say don't look for /tmp. That is, rely on the environment as the sole means to find the correct directory and if that is deficient, declare an error.
I agree it's not a good idea to look for a fixed path. I don't have broad enough UNIX systems experience to make the call on whether to look for additional environment variables. If TMPDIR *is* the POSIX standard should that be all that we support?
- if the path does not exist should one be created? No, the application should define how to handle that, not the library. agreed.
+1
An accessor should not have the side effect of creating a directory. Leave that for higher level code.
Agreed. Thanks, Jeff

On Mon, Oct 11, 2010 at 9:19 AM, Jeff Flinn <TriumphSprint2000@hotmail.com> wrote:
Stewart, Robert wrote:
Jeff Flinn wrote:
Ulrich Eckhardt wrote:
In my experience, there are actually four of these TMP, TEMP, TMPDIR and TEMPDIR.
http://en.wikipedia.org/wiki/TMPDIR calls TMPDIR the "canonical Unix environment variable" and refers to the following for that justification:
Is there any consensus on this? What order should they be checked? Given the above links, I'd say TMPDIR should be first.
How about: TMPDIR, TMP, TEMP, TEMPDIR?
Is the above reference sufficient to only rely on TMPDIR?
I don't think so, but I'm inclined to say don't look for /tmp. That is, rely on the environment as the sole means to find the correct directory and if that is deficient, declare an error.
I agree it's not a good idea to look for a fixed path. I don't have broad enough UNIX systems experience to make the call on whether to look for additional environment variables. If TMPDIR *is* the POSIX standard should that be all that we support?
I'm not going to pretend to be an expert, but I just ran a simple test. Of those environment variables the only one I had set was TMPDIR (I did not set up my envs and was surprised, actually). I compiled and ran a program that did nothing more than print the return of tmpnam(NULL) to std::cout. It resulted in a file that was in a different directory than ${TMPDIR} (and not /tmp either). env | grep 'directory.in.output' provided me with nothing. So I do not know where it got the directory for tmpnam(), but not from any env var. Is it wrong for me to think tmpnam() would name to something in my temporary directory?

John B. Turpish wrote:
On Mon, Oct 11, 2010 at 9:19 AM, Jeff Flinn <TriumphSprint2000@hotmail.com> wrote:
Stewart, Robert wrote:
Jeff Flinn wrote:
http://en.wikipedia.org/wiki/TMPDIR calls TMPDIR the "canonical Unix environment variable" and refers to the following for that justification:
Is the above reference sufficient to only rely on TMPDIR?
I don't think so, but I'm inclined to say don't look for /tmp. That is, rely on the environment as the sole means to find the correct directory and if that is deficient, declare an error.
I agree it's not a good idea to look for a fixed path. I don't have broad enough UNIX systems experience to make the call on whether to look for additional environment variables. If TMPDIR *is* the POSIX standard should that be all that we support?
I'm not going to pretend to be an expert, but I just ran a simple test. Of those environment variables the only one I had set was TMPDIR (I did not set up my envs and was surprised, actually). I compiled and ran a program that did nothing more than print the return of tmpnam(NULL) to std::cout. It resulted in a file that was in a different directory than ${TMPDIR} (and not /tmp either). env | grep 'directory.in.output' provided me with nothing. So I do not know where it got the directory for tmpnam(), but not from any env var.
According to <http://linux.die.net/man/3/tmpnam>, one should not use tmpname(3) but should instead call mkstemp(3) or tmpfile(3). The former makes a unique filename from a supplied template, so it is the caller's responsibility to select the directory. The latter creates a file which is deleted automatically when closed or when the process terminates. Neither mentions e-vars as influencing their behavior.
Is it wrong for me to think tmpnam() would name to something in my temporary directory?
I wouldn't say it was wrong, but it was clearly misguided. According to <http://linux.die.net/man/1/mktemp>, mktemp(1) references TMPDIR and falls back on /tmp unless "-p directory" was set on the command line. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On Tue, Oct 12, 2010 at 8:49 PM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
John B. Turpish wrote:
'directory.in.output' provided me with nothing. So I do not know where it got the directory for tmpnam(), but not from any env var.
According to <http://linux.die.net/man/3/tmpnam>, one should not use tmpname(3) but should instead call mkstemp(3) or tmpfile(3). The former makes a unique filename from a supplied template, so it is the caller's responsibility to select the directory. The latter creates a file which is deleted automatically when closed or when the process terminates. Neither mentions e-vars as influencing their behavior.
What I was getting at is there's already a function in the standard C library that needs to determine where to put temporary files - and in my mind that would be what the temporary directory is - and its result disagrees with what's being discussed here. mkstemp() doesn't have to come up with directory itself - as you pointed out. tmpfile() would, but printing the result of the decision not as convenient for a simple test as with tmpnam(). Besides, if the use case (not positive what it is, actually) was covered by tmpfile() then there would be no need for the function being discussed.

John B. Turpish wrote:
On Tue, Oct 12, 2010 at 8:49 PM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
John B. Turpish wrote:
'directory.in.output' provided me with nothing. So I do not know where it got the directory for tmpnam(), but not from any env var. According to <http://linux.die.net/man/3/tmpnam>, one should not use tmpname(3) but should instead call mkstemp(3) or tmpfile(3). The former makes a unique filename from a supplied template, so it is the caller's responsibility to select the directory. The latter creates a file which is deleted automatically when closed or when the process terminates. Neither mentions e-vars as influencing their behavior.
What I was getting at is there's already a function in the standard C library that needs to determine where to put temporary files - and in my mind that would be what the temporary directory is - and its result disagrees with what's being discussed here. mkstemp() doesn't have to come up with directory itself - as you pointed out. tmpfile() would, but printing the result of the decision not as convenient for a simple test as with tmpnam(). Besides, if the use case (not positive what it is, actually) was covered by tmpfile() then there would be no need for the function being discussed.
My primary use cases are in interacting with legacy 3rd party apps that read/write from/to the users temp directory with advertised file names, and an historical place to direct users if they want to see intermediate level logged data. Qt was previously used for this, but it interferes with legacy code when run on a mac under rosetta, causes false memory leaks from boost unit tests due, I think, to caching in static data members the path's after the first call, and appears to bring in a lot of extraneous code that doubles my executable sizes. Jeff

On Wed, Oct 13, 2010 at 7:03 PM, Jeff Flinn <TriumphSprint2000@hotmail.com> wrote:
John B. Turpish wrote:
On Tue, Oct 12, 2010 at 8:49 PM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
John B. Turpish wrote:
'directory.in.output' provided me with nothing. So I do not know where it got the directory for tmpnam(), but not from any env var.
According to <http://linux.die.net/man/3/tmpnam>, one should not use tmpname(3) but should instead call mkstemp(3) or tmpfile(3). The former makes a unique filename from a supplied template, so it is the caller's responsibility to select the directory. The latter creates a file which is deleted automatically when closed or when the process terminates. Neither mentions e-vars as influencing their behavior.
What I was getting at is there's already a function in the standard C library that needs to determine where to put temporary files - and in my mind that would be what the temporary directory is - and its result disagrees with what's being discussed here. mkstemp() doesn't have to come up with directory itself - as you pointed out. tmpfile() would, but printing the result of the decision not as convenient for a simple test as with tmpnam(). Besides, if the use case (not positive what it is, actually) was covered by tmpfile() then there would be no need for the function being discussed.
My primary use cases are in interacting with legacy 3rd party apps that read/write from/to the users temp directory with advertised file names, and an historical place to direct users if they want to see intermediate level logged data.
I get the temporary directory in Windows to create zip files in. These get added to an email as attachments. The files need to have well-known names formed by the application. I'm just interested in a writable place they can be created in and then soon deleted. Regards, Pete

I've updated ticket#4724 with temp_dir_path2.patch which reflects the discussion in this thread. POSIX now uses the first environment variable from the list TMPDIR, TMP, TEMP, TEMPDIR. Windows still uses GetTempPath. Error handling is consistent with the rest of filesystem. operations_test.hpp tests the existence of the path returned by temp_dir_path, and the ability to create a file, write to it, read from it, and remove it from the directory. I've run tests on Window XP: msvc8, Mac OSX 10.5.8: Xcode 3.1.2 using gcc 4.0.1. Beman, do you think we can get this into 1.45? Thanks, Jeff

Jeff Flinn wrote:
I've updated ticket#4724 with temp_dir_path2.patch which reflects the discussion in this thread.
POSIX now uses the first environment variable from the list TMPDIR, TMP, TEMP, TEMPDIR. Windows still uses GetTempPath.
Error handling is consistent with the rest of filesystem.
operations_test.hpp tests the existence of the path returned by temp_dir_path, and the ability to create a file, write to it, read from it, and remove it from the directory.
Did you test the various combinations of e-vars being set? How are you testing the error handling code? _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Stewart, Robert wrote:
Jeff Flinn wrote:
I've updated ticket#4724 with temp_dir_path2.patch which reflects the discussion in this thread.
POSIX now uses the first environment variable from the list TMPDIR, TMP, TEMP, TEMPDIR. Windows still uses GetTempPath.
Error handling is consistent with the rest of filesystem.
operations_test.hpp tests the existence of the path returned by temp_dir_path, and the ability to create a file, write to it, read from it, and remove it from the directory.
Did you test the various combinations of e-vars being set?
Yes, manually(not within operations_test.cpp) on mac by setting/unsetting the environment vars, not on windows though as I've not been able to make GetTempPath to fail. Not sure if mucking with the environ is acceptable to Beman's tests.
How are you testing the error handling code?
Same as above. Any thoughts on how to proceed? Thanks, Jeff

Jeff Flinn wrote:
Stewart, Robert wrote:
Jeff Flinn wrote:
Did you test the various combinations of e-vars being set?
Yes, manually(not within operations_test.cpp) on mac by setting/unsetting the environment vars, not on windows though as I've not been able to make GetTempPath to fail. Not sure if mucking with the environ is acceptable to Beman's tests.
I'm assuming that temp_dir_path()'s test code would be in a separate executable, so that wouldn't be an issue.
How are you testing the error handling code?
Same as above. Any thoughts on how to proceed?
Use setenv() and unsetenv() to modify the environment and run the test to verify you get the expected results. Set each of the e-vars singly, in turn, and test with each. Set each pair of e-vars, in turn, and verify the results for each. Etc. Set just TMPDIR to an invalid, but non-empty, pathname and test for the expected error. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Stewart, Robert wrote:
Jeff Flinn wrote:
Stewart, Robert wrote:
Jeff Flinn wrote: Did you test the various combinations of e-vars being set? Yes, manually(not within operations_test.cpp) on mac by setting/unsetting the environment vars, not on windows though as I've not been able to make GetTempPath to fail. Not sure if mucking with the environ is acceptable to Beman's tests.
I'm assuming that temp_dir_path()'s test code would be in a separate executable, so that wouldn't be an issue.
How are you testing the error handling code? Same as above. Any thoughts on how to proceed?
Use setenv() and unsetenv() to modify the environment and run the test to verify you get the expected results.
Set each of the e-vars singly, in turn, and test with each.
Set each pair of e-vars, in turn, and verify the results for each.
Etc.
Set just TMPDIR to an invalid, but non-empty, pathname and test for the expected error.
I've attached an updated patch to ticket #4742. This adds tests to operations_test.cpp that test the error handling for both returned error code and thrown filesystem_error. Additionally it tests proper retrieval of the path from the list of env vars for each of the platforms. Also, temp_dir_path now also sets the error_code to ENOTDIR upon failure. These test pass on Windows XP with MSVC8 and Mac OSX10.5.8 with Xcode3.1.2 using gcc 4.0.1 I'd appreciate it if others could run the tests on other os/compilers as well. Thanks, Jeff

On Thu, Oct 14, 2010 at 3:05 PM, Jeff Flinn <TriumphSprint2000@hotmail.com> wrote:
I've attached an updated patch to ticket #4742.
This adds tests to operations_test.cpp that test the error handling for both returned error code and thrown filesystem_error. Additionally it tests proper retrieval of the path from the list of env vars for each of the platforms.
Also, temp_dir_path now also sets the error_code to ENOTDIR upon failure.
These test pass on Windows XP with MSVC8 and Mac OSX10.5.8 with Xcode3.1.2 using gcc 4.0.1
I'd appreciate it if others could run the tests on other os/compilers as well.
First, thanks to Jeff for a nice piece of work! For those of you who didn't actually look at his patch file, he provided a working implementation, test code, and documentation. All in the style of the current code, and fully integrated into the library. A joy to work with. I've applied the patch to my working copy, inspected the code and documentation, and tested with the compilers on my Windows machine. Here are my reactions: * This is useful functionality and I'm planning to accept it into the library. A few nits follow, but they are all trivial to fix. * For consistency with the rest of the library, the name should be "temp_directory_path" rather than "temp_dir_path". * I'll do a bit of doc rewording to make them a bit less Windows and POSIX centric. * There are compilation failures (see below) with MinGW. I'm guessing this is a minor configuration issue with the test code that will be trivial to fix. * And of course Jeff will be given credit for contributing this nice addition to Boost.Filesystem. Thanks, --Beman ..\v3\test\operations_test.cpp: In function 'void<unnamed>::temp_dir_path_tests()': ..\v3\test\operations_test.cpp:1606:73: error: no matching function for call to '<unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(const char*, int, int)' ..\v3\test\operations_test.cpp:1578:9: note: candidates are: <unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(const boost::filesystem3::path::value_type*, const boost::filesystem3::path::value_type*, const boost::filesystem3::path::value_type*) ..\v3\test\operations_test.cpp:1573:7: note: <unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(const<unnamed>::temp_dir_path_tests()::guarded_tmp_vars&) ..\v3\test\operations_test.cpp:1611:73: error: no matching function for call to '<unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(int, const char*, int)' ..\v3\test\operations_test.cpp:1578:9: note: candidates are: <unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(const boost::filesystem3::path::value_type*, const boost::filesystem3::path::value_type*, const boost::filesystem3::path::value_type*) ..\v3\test\operations_test.cpp:1573:7: note: <unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(const<unnamed>::temp_dir_path_tests()::guarded_tmp_vars&) ..\v3\test\operations_test.cpp:1616:73: error: no matching function for call to '<unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(int, int, const char*)' ..\v3\test\operations_test.cpp:1578:9: note: candidates are: <unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(const boost::filesystem3::path::value_type*, const boost::filesystem3::path::value_type*, const boost::filesystem3::path::value_type*) ..\v3\test\operations_test.cpp:1573:7: note: <unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(const<unnamed>::temp_dir_path_tests()::guarded_tmp_vars&)

Beman Dawes wrote:
On Thu, Oct 14, 2010 at 3:05 PM, Jeff Flinn <TriumphSprint2000@hotmail.com> wrote:
I've attached an updated patch to ticket #4742.
This adds tests to operations_test.cpp that test the error handling for both returned error code and thrown filesystem_error. Additionally it tests proper retrieval of the path from the list of env vars for each of the platforms.
Also, temp_dir_path now also sets the error_code to ENOTDIR upon failure.
These test pass on Windows XP with MSVC8 and Mac OSX10.5.8 with Xcode3.1.2 using gcc 4.0.1
I'd appreciate it if others could run the tests on other os/compilers as well.
First, thanks to Jeff for a nice piece of work!
For those of you who didn't actually look at his patch file, he provided a working implementation, test code, and documentation. All in the style of the current code, and fully integrated into the library. A joy to work with.
Thanks.
I've applied the patch to my working copy, inspected the code and documentation, and tested with the compilers on my Windows machine. Here are my reactions:
* This is useful functionality and I'm planning to accept it into the library. A few nits follow, but they are all trivial to fix.
* For consistency with the rest of the library, the name should be "temp_directory_path" rather than "temp_dir_path".
Agreed.
* I'll do a bit of doc rewording to make them a bit less Windows and POSIX centric.
Sounds good.
* There are compilation failures (see below) with MinGW. I'm guessing this is a minor configuration issue with the test code that will be trivial to fix.
* And of course Jeff will be given credit for contributing this nice addition to Boost.Filesystem.
Thanks,
--Beman
..\v3\test\operations_test.cpp: In function 'void<unnamed>::temp_dir_path_tests()': ..\v3\test\operations_test.cpp:1606:73: error: no matching function for call to '<unnamed>::temp_dir_path_tests()::guarded_tmp_vars::guarded_tmp_vars(const char*, int, int)'
Looks like that platform is compiling the windows code with test_temp_dir.BOOST_FILESYSTEM_C_STR returning a const char*. Jeff

Jeff's contribution has been committed to trunk, with the name temp_directory_path(). It is now passing all tests on Windows with VC++ 8, 9, 10, cygwin/gcc 4.3, and mingw/gcc 4.5. Ubuntu and OpenSolaris set no environmental variables naming the temporary directory. They do seem to come with a /tmp directory however. So maybe for POSIX-like systems, we will have to look first for the environmental variables, and then if not found look for specific directories. --Beman

On Sat, Oct 16, 2010 at 6:42 PM, Beman Dawes <bdawes@acm.org> wrote:
Ubuntu and OpenSolaris set no environmental variables naming the temporary directory. They do seem to come with a /tmp directory however.
So maybe for POSIX-like systems, we will have to look first for the environmental variables, and then if not found look for specific directories.
I've now done that, changed the tests accordingly, and verified they are passing on Ubuntu Linux. If anyone is aware of any POSIX-like operating systems that don't set TMPDIR, TMP, TEMP, or TEMPDIR environmental variables naming the temporary directory or don't supply a temporary directory named "/tmp", please let us know the name of the temporary directory. Other than that, I guess we just wait for tests to cycle. --Beman

Beman Dawes wrote:
On Sat, Oct 16, 2010 at 6:42 PM, Beman Dawes <bdawes@acm.org> wrote:
Ubuntu and OpenSolaris set no environmental variables naming the temporary directory. They do seem to come with a /tmp directory however.
So maybe for POSIX-like systems, we will have to look first for the environmental variables, and then if not found look for specific directories.
I've now done that, changed the tests accordingly, and verified they are passing on Ubuntu Linux.
If anyone is aware of any POSIX-like operating systems that don't set TMPDIR, TMP, TEMP, or TEMPDIR environmental variables naming the temporary directory or don't supply a temporary directory named "/tmp", please let us know the name of the temporary directory.
Other than that, I guess we just wait for tests to cycle.
Awesome, thanks for getting this in Beman! As I previously mentioned to you, I have initial implementations for a home_directory_path and application_path/current_process_path. I'll start a new thread on those topics, and provide patches based on the latest trunk. Jeff

"Beman Dawes" <bdawes@acm.org> wrote in message news:AANLkTim3zgLX1Q5f5YUko6tsZdQW2DZy9iqkf3GFaaU1@mail.gmail.com...
Other than that, I guess we just wait for tests to cycle.
Would it be perhaps possible to provide a lower-level function (even in the detail namespace) that uses a plain char buffer and an error code, that is free of std::vectors, std::strings, boost::paths, system::error_codes and other things one might not want to pay for (especially if one does not use them otherwise) just to make a system API call..? The 'proper' version can then wrap the thinner one... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

On Tue, Oct 19, 2010 at 3:35 AM, Domagoj Saric <dsaritz@gmail.com> wrote:
"Beman Dawes" <bdawes@acm.org> wrote in message news:AANLkTim3zgLX1Q5f5YUko6tsZdQW2DZy9iqkf3GFaaU1@mail.gmail.com...
Other than that, I guess we just wait for tests to cycle.
Would it be perhaps possible to provide a lower-level function (even in the detail namespace) that uses a plain char buffer and an error code, that is free of std::vectors, std::strings, boost::paths, system::error_codes and other things one might not want to pay for (especially if one does not use them otherwise) just to make a system API call..? The 'proper' version can then wrap the thinner one...
It would be technically possible, of course, but ... What you are really asking for, I think, is a C language interface or something pretty close to that. I could have designed the library that way, but didn't want to add a third way for users to do things, and didn't want to take on the increased documentation, test, etc, workload. --Beman
participants (7)
-
Beman Dawes
-
Domagoj Saric
-
Jeff Flinn
-
John B. Turpish
-
PB
-
Stewart, Robert
-
Ulrich Eckhardt