gpt4 book ai didi

c - 从挂起恢复时出现段错误

转载 作者:行者123 更新时间:2023-11-30 16:00:48 26 4
gpt4 key购买 nike

我正在使用 GTK 编写一个非常简单的电池状态图标。它是一个 GtkStatusIcon,在工具提示中显示当前电池状态。为了获取电池信息,我解析命令acpi的输出,该输出通常类似于:

Battery 0: Discharging, 70%, 01:00:00 remaining

My battery status icon runs just fine but when I suspend my computer and then I resume it, my program crashes with segmentation fault.

The whole code is this (I've commented it):

#include <gtk/gtk.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

#define DEFAULT_ARRAY_SIZE 3
#define DEFAULT_TIME_UPDATE 5

const gchar * acpi_command = "acpi";

typedef enum batteryState{
CHARGING,
DISCHARGING,
} BatteryState;

typedef struct batteryTray {
GtkStatusIcon * tray_icon;
gchar * tooltip;
gchar * icon;
} BatteryTray;

typedef struct battery {
gchar * status;
gint percentage;
gchar * extra;
BatteryTray batteryTray;
BatteryState batteryState;
} Battery;

static void update_status_battery(Battery * battery);
static gboolean update_status_tray(Battery * battery);
static gchar * get_status_icon_name(Battery * battery);
static void create_tray_icon(Battery * battery);
static void parse_acpi_output(Battery * battery, gchar * acpi_output);
static char * get_acpi_output(const gchar * acpi_command);

static void update_status_battery(Battery * battery)
{
if(strcmp(battery->status, "Charging") == 0)
battery->batteryState = CHARGING;
else if(strcmp(battery->status, "Discharging") == 0)
battery->batteryState = DISCHARGING;
}

static gboolean update_status_tray(Battery * battery)
{
gchar * icon_name = get_status_icon_name(battery);
gchar * acpi_out = get_acpi_output(acpi_command);

parse_acpi_output(battery, acpi_out);
update_status_battery(battery);

battery->batteryTray.tooltip = g_strdup_printf("%s (%d%%) %s",
battery->status,
battery->percentage,
battery->extra);

gtk_status_icon_set_tooltip_text(battery->batteryTray.tray_icon,
battery->batteryTray.tooltip);

gtk_status_icon_set_from_icon_name(battery->batteryTray.tray_icon,
icon_name);

return TRUE;
}

static gchar * get_status_icon_name(Battery * battery)
{

GString * icon_name = g_string_new("notification-battery");

if (battery->percentage < 20)
g_string_append(icon_name, "-low");
else if (battery->percentage < 40)
g_string_append(icon_name, "-020");
else if (battery->percentage < 80)
g_string_append(icon_name, "-060");
else
g_string_append(icon_name, "-100");

if(battery->batteryState == CHARGING) {
g_string_append(icon_name, "-plugged");
}

return icon_name->str;
}

static void create_tray_icon(Battery * battery)
{
/* create the gtkstatusicon and call the function
`update_status_tray` every 5 seconds */

battery->batteryTray.tray_icon = gtk_status_icon_new();
battery->batteryTray.tooltip = "battery";
gtk_status_icon_set_tooltip(battery->batteryTray.tray_icon,
battery->batteryTray.tooltip);
gtk_status_icon_set_visible(battery->batteryTray.tray_icon,
TRUE);

update_status_tray(battery);
g_timeout_add_seconds(DEFAULT_TIME_UPDATE, (GSourceFunc) update_status_tray, battery);
}

static void parse_acpi_output(Battery * battery, gchar * acpi_output)
{
/* acpi output is like:
Battery 0: Discharging, 70%, 01:00:00 remaining

In this function I assign "Discharging" to battery->status
70 to battery->percentage
and "01:00:00 remaining" to battery->extra

I use strtok to split the acpi output into tokens delimited by ',' and
then, if there's a blank character ' ' in front of a token, i 'remove' it.
*/

gint i = 0;
gchar * t;
gchar ** values_array;

/* find the position of ':' in the string */
int pos = strchr(acpi_output, ':') - acpi_output;
t = strtok(acpi_output + pos + 1, ",");

values_array = malloc(DEFAULT_ARRAY_SIZE * sizeof(gchar));

while(t != NULL) {
/* 'remove' the blank character */
values_array[i++] = t[0] == ' ' ? t + 1 : t;
t = strtok(NULL, ",");
}

/* remove newline */
if(values_array[2][strlen(values_array[2]) - 1] == '\n') {
values_array[2][strlen(values_array[2]) - 1] = '\0';
}

battery->status = values_array[0];
battery->percentage = atoi(values_array[1]);
battery->extra = values_array[2];

free(values_array);
}

static gchar * get_acpi_output(const gchar * acpi_command)
{
gchar * output;
GError * error = NULL;

/* assign the output of the acpi command to 'output' */
g_spawn_command_line_sync(acpi_command, &output, NULL, NULL, &error);
return output;
}

int main(int argc, char ** argv)
{
Battery battery;

gtk_init(&argc, &argv);
create_tray_icon(&battery);
gtk_main();

return 0;
}

我真的不明白,希望有人能帮助我。

最佳答案

有很多地方可以进行更多的错误检查;也许代码之外的某些东西在唤醒期间失败了。例如,您不检查 g_spawn_command_line_sync 的结果 - 您假设 output 返回时指向有效字符串,但也许情况并非总是如此。您假设(但实际上并未确认)您运行的工具的输出中包含一定数量的标记,但也许并不总是如此。

关于c - 从挂起恢复时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7421628/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com