pkgtools

morpheus pkg tools
git clone git://git.2f30.org/pkgtools
Log | Files | Refs | README | LICENSE

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:
MMakefile | 1+
Minfopkg.c | 5+++++
Minstallpkg.c | 31+++++++++++++++++++++++++++++++
Alock.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mremovepkg.c | 5+++++
Mutil.h | 3+++
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