aboutsummaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/proc.c b/proc.c
new file mode 100644
index 0000000..22cd23a
--- /dev/null
+++ b/proc.c
@@ -0,0 +1,223 @@
+/*
+ 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>
+
+#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 = 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 = 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);
+ class_sethelpsymbol(proc_class, gensym("cxc/proc.pd"));
+}
+