[pacman-dev] [PATCH 2/4] Add very basic transaction hooks to alpm.

Victor Lowther victor.lowther at gmail.com
Tue Jul 27 04:43:22 EDT 2010


libalpm compliant programs now support running pre-commit and post-commit
hooks.  Currently, the implementation is as simple as I can make it --
if /etc/pacman.d/hooks.d/transact.sh exists, it will be run with the
'pre-commit' parameter just before a transaction is committed, and it will
be run with 'post-commit' after the transaction has been completed.

The intent is for transact.sh to be a wrapper that calls scripts in
/etc/pacman.d/hooks.d/transact.d with the arg it is passed, but since this
is just for a demo I did not actually include any of that.

I also didn't bother adhering to any of the coding standards, as that will
be easy enough to fix up once we have something a bit more fleshed out.
---
 lib/libalpm/hooks.c |   28 ++++++++++++++++++++++++++++
 lib/libalpm/hooks.h |    4 ++++
 lib/libalpm/trans.c |    4 +++-
 3 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/lib/libalpm/hooks.c b/lib/libalpm/hooks.c
index 9630c70..5982ea5 100644
--- a/lib/libalpm/hooks.c
+++ b/lib/libalpm/hooks.c
@@ -30,6 +30,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/statvfs.h>
+#include <sys/wait.h>
 #include <errno.h>
 
 /* libalpm */
@@ -46,3 +47,30 @@
 #include "alpm.h"
 #include "deps.h"
 #include "cache.h"
+
+int alpm_hook_transact(char* phase) {
+  char filename[PATH_MAX];
+  struct stat sbuf;
+  pid_t childpid, retpid;
+  int status;
+  /* ignore transaction hooks when targeting another root filesystem
+  if (!strcmp(handle->root,"/"))
+  return 1;*/
+  snprintf(filename,PATH_MAX,"%s/transact.sh",ALPM_HOOKS_DIR);
+  /* if we cannot stat transact.sh, just return */
+  if (stat(filename,&sbuf) != 0)
+    return 1;
+  fflush(NULL);
+  childpid=fork();
+  if (childpid == -1) {
+    return 1;
+  } else if (childpid == 0) {
+    execl(filename,"transact.sh",phase,(char *)0);
+  } else {
+    /* return the exit status of the transact.sh program. */
+    do {
+      retpid = waitpid(childpid,&status,0);
+    } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+  }
+  return !WEXITSTATUS(status);
+}
diff --git a/lib/libalpm/hooks.h b/lib/libalpm/hooks.h
index d60b1f4..f79d2c4 100644
--- a/lib/libalpm/hooks.h
+++ b/lib/libalpm/hooks.h
@@ -25,4 +25,8 @@
 
 #include "alpm.h"
 
+#define ALPM_HOOKS_DIR "/etc/pacman.d/hooks.d"
+
+int alpm_hook_transact(char*);
+
 #endif /*ALPM_HOOKS_H */
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index 523f33b..ed26aa6 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -195,7 +195,8 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data)
 	if(trans->add == NULL && trans->remove == NULL) {
 		return(0);
 	}
-
+        if (! alpm_hook_transact("pre-commit"))
+          return (-1);
 	trans->state = STATE_COMMITING;
 
 	if(trans->add == NULL) {
@@ -211,6 +212,7 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data)
 	}
 
 	trans->state = STATE_COMMITED;
+        alpm_hook_transact("post-commit");
 
 	return(0);
 }
-- 
1.7.1.1




More information about the pacman-dev mailing list