16 /* Internal interface */
18 #define RPMLOCK_FILE "/var/lib/rpm/transaction.lock"
21 RPMLOCK_READ = 1 << 0,
22 RPMLOCK_WRITE = 1 << 1,
23 RPMLOCK_WAIT = 1 << 2,
31 static rpmlock *rpmlock_new(const char *rootdir)
33 rpmlock *lock = (rpmlock *)malloc(sizeof(rpmlock));
35 mode_t oldmask = umask(022);
36 char *path = (char *)malloc(strlen(rootdir)+
37 strlen(RPMLOCK_FILE));
42 sprintf(path, "%s/%s", rootdir, RPMLOCK_FILE);
43 lock->fd = open(RPMLOCK_FILE, O_RDWR|O_CREAT, 0644);
46 lock->fd = open(RPMLOCK_FILE, O_RDONLY);
51 lock->openmode = RPMLOCK_READ;
54 lock->openmode = RPMLOCK_WRITE | RPMLOCK_READ;
60 static void rpmlock_free(rpmlock *lock)
68 static int rpmlock_acquire(rpmlock *lock, int mode)
71 if (lock && (mode & lock->openmode)) {
74 if (mode & RPMLOCK_WAIT)
78 if (mode & RPMLOCK_READ)
79 info.l_type = F_RDLCK;
81 info.l_type = F_WRLCK;
82 info.l_whence = SEEK_SET;
85 if (fcntl(lock->fd, cmd, &info) != -1)
91 static void rpmlock_release(rpmlock *lock)
95 info.l_type = F_UNLCK;
96 info.l_whence = SEEK_SET;
99 fcntl(lock->fd, F_SETLK, &info);
104 /* External interface */
106 void *rpmtsAcquireLock(rpmts ts)
108 const char *rootDir = rpmtsRootDir(ts);
112 lock = rpmlock_new(rootDir);
114 rpmMessage(RPMMESS_ERROR, _("can't create transaction lock\n"));
115 } else if (!rpmlock_acquire(lock, RPMLOCK_WRITE)) {
116 if (lock->openmode & RPMLOCK_WRITE)
117 rpmMessage(RPMMESS_WARNING,
118 _("waiting for transaction lock\n"));
119 if (!rpmlock_acquire(lock, RPMLOCK_WRITE|RPMLOCK_WAIT)) {
120 rpmMessage(RPMMESS_ERROR,
121 _("can't create transaction lock\n"));
129 void rpmtsFreeLock(void *lock)
131 rpmlock_release((rpmlock *)lock); /* Not really needed here. */
132 rpmlock_free((rpmlock *)lock);