[pacman-dev] FS#9424 : storing pid in db.lck

Xavier shiningxc at gmail.com
Tue Feb 19 06:25:32 EST 2008


Quote from the feature request :
> Pacman would be able to handle automatically lock file removal without user
> interaction if db.lck was dead, but it would still be locked if it was
> alive.

That looks interesting, and there is also a patch attached, that I am
repasting here:


diff -Naur pacman-3.1.1/lib/libalpm/alpm.h pacman-3.1.1.bak/lib/libalpm/alpm.h
--- pacman-3.1.1/lib/libalpm/alpm.h	2008-01-20 20:14:45.000000000 +0100
+++ pacman-3.1.1.bak/lib/libalpm/alpm.h	2008-02-03 03:58:03.000000000 +0100
@@ -428,6 +428,7 @@
 	PM_ERR_HANDLE_NULL,
 	PM_ERR_HANDLE_NOT_NULL,
 	PM_ERR_HANDLE_LOCK,
+	PM_ERR_INSTANCE_RUNNING,
 	/* Databases */
 	PM_ERR_DB_OPEN,
 	PM_ERR_DB_CREATE,
diff -Naur pacman-3.1.1/lib/libalpm/error.c pacman-3.1.1.bak/lib/libalpm/error.c
--- pacman-3.1.1/lib/libalpm/error.c	2008-01-20 20:14:45.000000000 +0100
+++ pacman-3.1.1.bak/lib/libalpm/error.c	2008-02-03 03:58:03.000000000 +0100
@@ -56,6 +56,8 @@
 			return _("library already initialized");
 		case PM_ERR_HANDLE_LOCK:
 			return _("unable to lock database");
+		case PM_ERR_INSTANCE_RUNNING:
+			return _("another instance is running");
 		/* Databases */
 		case PM_ERR_DB_OPEN:
 			return _("could not open database");
diff -Naur pacman-3.1.1/lib/libalpm/trans.c pacman-3.1.1.bak/lib/libalpm/trans.c
--- pacman-3.1.1/lib/libalpm/trans.c	2008-01-20 20:17:05.000000000 +0100
+++ pacman-3.1.1.bak/lib/libalpm/trans.c	2008-02-03 03:58:03.000000000 +0100
@@ -75,6 +75,8 @@
 	handle->lckfd = _alpm_lckmk();
 	if(handle->lckfd == -1) {
 		RET_ERR(PM_ERR_HANDLE_LOCK, -1);
+	} else if(handle->lckfd == -2) {
+		RET_ERR(PM_ERR_INSTANCE_RUNNING, -1);
 	}
 
 	handle->trans = _alpm_trans_new();
diff -Naur pacman-3.1.1/lib/libalpm/util.c pacman-3.1.1.bak/lib/libalpm/util.c
--- pacman-3.1.1/lib/libalpm/util.c	2008-01-20 20:17:05.000000000 +0100
+++ pacman-3.1.1.bak/lib/libalpm/util.c	2008-02-03 17:49:53.000000000 +0100
@@ -330,30 +330,64 @@
 	return newstr;
 }
 
-
 /* Create a lock file */
 int _alpm_lckmk()
 {
-	int fd, count = 0;
+	/*
+	* pid: string representing pacman pid
+	* tmpfile: string containing the temporary file
+	* sizeofpid: integer that stores sizeof(pid)
+	*/
+	char pid[7], tmpfile[19]="/tmp/pacman-lock-", existingpid[7], runningprocess[15]="/proc/";
+	int fd, count, sizeofpid;
 	char *dir, *ptr;
-	const char *file = alpm_option_get_lockfile();
-
+	struct stat st;
+	const char *lockfile = alpm_option_get_lockfile();
+	
 	/* create the dir of the lockfile first */
-	dir = strdup(file);
+	dir = strdup(lockfile);
 	ptr = strrchr(dir, '/');
 	if(ptr) {
 		*ptr = '\0';
 	}
 	_alpm_makepath(dir);
+	
+	// fill with zeroes
+	for (count=0; count<sizeof(existingpid); count++) {
+		existingpid[count]='\0';
+	}
 
-	while((fd = open(file, O_WRONLY | O_CREAT | O_EXCL, 0000)) == -1 && errno == EACCES) {
+	/* check if there is another lock, and if so, check if its associated process is running */
+	if ((fd = open(lockfile, O_RDONLY , 0000)) != -1) {
+		read(fd, existingpid, sizeof(existingpid));
+		int n = read(fd, existingpid, sizeof(existingpid));
+		close(fd);
+		existingpid[n] = '\0';
+		strcat(runningprocess,existingpid);
+		if (stat(runningprocess, &st) != -1 && S_ISDIR(st.st_mode)) {
+			return -2;
+		}
+	}
+	if (unlink(lockfile) == -1 && errno != ENOENT) {
+		return -1;
+	}
+	
+	sizeofpid = sprintf(pid, "%d", getpid());
+	strcat(tmpfile,pid);
+
+	count=0;
+	while((fd = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0444)) == -1 && errno == EACCES) {
 		if(++count < 1) {
 			sleep(1);
-		}	else {
+		} else {
 			return(-1);
 		}
 	}
 
+	write(fd, pid, sizeofpid);
+	
+	symlink(tmpfile, lockfile);
+
 	FREE(dir);
 
 	return(fd > 0 ? fd : -1);
@@ -362,13 +396,23 @@
 /* Remove a lock file */
 int _alpm_lckrm()
 {
-	const char *file = alpm_option_get_lockfile();
-	if(unlink(file) == -1 && errno != ENOENT) {
+	char pid[7], tmpfile[19]="/tmp/pacman-lock-";
+	const char *lockfile = alpm_option_get_lockfile();
+	int unlinkstatus=0;
+	
+	sprintf(pid, "%d", getpid());
+	strcat(tmpfile,pid);
+	
+	if(unlink(tmpfile) == -1 && errno != ENOENT) {
+		unlinkstatus=-1;
+	}
+	if(unlink(lockfile) == -1 && errno != ENOENT) {
 		return(-1);
 	}
-	return(0);
+	return (unlinkstatus);
 }
 
+
 /* Compression functions */
 
 int _alpm_unpack(const char *archive, const char *prefix, const char *fn)




More information about the pacman-dev mailing list