Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com Message-ID: <003501befc8b$a18bcce0$0100000a@cstreet> From: "John Poplett" To: Subject: B20.1: bug in mkstemp Date: Sat, 11 Sep 1999 14:27:03 -0500 MIME-Version: 1.0 X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 4.72.3110.5 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0031_01BEFC61.B76A5920" X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 ------=_NextPart_000_0031_01BEFC61.B76A5920 Content-Type: multipart/alternative; boundary="----=_NextPart_001_0032_01BEFC61.B76A5920" ------=_NextPart_001_0032_01BEFC61.B76A5920 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable mkstemp fails with an access errror when an attempt is made to create = more than one file using the same mkstemp template. This problem was = reported previously by Rob Mayoff. =20 In Rob's original report, he gives the following program that = demonstrates the problem: In this program, the second call to mkstemp will fail: =20 #include #include =20 main() { char path[MAXPATHLEN]; int fd, rc; =20 sprintf(path, "/tmp/test.XXXXXX"); fd =3D mkstemp(path); if (fd < 0) { perror("mkstemp 1"); exit(1); } rc =3D unlink(path); if (rc < 0) { perror("unlink"); exit(1); } sprintf(path, "/tmp/test.XXXXXX"); fd =3D mkstemp(path); if (fd < 0) { perror("mkstemp 2"); exit(1); } rc =3D unlink(path); if (rc < 0) { perror("unlink"); exit(1); } =20 exit(0); } =20 The fix should be simply to treat EACCES just like EEXIST in mkstemp. =20 I have applied a patch to the runtime source file, mktemp.c, as Rob = suggests and=20 verified the fix. I include the patch as an attachment. =20 John =20 John Poplett jpoplett AT mindspring DOT com ------=_NextPart_001_0032_01BEFC61.B76A5920 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
mkstemp fails with an access errror when an attempt = is made to=20 create more than one file using the same mkstemp template. This problem = was=20 reported previously by Rob Mayoff.
 
In Rob's original report, he gives the following = program that=20 demonstrates the problem:
 
In this program, the second call to mkstemp will=20 fail:
 
#include <stdio.h>
#include=20 <sys/param.h>
 
main()
{
  char=20 path[MAXPATHLEN];
        int fd,=20 rc;
 
        = sprintf(path,=20 "/tmp/test.XXXXXX");
      &nb= sp; fd=20 =3D mkstemp(path);
        if (fd = < 0) {=20 perror("mkstemp 1"); exit(1);=20 }
        rc =3D=20 unlink(path);
        if (rc < = 0) {=20 perror("unlink"); exit(1);=20 }
        sprintf(path,=20 "/tmp/test.XXXXXX");
      &nb= sp; fd=20 =3D mkstemp(path);
        if (fd = < 0) {=20 perror("mkstemp 2"); exit(1);=20 }
        rc =3D=20 unlink(path);
        if (rc < = 0) {=20 perror("unlink"); exit(1); }
 
       =20 exit(0);
}
 
The fix should be simply to treat EACCES just like = EEXIST in=20 mkstemp.
 
I have applied a patch to the runtime source file, = mktemp.c,=20 as Rob suggests and
verified the fix. I include the patch as an=20 attachment.
 
John
 
John Poplett
jpoplett AT mindspring DOT com
------=_NextPart_001_0032_01BEFC61.B76A5920-- ------=_NextPart_000_0031_01BEFC61.B76A5920 Content-Type: application/octet-stream; name="mktemp.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="mktemp.c" /* This is file MKTEMP.C */ /* This file may have been modified by DJ Delorie (Jan 1991). If so, ** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave, ** Rochester NH, 03867-2954, USA. */ /* * Copyright (c) 1987 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that: (1) source distributions retain this entire copyright * notice and comment, and (2) distributions including binaries display * the following acknowledgement: ``This product includes software * developed by the University of California, Berkeley and its = contributors'' * in the documentation or other materials provided with the = distribution * and in all advertising materials mentioning features or use of this * software. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* FUNCTION <>, <>---generate unused file name INDEX mktemp INDEX mkstemp INDEX _mktemp_r INDEX _mkstemp_r ANSI_SYNOPSIS #include char *mktemp(char *<[path]>); int mkstemp(char *<[path]>); char *_mktemp_r(void *<[reent]>, char *<[path]>); int *_mkstemp_r(void *<[reent]>, char *<[path]>); TRAD_SYNOPSIS #include char *mktemp(<[path]>) char *<[path]>; int mkstemp(<[path]>) char *<[path]>; char *_mktemp_r(<[reent]>, <[path]>) char *<[reent]>; char *<[path]>; int _mkstemp_r(<[reent]>, <[path]>) char *<[reent]>; char *<[path]>; DESCRIPTION <> and <> attempt to generate a file name that is not yet in use for any existing file. <> creates the file and=20 opens it for reading and writing; <> simply generates the file = name. You supply a simple pattern for the generated file name, as the string at <[path]>. The pattern should be a valid filename (including path information if you wish) ending with some number of `<>' characters. The generated filename will match the leading part of the name you supply, with the trailing `<>' characters replaced by some combination of digits and letters. The alternate functions <<_mktemp_r>> and <<_mkstemp_r>> are reentrant versions. The extra argument <[reent]> is a pointer to a reentrancy structure. RETURNS <> returns the pointer <[path]> to the modified string representing an unused filename, unless it could not generate one, or the pattern you provided is not suitable for a filename; in that case, it returns <>. <> returns a file descriptor to the newly created file, unless it could not generate an unused filename, or the pattern you provided is not suitable for a filename; in that case, it returns <<-1>>. PORTABILITY ANSI C does not require either <> or <>; the System V Interface Definition requires <> as of Issue 2. Supporting OS subroutines required: <>, <>, <>. */ #include #include #include #include #include #include #include #undef _getpid_r #undef _open_r #undef _stat_r #define _getpid_r(a) getpid() #define _open_r(a,b,c,d) open(b,c,d) #define _stat_r(a,b,c) _stat(b,c) static _DEFUN (_gettemp, (ptr, path, doopen), struct _reent *ptr _AND char *path _AND register int *doopen) { register char *start, *trv; struct stat sbuf; unsigned int pid; pid =3D _getpid_r (ptr); for (trv =3D path; *trv; ++trv) /* extra X's get set to 0's */ continue; while (*--trv =3D=3D 'X') { *trv =3D (pid % 10) + '0'; pid /=3D 10; } /* * Check the target directory; if you have six X's and it * doesn't exist this runs for a *very* long time. */ for (start =3D trv + 1;; --trv) { if (trv <=3D path) break; if (*trv =3D=3D '/') { *trv =3D '\0'; if (_stat_r (ptr, path, &sbuf)) return (0); if (!(sbuf.st_mode & S_IFDIR)) { ptr->_errno =3D ENOTDIR; return (0); } *trv =3D '/'; break; } } for (;;) { if (doopen) { if ((*doopen =3D _open_r (ptr, path, O_CREAT | O_EXCL | O_RDWR, = 0600)) >=3D 0) return 1; #ifdef __CYGWIN32__ if (ptr->_errno !=3D EEXIST && ptr->_errno !=3D EACCES) #else if (ptr->_errno !=3D EEXIST) #endif return 0; } else if (_stat_r (ptr, path, &sbuf)) return (ptr->_errno =3D=3D ENOENT ? 1 : 0); /* tricky little algorithm for backward compatibility */ for (trv =3D start;;) { if (!*trv) return 0; if (*trv =3D=3D 'z') *trv++ =3D 'a'; else { if (isdigit (*trv)) *trv =3D 'a'; else ++ * trv; break; } } } /*NOTREACHED*/ } _DEFUN (_mkstemp_r, (ptr, path), struct _reent *ptr _AND char *path) { int fd; return (_gettemp (ptr, path, &fd) ? fd : -1); } char * _DEFUN (_mktemp_r, (ptr, path), struct _reent *ptr _AND char *path) { return (_gettemp (ptr, path, (int *) NULL) ? path : (char *) NULL); } #ifndef _REENT_ONLY _DEFUN (mkstemp, (path), char *path) { int fd; return (_gettemp (_REENT, path, &fd) ? fd : -1); } char * _DEFUN (mktemp, (path), char *path) { return (_gettemp (_REENT, path, (int *) NULL) ? path : (char *) NULL); } #endif /* ! defined (_REENT_ONLY) */ ------=_NextPart_000_0031_01BEFC61.B76A5920 Content-Type: text/plain; charset=us-ascii -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com ------=_NextPart_000_0031_01BEFC61.B76A5920--