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)