annotate src/lib/file-create-locked.c @ 23007:36e01285b5b8

lib: buffer - Improve header comment for buffer_insert() and buffer_delete().
author Stephan Bosch <stephan.bosch@dovecot.fi>
date Mon, 18 Mar 2019 00:52:37 +0100
parents cb108f786fb4
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
22713
cb108f786fb4 Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22434
diff changeset
1 /* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "str.h"
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "safe-mkstemp.h"
22272
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
6 #include "mkdir-parents.h"
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "file-lock.h"
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include "file-create-locked.h"
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include <unistd.h>
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include <fcntl.h>
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 #include <sys/stat.h>
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13
22272
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
14 /* Try mkdir() + lock creation multiple times. This allows the lock file
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
15 creation to work even while the directory is simultaneously being
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
16 rmdir()ed. */
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
17 #define MAX_MKDIR_COUNT 10
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 #define MAX_RETRY_COUNT 1000
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 static int
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 try_lock_existing(int fd, const char *path,
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 const struct file_create_settings *set,
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 struct file_lock **lock_r, const char **error_r)
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 struct stat st1, st2;
18743
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
26 int ret;
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 if (fstat(fd, &st1) < 0) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 *error_r = t_strdup_printf("fstat(%s) failed: %m", path);
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 return -1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 }
18744
57f8c2a6209b lib: file_create_locked() lock method is now configurable
Timo Sirainen <tss@iki.fi>
parents: 18743
diff changeset
32 if (file_wait_lock_error(fd, path, F_WRLCK, set->lock_method,
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 set->lock_timeout_secs, lock_r, error_r) <= 0)
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 return -1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 if (stat(path, &st2) == 0) {
18743
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
36 ret = st1.st_ino == st2.st_ino &&
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 CMP_DEV_T(st1.st_dev, st2.st_dev) ? 1 : 0;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 } else if (errno == ENOENT) {
18743
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
39 ret = 0;
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 } else {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 *error_r = t_strdup_printf("stat(%s) failed: %m", path);
18743
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
42 ret = -1;
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 }
18743
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
44 if (ret <= 0) {
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
45 /* the fd is closed next - no need to unlock */
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
46 file_lock_free(lock_r);
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
47 }
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
48 return ret;
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 }
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 static int
22272
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
52 try_mkdir(const char *path, const struct file_create_settings *set,
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
53 const char **error_r)
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
54 {
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
55 uid_t uid = set->mkdir_uid != 0 ? set->mkdir_uid : (uid_t)-1;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
56 gid_t gid = set->mkdir_gid != 0 ? set->mkdir_gid : (gid_t)-1;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
57 const char *p = strrchr(path, '/');
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
58 if (p == NULL)
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
59 return 0;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
60
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
61 const char *dir = t_strdup_until(path, p);
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
62 int ret;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
63 if (uid != (uid_t)-1)
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
64 ret = mkdir_parents_chown(dir, set->mkdir_mode, uid, gid);
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
65 else {
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
66 ret = mkdir_parents_chgrp(dir, set->mkdir_mode,
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
67 gid, set->gid_origin);
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
68 }
22434
339d2a356620 lib: file_create_locked() - Treat mkdir() EEXIST error as success
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22272
diff changeset
69 if (ret < 0 && errno != EEXIST) {
22272
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
70 *error_r = t_strdup_printf("mkdir_parents(%s) failed: %m", dir);
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
71 return -1;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
72 }
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
73 return 1;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
74 }
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
75
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
76 static int
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77 try_create_new(const char *path, const struct file_create_settings *set,
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 int *fd_r, struct file_lock **lock_r, const char **error_r)
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79 {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 string_t *temp_path = t_str_new(128);
22272
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
81 int fd, orig_errno, ret = 1;
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82 int mode = set->mode != 0 ? set->mode : 0600;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 uid_t uid = set->uid != 0 ? set->uid : (uid_t)-1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84 uid_t gid = set->gid != 0 ? set->gid : (gid_t)-1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86 str_append(temp_path, path);
22272
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
87 for (unsigned int i = 0; ret > 0; i++) {
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
88 if (uid != (uid_t)-1)
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
89 fd = safe_mkstemp(temp_path, mode, uid, gid);
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
90 else
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
91 fd = safe_mkstemp_group(temp_path, mode, gid, set->gid_origin);
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
92 if (fd != -1 || errno != ENOENT || set->mkdir_mode == 0 ||
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
93 i >= MAX_MKDIR_COUNT)
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
94 break;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
95
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
96 int orig_errno = errno;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
97 if ((ret = try_mkdir(path, set, error_r)) < 0)
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
98 return -1;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
99 errno = orig_errno;
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
100 }
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101 if (fd == -1) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102 *error_r = t_strdup_printf("safe_mkstemp(%s) failed: %m", path);
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103 return -1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 }
22272
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
105
651fa80715a3 lib: file_create_locked() - Add settings to mkdir() missing parent directories
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22268
diff changeset
106 ret = -1;
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107 if (file_try_lock_error(fd, str_c(temp_path), F_WRLCK,
18744
57f8c2a6209b lib: file_create_locked() lock method is now configurable
Timo Sirainen <tss@iki.fi>
parents: 18743
diff changeset
108 set->lock_method, lock_r, error_r) <= 0) {
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 } else if (link(str_c(temp_path), path) < 0) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110 if (errno == EEXIST) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111 /* just created by somebody else */
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 ret = 0;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 } else if (errno == ENOENT) {
20379
53ae51fb323e lib: file_create_locked() - Unexpectedly deleted temp file is error.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
114 /* nobody should be deleting the temp file unless the
53ae51fb323e lib: file_create_locked() - Unexpectedly deleted temp file is error.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
115 entire directory is deleted. */
53ae51fb323e lib: file_create_locked() - Unexpectedly deleted temp file is error.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
116 *error_r = t_strdup_printf(
53ae51fb323e lib: file_create_locked() - Unexpectedly deleted temp file is error.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
117 "Temporary file %s was unexpectedly deleted",
53ae51fb323e lib: file_create_locked() - Unexpectedly deleted temp file is error.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
118 str_c(temp_path));
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 } else {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 *error_r = t_strdup_printf("link(%s, %s) failed: %m",
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 str_c(temp_path), path);
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122 }
19145
9ce9bd7fba83 lib: file_create_locked() may have leaked memory on some race conditions.
Timo Sirainen <tss@iki.fi>
parents: 19136
diff changeset
123 file_lock_free(lock_r);
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124 } else {
22268
382ee00c9669 lib: file_create_locked() - update lock path after link()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
125 file_lock_set_path(*lock_r, path);
19136
fefaa6d09a81 Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents: 18744
diff changeset
126 i_unlink_if_exists(str_c(temp_path));
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 *fd_r = fd;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 return 1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 }
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 orig_errno = errno;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 i_close_fd(&fd);
19136
fefaa6d09a81 Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents: 18744
diff changeset
132 i_unlink_if_exists(str_c(temp_path));
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133 errno = orig_errno;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134 return ret;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135 }
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 int file_create_locked(const char *path, const struct file_create_settings *set,
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 struct file_lock **lock_r, bool *created_r,
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139 const char **error_r)
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141 unsigned int i;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 int fd, ret;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 for (i = 0; i < MAX_RETRY_COUNT; i++) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145 fd = open(path, O_RDWR);
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 if (fd != -1) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 ret = try_lock_existing(fd, path, set, lock_r, error_r);
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 if (ret > 0) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149 /* successfully locked an existing file */
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 *created_r = FALSE;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 return fd;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 }
18743
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
153 i_close_fd(&fd);
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
154 if (ret < 0)
1d088dc567bd lib: file_create_locked() was leaking fds and locks.
Timo Sirainen <tss@iki.fi>
parents: 18742
diff changeset
155 return -1;
18740
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156 } else if (errno != ENOENT) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 *error_r = t_strdup_printf("open(%s) failed: %m", path);
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 return -1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 } else {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
160 /* try to create the file */
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
161 ret = try_create_new(path, set, &fd, lock_r, error_r);
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 if (ret < 0)
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163 return -1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
164 if (ret > 0) {
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165 /* successfully created a new locked file */
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 *created_r = TRUE;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
167 return fd;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
168 }
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169 /* the file was just created - try again opening and
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 locking it */
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 }
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172 }
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173 *error_r = t_strdup_printf("Creating a locked file %s keeps failing", path);
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174 errno = EINVAL;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175 return -1;
78bbfe4e4e8e lib: Added file_create_locked()
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
176 }