blob: ebfb12857332527af8df8dd3a447d8678165176f [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
2 * Copyright (C) 2012 Sami Kerola <kerolasa@iki.fi>
3 */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <sys/stat.h>
8#include <unistd.h>
9#include <sys/time.h>
10#include <sys/resource.h>
11
12#include "c.h"
13#include "fileutils.h"
14#include "pathnames.h"
15#include "xalloc.h"
16
17#define _PATH_TMP "/tmp"
18/* Create open temporary file in safe way. Please notice that the
19 * file permissions are -rw------- by default. */
20int xmkstemp(char **tmpname, char *dir)
21{
22 char *localtmp;
23 char *tmpenv;
24 mode_t old_mode;
25 int fd;
26
27 /* Some use cases must be capable of being moved atomically
28 * with rename(2), which is the reason why dir is here. */
29 if (dir != NULL)
30 tmpenv = dir;
31 else
32 tmpenv = getenv("TMPDIR");
33
34 if (tmpenv)
35 xasprintf(&localtmp, "%s/%s.XXXXXX", tmpenv,
36 program_invocation_short_name);
37 else
38 xasprintf(&localtmp, "%s/%s.XXXXXX", _PATH_TMP,
39 program_invocation_short_name);
40 old_mode = umask(077);
41 fd = mkstemp(localtmp);
42 umask(old_mode);
43 if (fd == -1) {
44 free(localtmp);
45 localtmp = NULL;
46 }
47 *tmpname = localtmp;
48 return fd;
49}
50
51/*
52 * portable getdtablesize()
53 */
54int get_fd_tabsize(void)
55{
56 int m;
57
58#if defined(HAVE_GETDTABLESIZE)
59 m = getdtablesize();
60#elif defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
61 struct rlimit rl;
62
63 getrlimit(RLIMIT_NOFILE, &rl);
64 m = rl.rlim_cur;
65#elif defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
66 m = sysconf(_SC_OPEN_MAX);
67#else
68 m = OPEN_MAX;
69#endif
70 return m;
71}
72
73#ifdef TEST_PROGRAM
74int main(void)
75{
76 FILE *f;
77 char *tmpname;
78 f = xfmkstemp(&tmpname, NULL);
79 unlink(tmpname);
80 free(tmpname);
81 fclose(f);
82 return EXIT_FAILURE;
83}
84#endif