📄 linux.c
字号:
gint i; if ((f = fopen(PROC_NET_DEV_FILE, "r"))) { fgets(buf, sizeof(buf), f); /* Waste the first line. */ fgets(buf, sizeof(buf), f); /* Look for "units" in this line */ s = strtok(buf, delim); for (i = 0; s; ++i) { if (strcmp(s, "bytes") == 0) { if (rx_bytes_index == 0) rx_bytes_index = i; else tx_bytes_index = i; } if (strcmp(s, "packets") == 0) { if (rx_packets_index == 0) rx_packets_index = i; else tx_packets_index = i; } s = strtok(NULL, delim); } fclose(f); } if (_GK.debug_level & DEBUG_NET) printf(_("rx_bytes=%d tx_bytes=%d rx_packets=%d tx_packets=%d\n"), rx_bytes_index, tx_bytes_index, rx_packets_index, tx_packets_index); }gbooleangkrellm_sys_net_init(void) { get_io_indices(); gkrellm_net_set_lock_directory("/var/lock"); gkrellm_net_add_timer_type_ppp("ppp0"); gkrellm_net_add_timer_type_ippp("ippp0"); gkrellm_net_use_routed(TRUE /* Always TRUE from sysdep code */); return TRUE; }/* ===================================================================== *//* Memory/Swap monitor interface */#define PROC_MEMINFO_FILE "/proc/meminfo"#define PROC_VMSTAT_FILE "/proc/vmstat"static guint64 swap_total, swap_used; /* Kernels >= 2.5.x have tagged formats only in kb units. */static voidtagged_format_meminfo(gchar *buf, guint64 *mint) { sscanf(buf,"%Lu", mint); *mint *= 1024; }voidgkrellm_sys_mem_read_data(void) { FILE *f; gchar buf[160]; gboolean using_tagged = FALSE; guint64 total, used, x_used, free, shared, buffers, cached, slab; /* Default 0, so we don't get arbitrary values if not found, | e.g. MemShared is not present in 2.6. */ total = used = x_used = free = shared = buffers = cached = slab = 0LL; if ((f = fopen(PROC_MEMINFO_FILE, "r")) == NULL) return; while ((fgets(buf, sizeof(buf), f)) != NULL) { if (buf[0] == 'M') { if (!strncmp(buf, "Mem:", 4)) sscanf(buf + 5, "%Lu %Lu %Lu %Lu %Lu %Lu", &total, &x_used, &free, &shared, &buffers, &cached); else if (!strncmp(buf, "MemTotal:", 9)) { tagged_format_meminfo(buf + 10, &total); using_tagged = TRUE; } else if (!strncmp(buf, "MemFree:", 8)) tagged_format_meminfo(buf + 9, &free); else if (!strncmp(buf, "MemShared:", 10)) tagged_format_meminfo(buf + 11, &shared); } else if (buf[0] == 'S') { if (!strncmp(buf, "Swap:", 5)) sscanf(buf + 6,"%Lu %Lu", &swap_total, &swap_used); else if (!strncmp(buf, "SwapTotal:", 10)) tagged_format_meminfo(buf + 11, &swap_total); else if (!strncmp(buf, "SwapFree:", 9)) tagged_format_meminfo(buf + 10, &swap_used); else if (!strncmp(buf, "Slab:", 5)) tagged_format_meminfo(buf + 6, &slab); } else if (buf[0] == 'B' && !strncmp(buf, "Buffers:", 8)) tagged_format_meminfo(buf + 9, &buffers); else if (buf[0] == 'C' && !strncmp(buf, "Cached:", 7)) tagged_format_meminfo(buf + 8, &cached); } fclose(f); if (using_tagged) { x_used = total - free; swap_used = swap_total - swap_used; } used = x_used - buffers - cached - slab; gkrellm_mem_assign_data(total, used, free, shared, buffers, cached + slab); } /* Kernel >= 2.6 swap page in/out is in /proc/vmstat. | Kernel <= 2.4 swap page in/out is in /proc/stat read in read_proc_stat(). | Swap total/used for all kernels is read in mem_read_data() above. */voidgkrellm_sys_swap_read_data(void) { static FILE *f; gchar buf[128]; if (!f && kernel_2_6) f = fopen(PROC_VMSTAT_FILE, "r"); if (f) { while (fgets(buf, sizeof(buf), f) != NULL) { if (buf[0] != 'p' || buf[1] != 's') continue; sscanf(buf, "pswpin %lu", &swapin); if (fgets(buf, sizeof(buf), f) == NULL) break; sscanf(buf, "pswpout %lu", &swapout); } rewind(f); } gkrellm_swap_assign_data(swap_total, swap_used, swapin, swapout); }gbooleangkrellm_sys_mem_init(void) { return TRUE; }/* ===================================================================== *//* FS monitor interface */#include <sys/vfs.h>#include <sys/wait.h>#include <sys/ioctl.h>#include <linux/cdrom.h>#include <mntent.h>#define PROC_MOUNTS_FILE "/proc/mounts" /* A list of mounted file systems can be read from /proc/mounts or | /etc/mtab (getmntent). Using /proc/mounts eliminates disk accesses, | but for some reason /proc/mounts reports a "." for the mounted | directory for smbfs types. So I use /proc/mounts with a fallback | to using getmntent(). */#if !defined (_PATH_MOUNTED)#define _PATH_MOUNTED "/etc/mtab"#endifstatic voidfix_fstab_name(gchar *buf) { gchar *rp, *wp; if (buf[0] == '\0') return; rp = buf; wp = buf; do /* This loop same as in libc6 getmntent() */ if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0') { *wp++ = ' '; /* \040 is a SPACE. */ rp += 3; } else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2') { *wp++ = '\t'; /* \012 is a TAB. */ rp += 3; } else if (rp[0] == '\\' && rp[1] == '\\') { *wp++ = '\\'; /* \\ is a \ */ rp += 1; } else *wp++ = *rp; while (*rp++ != '\0'); }gbooleangkrellm_sys_fs_fstab_modified(void) { struct stat s; static time_t fstab_mtime; gint modified = FALSE; if (stat("/etc/fstab", &s) == 0 && s.st_mtime != fstab_mtime) modified = TRUE; fstab_mtime = s.st_mtime; return modified; }voidgkrellm_sys_fs_get_fstab_list(void) { FILE *f; gchar buf[1024], *s; gchar dev[512], dir[512], type[128], opt[256]; if ((f = fopen("/etc/fstab", "r")) == NULL) return; while (fgets(buf, sizeof(buf), f)) { s = buf; while (*s == ' ' || *s == '\t') ++s; if (*s == '\0' || *s == '#' || *s == '\n') continue; dev[0] = dir[0] = type[0] = opt[0] = '\0'; sscanf(s, "%511s %511s %127s %255s", dev, dir, type, opt); fix_fstab_name(dev); fix_fstab_name(dir); fix_fstab_name(type); fix_fstab_name(opt); if ( type[0] == '\0' || !strcmp(type, "devpts") || !strcmp(type, "swap") || !strcmp(type, "proc") || !strcmp(type, "sysfs") || !strcmp(type, "usbdevfs") || !strcmp(type, "usbfs") || !strcmp(type, "ignore") ) continue; gkrellm_fs_add_to_fstab_list(dir, dev, type, opt); } fclose(f); }static voidgetmntent_fallback(gchar *dir, gint dirsize, gchar *dev) { FILE *f; struct mntent *mnt; if ((f = setmntent(_PATH_MOUNTED, "r")) == NULL) return; while ((mnt = getmntent(f)) != NULL) { if (!strcmp(dev, mnt->mnt_fsname)) { snprintf(dir, dirsize, "%s", mnt->mnt_dir); break; } } endmntent(f); }voidgkrellm_sys_fs_get_mounts_list(void) { FILE *f; gchar *s, buf[512], dev[256], dir[256], type[64]; if ((f = fopen(PROC_MOUNTS_FILE, "r")) == NULL) return; while (fgets(buf, sizeof(buf), f)) { sscanf(buf, "%255s %255s %63s", dev, dir, type); if ( !strcmp(type, "devpts") || !strcmp(type, "proc") || !strcmp(type, "usbdevfs") || !strcmp(type, "usbfs") || !strcmp(type, "sysfs") ) continue; /* Strip trailing / from the directory. */ s = strrchr(dir, (int) '/'); if (s && s != dir && *(s+1) == '\0') *s = '\0'; if (dir[0] == '.') getmntent_fallback(dir, sizeof(dir), dev); gkrellm_fs_add_to_mounts_list(dir, dev, type); } fclose(f); }voidgkrellm_sys_fs_get_fsusage(gpointer fs, gchar *dir) { struct statfs st; if (!statfs(dir, &st)) gkrellm_fs_assign_fsusage_data(fs, (glong) st.f_blocks, (glong) st.f_bavail, (glong) st.f_bfree, (glong) st.f_bsize); else gkrellm_fs_assign_fsusage_data(fs, 0, 0, 0, 0); }static voideject_linux_cdrom(gchar *device) {#if defined(CDROMEJECT) gint d; if ((d = open(device, O_RDONLY|O_NONBLOCK)) >= 0) { ioctl(d, CDROMEJECT); close(d); }#endif }gbooleangkrellm_sys_fs_init(void) { gchar *eject_command = NULL, *close_command = NULL;#if defined(WEXITSTATUS) gint n; n = system("eject -d > /dev/null 2>&1"); if (WEXITSTATUS(n) == 0) { eject_command = "eject %s"; close_command = "eject -t %s"; }#endif gkrellm_fs_setup_eject(eject_command, close_command, eject_linux_cdrom, NULL); return TRUE; }/* ===================================================================== *//* Battery monitor interface *//* ---------------------------- *//* ACPI battery interface */#define ACPI_BATTERY_DIR "/proc/acpi/battery/"#define ACPI_AC_ADAPTOR_DIR "/proc/acpi/ac_adapter/"typedef struct { gint id; gchar *info, *state; gint full_cap; gboolean got_full_cap, full_cap_bug; } BatteryFile;static gchar *acpi_ac_state_file;static GList *acpi_battery_list;#if !defined(F_OK)#define F_OK 0#endifstatic gchar *get_acpi_battery_file(gchar *dir, gchar *subdir, gchar *name) { gchar *path; /* dir is expected to have trailing '/' */ path = g_strconcat(dir, subdir, "/", name, NULL); if (!access(path, F_OK)) return path; g_free(path); return NULL; }static gbooleansetup_acpi_battery(gchar *bat) { BatteryFile *bf; gchar *info; static gint id; info = g_strconcat(ACPI_BATTERY_DIR, bat, "/info", NULL); if (_GK.debug_level & DEBUG_BATTERY) printf("setup_acpi_battery: %s\n", info); if (!access(info, F_OK)) { bf = g_new0(BatteryFile, 1); bf->id = id++; bf->info = info; bf->state = get_acpi_battery_file(ACPI_BATTERY_DIR, bat, "state"); if (!bf->state) bf->state = get_acpi_battery_file(ACPI_BATTERY_DIR, bat, "status"); acpi_battery_list = g_list_append(acpi_battery_list, bf); if (_GK.debug_level & DEBUG_BATTERY) printf("setup_acpi_battery: %s\n", bf->state ? bf->state : "no state"); return TRUE; } g_free(info); return FALSE; }static gbooleansetup_ac_adapter(gchar **state, gchar *ac) { gchar *path; path = get_acpi_battery_file(ACPI_AC_ADAPTOR_DIR, ac, "state"); if (!path) path = get_acpi_battery_file(ACPI_AC_ADAPTOR_DIR, ac, "status"); *state = path; if (_GK.debug_level & DEBUG_BATTERY) printf("setup_ac_adaptor: %s\n", path ? path : "no state"); return path ? TRUE : FALSE; }static voidacpi_setup(void) { DIR *d; struct dirent *de; if ((d = opendir(ACPI_BATTERY_DIR)) == NULL) return; while ((de = readdir(d)) != NULL) { if ( strcmp(de->d_name, ".") && strcmp(de->d_name, "..") ) setup_acpi_battery(de->d_name); } closedir(d); if (!acpi_battery_list) return; if ((d = opendir(ACPI_AC_ADAPTOR_DIR)) != NULL) { while ((de = readdir(d)) != NULL) { if ( strcmp(de->d_name, ".") && strcmp(de->d_name, "..") && setup_ac_adapter(&acpi_ac_state_file, de->d_name) ) break; } closedir(d); } }static gbooleanfgets_lower_case(gchar *buf, gint len, FILE *f) { guchar *s; if (!fgets(buf, len, f)) return FALSE; s = (guchar *) buf; if (isupper(*s)) while (*s) { if (isupper(*s)) *s = tolower(*s); ++s; } return TRUE; }static gbooleanacpi_battery_data(BatteryFile *bf) { FILE *f; gchar buf[128], s1[32]; gboolean on_line, charging, available, have_charging_state; gint percent = 0, time_left = -1; gint cur_cap = 0, cur_rate = 0; extern gint gkrellm_battery_full_cap_fallback(void); if (!bf->got_full_cap) /* get battery capacity */ { if (_GK.debug_level & DEBUG_BATTERY) printf("getting full capacity: %s\n", bf->info); if ((f = fopen(bf->info, "r")) == NULL) return FALSE; bf->got_full_cap = TRUE; while (fgets_lower_case(buf, sizeof(buf), f)) { /* present: {yes|no} | design capacity: 53280 mWh | last full capacity: 51282 mWh | battery technology: rechargeable | design voltage: 14800 mV | design capacity warning: 5120 mWh | design capacity low: 0 mWh | capacity granularity 1: 1480 mWh
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -