123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #include "pointset.h"
- #include <cassert>
- // for subprocesses
- #include <cstdlib>
- #include <unistd.h>
- #include <sys/wait.h>
- #include <fcntl.h>
- // extern "C" {
- // #include "discr_calc/dem_discr.h"
- // }
- pointset::pointset(int dim, int npoints) : dim(dim), npoints(npoints) {
- assert(dim > 0);
- assert(npoints > 0);
- data = new double*[npoints];
- for(int y = 0; y < npoints; y++)
- data[y] = new double[dim];
- }
- pointset::~pointset() {
- for(int y = 0; y < npoints; y++)
- delete[] data[y];
- delete[] data;
- }
- double* pointset::point(int i) {
- assert(0 <= i && i < npoints);
- return data[i];
- }
- double pointset::discrepancy() {
- // computing by direct call
- // (it does not seem to work several times... -> have a look on global variables)
- // double lower;
- // return oydiscr(data, dim, npoints, &lower);
- // computing by launching discr_calc/dem_discr as a child process
- double result;
- int status = -1, pid;
- int pipefd_in[2], pipefd_out[2], null; // in/out : from parent's point of view
- if(pipe(pipefd_in) || pipe(pipefd_out)) {
- perror("pipe()");
- exit(1);
- }
- switch(pid = fork()) {
- case -1: // error
- perror("fork()");
- exit(1);
- case 0: // child
- close(pipefd_in[0]);
- close(pipefd_out[1]);
- // replace stdin
- dup2(pipefd_out[0], 0);
- // replace stdout
- dup2(pipefd_in[1], 1);
- // replace stderr :P
- null = open("/dev/null", O_RDONLY);
- dup2(null, 2);
- close(null);
- // launch process !
- char dim_str[20], npoints_str[20];
- sprintf(dim_str, "%d", dim);
- sprintf(npoints_str, "%d", npoints);
- execl("discr_calc/dem_discr", "dem_discr", dim_str, npoints_str, (char*)NULL);
- // if we get to this line, the command has failed
- perror("execl()");
- exit(1);
- default: // father
- close(pipefd_in[1]);
- close(pipefd_out[0]);
- // write data into pipefd_in
- FILE *f = fdopen(pipefd_out[1], "w");
- if(f == NULL) {
- perror("fdopen()");
- exit(1);
- }
- dump(f);
- fclose(f);
- close(pipefd_out[1]);
- // read result
- f = fdopen(pipefd_in[0], "r");
- if(f == NULL) {
- perror("fdopen()");
- exit(1);
- }
- if(fscanf(f, "%lf", &result) != 1) {
- perror("fscanf()");
- exit(1);
- }
- fclose(f);
- close(pipefd_in[0]);
- // wait for child to terminate
- waitpid(pid, &status, 0);
- if(status != 0) {
- fprintf(stderr, "child process terminate with status %d\n", status);
- exit(1);
- }
- }
- return result;
- }
- void pointset::dump(FILE* f) {
- for(int y = 0; y < npoints; y++)
- for(int x = 0; x < dim; x++)
- fprintf(f, "%lf%c", data[y][x], (x==dim-1) ? '\n' : '\t');
- }
|