hal/hald/linux2/addons addon-acpi.c,1.11,1.12

Ryan Lortie desrt at freedesktop.org
Tue Oct 11 19:24:35 PDT 2005


Update of /cvs/hal/hal/hald/linux2/addons
In directory gabe:/tmp/cvs-serv13730/hald/linux2/addons

Modified Files:
	addon-acpi.c 
Log Message:
2005-10-11  Ryan Lortie  <desrt at desrt.ca>

        * hald/linux2/addons/addon-acpi.c: Cleanup existing code to avoid
          reinventing the fgets() wheel.  Also deal gracefully with acpid
          restarts (we used to exit in this case).



Index: addon-acpi.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/addons/addon-acpi.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- addon-acpi.c	27 Sep 2005 09:42:13 -0000	1.11
+++ addon-acpi.c	12 Oct 2005 02:24:33 -0000	1.12
@@ -4,6 +4,7 @@
  * addon-acpi.c : Listen to ACPI events and modify hal device objects
  *
  * Copyright (C) 2005 David Zeuthen, <david at fubar.dk>
+ * Copyright (C) 2005 Ryan Lortie <desrt at desrt.ca>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +31,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#include <stdint.h>
+#include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -40,117 +41,70 @@
 
 #include "../probing/shared.h"
 
-static char *
-read_line (int fd)
+static FILE *
+acpi_get_event_fp_kernel (void)
 {
-	unsigned int i;
-	unsigned int r;
-	static char buf[256];
-	char *res;
-	dbus_bool_t searching;
-
-	i = 0;
-	res = NULL;
-	searching = TRUE;
-
-	while (searching) {
-		while (i < sizeof (buf)) {
-			r = read(fd, buf + i, 1);
-			if (r < 0 && errno != EINTR) {
-				/* we should do something with the data */
-				dbg ("ERR read(): %s\n", strerror(errno));
-				goto out;
-			} else if (r == 0) {
-				/* signal this in an almost standard way */
-				errno = EPIPE;
-				return NULL;
-			} else if (r == 1) {
-				/* scan for a newline */
-				if (buf[i] == '\n') {
-					searching = FALSE;
-					buf[i] = '\0';
-					res = buf;
-					goto out;
-				}
-				i++;
-			}
-		}
+	FILE *fp = NULL;
 
-		if (i >= sizeof (buf)) {
-			dbg ("ERR: buffer size of %d is too small\n", sizeof (buf));
-			goto out;
-		}
+#ifdef ACPI_PROC
+	fp = fopen ("/proc/acpi/event", "r");
 
-	}
+	if (fp == NULL)
+		dbg ("Cannot open /proc/acpi/event: %s", strerror (errno));
+#endif
 
-out:	
-	return res;
+	return fp;
 }
 
-int
-main (int argc, char *argv[])
+static FILE *
+acpi_get_event_fp_acpid (void)
 {
-	int fd;
-	struct sockaddr_un addr;
-	LibHalContext *ctx = NULL;
-	DBusError error;
-	char acpi_path[256];
-	char acpi_name[256];
-	unsigned int acpi_num1;
-	unsigned int acpi_num2;
-
-	fd = -1;
-
-	if ((getenv ("HALD_VERBOSE")) != NULL)
-		is_verbose = TRUE;
-
-	dbus_error_init (&error);
-	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
-		goto out;
+	FILE *fp = NULL;
 
 #ifdef ACPI_ACPID
-	/* receive event from acpi daemon */
-	fd = socket(AF_UNIX, SOCK_STREAM, 0);
-	if (fd < 0) {
-		dbg ("Cannot create socket");
-		goto out;
+	struct sockaddr_un addr;
+	int fd;
+
+	if( (fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0 ) {
+		dbg ("Cannot create socket: %s", strerror (errno));
+		return NULL;
 	}
-	memset(&addr, 0, sizeof(addr));
+
+	memset (&addr, 0, sizeof addr);
 	addr.sun_family = AF_UNIX;
-	snprintf (addr.sun_path, sizeof (addr.sun_path), "%s", "/var/run/acpid.socket");
-	if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
+	strncpy (addr.sun_path, "/var/run/acpid.socket", sizeof addr.sun_path);
+
+	if (connect (fd, (struct sockaddr *) &addr, sizeof addr) < 0) {
+		dbg ("Cannot connect to acpid socket: %s", strerror (errno));
 		close (fd);
-		dbg ("Cannot connect to acpid socket");
-		fd = -1;
-	}
-#endif
+	} else {
+		fp = fdopen (fd, "r");
 
-#ifdef ACPI_PROC
-	/* connect directly to the kernel */
-	if (fd < 0) {
-		fd = open ("/proc/acpi/event", O_RDONLY);
-		dbg ("Cannot open /proc/acpi/event: %s", strerror (errno));
+		if (fp == NULL)
+		{
+			dbg ("fdopen failed: %s", strerror (errno));
+			close (fd);
+		}
 	}
 #endif
 
-	if (fd < 0) {
-		dbg ("Cannot connect to acpi event source - bailing out");
-		goto out;
-	}
+	return fp;
+}
 
-	/* main loop */
-	while (1) {
-		char *event;
+static void
+main_loop (LibHalContext *ctx, FILE *eventfp)
+{
+	unsigned int acpi_num1;
+	unsigned int acpi_num2;
+	char acpi_path[256];
+	char acpi_name[256];
+	DBusError error;
+	char event[256];
 
-		/* read and handle an event */
-		event = read_line (fd);
-		if (event) {
-			dbg ("ACPI event %s\n", event);
-		} else if (errno == EPIPE) {
-			dbg ("connection closed\n");
-			break;
-		}
+	dbus_error_init (&error);
 
+	while (fgets (event, sizeof event, eventfp))
+	{
 		dbg ("event is '%s'", event);
 
 		if (sscanf (event, "%s %s %x %x", acpi_path, acpi_name, &acpi_num1, &acpi_num2) == 4) {
@@ -162,19 +116,15 @@
 				dbg ("button event");
 
 				/* TODO: only rescan if button got state */
-				dbus_error_init (&error);
 				libhal_device_rescan (ctx, udi, &error);
 
-				dbus_error_init (&error);
 				libhal_device_emit_condition (ctx, udi, "ButtonPressed", "", &error);
 
 			} else if (strncmp (acpi_path, "ac_adapter", sizeof ("ac_adapter") - 1) == 0) {
 				dbg ("ac_adapter event");
-				dbus_error_init (&error);
 				libhal_device_rescan (ctx, udi, &error);
 			} else if (strncmp (acpi_path, "battery", sizeof ("battery") - 1) == 0) {
 				dbg ("battery event");
-				dbus_error_init (&error);
 				libhal_device_rescan (ctx, udi, &error);
 			}
 
@@ -183,11 +133,50 @@
 		}
 		
 	}
-	
-	
-out:
-	if (fd >= 0)
-		close (fd);
 
-	return 0;
+	dbus_error_free (&error);
+	fclose (eventfp);
+}
+
+int
+main (int argc, char **argv)
+{
+	LibHalContext *ctx = NULL;
+	int reconnecting = FALSE;
+	DBusError error;
+	FILE *eventfp;
+
+	if (getenv ("HALD_VERBOSE") != NULL)
+		is_verbose = TRUE;
+
+	dbus_error_init (&error);
+
+	if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
+		dbg ("Unable to initialise libhal context: %s", error.message);
+		return 1;
+	}
+
+	/* If we can connect directly to the kernel then do so. */
+	if ((eventfp = acpi_get_event_fp_kernel ())) {
+		main_loop (ctx, eventfp);
+		return 1;
+	}
+
+	/* Else, try to use acpid. */
+	while ((eventfp = acpi_get_event_fp_acpid ()) || reconnecting)
+	{
+		if (eventfp != NULL)
+			main_loop (ctx, eventfp);
+
+		/* If main_loop exits or we failed a reconnect attempt then
+		 * sleep for 5s and try to reconnect (again). */
+		reconnecting = TRUE;
+		sleep (5);
+	}
+
+	dbg ("Cannot connect to acpi event source - bailing out");
+
+	return 1;
 }
+
+/* vim:set sw=8 noet: */




More information about the hal-commit mailing list