a4105ac229cb3d86f6e8ed742cf84b85bb396993
[monky] / src / diskio.c
1 /*
2  * Conky, a system monitor, based on torsmo
3  *
4  * Any original torsmo code is licensed under the BSD license
5  *
6  * All code written since the fork of torsmo is licensed under the GPL
7  *
8  * Please see COPYING for details
9  *
10  * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
11  * Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al.
12  * (see AUTHORS)
13  * All rights reserved.
14  *
15  * This program is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation, either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  * You should have received a copy of the GNU General Public License
25  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26  *
27  *  $Id$
28  */
29
30 #include "conky.h"
31 #include <limits.h>
32 #include <stdio.h>
33
34 static struct diskio_stat diskio_stats_[MAX_DISKIO_STATS];
35 struct diskio_stat *diskio_stats = diskio_stats_;
36
37 void clear_diskio_stats(void)
38 {
39         unsigned i;
40         for(i = 0; i < MAX_DISKIO_STATS; i++) {
41                 if (diskio_stats[i].dev) {
42                         free(diskio_stats[i].dev);
43                         diskio_stats[i].dev = 0;
44                 }
45         }
46 }
47
48 struct diskio_stat *prepare_diskio_stat(const char *s)
49 {
50         struct diskio_stat *new = 0;
51         unsigned i;
52         FILE *fp;
53         int found = 0;
54         char device[text_buffer_size], fbuf[text_buffer_size];
55         static int rep = 0;
56         /* lookup existing or get new */
57         for (i = 0; i < MAX_DISKIO_STATS; i++) {
58                 if (diskio_stats[i].dev) {
59                         if (strcmp(diskio_stats[i].dev, s) == 0) {
60                                 return &diskio_stats[i];
61                         }
62                 } else {
63                         new = &diskio_stats[i];
64                         break;
65                 }
66         }
67         /* new dev */
68         if (!new) {
69                 ERR("too many diskio stats");
70                 return 0;
71         }
72         if (new->dev) {
73                 free(new->dev);
74                 new->dev = 0;
75         }
76         if (strncmp(s, "/dev/", 5) == 0) {
77                 // supplied a /dev/device arg, so cut off the /dev part
78                 new->dev = strndup(s + 5, text_buffer_size);
79         } else {
80                 new->dev = strndup(s, text_buffer_size);
81         }
82         /*
83          * check that device actually exists
84          */
85         
86         if (!(fp = open_file("/proc/diskstats", &rep))) {
87                 ERR("cannot read from /proc/diskstats");
88                 return 0;
89         }
90
91         while (!feof(fp)) {
92                 fgets(fbuf, text_buffer_size, fp);
93                 if (sscanf(fbuf, "%*u %*u %255s %*u %*u %*u %*u %*u %*u %*u", device)) {
94                         // check for device match
95                         if (strncmp(new->dev, device, 256) == 0) {
96                                 found = 1;
97                                 break;
98                         }
99                 }
100         }
101         fclose(fp);
102         fp = 0;
103         if (!found) {
104                 ERR("diskio device '%s' does not exist", s);
105                 return 0;
106         }
107         new->current = 0;
108         new->current_read = 0;
109         new ->current_write = 0;
110         new->last = UINT_MAX;
111         new->last_read = UINT_MAX;
112         new->last_write = UINT_MAX;
113         return new;
114 }