Re:[boost] Serialization and tmpnam

Guillaume Melquiond wrote:
I see the serialization library uses "tmpnam" quite a lot. I don't know what the status of this function is on other operating system. But on GNU/Linux at least (and I suppose it is the same for any POSIX system), it is considered to be bad practice [1]. Such a bad practice that the linker ld is especially programed to complain whenever somebody uses this function. Moreover, I see that Borland and Microsoft compilers "have brain->dead tmpnam functions" [2] so a replacement was needed.
So it may be a good idea to completely remove the function "tmpnam" from the Serialization library and use a saner replacement instead. This way, the library tests would compile without any complaint from the linker on Linux.
I need this functionality to run the tests. What is the best way to go about it? Robert Ramey

On Thu, Jul 15, 2004 at 10:02:22AM -0700, Robert Ramey wrote:
Guillaume Melquiond wrote: [...]
So it may be a good idea to completely remove the function "tmpnam" from the Serialization library and use a saner replacement instead. This way, the library tests would compile without any complaint from the linker on Linux.
I need this functionality to run the tests. What is the best way to go about it?
The (linux) man page tmpnam(3) recommends to use mkstemp(3) instead. (It should be available on most Unix systems since it is a POSIX function. I don't know about Windows.) However, mkstemp(3) not only generates a unique filename but it also opens the corresponding file and returns the file descriptor. You'd have to close the file, possibly remove it, and then pass the filename to the constructor of your stream which will create and open the file again. That sounds like a hack to me and may not be portable. But do you really need a new temporary filename in each test run? I fail to see why it is a problem if each test uses a dedicated filename. It does not make sense to run several instances of a particular test in parallel, does it? Regards Christoph -- http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/cludwig.html LiDIA: http://www.informatik.tu-darmstadt.de/TI/LiDIA/Welcome.html

Christoph Ludwig <cludwig@cdc.informatik.tu-darmstadt.de> writes:
On Thu, Jul 15, 2004 at 10:02:22AM -0700, Robert Ramey wrote:
Guillaume Melquiond wrote: [...]
So it may be a good idea to completely remove the function "tmpnam" from the Serialization library and use a saner replacement instead. This way, the library tests would compile without any complaint from the linker on Linux.
I need this functionality to run the tests. What is the best way to go about it?
The (linux) man page tmpnam(3) recommends to use mkstemp(3) instead. (It should be available on most Unix systems since it is a POSIX function. I don't know about Windows.)
However, mkstemp(3) not only generates a unique filename but it also opens the corresponding file and returns the file descriptor. You'd have to close the file, possibly remove it, and then pass the filename to the constructor of your stream which will create and open the file again. That sounds like a hack to me and may not be portable.
And I think it undermines the big reason tmpnam is not recommended: someone can come along and grab the same name and you will overwrite their file by mistake. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
However, mkstemp(3) not only generates a unique filename but it also opens the corresponding file and returns the file descriptor. You'd have to close the file, possibly remove it, and then pass the filename to the constructor of your stream which will create and open the file again. That sounds like a hack to me and may not be portable.
And I think it undermines the big reason tmpnam is not recommended: someone can come along and grab the same name and you will overwrite their file by mistake.
Actually, even worse: somebody can create a link from /tmp/xyz to /your/home/dir/the_most_important_file and when you open /tmp/xyz for writing, you will wipe the important file of yours. This is in fact much worse then overwriting some other user's temporary file -- which I think is not possible on Unix. The right solution in Unix is to pass O_EXCL|O_CREAT flags to the 'open' system call -- which will make sure that the file does not exist. Or you can use mkstemp, as Martin says. Something like this will do: char name[] = "testXXXXXX"; int fd = mkstemp(name); std::ofstream ofs(name); ofs << "foo"; It is also possible to make OS remove the file no matter what happens to your program by calling "unlink(name)" while the file is still open. However, this will remove the file from directory listing, so all streams must be opened before calling unlink, like this: char name[] = "testXXXXXX"; int fd = mkstemp(name); std::ofstream ofs(name); std::ifstream ifs(name); unlink(name); ofs << "foo" << std::flush; std::cout << "Name is: " << name << "\n"; std::cout << "Content is : " << ifs.rdbuf() << "\n"; - Volodya

Le jeu 15/07/2004 à 19:02, Robert Ramey a écrit :
Guillaume Melquiond wrote:
So it may be a good idea to completely remove the function "tmpnam" from the Serialization library and use a saner replacement instead. This way, the library tests would compile without any complaint from the linker on Linux.
I need this functionality to run the tests. What is the best way to go about it?
I don't know what the best way is. However, some other libraries also need to write to files during their tests. For example, the filesystem library doesn't even bother and it directly creates some directories [1]. When running regression tests, they end in boost/status. You could work the same way: simply create a file with a given name rather than trying to create a temporary file. If you think it is a bit ugly, I have the same opinion. A better way would probably for bjam to provide a clean sandbox where test programs could play rather than letting them work in boost/status. But I don't know how easy it would be. Regards, Guillaume [1] Speaking of which, filesystem/test/convenience_test.cpp could at least delete its test directory at the end of its execution.

Robert Ramey wrote:
Guillaume Melquiond wrote:
...
So it may be a good idea to completely remove the function "tmpnam" from the Serialization library and use a saner replacement instead. This way, the library tests would compile without any complaint from the linker on Linux.
I need this functionality to run the tests. What is the best way to go about it?
int mkstemp(char *template) on POSIX systems. HTH, m

Robert Ramey wrote:
Guillaume Melquiond wrote:
I see the serialization library uses "tmpnam" quite a lot. I don't know what the status of this function is on other operating system. But on GNU/Linux at least (and I suppose it is the same for any POSIX system), it is considered to be bad practice [1]. Such a bad practice that the linker ld is especially programed to complain whenever somebody uses this function. Moreover, I see that Borland and Microsoft compilers "have brain->dead tmpnam functions" [2] so a replacement was needed.
So it may be a good idea to completely remove the function "tmpnam" from the Serialization library and use a saner replacement instead. This way, the library tests would compile without any complaint from the linker on Linux.
I need this functionality to run the tests. What is the best way to go about it?
The main danger of tmpnam is not that someone else may use the name, since a new unique name is returned each time, but rather that one may not have the rights to create a file in the current directory. Under Windows you could try: 1) tmpnam 2) _tempnam for compilers which support it ( both VC++ and C++ Builder do ) 3) GetTempPath followed by GetTempFileName, both Windows APi functions I don't see any mkstemp under Windows. It would be nice if the filesystem library had a way of creating a temporary file.

In article <009c01c46bb4$22145660$02fea8c0@eldiener>, "Eddie Diener" <eddielee@tropicsoft.com> wrote:
The main danger of tmpnam is not that someone else may use the name, since a new unique name is returned each time, but rather that one may not have the rights to create a file in the current directory.
No, the main danger of tmpnam is that using tmpnam forces you into a situation where you have a race condition that opens a security hole. <http://www.suse.co.uk/uk/private/support/online_help/howto/secprog/secprog3....
has a good description of the problem.
meeroh -- If this message helped you, consider buying an item from my wish list: <http://web.meeroh.org/wishlist>
participants (8)
-
Christoph Ludwig
-
David Abrahams
-
Eddie Diener
-
Guillaume Melquiond
-
Martin Wille
-
Miro Jurisic
-
Robert Ramey
-
Vladimir Prus