:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / crtdll / stdio / tmpfile.c
1 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
2 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
3 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
4 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
5 //#include <crtdll/stubs.h>
6 #include <crtdll/stdio.h>
7 #include <crtdll/string.h>
8 #include <crtdll/stdlib.h>
9 #include <crtdll/errno.h>
10 #include <crtdll/fcntl.h>
11 //#include <crtdll/unistd.h>
12 #include <crtdll/io.h>
13 #include <crtdll/internal/file.h>
14 #include <crtdll/share.h>
15
16 #if 0
17 #ifndef __dj_include_stdio_h_
18 #define _name_to_remove _tmpfname
19 #endif
20 #endif
21
22 FILE *  __alloc_file(void);
23
24 FILE *
25 tmpfile(void)
26 {
27   int  temp_fd;
28   FILE *f;
29   char *temp_name = tmpnam(0);
30   char *n_t_r = (char *)malloc(L_tmpnam);
31
32   if (!n_t_r)
33     return 0;
34
35   /* We could have a race condition, whereby another program
36      (in another virtual machine, or if the temporary file is
37      in a directory which is shared via a network) opens the
38      file returned by `tmpnam' between the call above and the
39      moment when we actually open the file below.  This loop
40      retries the call to `tmpnam' until we actually succeed
41      to create the file which didn't exist before.  */
42   do {
43    // errno = 0;
44     temp_fd = _open(temp_name, 0, SH_DENYRW);
45   //  if (  errno == ENOENT )
46 //      break;
47   } while (temp_fd == -1 && (temp_name = tmpnam(0)) != 0);
48
49   if (temp_name == 0)
50     return 0;
51
52   /* This should have been fdopen(temp_fd, "wb+"), but `fdopen'
53      is non-ANSI.  So we need to dump some of its guts here.  Sigh...  */
54   f = __alloc_file();
55   if (f)
56   {
57     f->_file   = temp_fd;
58     f->_cnt    = 0;
59     f->_bufsiz = 0;
60     f->_flag   = _IORMONCL | _IOREAD | _IOWRT;
61     f->_name_to_remove = n_t_r;
62     strcpy(f->_name_to_remove, temp_name);
63     f->_base = f->_ptr = NULL;
64   }
65   else
66   {
67     close(temp_fd);
68     remove(temp_name);
69     free(n_t_r);
70   }
71   return f;
72 }