?? slaveforward.next
字號:
//============================================================// COOOL version 1.1 --- Nov, 1995// Center for Wave Phenomena, Colorado School of Mines//============================================================//// This code is part of a preliminary release of COOOL (CWP// Object-Oriented Optimization Library) and associated class // libraries. //// The COOOL library is a free software. You can do anything you want// with it including make a fortune. However, neither the authors,// the Center for Wave Phenomena, nor anyone else you can think of// makes any guarantees about anything in this package or any aspect// of its functionality.//// Since you've got the source code you can also modify the// library to suit your own purposes. We would appreciate it // if the headers that identify the authors are kept in the // source code.// *****************************************************************// Modified from SlaveObjFcn by Martin Smith and Terri L. Fischer// H. Lydia Deng 03/13/94// *****************************************************************#ifndef _POSIX_SOURCE #define _POSIX_SOURCE #endif#ifdef KERNEL#undef KERNEL#endif#ifndef __STDC__#define __STDC__#endif#include <stdlib.h>#include <stdio.h>#include <math.h>#include <stream.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <sys/ioctl.h>#include <sys/termios.h>#include <unistd.h>#include <errno.h>#include <signal.h>#include <SlaveForward.hh>extern "C" { int unlink(const char*); int fork(); int dup2(int, int); int ioctl(int, int, ...);}static const char* myNameIs = "SlaveForward";my_read(int sd, char* buff, int n){ int bcount = 0; int bread = 0; while (bcount < n) { if ((bread = read(sd, buff, n-bcount)) > 0) { bcount += bread; //increment byte count buff += bread; // move buffer pointer for next read } if (bread <0) return(-1); // signal an error } return(bcount);}my_write(int sd, char* buff, int n){ int bcount = 0; int bwrite = 0; while (bcount < n) { if ((bwrite = write(sd, buff, n-bcount)) > 0) { bcount += bwrite; //increment byte count buff += bwrite; // move buffer pointer for next write } if (bwrite <0) return(-1); // signal an error } return(bcount);}const char* SlaveForward::className() const { return myNameIs;}List<double> SlaveForward::dataList(const Model<double>& p){ List<double> ldata; int n = p.modSize(); // send slave the first signal: flag for computing derivatives char lt[32]; linebuffer[0] = '\0'; sprintf(lt, "%d ", 0); strcat(linebuffer, lt); for(int i = 0; i < n; i++) { sprintf(lt, "%g ", p.elem(i)); strcat(linebuffer, lt); } strcat(linebuffer, "\n"); int nl = strlen(linebuffer); if ((my_write(master_fd, linebuffer, nl)) < nl) { cerr<<"There is not enough buffer space for the writing. \n"; exit(1); } if(isVerbose) cerr << "slave put: " << linebuffer <<endl; double f; char* q = new char; strcpy(q,""); linebuffer[0] = '\0'; read(master_fd, q, 1); while ( q[0] == ' ' || q[0] == '\n' || q[0] == '\r' ) read(master_fd, q, 1); strncat(linebuffer, q, 1); for(;;) { read(master_fd, q, 1); if(q[0] == '\r') continue; if(q[0] == '\n') break; strncat(linebuffer, q, 1); } if(isVerbose) cerr << "slave got: " << linebuffer << endl; if(sscanf(linebuffer, "%lg", &f) != 1) { cerr << "SlaveError:: bad output from slave:" << endl; cerr << "\"" << linebuffer << "\"\n"; exit(1); } ldata += f; delete q; return ldata;}List<double> SlaveForward::dataList(const Model<long>& p){ Model<double> m(p.modSize()); m = p; return dataList(m);}static char* newcopy(const AString& s, const int first, const int length){ char* q = new char[length + 1]; q[length] = 0; for(int i = first; i < first + length; i++) q[i - first] = s[i]; return q;}Vector<double>* SlaveForward::gradient(const Model<double>& p){ List<double> ldata; int n = p.modSize(); // send slave the first signal: flag for computing derivatives char lt[32]; linebuffer[0]='\0'; sprintf(lt, "%d ", 1); strcat(linebuffer, lt); for(int i = 0; i < n; i++) { sprintf(lt, "%g ", p.elem(i)); strcat(linebuffer, lt); } strncat(linebuffer,"\n",1); int nl = strlen(linebuffer); if ((my_write(master_fd, linebuffer, nl)) < nl) cerr<<"There is not enough buffer space for the writing. \n"; if(isVerbose) cerr << "slave put: " << linebuffer <<endl; double f; char* q = new char; strcpy(q,""); for (int il=0; il<n; il++) { linebuffer[0] = '\0'; read(master_fd, q, 1); while ( q[0] == ' ' || q[0] == '\n' || q[0] == '\r' ) read(master_fd, q, 1); strncat(linebuffer, q, 1); for(;;) { read(master_fd, q, 1); if(q[0] == '\r') continue; if(q[0] == '\n' || q[0] == ' ') break; strncat(linebuffer, q, 1); } if(isVerbose) cerr << il<<"th component of slave got: " << linebuffer << endl; if(sscanf(linebuffer, "%lg", &f) != 1) { cerr << "SlaveError:: bad output from slave:" << endl; cerr << "\"" << linebuffer << "\"\n"; exit(1); } ldata += f; } delete q; Vector<double>* g = new Vector<double>(ldata.ToVect()); if (isVerbose) cerr << "slave got: "<<g[0]<<endl; return g;}Vector<double>* SlaveForward::gradient(const Model<long>& p){ Model<double> m(p.modSize()); m = p; return gradient(m);}static char* newcopy(const AString& s, const int first, const int length){ char* q = new char[length + 1]; q[length] = 0; for(int i = first; i < first + length; i++) q[i - first] = s[i]; return q;}/*** pty code is stolen from Don Libe's expect(1). Thank you,** Don and the NIST.*//* * Ioctl control packet */#define NCC 8struct termio { unsigned short c_iflag; /* input modes */ unsigned short c_oflag; /* output modes */ unsigned short c_cflag; /* control modes */ unsigned short c_lflag; /* line discipline modes */ char c_line; /* line discipline */ unsigned char c_cc[NCC]; /* control chars */};static char* ptytemplate = "/dev/ptyXX";static char* ttytemplate = "/dev/ttyXX";static const int bank_index = 8;static const int file_index = 9;static const char* filedigits = "0123456789abcdef";/*** static values for termio structure kludged from stty -a** for my tube this morning. (mls)*/static struct termio tflags = { BRKINT | IGNPAR | ISTRIP | ICRNL | IXON, OPOST | ONLCR, B9600 | CS7 | CREAD | PARENB, ISIG | ICANON | IEXTEN, 0, { 0x03, 0x1c, 0x7f, 0x15, 0x04, 0x00, 0x00, 0x00}};int SlaveForward::makePtyName(){ for(int b = 'p'; b <= 'z'; b++) { struct stat s; ptyfile[bank_index] = b; ptyfile[file_index] = filedigits[0]; ttyfile[bank_index] = b; if(stat(ptyfile, &s) < 0) return -1; for(const char* f = filedigits; *f != '\0'; f++) { ptyfile[file_index] = *f; if(isVerbose) cerr << "Trying " << ptyfile << endl; if(access(ptyfile, R_OK|W_OK) != 0) continue; ttyfile[file_index] = *f; if(access(ttyfile, R_OK|W_OK) != 0) continue; master_fd = open(ptyfile, O_RDWR); if(master_fd >= 0) return master_fd; if(isVerbose) { cerr << "SlaveForward:: master open failed [" << master_fd << "] on " << ptyfile << endl; cerr << "Forward: " << sys_errlist[errno] << endl; } master_fd = -1; } } return -1;}int SlaveForward::getMasterFD(){ if(master_fd < 0) { if(makePtyName() < 0) { cerr << "SlaveForward:: makeptyname failed.\n"; exit(1); } fcntl(master_fd, F_SETFD, FD_CLOEXEC); //this is the flag for POSIX } return master_fd;}int SlaveForward::getSlaveFD(){ if(slave_fd < 0) { slave_fd = open(ttyfile, O_RDWR); if(slave_fd < 0) { cerr << "SlaveForward::getSlaveFD couldn't open " << ttyfile << endl; exit(1); } tflags.c_lflag &= ~ECHO; if((ioctl(slave_fd, TIOCSETA, &tflags) != 0)) { cerr << "SlaveForward::getSlaveFD" << " couldn't set ttyflags for " << ttyfile << endl; exit(1); } } return slave_fd;}static void sigcatcher(){ exit(1);}int SlaveForward::runCommand(const AString& command, const AString& arguments){ char ** argarray = new char*[arguments.length() + 1]; argarray[0] = newcopy(command, 0, command.length()); argarray[1] = 0; int na = 1; int nc = 0; int nb; for(;;) { while((nc < arguments.length()) && (arguments[nc] == ' ')) ++nc; if(nc >= arguments.length()) break; nb = nc + 1; while((nb < arguments.length()) && (arguments[nb] != ' ')) ++nb; argarray[na++] = newcopy(arguments, nc, nb - nc); argarray[na] = 0; if(nb >= arguments.length()) break; nc = nb + 1; }// signal(SIGUSR1, (SIG_PF) sigcatcher); //original from Martin Smith signal(SIGUSR1, & sigcatcher); int childpid; childpid = fork(); if(childpid == 0) { int slavefd = getSlaveFD(); dup2(slavefd, 0); dup2(slavefd, 1); close(slavefd); execvp((const char*) command, argarray); cerr << "SlaveForward:: execvp failed: " << sys_errlist[errno] << endl; kill(getppid(), SIGUSR1); exit(1); } if(childpid < 0) { cerr << "SlaveForward:: couldn't fork." << endl; exit(1); } return childpid;}SlaveForward::SlaveForward(int ndim, int ndat, AString& cmdstr, const AString& argstr, int setVerbose) :Forward(setVerbose){ isVerbose = setVerbose; ndata = ndat; linebuffer = new char[ndim * 20 + 1024]; master_fd = -1; slave_fd = -1; ptyfile = new char[strlen(ptytemplate) + 1]; strcpy(ptyfile, ptytemplate); ttyfile = new char[strlen(ttytemplate) + 1]; strcpy(ttyfile, ttytemplate); getMasterFD(); if(master_fd < 0) { cerr << "SlaveForward:: couldn't get good master_fd." << endl; exit(1); } command = cmdstr; cmdargs = argstr; int childID = runCommand(command, cmdargs); if (childID <0) { cerr << "SlaveForward:: runCommand failed." << endl; exit(1); }}SlaveForward::~SlaveForward(){ if (isVerbose) cerr << "Destroying Slave Forward objects!" << endl; if(master_fd >= 0) close(master_fd); if(slave_fd >= 0) close(slave_fd); delete [] linebuffer; delete [] ptyfile; delete [] ttyfile;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -