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 03:58:03.000000000 +0100 @@ -330,30 +330,55 @@ 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 = 0, 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); - 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)); + close(fd); + strcat(runningprocess,existingpid); + if (stat(runningprocess, &st) != -1 && S_ISDIR(st.st_mode)) { + return -2; + } else { + unlink(lockfile); + } + } + + sizeofpid = sprintf(pid, "%d", getpid()); + strcat(tmpfile,pid); + + while((fd = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0000)) == -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 +387,22 @@ /* 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(); + + sprintf(pid, "%d", getpid()); + strcat(tmpfile,pid); + + if(unlink(tmpfile) == -1 && errno != ENOENT) { + return(-1); + } + if(unlink(lockfile) == -1 && errno != ENOENT) { return(-1); } return(0); } + /* Compression functions */ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)