6 #include <rpm/rpmlog.h>
7 #include <rpm/rpmfileutil.h>
9 #include "lib/rpmlock.h"
13 /* Internal interface */
23 static rpmlock rpmlock_new(const char *lock_path, const char *descr)
25 rpmlock lock = (rpmlock) malloc(sizeof(*lock));
28 mode_t oldmask = umask(022);
29 lock->fd = open(lock_path, O_RDWR|O_CREAT, 0644);
30 (void) umask(oldmask);
34 lock->fd = open(lock_path, O_RDONLY);
39 lock->openmode = RPMLOCK_READ;
42 lock->openmode = RPMLOCK_WRITE | RPMLOCK_READ;
45 lock->path = xstrdup(lock_path);
46 lock->descr = xstrdup(descr);
53 static void rpmlock_free(rpmlock lock)
55 if (--lock->fdrefs == 0) {
58 (void) close(lock->fd);
63 static int rpmlock_acquire(rpmlock lock, int mode)
67 if (!(mode & lock->openmode))
70 if (lock->fdrefs > 1) {
75 if (mode & RPMLOCK_WAIT)
79 if (mode & RPMLOCK_READ)
80 info.l_type = F_RDLCK;
82 info.l_type = F_WRLCK;
83 info.l_whence = SEEK_SET;
87 if (fcntl(lock->fd, cmd, &info) != -1)
96 static void rpmlock_release(rpmlock lock)
98 /* if not locked then we must not release */
99 if (lock->fdrefs <= 1)
102 if (--lock->fdrefs == 1) {
104 info.l_type = F_UNLCK;
105 info.l_whence = SEEK_SET;
109 (void) fcntl(lock->fd, F_SETLK, &info);
114 /* External interface */
115 rpmlock rpmlockNew(const char *lock_path, const char *descr)
117 rpmlock lock = rpmlock_new(lock_path, descr);
119 rpmlog(RPMLOG_ERR, _("can't create %s lock on %s (%s)\n"),
120 descr, lock_path, strerror(errno));
125 int rpmlockAcquire(rpmlock lock)
127 int locked = 0; /* assume failure */
128 int maywait = isatty(STDIN_FILENO); /* dont wait within scriptlets */
131 locked = rpmlock_acquire(lock, RPMLOCK_WRITE);
132 if (!locked && (lock->openmode & RPMLOCK_WRITE) && maywait) {
133 rpmlog(RPMLOG_WARNING, _("waiting for %s lock on %s\n"),
134 lock->descr, lock->path);
135 locked = rpmlock_acquire(lock, (RPMLOCK_WRITE|RPMLOCK_WAIT));
138 rpmlog(RPMLOG_ERR, _("can't create %s lock on %s (%s)\n"),
139 lock->descr, lock->path, strerror(errno));
145 void rpmlockRelease(rpmlock lock)
148 rpmlock_release(lock);
151 rpmlock rpmlockNewAcquire(const char *lock_path, const char *descr)
153 rpmlock lock = rpmlockNew(lock_path, descr);
154 if (!rpmlockAcquire(lock))
155 lock = rpmlockFree(lock);
159 rpmlock rpmlockFree(rpmlock lock)
162 rpmlock_release(lock);