File: proc.c

package info (click to toggle)
pd-cxc 0.5.2-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster
  • size: 500 kB
  • sloc: ansic: 3,528; makefile: 347
file content (229 lines) | stat: -rw-r--r-- 6,284 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/*
  cxc@web.fm, 200203
  interface to the linux proc filesystem
  TODO: stat, number of users, network stats (tx,rx,etc)
 */

#include "m_pd.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//#include <unistd.h>
// later for number of users
// #include <utmp.h>

/* support older Pd versions without sys_fopen(), sys_fclose(), and, sys_close() */
#if PD_MAJOR_VERSION == 0 && PD_MINOR_VERSION < 44
#define sys_fopen fopen
#define sys_fclose fclose
#define sys_close close
#endif

#ifndef SSIZE_MAX
#define SSIZE_MAX 255
#endif

#ifndef RAND_MAX
#define RAND_MAX 2147483647
#endif

#ifndef MAXOUTAT
#define MAXOUTAT 50
#endif

t_class *proc_class;

typedef struct proc
{
  t_object x_obj;
  // t_float  x_RM;
  t_atom   x_at[MAXOUTAT];
  int      x_atc;
} t_proc;

void proc_float(t_proc *x, t_floatarg f)
{
    post("cxc/proc.c: %f", f);
}

void proc_cpuinfo(t_proc *x)
{
  char name[255];        // filename
  char rest[255];        // string value
  t_float restf;         // float value
  char bla[1];
  FILE* fp;              // info file descriptor
  //  t_float val;
  int   ac;              // atom count
  t_atom* at = x->x_at;  // out atom
  int atc    = x->x_atc; // out atom count

  //name = "/proc/cpuinfo";
  sprintf(name,"%s","/proc/cpuinfo");
  //val   = 0;
  restf = 0;
  ac    = 0;
  
  fp = sys_fopen(name,"r");
  if (!fp) {
    post("cxc/proc.c: unable to open %s",name);
    return;
  }
  //*name = 0;
  while(!feof(fp))
    {
/*     fread(bla,1,1,fp); */
/*     post("cxc/proc.c: '%s'",bla); */
    //ac = fscanf(fp,"%s\t: %s",name,rest);
    ac = fscanf(fp,"%s\t: %f",name,&restf);
    // fscanf(fp,"%s\t%s %d",name,rest,&val);
    if((!strcmp("MHz",name) ||
	!strcmp("processor",name) ||
	!strcmp("bogomips",name)) &&
       ac != -1)
      {
	if(!strcmp("MHz",name)) {
	  //val = (t_float)sprintf("%f",rest);
	  SETFLOAT(at+atc,restf);
	  atc++;
	} else if (!strcmp("processor",name)) {
	  SETFLOAT(at+atc,restf);
	  atc++;
	} else if (!strcmp("bogomips",name)) {
	  SETFLOAT(at+atc,restf);
	  atc++;
	}
#ifdef DEBUG
	post("cxc/proc.c: count %d, '%s' -> '%f'",ac,name,restf);
#endif
      }
    }
 outlet_anything(x->x_obj.ob_outlet, gensym("cpuinfo"),atc,at);
}

/////////////////////////////////////////////////////////////////
// more generic proc function: file to open is the message itself
void proc_proc(t_proc *x, t_symbol *s)
{
  char name[255];        // filename
  char rest[255];        // string value
  t_float restf;         // float value
  t_float restg;         // another float, needing more etc
  t_float resth;         // another float, needing more etc
                         // unsmart, convert the whole line
                         // into an atom vector or something ...
  int a,b,c;             // few helper ints for scanf
  char bla[1];
  FILE* fp;              // info file descriptor
  //  t_float val;
  int   ac;              // atom count
  t_atom* at = x->x_at;  // out atom
  int atc    = x->x_atc; // out atom count
  
  //post("cxc/proc.c: %s",s->s_name);

  //sprintf(name,"%s","/proc/cpuinfo");
  sprintf(name,"/proc/%s",s->s_name);
  //val   = 0;
  restf = 0;
  ac    = 0;
  
  fp = sys_fopen(name,"r");
  if (!fp) {
    post("cxc/proc.c: unable to open %s",name);
    return;
  }
  //*name = 0;
  while(!feof(fp)) {
    /*     fread(bla,1,1,fp); */
    /*     post("cxc/proc.c: '%s'",bla); */
    //ac = fscanf(fp,"%s\t: %s",name,rest);
//    ac = fscanf(fp,"%s\t: %f",name,&restf);
    // fscanf(fp,"%s\t%s %d",name,rest,&val);

    //////////////////////////////////////////////////
    // cpuinfo (rel. compl. parse)
    if(!strcmp("cpuinfo",s->s_name)) {
      ac = fscanf(fp,"%s\t: %f",name,&restf);

#ifdef DEBUG
      if((!strcmp("MHz",name) ||
	  !strcmp("processor",name) ||
	  !strcmp("bogomips",name)) &&
	 ac != -1) {
	post("cxc/proc.c: count %d, '%s' -> '%f'",ac,name,restf);
      }
#endif

      if(!strcmp("MHz",name)) {
	//val = (t_float)sprintf("%f",rest);
	SETFLOAT(at+atc,restf);
	atc++;
      } else if (!strcmp("processor",name)) {
	SETFLOAT(at+atc,restf);
	atc++;
      } else if (!strcmp("bogomips",name)) {
	SETFLOAT(at+atc,restf);
	atc++;
      }
      //////////////////////////////////////////////////
      // uptime (easy, just two floats ...
    } else if (!strcmp("uptime",s->s_name)) {
      ac = fscanf(fp,"%f %f",&restf,&restg);
      SETFLOAT(at+atc,restf); atc++;
      SETFLOAT(at+atc,restg); atc++;
      // why break here?
      break;
      //////////////////////////////////////////////////
      // loadavg
    } else if (!strcmp("loadavg",s->s_name)) {
      ac = fscanf(fp,"%f %f %f %d/%d %d",&restf,&restg,&resth,&a,&b,&c);
      SETFLOAT(at+atc,restf); atc++;
      SETFLOAT(at+atc,restg); atc++;
      SETFLOAT(at+atc,resth); atc++;
      SETFLOAT(at+atc,(t_float)a); atc++;
      SETFLOAT(at+atc,(t_float)b); atc++;
      SETFLOAT(at+atc,(t_float)c); atc++;
      // why break here?
      break;
      //////////////////////////////////////////////////
      // version (linux version)
    } else if (!strcmp("version",s->s_name)) {
      ac = fscanf(fp,"%s %s %d.%d.%d *",name,rest,&a,&b,&c);
      SETFLOAT(at+atc,a); atc++;
      SETFLOAT(at+atc,b); atc++;
      SETFLOAT(at+atc,c); atc++;
      // why break here?
      break;
/*     } else if (!strcmp("stat",s->s_name)) { */
/*       break; */
    } else {
      post("cxc/proc.c: %s not yet implemented",s->s_name);
      break;
    }
  }
 fclose(fp);
 outlet_anything(x->x_obj.ob_outlet, gensym(s->s_name),atc,at);
}

void *proc_new(void)
{
    t_proc *x = (t_proc *)pd_new(proc_class);
    x->x_atc = 0;
    outlet_new(&x->x_obj, &s_anything);
    return (void *)x;
}

void proc_setup(void)
{
  // post("proc_setup");
    proc_class = class_new(gensym("proc"), (t_newmethod)proc_new, 0,
    	sizeof(t_proc), 0, 0);
    class_addmethod(proc_class, (t_method)proc_cpuinfo, gensym("cpuinfo"), 0);
    class_addmethod(proc_class, (t_method)proc_proc,    gensym("proc"),    A_SYMBOL);
    //class_addmethod(proc_class, (t_method)proc_RAND_MAX, gensym("RAND_MAX"), 0);
    //class_addmethod(proc_class, (t_method)proc_getenv, gensym("getenv"), A_SYMBOL);
    //class_addmethod(proc_class, (t_method)proc_setenv, gensym("setenv"), A_SYMBOL, A_SYMBOL);
    class_addfloat(proc_class, proc_float);
}