From dev-return-8329-apmail-stdcxx-dev-archive=stdcxx.apache.org@stdcxx.apache.org Sat Nov 01 22:03:48 2008 Return-Path: Delivered-To: apmail-stdcxx-dev-archive@www.apache.org Received: (qmail 63572 invoked from network); 1 Nov 2008 22:03:48 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Nov 2008 22:03:48 -0000 Received: (qmail 15115 invoked by uid 500); 1 Nov 2008 22:03:54 -0000 Delivered-To: apmail-stdcxx-dev-archive@stdcxx.apache.org Received: (qmail 15093 invoked by uid 500); 1 Nov 2008 22:03:54 -0000 Mailing-List: contact dev-help@stdcxx.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@stdcxx.apache.org Delivered-To: mailing list dev@stdcxx.apache.org Received: (qmail 15082 invoked by uid 99); 1 Nov 2008 22:03:54 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Nov 2008 15:03:54 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of msebor@gmail.com designates 209.85.146.180 as permitted sender) Received: from [209.85.146.180] (HELO wa-out-1112.google.com) (209.85.146.180) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 01 Nov 2008 22:02:38 +0000 Received: by wa-out-1112.google.com with SMTP id m33so990176wag.31 for ; Sat, 01 Nov 2008 15:03:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:content-type :content-transfer-encoding; bh=PTK0GbyaMeH4w7zA5tDGUGr3uYCCI1M2o+GFjrcxGhs=; b=uroElr05/CKx+/P3db4GLg0uGalcRfrWwjiuOJ7ve53+MyGhJa8CebftZQlP+e4LJ3 D+k+Jm0RHHSPlyucZreNv50VVyM2HgnkJF2kSATX9uk5jlUDpXkAEczxrviOaQaah7GW uZghjgmg2eDmpHlrLET28UiGuaWHesp1VgIBQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject :content-type:content-transfer-encoding; b=n87ojyVHgASHjIJbbhRiB+r7385XWgE5VT4TKxLMDPC2ArDo9WMsPGyZ/KWhT9C2D1 R/VgDRmtAAlQpnppdIDph3NXc2QoxB08EhFPniGGWd2q68HxbOvMCW41D1HgSaMvh8aB Io5dZuNygxFhHK4KJ8HzUNFvoQFcwoYaqsZ24= Received: by 10.114.210.2 with SMTP id i2mr11400051wag.18.1225576998820; Sat, 01 Nov 2008 15:03:18 -0700 (PDT) Received: from bugsy.net (c-71-229-200-170.hsd1.co.comcast.net [71.229.200.170]) by mx.google.com with ESMTPS id y25sm7541118pod.9.2008.11.01.15.03.16 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 01 Nov 2008 15:03:17 -0700 (PDT) Message-ID: <490CD223.5050308@gmail.com> Date: Sat, 01 Nov 2008 16:03:15 -0600 From: Martin Sebor User-Agent: Thunderbird 2.0.0.16 (X11/20080723) MIME-Version: 1.0 To: dev@stdcxx.apache.org Subject: test for STDCXX-1019 ([Fwd: svn commit: r709784 - /stdcxx/branches/4.2.x/src/file.cpp]) Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Scott, as an FYI, the change below adds support for TMPDIR to std::filebuf::open() (in __rw_mkstemp()). I resolved the issue but I won't close it until we've added a test for it to the test suite. The test needs to verify that the function considers the TMPDIR variable and behaves reasonably when TMPDIR is invalid (either too long refers to a non-existent or inaccessible directory). Now that I think of it, I'm not sure the solution I implemented quite meets that goal: the function fails with an error in the edge case. I wonder if falling back on P_tmpdir instead of failing would be more robust. We should check to see what other implementations (e.g., tmpnam()) do. Let me know if you're interested in working on it. Martin -------- Original Message -------- Subject: svn commit: r709784 - /stdcxx/branches/4.2.x/src/file.cpp Date: Sat, 01 Nov 2008 21:49:58 -0000 From: sebor@apache.org Reply-To: dev@stdcxx.apache.org To: commits@stdcxx.apache.org Author: sebor Date: Sat Nov 1 14:49:58 2008 New Revision: 709784 URL: http://svn.apache.org/viewvc?rev=709784&view=rev Log: 2008-11-01 Scott Zhong Martin Sebor STDCXX-1019 * src/file.cpp (ENAMETOOLONG, PATH_MAX): Defined macro to a known value when not #defined by system headers. (__rw_mkstemp): Used the value of TMPDIR when set and not empty. Replaced calls to the POSIX unlink() function with the standard C function remove(). Modified: stdcxx/branches/4.2.x/src/file.cpp Modified: stdcxx/branches/4.2.x/src/file.cpp URL: http://svn.apache.org/viewvc/stdcxx/branches/4.2.x/src/file.cpp?rev=709784&r1=709783&r2=709784&view=diff ============================================================================== --- stdcxx/branches/4.2.x/src/file.cpp (original) +++ stdcxx/branches/4.2.x/src/file.cpp Sat Nov 1 14:49:58 2008 @@ -37,11 +37,12 @@ # define _RWSTD_NO_DEPRECATED_C_HEADERS #endif // _RWSTD_NO_DEPRECATED_C_HEADERS -#include // for ERANGE, errno +#include // for ENAMETOOLONG, ERANGE, errno #include // for ptrdiff_t -#include // for P_tmpdir, std{err,in,out}, tmpnam() +#include // for P_tmpdir, std{err,in,out}, remove(), tmpnam() #include // for mkstemp(), strtoul(), size_t #include // for isalpha(), isspace(), toupper() +#include // for memcpy() #if defined (_WIN32) && !defined (__CYGWIN__) @@ -58,6 +59,24 @@ # define _BINARY 0 #endif +#ifndef ENAMETOOLONG + // hardcode based on the known value on each platform +# ifdef _RWSTD_OS_AIX +# define ENAMETOOLONG 86 +# elif defined _RWSTD_OS_FREEBSD +# define ENAMETOOLONG 63 +# elif defined _RWSTD_OS_HP_UX +# define ENAMETOOLONG 248 +# elif defined _RWSTD_OS_LINUX +# define ENAMETOOLONG 36 +# elif defined _RWSTD_OS_SUN_OS +# define ENAMETOOLONG 78 +# endif +#endif // ENAMETOOLONG + +#ifndef PATH_MAX +# define PATH_MAX 1024 +#endif #include #include @@ -257,18 +276,48 @@ # define P_tmpdir "/tmp" # endif // P_tmpdir - char fnamebuf[] = P_tmpdir "/.rwtmpXXXXXX"; + // use TMPDIR and fall back on P_tmpdir as per POSIX + const char *tmpdir = getenv ("TMPDIR"); + if (0 == tmpdir || '\0' == *tmpdir) + tmpdir = P_tmpdir; + + // template for temporary file name + static const char rwtmpXXXXXX[] = "/.rwtmpXXXXXX"; + + // buffer for temporary pathname + char pathbuf [PATH_MAX]; + + // check to see if the buffer is large enough + const size_t len = strlen (tmpdir) - 1; + if (sizeof pathbuf < len + sizeof rwtmpXXXXXX) { + +# ifdef ENAMETOOLONG + // fail according to POSIX rules + errno = ENAMETOOLONG; +# endif // ENAMETOOLONG - fd = mkstemp (fnamebuf); + return -1; + } + // construct a template for temporary pathname + memcpy (pathbuf, tmpdir, len); + memcpy (pathbuf + len, rwtmpXXXXXX, sizeof rwtmpXXXXXX); + + // call mkstemp() to create a temporary file and fill + // pathbuf with its pathname + fd = mkstemp (pathbuf); + + // immediately delete the temporary file on success + // the open descriptor will refer to the file until + // it's explicitly closed or until the process exits if (fd >= 0) - unlink (fnamebuf); + remove (pathbuf); #else // if defined (_RWSTD_NO_MKSTEMP) modebits |= _RWSTD_O_EXCL | _RWSTD_O_CREAT; -#ifdef _WIN32 +# ifdef _WIN32 // tempnam(const char *dir, const char *prefix) will generate // a unique file name for a directory chosen by the following rules: @@ -286,7 +335,7 @@ // exist, tempnam will use the current working directory to // generate unique names. Currently, if both TMP and dir specify // names of directories that do not exist, the tempnam function - // call will fail. + // call will fail. // // The name returned by tempnam will be a concatenation of prefix // and a sequential number, which will combine to create a unique @@ -294,7 +343,7 @@ // names that have no extension. tempnam uses malloc to allocate // space for the filename; the program is responsible for freeing // this space when it is no longer needed. - char* const fname = tempnam (P_tmpdir, ".rwtmp"); + char* const fname = tempnam (tmpdir, ".rwtmp"); if (!fname) return -1; @@ -317,10 +366,10 @@ fd = open (fname, modebits, prot); - // unlink the file, forcing the OS to delete it when + // remove the file, forcing the OS to delete it when // the last file descriptor that refers to it is closed if (fd >= 0) - unlink (fname); + remove (fname); # endif // _WIN32 #endif // _RWSTD_NO_MKSTEMP