commit ce2b872a0f5883a7635d02ec07ddbb35da346d36
parent 03db2dc85f52de0ed7cb46aed0a6ce7ceea33305
Author: sin <sin@2f30.org>
Date: Thu, 12 Jun 2014 00:25:50 +0100
Lock the package database before using it
Diffstat:
6 files changed, 110 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -4,6 +4,7 @@ include config.mk
.SUFFIXES: .c .o
LIB = \
+ lock.o \
strlcat.o \
strlcpy.o
diff --git a/infopkg.c b/infopkg.c
@@ -32,6 +32,7 @@ main(int argc, char *argv[])
char *prefix = "/";
char path[PATH_MAX];
int Oflag = 0;
+ int lockfd;
int i;
int r;
@@ -56,6 +57,8 @@ main(int argc, char *argv[])
return EXIT_FAILURE;
}
+ lockfd = lockdb();
+
dir = opendir("var/pkg");
if (!dir) {
fprintf(stderr, "opendir %s: %s\n", "var/pkg",
@@ -79,6 +82,8 @@ main(int argc, char *argv[])
closedir(dir);
+ unlockdb(lockfd);
+
return EXIT_SUCCESS;
}
diff --git a/installpkg.c b/installpkg.c
@@ -34,9 +34,12 @@ usage(void)
int
main(int argc, char *argv[])
{
+ int r;
int i;
+ char cwd[PATH_MAX];
char *prefix = "/";
int fflag = 0;
+ int lockfd;
ARGBEGIN {
case 'v':
@@ -55,6 +58,24 @@ main(int argc, char *argv[])
if (argc < 1)
usage();
+ getcwd(cwd, sizeof(cwd));
+
+ r = chdir(prefix);
+ if (r < 0) {
+ fprintf(stderr, "chdir %s: %s\n", prefix,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ lockfd = lockdb();
+
+ r = chdir(cwd);
+ if (r < 0) {
+ fprintf(stderr, "chdir %s: %s\n", prefix,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
checkdb(prefix);
for (i = 0; i < argc; i++) {
if (vflag == 1)
@@ -71,6 +92,16 @@ main(int argc, char *argv[])
extract(prefix, argv[i]);
printf("installed %s\n", argv[i]);
}
+
+ r = chdir(prefix);
+ if (r < 0) {
+ fprintf(stderr, "chdir %s: %s\n", prefix,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ unlockdb(lockfd);
+
return EXIT_SUCCESS;
}
diff --git a/lock.c b/lock.c
@@ -0,0 +1,65 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define LOCKPATH "var/pkg/.lock"
+
+/* lock the package dabatase - assumes cwd is the root prefix */
+int
+lockdb(void)
+{
+ struct flock fl;
+ int r;
+ int fd;
+
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_pid = getpid();
+
+ fd = open(LOCKPATH, O_WRONLY | O_CREAT, 0600);
+ if (fd < 0) {
+ fprintf(stderr, "failed to create lockfile: %s\n",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ r = fcntl(fd, F_SETLKW, &fl);
+ if (r < 0) {
+ fprintf(stderr, "failed to obtain lock: %s\n",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ return fd;
+}
+
+/* unlock the package dabatase - assumes cwd is the root prefix */
+void
+unlockdb(int fd)
+{
+ struct flock fl;
+ int r;
+
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_pid = getpid();
+
+ r = fcntl(fd, F_SETLKW, &fl);
+ if (r < 0) {
+ fprintf(stderr, "failed to clear lock: %s\n",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ close(fd);
+
+ unlink(LOCKPATH);
+}
diff --git a/removepkg.c b/removepkg.c
@@ -38,6 +38,7 @@ main(int argc, char *argv[])
struct dirent *dp;
char filename[PATH_MAX];
char *prefix = "/";
+ int lockfd;
int found = 0;
int r;
int i;
@@ -66,6 +67,8 @@ main(int argc, char *argv[])
return EXIT_FAILURE;
}
+ lockfd = lockdb();
+
dir = opendir("var/pkg");
if (!dir) {
fprintf(stderr, "opendir %s: %s\n", "var/pkg",
@@ -104,6 +107,8 @@ main(int argc, char *argv[])
closedir(dir);
+ unlockdb(lockfd);
+
return EXIT_SUCCESS;
}
diff --git a/util.h b/util.h
@@ -6,6 +6,9 @@
extern char *argv0;
+int lockdb(void);
+void unlockdb(int);
+
#undef strlcat
size_t strlcat(char *, const char *, size_t);
#undef strlcpy