2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
5 * This file is part of the device-mapper userspace tools.
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
9 * of the GNU Lesser General Public License v.2.1.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 static int _create_dir_recursive(const char *dir)
27 log_verbose("Creating directory \"%s\"", dir);
28 /* Create parent directories */
29 orig = s = dm_strdup(dir);
30 while ((s = strchr(s, '/')) != NULL) {
33 rc = mkdir(orig, 0777);
34 if (rc < 0 && errno != EEXIST) {
36 log_sys_error("mkdir", orig);
43 /* Create final directory */
44 rc = mkdir(dir, 0777);
45 if (rc < 0 && errno != EEXIST) {
47 log_sys_error("mkdir", orig);
57 int dm_create_dir(const char *dir)
64 if (stat(dir, &info) < 0)
65 return _create_dir_recursive(dir);
67 if (S_ISDIR(info.st_mode))
70 log_error("Directory \"%s\" not found", dir);
74 int dm_fclose(FILE *stream)
76 int prev_fail = ferror(stream);
77 int fclose_fail = fclose(stream);
79 /* If there was a previous failure, but fclose succeeded,
80 clear errno, since ferror does not set it, and its value
81 may be unrelated to the ferror-reported failure. */
82 if (prev_fail && !fclose_fail)
85 return prev_fail || fclose_fail ? EOF : 0;
88 int dm_create_lockfile(const char *lockfile)
97 if((fd = open(lockfile, O_CREAT | O_WRONLY,
98 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
99 log_error("Cannot open lockfile [%s], error was [%s]",
100 lockfile, strerror(errno));
104 lock.l_type = F_WRLCK;
106 lock.l_whence = SEEK_SET;
109 if (fcntl(fd, F_SETLK, &lock) < 0) {
117 log_error("Cannot lock lockfile [%s], error was [%s]",
118 lockfile, strerror(errno));
126 log_error("process is already running");
132 if (ftruncate(fd, 0) < 0) {
133 log_error("Cannot truncate pidfile [%s], error was [%s]",
134 lockfile, strerror(errno));
136 goto fail_close_unlink;
139 memset(buffer, 0, sizeof(buffer));
140 snprintf(buffer, sizeof(buffer)-1, "%u\n", getpid());
142 bufferlen = strlen(buffer);
143 write_out = write(fd, buffer, bufferlen);
145 if ((write_out < 0) || (write_out == 0 && errno)) {
146 log_error("Cannot write pid to pidfile [%s], error was [%s]",
147 lockfile, strerror(errno));
149 goto fail_close_unlink;
152 if ((write_out == 0) || (write_out < bufferlen)) {
153 log_error("Cannot write pid to pidfile [%s], shortwrite of"
154 "[%" PRIsize_t "] bytes, expected [%" PRIsize_t "]\n",
155 lockfile, write_out, bufferlen);
157 goto fail_close_unlink;
160 if ((value = fcntl(fd, F_GETFD, 0)) < 0) {
161 log_error("Cannot get close-on-exec flag from pidfile [%s], "
162 "error was [%s]", lockfile, strerror(errno));
164 goto fail_close_unlink;
167 if (fcntl(fd, F_SETFD, value) < 0) {
168 log_error("Cannot set close-on-exec flag from pidfile [%s], "
169 "error was [%s]", lockfile, strerror(errno));
171 goto fail_close_unlink;
177 if (unlink(lockfile))
186 int dm_daemon_is_running(const char* lockfile)
191 if((fd = open(lockfile, O_RDONLY)) < 0)
194 lock.l_type = F_WRLCK;
196 lock.l_whence = SEEK_SET;
198 if (fcntl(fd, F_GETLK, &lock) < 0) {
199 log_error("Cannot check lock status of lockfile [%s], error was [%s]",
200 lockfile, strerror(errno));
209 return (lock.l_type == F_UNLCK) ? 0 : 1;