diff options
author | Richard Knight <q@1bpm.net> | 2021-08-16 02:56:49 +0100 |
---|---|---|
committer | Richard Knight <q@1bpm.net> | 2021-08-16 02:56:49 +0100 |
commit | 2e854bcb40d535957b589ad02e3f280e00b47865 (patch) | |
tree | 8fe2abbc86130af2d2ff74bbce943a68f2ec4c6d /src | |
download | csound-datacore-2e854bcb40d535957b589ad02e3f280e00b47865.tar.gz csound-datacore-2e854bcb40d535957b589ad02e3f280e00b47865.tar.bz2 csound-datacore-2e854bcb40d535957b589ad02e3f280e00b47865.zip |
pre strip down
Diffstat (limited to 'src')
-rw-r--r-- | src/maketable.cpp | 40 | ||||
-rw-r--r-- | src/opcodes.cpp | 770 | ||||
-rw-r--r-- | src/pmparser.cpp | 196 |
3 files changed, 1006 insertions, 0 deletions
diff --git a/src/maketable.cpp b/src/maketable.cpp new file mode 100644 index 0000000..511f838 --- /dev/null +++ b/src/maketable.cpp @@ -0,0 +1,40 @@ +#include <plugin.h> +#include "maketable.hpp" + +int maketable(csnd::Csound* csound, int size, FUNC **tablep, int channels) { + EVTBLK* evt; + MYFLT* pf; + + evt = (EVTBLK*) csound->malloc(sizeof(EVTBLK)); + evt->opcod = 'f'; + evt->strarg = NULL; + evt->pcnt = 5; + pf = &evt->p[0]; + pf[0] = FL(0); + pf[1] = FL(0); + pf[2] = evt->p2orig = FL(0); + pf[3] = evt->p3orig = -size; + pf[4] = FL(2); // gen number + pf[5] = FL(0); + int n = csound->get_csound()->hfgens(csound->get_csound(), tablep, evt, 1); + csound->free(evt); + if (UNLIKELY(n != 0)) { + return NOTOK; + } + + FUNC* table = *tablep; + + table->soundend = size; + table->nchanls = channels; + table->flenfrms = size; + table->gen01args.sample_rate = csound->sr(); + table->cpscvt = 0; + table->cvtbas = LOFACT; // * csound->sr() * csound->get_csound()->onedsr; + table->loopmode1 = 0; + table->loopmode2 = 0; + table->begin1 = 0; + table->end1 = size; + table->begin2 = 0; + table->end2 = size; + return OK; +}
\ No newline at end of file diff --git a/src/opcodes.cpp b/src/opcodes.cpp new file mode 100644 index 0000000..4e1265c --- /dev/null +++ b/src/opcodes.cpp @@ -0,0 +1,770 @@ +#include "pmparser.h" +#include "maketable.hpp" +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <limits.h> +#include <plugin.h> +#include <functional> +#include <vector> +#include <sys/mman.h> + +#ifdef USE_X11 +#include <X11/Xlib.h> +#include <X11/X.h> +#include <X11/Xutil.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> + +#define PROC_DIR "/proc/" + + + +struct mempsname : csnd::Plugin<1, 1> { + static constexpr char const *otypes = "S"; + static constexpr char const *itypes = "i"; + int init() { + int pid = inargs[0]; + char* path = (char*) csound->malloc(sizeof(char) * PATH_MAX); + sprintf(path, "%s%d/comm", PROC_DIR, pid); + + FILE* f = fopen(path, "r"); + char* buffer = (char*) csound->malloc(sizeof(char) * 1024); + size_t size = fread(buffer, sizeof(char), 1024, f); + + + fclose(f); + STRINGDAT &opath = outargs.str_data(0); + opath.size = strlen(buffer); + opath.data = buffer; + + csound->free(path); + return OK; + } +}; + + +struct memps : csnd::Plugin<1, 0> { + static constexpr char const *otypes = "i[]"; + static constexpr char const *itypes = ""; + + int init() { + + int* processes = (int*) csound->malloc(sizeof(int) * 1000); + int processnum = 0; + if (!getPIDs(processes, &processnum)) { + return csound->init_error("Cannot read proc directory"); + } + + csnd::Vector<MYFLT> &out = outargs.vector_data<MYFLT>(0); + out.init(csound, processnum); + + for (int i = 0; i < processnum; i++) { + out[i] = (MYFLT) processes[i]; + } + csound->free(processes); + return OK; + } + + bool isNumeric(char* input) { + char* p; + strtol(input, &p, 10); + return *p == 0; + } + + bool getPIDs(int* processes, int* processnum) { + uid_t thisUser = getuid(); + DIR* dir = opendir(PROC_DIR); + + struct dirent* de = NULL; + if (dir == NULL) { + //return false; // TODO breaks csound, why?? + } + char* path = (char*) csound->malloc(sizeof(char) * PATH_MAX); + while (NULL != (de = readdir(dir))) { + if (de->d_type == DT_DIR) { + if (isNumeric(de->d_name)) { + + struct stat fileInfo; + strcpy(path, PROC_DIR); + strcat(path, de->d_name); + if (stat(path, &fileInfo) == 0) { + if (fileInfo.st_uid == thisUser) { + (*processnum)++; + *processes = (int)atoi(de->d_name); + processes++; + } + } + } + } + } + csound->free(path); + return true; + } + +}; + + +#ifdef USE_X11 +struct winson : csnd::Plugin<1, 1> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "i"; + Display* display; + Window root; + int width; + int height; + MYFLT* buffer; + int buffer_size; + int buffer_read_position; + int buffer_write_position; + + int init() { + display = XOpenDisplay(NULL); + //root = DefaultRootWindow(display); + root = 0x2200004; + XWindowAttributes gwa; + XGetWindowAttributes(display, root, &gwa); + + width = gwa.width; + height = gwa.height; + buffer_size = width * height; + buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * buffer_size); + buffer_read_position = 0; + buffer_write_position = 0; + refill_buffer(); + return OK; + } + + int refill_buffer() { + buffer_write_position = 0; + XImage* image = XGetImage(display, root, 0, 0, width, height, AllPlanes, ZPixmap); + for (int x = 0; x < width; x++) { + for (int y=0; y < height; y++) { + buffer[buffer_write_position] = ((MYFLT) XGetPixel(image,x,y)) / 16777215; + buffer_write_position++; + } + } + return OK; + } + + int aperf() { + for (int i = 0; i < nsmps; i++) { + outargs(0)[i] = buffer[buffer_read_position]; + if (LIKELY(buffer_read_position + 1 < buffer_size)) { + buffer_read_position++; + } else { + refill_buffer(); + buffer_read_position = 0; + } + } + + return OK; + + } +}; +#endif + + +class MemLocation { +public: + unsigned long start; + unsigned long length; + unsigned long* content; // for mmap test.. + MemLocation(unsigned long start, unsigned long length) { + this->start = start; + this->length = length; + } +}; + + +class MemParser { +private: + csnd::Csound* csound; + int fd_mem; + int pid; + bool skip_zero; + int buffer_write_position; + std::vector<MemLocation*> locations; + + /* + void iterate_memory(std::function<void (unsigned long, unsigned long)> func) { + procmaps_iterator* maps = pmparser_parse(csound, pid); + procmaps_struct* maps_tmp = NULL; + while ((maps_tmp = pmparser_next(maps)) != NULL) { + if (maps_tmp->is_r && maps_tmp->is_w) { + func((unsigned long) maps_tmp->addr_start, (unsigned long) maps_tmp->length); + } + } + pmparser_free(csound, maps); + } + */ + + bool parsed; + void parse_memory() { + locations.clear(); + procmaps_iterator* maps = pmparser_parse(csound, pid); + procmaps_struct* maps_tmp = NULL; + while ((maps_tmp = pmparser_next(maps)) != NULL) { + if (maps_tmp->is_r && maps_tmp->is_w) { + locations.push_back( + new MemLocation( + (unsigned long) maps_tmp->addr_start, + (unsigned long) maps_tmp->length + ) + ); + std::cout << (unsigned long) maps_tmp->addr_start << "-" << (unsigned long) maps_tmp->length << "\n"; + } + } + pmparser_free(csound, maps); + parsed = true; + } + + // this idea ends up with more mem locations than expected, whytf? vector malloc not right with csound??? + void iterate_memory_step(std::function<bool (long, MYFLT)> func) { + if (!parsed) parse_memory(); + long i; + MYFLT val; int x = 0; + unsigned long* lbuffer = NULL; + std::cout << "sz=" << locations.size() << "\n"; + for (auto &location : locations) { + lbuffer = (unsigned long*) csound->malloc(sizeof(unsigned long) * location->length); + lseek(fd_mem, location->start, SEEK_SET); + read(fd_mem, lbuffer, location->length); + std::cout << (unsigned long) location->start << "-" << (unsigned long) location->length << "\n"; + for (i = 0; i < location->length; i++) { + val = ((MYFLT) lbuffer[i]) / ULONG_MAX; + if (!skip_zero || (skip_zero && val > 0)) { + if (!(func(i, val))) goto complete; + } + + } + + if (lbuffer != NULL) { + csound->free(lbuffer); // causes segfault, WHY??????????? + lbuffer = NULL; + } + + } + complete: + if (lbuffer != NULL) { + csound->free(lbuffer); // causes segfault, WHY??????????? + lbuffer = NULL; + } + + } + + // func arguments: index and value ; return false to stop iteration, true to continue + void Xiterate_memory_step(std::function<bool (long, MYFLT)> func) { + MYFLT val; + unsigned long* lbuffer = NULL; + procmaps_iterator* maps = pmparser_parse(csound, pid); + procmaps_struct* maps_tmp = NULL; + while ((maps_tmp = pmparser_next(maps)) != NULL) { + if (maps_tmp->is_r && maps_tmp->is_w) { + unsigned long start = (unsigned long) maps_tmp->addr_start; + unsigned long length = (unsigned long) maps_tmp->length; + lbuffer = (unsigned long*) csound->malloc(sizeof(unsigned long) * length); + lseek(fd_mem, start, SEEK_SET); + read(fd_mem, lbuffer, length); + for (long i = 0; i < length; i++) { + val = ((MYFLT) lbuffer[i]) / ULONG_MAX; + if (!skip_zero || (skip_zero && val > 0)) { + if (!(func(i, val))) goto complete; + } + } + + if (lbuffer != NULL) { + //csound->free(lbuffer); // causes segfault, WHY??????????? + //lbuffer = NULL; + } + + } + } + complete: + if (lbuffer != NULL) { + csound->free(lbuffer); // causes segfault, WHY??????????? + lbuffer = NULL; + } + pmparser_free(csound, maps); + } + +public: + long total_size; + MYFLT* buffer; + int buffer_size; + + MemParser(csnd::Csound* csound, int pid, bool skip_zero) { + this->csound = csound; + this->skip_zero = skip_zero; + this->pid = pid; + parsed = false; + total_size = 0; + buffer = NULL; + buffer_size = 0; + buffer_write_position = 0; + char* mem_path = (char*) csound->malloc(sizeof(char) * 50); + sprintf(mem_path, "/proc/%d/mem", pid); + fd_mem = open(mem_path, O_RDWR); + csound->free(mem_path); + } + + ~MemParser() { + close(fd_mem); + if (buffer != NULL) { + csound->free(buffer); + } + } + + void allocate_buffer(int buffer_size) { + buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * buffer_size); + this->buffer_size = buffer_size; + } + + long get_size() { + total_size = 0; + iterate_memory_step( + [&](long index, MYFLT val) { + total_size ++; + return true; + } + ); + return total_size; + } + + + int fill_buffer(MYFLT offset) { + if (total_size == 0) { + total_size = get_size(); + } + buffer_write_position = 0; + if (offset > 1) offset = 1; + long offset_position = total_size * offset; + /*if (UNLIKELY(offset_position > total_size - (buffer_size + 1))) { + offset_position = total_size - (buffer_size + 1); + }*/ + bool active; + + iterate_memory_step( + [&](long index, MYFLT val) { + if (index < offset_position) return true; + //std::cout << index << "-" << offset_position << "\n"; + buffer[buffer_write_position] = val; + if (buffer_write_position < buffer_size) { + buffer_write_position ++; + } else { + buffer_write_position = 0; + return false; + } + return true; + } + ); + } + + void fill_table(FUNC* table, long length) { + long write_index = 0; + bool active = true; + + iterate_memory_step( + [&](long index, MYFLT val) { + table->ftable[write_index] = val; + write_index ++; + return true; + } + ); + } + +}; + + +// ifn mem2tab ipid, iskipzero=0 +struct mem2tab : csnd::Plugin<1, 2> { + static constexpr char const *otypes = "i"; + static constexpr char const *itypes = "io"; + + int init() { + FUNC *table; + MemParser* mp = new MemParser(csound, (int)inargs[0], (inargs[1] > 0)); + + long length = mp->get_size(); + if ((maketable(csound, (int)length, &table, 1)) != OK) { + return csound->init_error("Cannot create ftable"); + } + mp->fill_table(table, (int)length); + outargs[0] = table->fno; + return OK; + } +}; + + +// read memory from a given pid as audio +// aout memson ipid, koffset, kbuffer_readratio, ibuffersize=441000, iskipzero=0 +struct memson : csnd::Plugin<1, 5> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "ikkjo"; + MemParser* mp; + int buffer_read_position; + MYFLT last_offset; + + int init() { + mp = new MemParser(csound, (int)inargs[0], (inargs[4] > 0)); + mp->allocate_buffer((inargs[2] == -1)? 441000: (int) inargs[3]); + + buffer_read_position = 0; + last_offset = inargs[1]; + mp->fill_buffer(last_offset); + + return OK; + } + + int aperf() { + for (int i = 0; i < nsmps; i++) { + outargs(0)[i] = mp->buffer[buffer_read_position]; + if (LIKELY(buffer_read_position < mp->buffer_size*inargs[2])) { + buffer_read_position++; + } else { + buffer_read_position = 0; + } + } + if (inargs[1] != last_offset) { + last_offset = inargs[1]; + mp->fill_buffer(last_offset); + } + + return OK; + + } + + +}; + + + + + +typedef struct mmap { + unsigned long start; + unsigned long length; +} _mmap; + + +// read memory from a given pid as audio +// aout memson2 ipid, koffset, kbufsize [, iunsafe] +// where kbufsize is 0 to 1 and koffset is 0 to 1 +struct memson2 : csnd::Plugin<1, 4> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "ikkj"; + int pid; + int buffer_read_position; + int buffer_write_position; + int buffer_size; + int max_buffer_size; + unsigned long total_locations; + MYFLT* buffer; + MYFLT last_buffer_ratio; + MYFLT last_offset; + char* mem_path; + bool unsafe; + + int init() { + max_buffer_size = 441000; + buffer_size = (int) (inargs[2] * max_buffer_size); + last_buffer_ratio = inargs[2]; + last_offset = inargs[1]; + unsafe = (((int)inargs[3]) == 1); + csound->plugin_deinit(this); + pid = (int) inargs[0]; + buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * max_buffer_size); + mem_path = (char*) csound->malloc(sizeof(char) * 50); + sprintf(mem_path, "/proc/%d/mem", pid); + + buffer_read_position = 0; + buffer_write_position = 0; + total_locations = max_locations(); + refill_buffer(inargs[1], true); + + return OK; + } + + int deinit() { + csound->free(mem_path); + return OK; + } + + unsigned long max_locations() { + procmaps_iterator* maps = pmparser_parse(csound, pid); + int fd_mem = open(mem_path, O_RDWR); + unsigned long len = 0; + procmaps_struct* maps_tmp = NULL; + while ((maps_tmp = pmparser_next(maps)) != NULL) { + if (maps_tmp->is_r && maps_tmp->is_w) { + len += maps_tmp->length; + } + } + pmparser_free(csound, maps); + close(fd_mem); + return len; + } + + int read_mem(int fd_mem, unsigned long start, unsigned long length) { + length = length; // 4; // ?????????????????????????????????????????????????????? + // lbuffer as unsigned char + // https://unix.stackexchange.com/questions/6301/how-do-i-read-from-proc-pid-mem-under-linux + unsigned long* lbuffer = (unsigned long*) csound->malloc(sizeof(unsigned long) * length); + lseek(fd_mem, start, SEEK_SET); + read(fd_mem, lbuffer, length); + + int i; + for (i = 0; i < length; i++) { + //std::cout << "a " << buffer_write_position << "x " << buffer_size << "\n"; + MYFLT val = ((MYFLT)lbuffer[i]) / ULONG_MAX; + buffer[buffer_write_position] = val; + if (buffer_write_position + 1 < buffer_size) { + buffer_write_position++; + } else { + return 1; + } + } + return 0; + } + + + int refill_buffer(MYFLT offset, bool first) { + buffer_write_position = 0; + if (offset > 1) offset = 1; + long offset_position = total_locations * offset; + if (UNLIKELY(offset_position > total_locations - (buffer_size + 1))) { + offset_position = total_locations - (buffer_size + 1); + } + procmaps_iterator* maps = pmparser_parse(csound, pid); + + if (maps == NULL) { + //csound->message("cannot open maps"); + return NOTOK; //csound->perf_error("cannot open maps", this->insdshead); + } + + int fd_mem = open(mem_path, O_RDWR); + if (fd_mem == -1) { + //csound->message("cannot open memory"); + return NOTOK; + } + + long position = 0; + unsigned long aof = 0; + procmaps_struct* maps_tmp = NULL; + int res = 0; + while ((maps_tmp = pmparser_next(maps)) != NULL) { + if (maps_tmp->is_r && maps_tmp->is_w) { + if (position >= offset_position) { + aof = position - offset_position; // not quite right, length needs sorting + res = read_mem(fd_mem, ((unsigned long) maps_tmp->addr_start) + aof, (unsigned long) maps_tmp->length); + } + position += maps_tmp->length; + if (res == 1) { + break; + } + } + } + pmparser_free(csound, maps); + close(fd_mem); + return OK; + } + + int aperf() { + if (last_offset != inargs[1] || last_buffer_ratio != inargs[2]) { + last_offset = inargs[1]; + last_buffer_ratio = inargs[2]; + buffer_size = (int) (inargs[2] * max_buffer_size); + refill_buffer(inargs[1], false); + buffer_read_position = 0; + + } + for (int i = 0; i < nsmps; i++) { + outargs(0)[i] = buffer[buffer_read_position]; + if (LIKELY(buffer_read_position + 1 < buffer_size)) { + buffer_read_position++; + } else { + refill_buffer(inargs[1], false); + buffer_read_position = 0; + } + } + + return OK; + + } + + +}; + + + + + +// read memory from a given pid as audio +struct memson3 : csnd::Plugin<1, 3> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "ikk"; + int pid; + int buffer_read_position; + int buffer_write_position; + int buffer_size; + int max_buffer_size; + unsigned long total_locations; + MYFLT* buffer; + unsigned char* lbuffer; + MYFLT last_buffer_ratio; + MYFLT last_offset; + char* mem_path; + + int init() { + max_buffer_size = 441000; + buffer_size = (int) (inargs[2] * max_buffer_size); + last_buffer_ratio = inargs[2]; + last_offset = inargs[1]; + csound->plugin_deinit(this); + pid = (int) inargs[0]; + buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * max_buffer_size); + lbuffer = (unsigned char*) csound->malloc(sizeof(unsigned char) * max_buffer_size); + mem_path = (char*) csound->malloc(sizeof(char) * 50); + sprintf(mem_path, "/proc/%d/mem", pid); + + buffer_read_position = 0; + buffer_write_position = 0; + total_locations = max_locations(); + refill_buffer(inargs[1]); + + return OK; + } + + int deinit() { + csound->free(mem_path); + return OK; + } + + unsigned long max_locations() { + procmaps_iterator* maps = pmparser_parse(csound, pid); + int fd_mem = open(mem_path, O_RDWR); + unsigned long len = 0; + procmaps_struct* maps_tmp = NULL; + while ((maps_tmp = pmparser_next(maps)) != NULL) { + if (maps_tmp->is_r && maps_tmp->is_w) { + len += maps_tmp->length; + } + } + pmparser_free(csound, maps); + close(fd_mem); + return len; + } + + int read_mem(int fd_mem, unsigned long start, unsigned long length) { + length = length; // 4; // ?????????????????????????????????????????????????????? + // lbuffer as unsigned char + // https://unix.stackexchange.com/questions/6301/how-do-i-read-from-proc-pid-mem-under-linux + lseek(fd_mem, start, SEEK_SET); + read(fd_mem, lbuffer, length); + + int i; + for (i = 0; i < length; i++) { + //std::cout << "a " << buffer_write_position << "x " << buffer_size << "\n"; + MYFLT val = ((MYFLT)lbuffer[i]) / UCHAR_MAX; + buffer[buffer_write_position] = val; + if (buffer_write_position + 1 < buffer_size) { + buffer_write_position++; + } else { + return 1; + } + } + return 0; + } + + + int refill_buffer(MYFLT offset) { + buffer_write_position = 0; + if (offset > 1) offset = 1; + long offset_position = total_locations * offset; + if (UNLIKELY(offset_position > total_locations - (buffer_size + 1))) { + offset_position = total_locations - (buffer_size + 1); + } + procmaps_iterator* maps = pmparser_parse(csound, pid); + + if (maps == NULL) { + //csound->message("cannot open maps"); + return NOTOK; //csound->perf_error("cannot open maps", this->insdshead); + } + + int fd_mem = open(mem_path, O_RDWR); + if (fd_mem == -1) { + //csound->message("cannot open memory"); + return NOTOK; + } + + long position = 0; + unsigned long aof = 0; + procmaps_struct* maps_tmp = NULL; + int res = 0; + while ((maps_tmp = pmparser_next(maps)) != NULL) { + if (maps_tmp->is_r && maps_tmp->is_w) { + if (position >= offset_position) { + aof = position - offset_position; // not quite right, length needs sorting + res = read_mem(fd_mem, ((unsigned long) maps_tmp->addr_start) + aof, (unsigned long) maps_tmp->length); + } + position += maps_tmp->length; + if (res == 1) { + break; + } + } + } + pmparser_free(csound, maps); + close(fd_mem); + return OK; + } + + int aperf() { + if (last_offset != inargs[1] || last_buffer_ratio != inargs[2]) { + last_offset = inargs[1]; + last_buffer_ratio = inargs[2]; + buffer_size = (int) (inargs[2] * max_buffer_size); + refill_buffer(inargs[1]); + buffer_read_position = 0; + + } + for (int i = 0; i < nsmps; i++) { + outargs(0)[i] = buffer[buffer_read_position]; + if (LIKELY(buffer_read_position + 1 < buffer_size)) { + buffer_read_position++; + } else { + refill_buffer(inargs[1]); + buffer_read_position = 0; + } + } + + return OK; + + } + + +}; + + + +#include <modload.h> + +void csnd::on_load(csnd::Csound *csound) { + csnd::plugin<memson>(csound, "memson", csnd::thread::ia); + csnd::plugin<memson2>(csound, "memson2", csnd::thread::ia); + csnd::plugin<memson3>(csound, "memson3", csnd::thread::ia); + csnd::plugin<memps>(csound, "memps", csnd::thread::i); + csnd::plugin<mempsname>(csound, "mempsname", csnd::thread::i); + csnd::plugin<mem2tab>(csound, "mem2tab", csnd::thread::i); + + +#ifdef USE_X11 + csnd::plugin<winson>(csound, "winson", csnd::thread::ia); +#endif +} + diff --git a/src/pmparser.cpp b/src/pmparser.cpp new file mode 100644 index 0000000..e7be9ba --- /dev/null +++ b/src/pmparser.cpp @@ -0,0 +1,196 @@ +/* + @Author : ouadimjamal@gmail.com + @date : December 2015 + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. No representations are made about the suitability of this +software for any purpose. It is provided "as is" without express or +implied warranty. +*/ + +#include "pmparser.h" +#include <stdio.h> +#include <stdlib.h> +#include <plugin.h> + + + + +procmaps_iterator* pmparser_parse(csnd::Csound* csound, int pid){ + procmaps_iterator* maps_it = (procmaps_iterator*) csound->malloc(sizeof(procmaps_iterator)); + char maps_path[500]; + if(pid>=0 ){ + sprintf(maps_path,"/proc/%d/maps",pid); + }else{ + sprintf(maps_path,"/proc/self/maps"); + } + FILE* file=fopen(maps_path,"r"); + if(!file){ + fprintf(stderr,"pmparser : cannot open the memory maps, %s\n",strerror(errno)); + return NULL; + } + int ind=0;char buf[PROCMAPS_LINE_MAX_LENGTH]; + int c; + procmaps_struct* list_maps=NULL; + procmaps_struct* tmp; + procmaps_struct* current_node=list_maps; + char addr1[20],addr2[20], perm[8], offset[20], dev[10],inode[30],pathname[PATH_MAX]; + while( !feof(file) ){ + fgets(buf,PROCMAPS_LINE_MAX_LENGTH,file); + //allocate a node + tmp=(procmaps_struct*)csound->malloc(sizeof(procmaps_struct)); + //fill the node + _pmparser_split_line(buf,addr1,addr2,perm,offset, dev,inode,pathname); + //printf("#%s",buf); + //printf("%s-%s %s %s %s %s\t%s\n",addr1,addr2,perm,offset,dev,inode,pathname); + //addr_start & addr_end + unsigned long l_addr_start; + sscanf(addr1,"%lx",(long unsigned *)&tmp->addr_start ); + sscanf(addr2,"%lx",(long unsigned *)&tmp->addr_end ); + //size + tmp->length=(unsigned long)(tmp->addr_end-tmp->addr_start); + //perm + strcpy(tmp->perm,perm); + tmp->is_r=(perm[0]=='r'); + tmp->is_w=(perm[1]=='w'); + tmp->is_x=(perm[2]=='x'); + tmp->is_p=(perm[3]=='p'); + + //offset + sscanf(offset,"%lx",&tmp->offset ); + //device + strcpy(tmp->dev,dev); + //inode + tmp->inode=atoi(inode); + //pathname + strcpy(tmp->pathname,pathname); + tmp->next=NULL; + //attach the node + if(ind==0){ + list_maps=tmp; + list_maps->next=NULL; + current_node=list_maps; + } + current_node->next=tmp; + current_node=tmp; + ind++; + //printf("%s",buf); + } + + //close file + fclose(file); + + + //g_last_head=list_maps; + maps_it->head = list_maps; + maps_it->current = list_maps; + return maps_it; +} + + +procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it){ + if(p_procmaps_it->current == NULL) + return NULL; + procmaps_struct* p_current = p_procmaps_it->current; + p_procmaps_it->current = p_procmaps_it->current->next; + return p_current; + /* + if(g_current==NULL){ + g_current=g_last_head; + }else + g_current=g_current->next; + + return g_current; + */ +} + + + +void pmparser_free(csnd::Csound* csound, procmaps_iterator* p_procmaps_it){ + procmaps_struct* maps_list = p_procmaps_it->head; + if(maps_list==NULL) return ; + procmaps_struct* act=maps_list; + procmaps_struct* nxt=act->next; + while(act!=NULL){ + csound->free(act); + act=nxt; + if(nxt!=NULL) + nxt=nxt->next; + } + +} + + +void _pmparser_split_line( + char*buf,char*addr1,char*addr2, + char*perm,char* offset,char* device,char*inode, + char* pathname){ + // + int orig=0; + int i=0; + //addr1 + while(buf[i]!='-'){ + addr1[i-orig]=buf[i]; + i++; + } + addr1[i]='\0'; + i++; + //addr2 + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + addr2[i-orig]=buf[i]; + i++; + } + addr2[i-orig]='\0'; + + //perm + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + perm[i-orig]=buf[i]; + i++; + } + perm[i-orig]='\0'; + //offset + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + offset[i-orig]=buf[i]; + i++; + } + offset[i-orig]='\0'; + //dev + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + device[i-orig]=buf[i]; + i++; + } + device[i-orig]='\0'; + //inode + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' '){ + inode[i-orig]=buf[i]; + i++; + } + inode[i-orig]='\0'; + //pathname + pathname[0]='\0'; + while(buf[i]=='\t' || buf[i]==' ') + i++; + orig=i; + while(buf[i]!='\t' && buf[i]!=' ' && buf[i]!='\n'){ + pathname[i-orig]=buf[i]; + i++; + } + pathname[i-orig]='\0'; + +} |