/alps/fastwriter

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/fastwriter
1 by Suren A. Chilingaryan
Initial release
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <sys/types.h>
4
#include <sys/stat.h>
5
#include <fcntl.h>
6
#include <unistd.h>
7
#include <string.h>
8
#include <strings.h>
9
#include <errno.h>
10
11
#define MEMINFO_FILE "/proc/meminfo"
12
#define MTAB_FILE "/etc/mtab"
13
14
#define BAD_OPEN_MESSAGE					\
15
"Error: /proc must be mounted\n"				\
16
"  To mount /proc at boot you need an /etc/fstab line like:\n"	\
17
"      /proc   /proc   proc    defaults\n"			\
18
"  In the meantime, run \"mount /proc /proc -t proc\"\n"
19
20
/* This macro opens filename only if necessary and seeks to 0 so
21
 * that successive calls to the functions are more efficient.
22
 * It also reads the current contents of the file into the global buf.
23
 */
24
#define FILE_TO_BUF(filename) do{				\
25
    static int fd, local_n;					\
26
    if ((fd = open(filename, O_RDONLY)) == -1) {		\
27
	fputs(BAD_OPEN_MESSAGE, stderr);			\
28
	fflush(NULL);						\
16 by Suren A. Chilingaryan
RPM support
29
	return -102;						\
1 by Suren A. Chilingaryan
Initial release
30
    }								\
31
    lseek(fd, 0L, SEEK_SET);					\
32
    if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) {	\
33
	perror(filename);					\
34
	fflush(NULL);						\
16 by Suren A. Chilingaryan
RPM support
35
	return -103;						\
1 by Suren A. Chilingaryan
Initial release
36
    }								\
37
    buf[local_n] = '\0';					\
38
    close(fd);							\
39
}while(0)
40
41
42
typedef struct mem_table_struct {
43
  const char *name;     /* memory type name */
44
  unsigned long *slot; /* slot in return struct */
45
} mem_table_struct;
46
47
static int compare_mem_table_structs(const void *a, const void *b){
48
  return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name);
49
}
50
5 by Suren A. Chilingaryan
Properly detect /dev/null as raw device and do not set DIRECT flag on raw devices
51
size_t fastwriter_get_free_memory(void){
1 by Suren A. Chilingaryan
Initial release
52
  char buf[4096];
53
  unsigned long kb_main_buffers, kb_main_cached, kb_main_free;
54
  char namebuf[16]; /* big enough to hold any row name */
55
  mem_table_struct findme = { namebuf, NULL};
56
  mem_table_struct *found;
57
  char *head;
58
  char *tail;
59
60
  const mem_table_struct mem_table[] = {
61
    {"Buffers",      &kb_main_buffers}, // important
62
    {"Cached",       &kb_main_cached},  // important
63
    {"MemFree",      &kb_main_free},    // important
64
  };
65
  const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct);
66
67
  FILE_TO_BUF(MEMINFO_FILE);
68
69
  head = buf;
70
  for(;;){
71
    tail = strchr(head, ':');
72
    if(!tail) break;
73
    *tail = '\0';
74
    if(strlen(head) >= sizeof(namebuf)){
75
      head = tail+1;
76
      goto nextline;
77
    }
78
    strcpy(namebuf,head);
79
    found = bsearch(&findme, mem_table, mem_table_count,
80
        sizeof(mem_table_struct), compare_mem_table_structs
81
    );
82
    head = tail+1;
83
    if(!found) goto nextline;
84
    *(found->slot) = strtoul(head,&tail,10);
85
nextline:
86
    tail = strchr(head, '\n');
87
    if(!tail) break;
88
    head = tail+1;
89
  }
90
  
91
  return (kb_main_buffers + kb_main_cached + kb_main_free) * 1024;
92
}
93
94
5 by Suren A. Chilingaryan
Properly detect /dev/null as raw device and do not set DIRECT flag on raw devices
95
int fastwriter_get_file_fs(const char *fname, size_t size, char *fs) {
1 by Suren A. Chilingaryan
Initial release
96
  int err = 0;
97
  char buf[4096];
98
  char *fn;
99
100
  char *head;
101
  char *tail;
102
103
  size_t len, max = 0;
104
  struct stat st;
105
  
106
  if ((!fname)||(!fs)||(size < 3)) return EINVAL;
107
  
108
  if (*fname == '/') {
109
    fn = (char*)fname;
110
  } else {
111
    if (!getcwd(buf, 4095)) return errno;
112
    fn = malloc(strlen(fname) + strlen(buf) + 2);
113
    if (!fn) return ENOMEM;
114
    sprintf(fn, "%s/%s", buf, fname);
115
  }
116
  
117
  if (!stat(fn, &st)) {
5 by Suren A. Chilingaryan
Properly detect /dev/null as raw device and do not set DIRECT flag on raw devices
118
    if (!S_ISREG(st.st_mode)) {
1 by Suren A. Chilingaryan
Initial release
119
	strcpy(fs, "raw");
120
	goto clean;
121
    }
122
  }
123
  
124
  FILE_TO_BUF(MTAB_FILE);
125
126
  head = buf;
127
  for(;;){
128
    head = strchr(head, ' ');
129
    if(!head) break;
130
131
    head += 1;
132
    tail = strchr(head, ' ');
133
    if(!tail) break;
134
    
135
    *tail = '\0';
136
137
    len = strlen(head);
138
    if((len <= max)||(strncmp(head, fn, len))) {
139
      head = tail+1;
140
      goto nextline;
141
    }
142
    
143
    head = tail + 1;
144
    tail = strchr(head, ' ');
145
    if(!tail) break;
146
147
    *tail = '\0';
148
149
    if (!strncasecmp(head,"root",4)) {
150
	head = tail+1;
151
	goto nextline;
152
    }
153
    
154
    max = len;
155
156
    if (strlen(head) >= size) err = EFAULT;
157
    else {
158
	err = 0;
159
	strcpy(fs, head);
160
    }
161
    
162
    head = tail+1;
163
nextline:
164
    tail = strchr(head, '\n');
165
    if(!tail) break;
166
    head = tail+1;
167
  }
168
169
clean:  
170
  if (fn != fname) free(fn);
171
172
  return err;
173
}