Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 207249 Details for
Bug 272447
xfce-extra/xfce4-sensors crashes if compiled with hddtemp support
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to hddtemp.c to enable connection to the hddtemp daemon via the loopback device (127.0.0.1) on port 7634.
hddtemp_daemon.diff (text/plain), 18.30 KB, created by
David W Noon
on 2009-10-15 20:26:49 UTC
(
hide
)
Description:
Patch to hddtemp.c to enable connection to the hddtemp daemon via the loopback device (127.0.0.1) on port 7634.
Filename:
MIME Type:
Creator:
David W Noon
Created:
2009-10-15 20:26:49 UTC
Size:
18.30 KB
patch
obsolete
>--- hddtemp.orig 2009-10-02 17:00:28.000000000 +0100 >+++ hddtemp.c 2009-10-06 11:41:17.000000000 +0100 >@@ -54,20 +54,25 @@ > #include <sys/utsname.h> > > #include <unistd.h> >+#include <errno.h> >+#include <sys/types.h> >+#include <sys/socket.h> >+#include <arpa/inet.h> > >-#ifdef HAVE_NETCAT >-#include "helpers.c" >-# ifndef NETCAT_PATH >-# define NETCAT_PATH "/bin/netcat" >+# ifndef HDDTEMP_PORT >+# define HDDTEMP_PORT 7634 > # endif > >-# ifndef HDDTEMP_PORT >-# define HDDTEMP_PORT "7634" >+# ifndef HDDTEMP_BUFFER_SIZE >+# define HDDTEMP_BUFFER_SIZE 1023UL >+# endif >+ >+# ifndef MAX_DISKS >+# define MAX_DISKS 200 > # endif > > # define DOUBLE_DELIMITER "||" > # define SINGLE_DELIMITER "|" >-#endif > > #ifdef HAVE_LIBNOTIFY > void >@@ -177,118 +182,165 @@ > #endif > } > >- >-#ifdef HAVE_NETCAT >-void >-read_disks_netcat (t_chip *chip) >+/* Function to obtain a socket connected to the hddtemp daemon on the current system. */ >+static int get_hddtemp_socket(void) > { >- char *stdoutput, *stderrput, *cmdline, *tmp, *tmp2, *tmp3; >- gboolean result; >- gint exit_status = 0; >- GError *error = NULL; >+ const int sock_fd = socket(AF_INET, SOCK_STREAM, 0); /* Create an IPv4 socket. */ > >- t_chipfeature *cf; >+ if (sock_fd != -1) >+ { >+ struct sockaddr_in ip_addr; > >- cmdline = g_strdup_printf ("%s localhost %s", NETCAT_PATH, HDDTEMP_PORT); >- //g_printf("cmdline=%s\n", cmdline); >+ /* Build a binary address for port 7634 on localhost. */ >+ memset(&ip_addr, 0x00, sizeof ip_addr); >+ ip_addr.sin_family = AF_INET; >+ ip_addr.sin_port = htons(HDDTEMP_PORT); >+ inet_pton(AF_INET, "127.0.0.1", &ip_addr.sin_addr); > >- result = g_spawn_command_line_sync ( (const gchar*) cmdline, >- &stdoutput, &stderrput, &exit_status, &error); >+ /* Now connect to the daemon. */ >+ if (connect(sock_fd, (struct sockaddr *) &ip_addr, sizeof ip_addr) != 0) >+ { >+ gchar * msg_txt; > >- if (!result) >- return; >+ msg_txt = g_strdup_printf("Connecting socket: %s", g_strerror(errno)); >+ /* g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, msg_txt); */ >+ quick_message(msg_txt); >+ g_free(msg_txt); >+ close(sock_fd); >+ return -1; >+ } >+ } >+ else >+ { >+ gchar * msg_txt; > >- //g_printf("stdouput=%s\n", stdoutput); >+ msg_txt = g_strdup_printf("Opening socket: %s", g_strerror(errno)); >+ /* g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, msg_txt); */ >+ quick_message(msg_txt); >+ g_free(msg_txt); >+ } > >- tmp = str_split (stdoutput, DOUBLE_DELIMITER); >- do { >- //g_printf ("Found token: %s\n", tmp); >- cf = g_new(t_chipfeature, 1); >+ return sock_fd; >+} > >- tmp2 = g_strdup (tmp); >- tmp3 = strtok (tmp2, SINGLE_DELIMITER); >- cf->devicename = g_strdup(tmp3); >- tmp3 = strtok (NULL, SINGLE_DELIMITER); >- cf->name = g_strdup(tmp3); >+/* This function reads all the bytes of the hddtemp daemon's output, >+ places them in a dynamically allocated buffer, which should be freed later, >+ and returns the length of the buffer. */ >+static gsize get_hddtemp_text(gchar ** stdoutput) >+{ >+ const int sock_fd = get_hddtemp_socket(); >+ gsize result_len = 0UL; > >- g_ptr_array_add(chip->chip_features, cf); >- chip->num_features++; >+ TRACE ("enters get_hddtemp_text"); > >- g_free (tmp2); >- } >- while ( (tmp = str_split(NULL, DOUBLE_DELIMITER)) ); >+ /* Ensure the socket is valid. */ >+ if (sock_fd != -1) >+ { >+ GIOChannel * const sock = g_io_channel_unix_new(sock_fd); /* Use Glib I/O channel for the socket. */ >+ GIOStatus rc; >+ GError * err_code = NULL; >+ gsize bytes_read = 0UL; >+ gchar input_buffer[HDDTEMP_BUFFER_SIZE+1]; > >- g_free (stdoutput); >-} >+ do >+ { >+ /* Read a buffer of bytes from the socket connected to the hddtemp daemon. */ >+ rc = g_io_channel_read_chars(sock, input_buffer, HDDTEMP_BUFFER_SIZE, &bytes_read, &err_code); > >-#else >-void >-read_disks_fallback (t_chip *chip) >-{ >- GError *error; >- GDir *gdir; >- t_chipfeature *chipfeature; >- const gchar* dirname; >+ /* The next piece of code should never be executed, but then ... */ >+ if (rc == G_IO_STATUS_ERROR) >+ { >+ gchar * msg_txt; > >- TRACE ("enters read_disks_fallback"); >+ msg_txt = g_strdup_printf("Reading socket: %s (%d)", err_code->message, err_code->code); >+ /* g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Reading socket: %s (%d)", err_code->message, err_code->code); */ >+ quick_message(msg_txt); >+ g_free(msg_txt); >+ g_error_free(err_code); >+ err_code = NULL; >+ break; >+ } > >- /* read from /proc/ide */ >- error = NULL; >- gdir = g_dir_open ("/proc/ide/", 0, &error); >+ /* If we received some bytes in this read, add it to the output string. */ >+ if (bytes_read > 0) >+ { >+ result_len += bytes_read; >+ if (*stdoutput == NULL) /* No bytes yet in the string. */ >+ { >+ *stdoutput = g_strndup(input_buffer, bytes_read); >+ } >+ else >+ { >+ gchar * const tmp = *stdoutput; /* Protect the reference to the bytes read previously. */ > >- while ( (dirname = g_dir_read_name (gdir))!=NULL ) { >- if ( strncmp (dirname, "hd", 2)==0 || strncmp (dirname, "sd", 2)==0) { >- /* TODO: look, if /dev/dirname exists? */ >- chipfeature = g_new0 (t_chipfeature, 1); >- chipfeature->devicename = g_strconcat ("/dev/", dirname, NULL); >- chipfeature->name = g_strdup(chipfeature->devicename); >- g_ptr_array_add (chip->chip_features, chipfeature); >- chip->num_features++; >+ /* Add a trailing NUL to the block of bytes. */ >+ input_buffer[bytes_read] = '\0'; >+ /* Concatenate this block to the bytes we have read previously. */ >+ *stdoutput = g_strconcat(tmp, input_buffer, NULL); >+ /* Free up the previous bytes. */ >+ g_free(tmp); >+ } >+ } >+ } while (rc != G_IO_STATUS_EOF); /* Keep looping until the hddtemp daemon closes the socket. */ >+ >+ if (g_io_channel_shutdown(sock, TRUE, &err_code) == G_IO_STATUS_ERROR) /* This should always work, but then ... */ >+ { >+ gchar * msg_txt; >+ >+ msg_txt = g_strdup_printf("Closing socket: %s (%d)", err_code->message, err_code->code); >+ /* g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, msg_txt); */ >+ quick_message(msg_txt); >+ g_free(msg_txt); >+ g_error_free(err_code); >+ err_code = NULL; > } > } > >- g_dir_close (gdir); >- >- /* FIXME: read SCSI info from where? SATA? */ >+ TRACE ("leaves get_hddtemp_text"); > >- TRACE ("leaves read_disks_fallback"); >+ /* Return value is the total number of bytes read through the socket. */ >+ return result_len; > } > >- > void >-read_disks_linux26 (t_chip *chip) >+read_disks(t_chip *chip) > { >- GDir *gdir; >- t_chipfeature *chipfeature; >- const gchar* dirname; >+ gchar * stdoutput = NULL; >+ t_chipfeature *cf; > >- TRACE ("enters read_disks_linux26"); >+ TRACE ("enters read_disks"); > >- /* read from /sys/block */ >- gdir = g_dir_open ("/sys/block/", 0, NULL); >- while ( (dirname = g_dir_read_name (gdir))!=NULL ) { >- /* if ( strncmp (dirname, "ram", 3)!=0 && >- strncmp (dirname, "loop", 4)!=0 && >- strncmp (dirname, "md", 2)!=0 && >- strncmp (dirname, "fd", 2)!=0 && >- strncmp (dirname, "mmc", 3)!=0 && >- strncmp (dirname, "dm-", 3)!=0 ) { */ >- if ( strncmp (dirname, "hd", 2)==0 || >- strncmp (dirname, "sd", 2)==0 ) { >- /* TODO: look, if /dev/dirname exists? */ >- chipfeature = g_new0 (t_chipfeature, 1); >- chipfeature->devicename = g_strconcat ("/dev/", dirname, NULL); /* /proc/ide/hda/model ?? */ >- chipfeature->name = g_strdup(chipfeature->devicename); >- g_ptr_array_add (chip->chip_features, chipfeature); >- chip->num_features++; >+ get_hddtemp_text(&stdoutput); >+ >+ if (stdoutput != NULL) >+ { >+ gchar ** string_vec = g_strsplit_set(stdoutput, SINGLE_DELIMITER, MAX_DISKS); >+ gint i, max_i = 0; >+ >+ while (string_vec[max_i] != NULL) >+ { >+ ++max_i; > } >- } > >- g_dir_close (gdir); >+ for (i = 1; i < max_i; i += 5) >+ { >+ if (strcmp(string_vec[i+2], "NOS") != 0) >+ { >+ cf = g_new(t_chipfeature, 1); >+ cf->devicename = g_strdup(string_vec[i]); >+ cf->name = g_strdup(string_vec[i]+5); /* Trim off "/dev/". */ > >- TRACE ("leaves read_disks_linux26"); >+ g_ptr_array_add(chip->chip_features, cf); >+ chip->num_features++; >+ } >+ } >+ >+ g_strfreev(string_vec); >+ g_free(stdoutput); >+ } >+ >+ TRACE ("leaves read_disks"); > } >-#endif > > void > remove_unmonitored_drives (t_chip *chip, gboolean *suppressmessage) >@@ -368,9 +420,9 @@ > int > initialize_hddtemp (GPtrArray *chips, gboolean *suppressmessage) > { >- int generation, major, result, retval; >- struct utsname *p_uname; >+ int retval; > t_chip *chip; >+ static const sensors_chip_name hdd_chip_name = { "Hard disks", 0, 0, "Hard disks" }; > > g_assert (chips!=NULL); > >@@ -378,9 +430,8 @@ > > chip = g_new (t_chip, 1); > >- chip->chip_name = (const sensors_chip_name *) >- ( _("Hard disks"), 0, 0, _("Hard disks") ); >- >+ chip->chip_name = &hdd_chip_name; >+ > chip->chip_features = g_ptr_array_new (); > chip->num_features = 0; > chip->description = g_strdup(_("S.M.A.R.T. harddisk temperatures")); >@@ -388,30 +439,9 @@ > chip->sensorId = g_strdup("Hard disks"); > chip->type = HDD; > >- p_uname = (struct utsname *) malloc (sizeof(struct utsname)); >- result = uname (p_uname); >- if (result!=0) { >- g_free(p_uname); >- return -1; >- } >- >- generation = atoi ( p_uname->release ); /* this might cause trouble on */ >- major = atoi ( p_uname->release+2 ); /* other systems than Linux! */ >- /* actually, wanted to use build time configuration therefore */ >- >- /* Note: This is actually supposed to be carried out by ifdef HAVE_LINUX >- and major/minor number stuff from compile time*/ >-#ifdef HAVE_NETCAT >- read_disks_netcat (chip); >-#else >- if (strcmp(p_uname->sysname, "Linux")==0 && major>=5) >- read_disks_linux26 (chip); >- else >- read_disks_fallback (chip); /* hopefully, that's a safe variant */ >-#endif >- >- g_free(p_uname); >+ read_disks(chip); > >+ /* This next call should no longer be necessary. */ > remove_unmonitored_drives (chip, suppressmessage); > DBG ("numfeatures=%d\n", chip->num_features); > if ( chip->num_features>0 ) { /* if (1) */ >@@ -433,17 +463,10 @@ > double > get_hddtemp_value (char* disk, gboolean *suppressmessage) > { >- gchar *standard_output, *standard_error; >- gchar *cmd_line, *msg_text; >-#ifndef HAVE_LIBNOTIFY >- gchar *checktext; >-#endif >- gint exit_status=0; >- double value; >- gboolean result, nevershowagain; >- GError *error; >- >- gchar *tmp, *tmp2, *tmp3; >+ gchar * standard_output = NULL; >+ gsize bytes_read; >+ double value = ZERO_KELVIN; >+ gboolean nevershowagain; > > if (suppressmessage!=NULL) > nevershowagain = *suppressmessage; >@@ -452,143 +475,29 @@ > > TRACE ("enters get_hddtemp_value for %s with suppress=%d", disk, nevershowagain); /* *suppressmessage); */ > >-#ifdef HAVE_NETCAT >- exit_status = 1; // assume error by default >- cmd_line = g_strdup_printf ( "%s localhost %s", NETCAT_PATH, HDDTEMP_PORT); >- result = g_spawn_command_line_sync ( (const gchar*) cmd_line, >- &standard_output, &standard_error, &exit_status, NULL); >- error = g_new(GError, 1); >- error->message = g_strdup (_("No concrete error detected.\n")); >- if (exit_status==0) >+ bytes_read = get_hddtemp_text(&standard_output); >+ if (standard_output != NULL) > { >- tmp3 = "-255"; >- tmp = str_split (standard_output, DOUBLE_DELIMITER); >- do { >- //g_printf ("Found token: %s for disk %s\n", tmp, disk); >- tmp2 = g_strdup (tmp); >- tmp3 = strtok (tmp2, SINGLE_DELIMITER); // device name >- if (strcmp(tmp3, disk)==0) >+ gchar ** string_vec = g_strsplit_set(standard_output, SINGLE_DELIMITER, MAX_DISKS); >+ gint i, max_i = 0; >+ >+ while (string_vec[max_i] != NULL) >+ { >+ ++max_i; >+ } >+ >+ for (i = 1; i < max_i; i += 5) >+ { >+ if (strcmp(string_vec[i], disk) == 0) > { >- tmp3 = strtok(NULL, SINGLE_DELIMITER); // name >- tmp3 = strdup(strtok(NULL, SINGLE_DELIMITER)); // value >- // tmp3 = strtok(NULL, SINGLE_DELIMITER); // temperature unit >- exit_status = 0; >- g_free(error); >- error = NULL; >- g_free (tmp2); >+ value = g_strtod(string_vec[i+2], NULL); > break; > } >- g_free (tmp2); > } >- while ( (tmp = str_split(NULL, DOUBLE_DELIMITER)) ); > >+ g_strfreev(string_vec); > g_free(standard_output); >- standard_output = tmp3; >- } >- else >- { >- error->message = g_strdup (standard_error); >- } >- >-#else >- error = NULL; >- cmd_line = g_strdup_printf ( "%s -n -q %s", PATH_HDDTEMP, disk); >- result = g_spawn_command_line_sync ( (const gchar*) cmd_line, >- &standard_output, &standard_error, &exit_status, &error); >-#endif >- >- msg_text = NULL; // wonder if this is still necessary >- >- DBG ("Exit code %d on %s with stdout of %s.\n", exit_status, disk, standard_output); >- >- /* filter those with no sensors out */ >- if (exit_status==0 && strncmp(disk, "/dev/fd", 6)==0) { /* is returned for floppy disks */ >- DBG("exit_status==0 && strncmp(disk, \"/dev/fd\", 6)==0"); >- value = 0.0; > } >- else if ((exit_status==256 || (standard_error && strlen(standard_error)>0)) >- && access (PATH_HDDTEMP, X_OK)==0) /* || strlen(standard_error)>0) */ >- { >- /* note that this check does only work for some versions of hddtemp. */ >- if (!nevershowagain) { >- msg_text = g_strdup_printf(_("\"hddtemp\" was not executed correctly, " >- "although it is executable. This is most probably due " >- "to the disks requiring root privileges to read their " >- "temperatures, and \"hddtemp\" not being setuid root." >- "\n\n" >- "An easy but dirty solution is to run \"chmod u+s %s" >- "\" as root user and restart this plugin " >- "or its panel.\n\n" >- "Calling \"%s\" gave the following error:\n%s\nwith a return value of %d.\n"), >- PATH_HDDTEMP, cmd_line, standard_error, exit_status); >- >-#ifdef HAVE_LIBNOTIFY >- //msg_text = g_strconcat(msg_text, _("\nYou can disable these notifications in the settings dialog.\n"); >- quick_message_notify (msg_text); >- nevershowagain = FALSE; >-#else >- checktext = g_strdup(_("Suppress this message in future")); >- nevershowagain = quick_message_with_checkbox(msg_text, checktext); >-#endif >- >- if (suppressmessage!=NULL) >- *suppressmessage = nevershowagain; >- } >- else { >- DBG ("Suppressing dialog with exit_code=256 or output on standard_error"); >- } >- >- value = ZERO_KELVIN; >- } >- /* else if (strlen(standard_error)>0) { >- msg_text = g_strdup_printf (_("An error occurred when executing" >- " \"%s\":\n%s"), cmd_line, standard_error); >- quick_message (msg_text); >- value = ZERO_KELVIN; >- } */ >- >- else if (error && (!result || exit_status!=0)) >- { >- DBG ("error %s\n", error->message); >- if (!nevershowagain) { >- msg_text = g_strdup_printf (_("An error occurred when executing" >- " \"%s\":\n%s"), cmd_line, error->message); >-#ifdef HAVE_LIBNOTIFY >- quick_message_notify (msg_text); >- nevershowagain = FALSE; >-#else >- checktext = g_strdup(_("Suppress this message in future")); >- nevershowagain = quick_message_with_checkbox (msg_text, checktext); >-#endif >- >- if (suppressmessage!=NULL) >- *suppressmessage = nevershowagain; >- } >- else { >- DBG ("Suppressing dialog because of error in g_spawn_cl"); >- } >- value = 0.0; >- } >- else if (standard_output && strlen(standard_output) > 0) >- { >- DBG("got the only useful return value of 0 and value of %s.\n", standard_output); >- /* hddtemp does not return floating values, but only integer ones. >- So have an easier life with atoi. >- FIXME: Use strtod() instead?*/ >- value = (double) (atoi ( (const char*) standard_output) ); >- } >- else { >- DBG("No condition applied."); >- value = 0.0; >- } >- >- g_free (cmd_line); >- g_free (standard_output); >- g_free (standard_error); >- g_free (msg_text); >-#ifndef HAVE_LIBNOTIFY >- g_free (checktext); >-#endif > > TRACE ("leaves get_hddtemp_value"); > >@@ -600,7 +509,6 @@ > refresh_hddtemp (gpointer chip_feature, gpointer data) > { > t_chipfeature *cf; >- double value; > > g_assert (chip_feature!=NULL); > >@@ -608,16 +516,7 @@ > > cf = (t_chipfeature *) chip_feature; > >- value = get_hddtemp_value (cf->devicename, NULL); >- >- /* actually, that's done in the gui part */ >- g_free (cf->formatted_value); >- /* if (scale == FAHRENHEIT) { >- cf->formatted_value = g_strdup_printf(_("%.1f °F"), (float) (value * 9/5 + 32) ); >- } else { // Celsius */ >- cf->formatted_value = g_strdup_printf(_("%.1f °C"), value); >- /* } */ >- cf->raw_value = value; >+ cf->raw_value = get_hddtemp_value (cf->devicename, NULL); > > TRACE ("leaves refresh_hddtemp"); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 272447
:
206161
|
206247
|
207178
|
207249
|
235471
|
235601