16 /* Internal interface */
18 #define RPMLOCK_FILE "/var/lib/rpm/transaction.lock"
20 /*@observer@*/ /*@unchecked@*/
21 static const char * _rpmlock_file = RPMLOCK_FILE;
24 RPMLOCK_READ = 1 << 0,
25 RPMLOCK_WRITE = 1 << 1,
26 RPMLOCK_WAIT = 1 << 2,
35 static rpmlock rpmlock_new(const char *rootdir)
36 /*@globals fileSystem @*/
37 /*@modifies fileSystem @*/
39 rpmlock lock = (rpmlock) malloc(sizeof(*lock));
41 mode_t oldmask = umask(022);
42 char *path = (char *)malloc(strlen(rootdir)+
43 strlen(RPMLOCK_FILE)+2);
48 sprintf(path, "%s/%s", rootdir, RPMLOCK_FILE);
49 lock->fd = open(RPMLOCK_FILE, O_RDWR|O_CREAT, 0644);
50 (void) umask(oldmask);
54 lock->fd = open(RPMLOCK_FILE, O_RDONLY);
59 lock->openmode = RPMLOCK_READ;
62 lock->openmode = RPMLOCK_WRITE | RPMLOCK_READ;
71 static void rpmlock_free(/*@only@*/ /*@null@*/ rpmlock lock)
72 /*@globals fileSystem, internalState @*/
73 /*@modifies lock, fileSystem, internalState @*/
76 (void) close(lock->fd);
81 static int rpmlock_acquire(/*@null@*/ rpmlock lock, int mode)
85 if (lock && (mode & lock->openmode)) {
88 if (mode & RPMLOCK_WAIT)
92 if (mode & RPMLOCK_READ)
93 info.l_type = F_RDLCK;
95 info.l_type = F_WRLCK;
96 info.l_whence = SEEK_SET;
100 if (fcntl(lock->fd, cmd, &info) != -1)
106 static void rpmlock_release(/*@null@*/ rpmlock lock)
107 /*@globals internalState @*/
108 /*@modifies internalState @*/
112 info.l_type = F_UNLCK;
113 info.l_whence = SEEK_SET;
117 (void) fcntl(lock->fd, F_SETLK, &info);
122 /* External interface */
124 void *rpmtsAcquireLock(rpmts ts)
126 const char *rootDir = rpmtsRootDir(ts);
131 lock = rpmlock_new(rootDir);
134 rpmMessage(RPMMESS_ERROR, _("can't create transaction lock\n"));
135 } else if (!rpmlock_acquire(lock, RPMLOCK_WRITE)) {
136 if (lock->openmode & RPMLOCK_WRITE)
137 rpmMessage(RPMMESS_WARNING,
138 _("waiting for transaction lock\n"));
139 if (!rpmlock_acquire(lock, RPMLOCK_WRITE|RPMLOCK_WAIT)) {
140 rpmMessage(RPMMESS_ERROR,
141 _("can't create transaction lock\n"));
150 void rpmtsFreeLock(void *lock)
152 rpmlock_release((rpmlock)lock); /* Not really needed here. */
153 rpmlock_free((rpmlock)lock);