source: tags/1.1/disparm.cpp @ 5

Last change on this file since 5 was 5, checked in by willem, 11 years ago

willem

File size: 24.1 KB
Line 
1#include <iostream>
2#include <fstream>
3#include <libgen.h>
4#include <cstdlib>
5#include <string.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9#include <unistd.h>
10
11#include "disparm.h"
12#include "tofromstring.h"
13#include "token.h"
14#include "shellenv.h"
15#include <errno.h>
16#include <dirent.h>
17
18const std::string disparm::keyname       = "DISPARM_KEY";
19const std::string disparm::committedname = "DISPARM_COMMITTED";
20const std::string disparm::valuename     = "DISPARM_VALUE";
21const std::string disparm::rcname        = "DISPARM_RC";
22const std::string disparm::linename      = "DISPARM_LINENO";
23
24const std::string disparm::defpath_pool   = "pool.disparm";
25const std::string disparm::definputfilename = "-";
26
27//
28//constructor disparm
29//
30disparm::disparm()
31{
32  char defpoolname_c[this->defpath_pool.length()+1];        // default path_pool
33  strcpy(defpoolname_c,this->defpath_pool.c_str());         
34  //
35  // A note about basename and dirname: they need as argument a char*
36  // NOT a const char*. Both functions may modify the argument,
37  // so, in general, do not use the same argument more than
38  // once.
39  //
40  char defpath_lockdir_c[this->defpath_lockdir.length()+1];  // default directory for the lockfile
41  strcpy(defpath_lockdir_c,this->defpath_lockdir.c_str());
42  this->setpath_pool(this->defpath_pool);
43  this->defpath_lockdir = std::string(dirname(defpoolname_c));
44  this->setpath_link("");
45  this->setpath_lock("");     // the name of the lock folder
46  this->setbaselinkfilename("");
47  this->setinputfilename(this->definputfilename);  // default input file name
48  this->setpath_lockdir(this->defpath_lockdir);      // default lock directory
49  this->setmaxiter(1);                             // default maximum times a string can be given out
50  this->pmarker="pp";                              // start of record with pointer to next string in pool
51  this->pmarkerlen = this->pmarker.length();
52  this->lockname="lock.disparm";
53
54  std::string shell = getenv("SHELL");
55  if (shell.find("csh") != std::string::npos) 
56    this->shelltype = SHELL_CSH;
57  else
58    this->shelltype = SHELL_SH;
59
60  //
61  // following items are returned on stdout as in:
62  // export DISPARM_KEY=1234
63  // See also above
64  //
65  this->key       = -1;     // key: pointer to next item in pool
66  this->status    = '0';
67  this->committed = 0;      // the number of times the string is given out
68  this->rc        = "OK";   // return code
69  this->value     = "";     // the string to give out
70  this->linenr    = 0;      // the line number in the pool
71
72  this->debug     = 0;
73
74  int rc = posix_memalign((void**)&buffer, 4096, 512);
75  if (rc != 0)
76    std::cerr << "Disparm: posix_memalign fails" << std::endl;
77}
78
79// destructor
80disparm::~disparm()
81{
82  free(this->buffer);
83}
84
85void disparm::removelock()
86{
87  unlink(this->path_link.c_str());
88  rmdir(this->path_lock.c_str());
89}
90
91void disparm::setpath_pool(std::string pool)
92{
93  this->path_pool = pool;
94}
95
96void disparm::setpath_link(std::string path_link)
97{
98  this->path_link = path_link;
99}
100
101void disparm::setpath_lock(std::string path_lock)
102{
103  this->path_lock = path_lock;
104}
105
106void disparm::setbaselinkfilename(std::string baselinkfilename)
107{
108  this->baselinkfilename = baselinkfilename;
109}
110
111int disparm::setpath_lockdir(std::string lockdir)
112{
113  this->path_lockdir = lockdir;
114  int rc = mkdir(path_lockdir.c_str(),0777);
115  if (rc ==0)
116    return 0;
117  else
118  {
119    if (errno == EEXIST)
120    {
121      struct stat buf;
122      stat(path_lockdir.c_str(),&buf);
123      if (S_ISDIR(buf.st_mode))
124        return 0;
125    }
126    else
127      return -1;
128  }
129  return 0;  // never reached
130}
131
132//
133// Create a name for the directory to be used as lock: this->path_lock
134// This directory will reside in this->path_lockdir
135// We try to generate a name for a linkfile that is unique.
136// In the name is also the creation time.
137// The link file will be placed in the lock directory
138//
139void disparm::createlinkfilename()
140{
141  if (this->debug)
142    this->debugger("Before createlinkfilename:");
143  char hostname[1025];
144  gethostname(hostname,1024);
145  char poolname_c[this->path_pool.length()+1];
146  strcpy(poolname_c,this->path_pool.c_str());
147  std::string poolnamebase = basename(poolname_c);
148  this->lockname=poolnamebase+".lock.disparm";
149  this->setpath_lock(this->path_lockdir + "/" + this->lockname);
150  std::string base = this->path_lock + "/" + poolnamebase + ".link.";
151  this->setbaselinkfilename(base);
152  this->setpath_link(   base
153                         + to_string(time(0))
154                         + "." 
155                         + hostname
156                         + "." 
157                         + to_string(getpid()));
158  if (this->debug)
159    this->debugger("After createlinkfilename:");
160}
161
162void disparm::setinputfilename(std::string inputfilename)
163{
164  this->inputfilename = inputfilename;
165}
166
167void disparm::setkey(std::streampos key)
168{
169  this->key = key;
170}
171
172std::streampos disparm::getkey(void)
173{
174  return this->key;
175}
176
177void disparm::setmaxiter(int maxiter)
178{
179  this->maxiter = maxiter;
180}
181
182//
183// Create poolfile from input file
184//
185// On return, s wil contain the output of createrc
186//
187int disparm::create(std::string &s)
188{
189  if (this->debug)
190    this->debugger("Before create:");
191  std::ifstream inp;
192  std::istream *pinp;
193  s = "";
194  //
195  // open inputfile, take care that stdin is also allowed
196  //
197  if (this->inputfilename == "-")
198    pinp = &std::cin;
199  else
200  {
201    inp.open(this->inputfilename.c_str());
202    if (!inp.is_open())
203    {
204      std::cerr<<"Cannot open '"<<inputfilename<<"'"<<std::endl;
205      this->rc = "FAIL";
206      s = this->createrc();
207      return 1;
208    }
209    pinp = &inp;
210  }
211  //
212  // open poolfile
213  //
214  std::string line;
215  std::fstream out;
216  out.open(this->path_pool.c_str(),std::fstream::in | std::fstream::out
217                               |  std::fstream::trunc);
218
219  //
220  // fill poolfile
221  //
222  token tok;
223  tok.setfile(out);
224  std::streampos p;
225  unsigned int linenr = 0;
226  while (getline(*pinp,line))
227  {
228    tok.setlinenr(++linenr);
229    tok.setcommitted(0);
230    tok.clearstatus();
231    tok.setvalue(line);
232    tok.writetoken(p);
233  }
234  tok.writelocpointer(0);
235
236  //
237  // close input file, only if it is not stdin
238  //
239  if (pinp == &inp)
240    inp.close();
241  out.close();
242
243  this->key = 0;
244  s = createrc();
245  if (this->debug)
246    this->debugger("After create:");
247
248  return 0;
249}
250
251//
252// get next string from pool
253//
254int disparm::next(std::string& s)
255{
256  if (this->debug)
257    this->debugger("Before next:");
258  int rc = this->realnext();
259  s = this->createrc();
260  if (this->debug)
261    this->debugger("After next:");
262  return rc;
263}
264
265//
266// create string to be eval'd by the shell
267//
268std::string disparm::createrc(void)
269{
270  std::string s = "";
271  s = s + shellenv(to_string(this->key),      this->keyname,      this->shelltype);
272  s = s + shellenv(to_string(this->committed),this->committedname,this->shelltype);
273  s = s + shellenv(to_string(this->value),    this->valuename,    this->shelltype);
274  s = s + shellenv(to_string(this->rc),       this->rcname,       this->shelltype);
275  s = s + shellenv(to_string(this->linenr),   this->linename,     this->shelltype);
276  return s;
277}
278
279//
280// get the next string from the pool
281//
282int disparm::realnext()
283{
284  std::fstream file;
285  bool good = 1;
286
287  this->key       = 0;
288  this->status    = '0';
289  this->committed = 0;
290  this->rc        = "OK";
291  this->linenr    = 0;
292  this->value     = "";
293
294  //
295  // get lock, return if that fails
296  //
297  if (this->getlock()!=0)
298  {
299    this->rc = "FAIL";
300    return 1;
301  }
302
303  //
304  // read next string from pool
305  // take care of ready records, maximum iterations
306  // allowed and some kinds of mishaps
307  //
308  // open first using O_DIRECT, to force a fresh cache.
309  int f = open(this->path_link.c_str(),O_DIRECT|O_RDONLY);
310  int bytesread = read(f,buffer,512);
311  if (bytesread <0)
312  {
313    std::cerr << "How strange: cannot read from poolfile." << std::endl;
314  }
315  close(f);
316  file.open (this->path_link.c_str(), std::fstream::in | std::fstream::out);
317  if (file.is_open())
318  {
319    token       tok;
320    std::string line;
321    tok.setfile(file);
322    std::streampos locpointer, posused, posnext;
323
324    //
325    // get pointer to next string
326    //
327    locpointer = tok.readlocpointer();
328    if (locpointer < 0)
329    {
330      std::cerr << "Corrupt parameterfile: cannot find locpointer\n" << std::endl;
331      this->rc = "FAIL";
332      good = 0;
333    }
334    //
335    // read next string from pool
336    //
337    if (good)
338    {
339      int rc = tok.readnext(locpointer,posused,posnext);
340      if (rc != 0)
341      {
342        std::cerr << __FILE__ << ":" << __LINE__ << std::endl;
343        std::cerr << "Corrupt or empty parameterfile: cannot read next line\n" << std::endl;
344        this->rc = "FAIL";
345        good = 0;
346      }
347    }
348    //
349    // keep reading until a valid record is found
350    // take appropriate action if no such record exists
351    //
352    if (good)
353    {
354      std::streampos locpointerold = locpointer;
355      bool allready = 1;  // to learn if all records are
356                          // ready
357      while (1)
358      {
359        if (!tok.getready())
360        {
361          allready = 0;
362          if (tok.getcommitted() >= this->maxiter)
363          {
364            good = 0;
365            this->rc = "MAX_EXCEEDED";
366            break;
367          }
368          this->key = posused;
369          this->status = tok.getstatus();
370          this->committed = tok.getcommitted();
371          this->value = tok.getvalue();
372          this->linenr = tok.getlinenr();
373          tok.setcommitted(tok.getcommitted()+1);
374          tok.writetoken(posused);
375          tok.writelocpointer(posused);
376          break;
377        }
378        locpointer = posnext;
379        if (locpointer == locpointerold)
380        {
381          //
382          // so we are cycling, nothing to find, it seems
383          //
384          good = 0;
385          if (allready)
386            this->rc = "ALL_READY";
387          else
388            this->rc = "MAX_EXCEEDED";
389          break;
390        }
391        int rc = tok.readnext(locpointer,posused,posnext);
392        if (rc != 0)
393        {
394          std::cerr << __FILE__ << ":" << __LINE__ << std::endl;
395          std::cerr << "Corrupt or empty parameterfile: cannot read next line\n" << std::endl;
396          this->rc = "FAIL";
397          good = 0;
398          break;
399        }
400      }
401    }
402  }
403  else
404  {
405    std::cerr << __FILE__ << ":" << __LINE__ << std::endl;
406    std::cerr<< this->arg << ": Strange error: cannot open '"<<path_link<<"'"<<std::endl;
407    return 1;
408  }
409
410  file.close();
411  this->removelock();
412  return !good;
413}
414
415//
416// get a lock on the poolfile
417//
418// The normal methods don't work on an nfs file system.
419// Luckily, there is a method based on the creation
420// of a directory, which is an atomic operation.
421// If we can create the directory, we are sure that no
422// other instantiation of this program was also successful.
423// After successful creation of the lock directory, we create
424// a hard link to the poolfile, and use this link to read from and
425// write to. We do not use the poolfile itself to read and write,
426// we can never be sure in a nfs filesystem of the status of a
427// file. It appears that creating a new hard link suffices to
428// get an up to date version of the poolfile.
429//
430int disparm::getlock(void)
431{
432  struct stat buf;
433  int rc;
434  int sleeptime=2;
435
436  int iter = 0;
437  int ntryremovelock = 0;
438  while(1)
439  {
440    rc  = stat(this->path_pool.c_str(),&buf);
441    std::string er="";
442    switch (errno)
443    {
444      case (EACCES): er="Search permission is denied for one of the  directories  in  the path prefix of path.  (See also path_resolution(7).)";
445                     break;
446
447      case(EBADF):  er="fd is bad.";
448                    break;
449
450      case(EFAULT): er="Bad address.";
451                    break;
452
453      case(ELOOP):  er="Too many symbolic links encountered while traversing the path.";
454                    break;
455
456      case(ENAMETOOLONG):er="File name too long.";
457                         break;
458
459      case(ENOENT): er="A component of path does not exist, or path is an empty string.";
460                    break;
461
462      case(ENOMEM): er="Out of memory (i.e., kernel memory).";
463                    break;
464
465      case(ENOTDIR):
466              er="A component of the path prefix of path is not a directory.";
467              break;
468
469      case(EOVERFLOW):er="(stat())  path refers to a file whose size cannot be represented in the type off_t.  This can occur when an application  compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64 calls stat() on a file whose size exceeds (2<<31)-1 bits";
470                      break;
471
472    }
473    if (rc !=0 )
474    {
475      perror("Disparm: Error stat poolfile:");
476      std::cerr << __FILE__ << ":" << __LINE__ << std::endl;
477      std::cerr<<er<<std::endl;
478      std::cerr<< this->arg << ": Cannot stat the pool file:'"<<this->path_pool.c_str()<<"'"<< std::endl;
479      return 1;
480    }
481    this->createlinkfilename();
482    //
483    // Try to create the lock directory
484    //
485    rc = mkdir(this->path_lock.c_str(), 0700);
486    if (rc == 0)
487    {
488      // Creation of lock directory was successful, now create link
489      // to the poolfile
490      // As an extra check: check if the number of hard links to the
491      // poolfile equals 2.
492      //
493      // Strange: sometimes, when many threads are involved on one node,
494      // the poolfile seems to be gone, get error: "no such file or directory"
495      // I guess this is a race condition in the NFS filesystem
496      // so, I'll try 10 times, and then give up.
497      //
498      int tries = 0;
499      while (1)
500      {
501        tries++;
502        int rc = link(this->path_pool.c_str(),this->path_link.c_str());
503        if (rc < 0)
504        {
505          if (tries < 10)
506          {
507            sleep(1);
508          }
509          else
510          {
511            perror("Disparm: Error making link:");
512            std::cerr << __FILE__ << ":" << __LINE__ << std::endl;
513            std::cerr<< this->arg << ": Cannot make link '"<<this->path_link<<"' to '"
514              <<this->path_pool<<"'"<<std::endl<<" Is poolname '"<<path_pool
515              <<"' correct?"<<std::endl;
516            return 1;
517          }
518        }
519        else
520          break;
521      }
522      //
523      // check if number of hard links equals 2
524      //
525      struct stat linkbuf;
526      rc = stat(this->path_link.c_str(),&linkbuf);
527      if (rc !=0)
528      {
529        std::cerr << this->arg << ": Cannot stat just created link'"<<this->path_link<<"'"<<std::endl;
530        return 1;
531      }
532      if (linkbuf.st_nlink == 2)
533      {
534        break;
535      }
536      else
537      {
538        rc = unlink(this->path_link.c_str());
539      }
540    }
541    //
542    // wait some time before trying again
543    //
544    iter++;
545#ifdef VERBOSE
546    std::cerr << iter <<": waiting for lock " << std::endl;
547#endif
548    sleep(sleeptime);
549    if (iter > 9)
550    {
551#ifdef VERBOSE
552      std::cerr << "Trying to remove locks" << std::endl;
553#endif
554      //
555      // remove stale link files
556      //
557      this->remove_lock_and_links();
558      ntryremovelock ++;
559      if (ntryremovelock > 100)
560      {
561        std::cerr << this->arg << ": Cannot get lock after many tries." << std::endl;
562        return 1;
563      }
564      iter = 0;
565    }
566  }
567  return 0;
568}
569
570//
571// mark string as ready
572//
573int disparm::ready()
574{
575  if (this->getlock()!=0)
576  {
577    return 1;
578  }
579
580  //
581  // if no key given as parameter, read it from environment
582  //
583  if (this->key < 0)
584  {
585    char * s = getenv(this->keyname.c_str());
586    if (s == NULL || *s == 0)
587    {
588      this->removelock();
589      std::cerr << this->arg << ": No key given" << std::endl;
590      return 1;
591    }
592    else
593    {
594      this->key = from_string<long long>(std::string(s));
595    }
596  }
597
598  std::streampos locpointer = this->key;
599  std::fstream file;
600
601  // open first using O_DIRECT, to force a fresh cache.
602  int f = open(this->path_link.c_str(),O_DIRECT|O_RDONLY);
603  int bytesread = read(f,buffer,512);
604  if (bytesread <0)
605  {
606    std::cerr << this->arg << ": cannot read from poolfile." << std::endl;
607    return 1;
608  }
609  close(f);
610  file.open (this->path_link.c_str(), std::fstream::in | std::fstream::out);
611  if (file.is_open())
612  {
613    token tok;
614    std::string line;
615    tok.setfile(file);
616    std::streampos posused,posnext;
617    //
618    // read next record
619    //
620    int rc = tok.readnext(locpointer,posused,posnext);
621    if (rc != 0)
622    {
623      std::cerr << __FILE__ << ":" << __LINE__ << std::endl;
624      std::cerr << this->arg << ": Corrupt or empty parameterfile: cannot read next line\n" << std::endl;
625      file.close();
626      this->removelock();
627      return 1;
628    }
629    //
630    // mark record as ready
631    //
632    tok.ready();
633    //
634    // write record back
635    //
636    tok.writetoken(locpointer);
637  }
638  else
639  {
640    std::cerr << this->arg << ": Cannot read " << this->path_link << std::endl;
641  }
642  file.close();
643  this->removelock();
644  return 0;
645}
646
647//
648// remove poolfile
649//
650int disparm::REMOVE()
651{
652  if (this->getlock()!=0)
653  {
654    return 1;
655  }
656  this->removelock();
657
658  int rc = unlink(this->path_pool.c_str());
659  if (rc)
660  {
661    std::cerr << this->arg << ": Cannot remove " << this->path_pool << std::endl;
662    return 1;
663  }
664  return 0;
665}
666
667//
668// return statistics about the pool
669// no wait for lock, so be careful interpretating the results
670//
671stats disparm::getstats()
672{
673  stats statistics;
674  token tok;
675  std::fstream file;
676  statistics.valid     =  0;
677  statistics.records   = -1;
678  statistics.committed = -1;
679  statistics.ready     = -1;
680  statistics.commax    = -1;
681
682
683  file.open (this->path_pool.c_str(), std::fstream::in | std::fstream::out);
684
685  if (file.is_open())
686  {
687    tok.setfile(file);
688    std::streampos pos = 0;
689    std::streampos posused;
690    std::streampos posnext;
691    statistics.valid     = 1;
692    statistics.records   = 0;
693    statistics.committed = 0;
694    statistics.ready     = 0;
695    statistics.commax    = 0;
696   
697    while(1)
698    {
699      tok.readnext(pos, posused,posnext);
700      if (pos != posused)
701        break;
702      if (tok.getready())
703        statistics.ready++;
704      if (tok.getcommitted()>0)
705        statistics.committed++;
706      if (tok.getcommitted() > statistics.commax)
707        statistics.commax = tok.getcommitted();
708      statistics.records++;
709      pos = posnext;
710    }
711    file.close();
712  }
713  else
714  {
715    std::cerr << this->arg << ": Cannot open poolfile '"<<this->path_pool<<"'"<<std::endl;
716  }
717
718  return statistics;
719}
720
721int disparm::echounhandled(void)
722{
723  token tok;
724  std::fstream file;
725
726  file.open (this->path_pool.c_str(), std::fstream::in | std::fstream::out);
727
728  if (file.is_open())
729  {
730    tok.setfile(file);
731    std::streampos pos = 0;
732    std::streampos posused;
733    std::streampos posnext;
734    std::cerr << "linenr:committed:value"<< std::endl;
735   
736    while(1)
737    {
738      tok.readnext(pos, posused,posnext);
739      if (pos != posused)
740        break;
741
742      if (!tok.getready()&&tok.getcommitted()>0)
743      {
744        std::cerr << tok.getlinenr() << ":"<<tok.getcommitted()<<":" << tok.getvalue() << std::endl;
745      }
746      pos = posnext;
747    }
748  }
749  else
750  {
751    std::cerr << this->arg << ": Cannot open pool file '"<<this->path_pool<<"'"<<std::endl;
752    return 1;
753  }
754
755  file.close();
756  return 0;
757}
758
759
760int disparm::remove_lock_and_links(const std::string path, const std::string dirl, const std::string path_lock, int timer)
761{
762  // removes lock and hard links in directory "dirl" to file "path"
763  // in directory "dir", if they are older than "time" seconds.
764  // Method:
765  // if lock is older than timer seconds, remove it.
766  // and:
767  // using readdir, examine all components of dirl and see
768  // if they have the same inode as "path". If so, remove, unless
769  // the realname is the same as the realname of "path"
770  //
771  DIR *pdir;
772  struct dirent *pent;
773  int rc;
774  struct stat buf;
775
776  pdir = opendir(dirl.c_str());
777  if (!pdir)
778  {
779    std::cerr << this->arg << ": Cannot read link directory '"<<dirl<<"'"<<std::endl;
780    return 1;
781  }
782  rc = stat(path.c_str(),&buf);
783  if (rc !=0)
784  {
785    std::cerr << this->arg << ": Cannot stat '"<<path<<"'"<<std::endl;
786    return 1;
787  }
788  ino_t inodenr = buf.st_ino;
789  char* rpathc = (char*)malloc(PATH_MAX+1);
790  rpathc = realpath(path.c_str(),rpathc);
791  std::string rpath = rpathc;
792  std::string rpath1;
793 
794  while ((pent=readdir(pdir)))
795  {
796    struct stat buf;
797    std::string name = pent->d_name;
798    if (name == ".") continue;
799    if (name == "..") continue;
800    rpathc = realpath((dirl+"/"+name).c_str(),rpathc);
801    rpath1 = rpathc;
802#ifdef VERBOSE
803    std::cerr<<"TD: looking at '"<<rpath1<<"'"<<std::endl;
804#endif
805    if (rpath != rpath1)
806    {
807      int rc = stat(rpath1.c_str(),&buf);
808      if (rc != 0)
809      {
810        std::cerr << this->arg << ": Cannot stat '"<<rpath1<<"'"<<" this cannot happen!" << std::endl;
811        free(rpathc);
812        return 1;
813      }
814      if (buf.st_ino == inodenr)
815      {
816#ifdef VERBOSE
817        std::cerr << "time: " << time(0) << " " << buf.st_mtime << " " << timer << std::endl;
818#endif
819        if (time(0) > buf.st_mtime + timer)
820        {
821          int rc = unlink(rpath1.c_str());
822          if (rc == 0)
823          {
824#ifdef VERBOSE
825            std::cerr<<"Unlinked '"<<rpath1<<"'"<<std::endl;
826#endif
827          }
828          else
829          {
830#ifdef VERBOSE
831            std::cerr<<"Could not unlink '"<<rpath1<<"'"<<std::endl;
832#endif
833          }
834        }
835        else
836        {
837#ifdef VERBOSE
838          std::cerr << "TD: not unlinking because time: '"<<rpath1<<"'"<<std::endl;
839#endif
840        }
841      }
842    }
843    else
844    {
845#ifdef VERBOSE
846      std::cerr<<"TD: not unlinking '"<<rpath1<<"'"<<std::endl;
847#endif
848    }
849  }
850  free(rpathc);
851  // look if lock can be removed, if yes: and make it so
852  rc = stat(path_lock.c_str(),&buf);
853  if (rc == 0)
854  {
855    if (time(0) > buf.st_mtime + timer)
856    {
857#ifdef VERBOSE
858      std::cerr << "Trying to remove '"<<path_lock<<"'"<<std::endl;
859#endif
860      rc = rmdir(path_lock.c_str());
861      // It could happen that rmdir failed, for example another process
862      // already deleted it, or path is invalid etc.
863      // We ignore this, relying on the fact that eventually
864      // getlock will time out.
865    }
866  }
867  return 0;
868}
869
870
871//
872// remove lock and links
873// method: do a glob on baselinkfilename and unlink
874// the files.
875//
876// Only remove if links are older than 60 seconds.
877//
878void disparm::remove_lock_and_links()
879{
880  if (this->debug)
881    this->debugger("Before remove_lock_and_links:");
882
883  remove_lock_and_links(this->path_pool,this->path_lockdir,this->path_lock,60);
884  if (this->debug)
885    this->debugger("Before remove_lock_and_links:");
886}
887
888void disparm::setdebug()
889{
890  this->debug = 1;
891}
892void disparm::debugger(const std::string s)
893{
894  std::cerr << s << std::endl;
895  std::cerr << "baselinkfilename: '" << this->baselinkfilename << "'" << std::endl;
896  std::cerr << "committed:        '" << this->committed << "'" << std::endl;
897  std::cerr << "committedname:    '" << this->committedname << "'" << std::endl;
898  std::cerr << "definputfilename: '" << this->definputfilename << "'" << std::endl;
899  std::cerr << "defpath_pool:     '" << this->defpath_pool << "'" << std::endl;
900  std::cerr << "defpath_lockdir:  '" << this->defpath_lockdir << "'" << std::endl;
901  std::cerr << "inputfilename:    '" << this->inputfilename << "'" << std::endl;
902  std::cerr << "key:              '" << this->key << "'" << std::endl;
903  std::cerr << "keyname:          '" << this->keyname << "'" << std::endl;
904  std::cerr << "linename:         '" << this->linename << "'" << std::endl;
905  std::cerr << "linenr:           '" << this->linenr << "'" << std::endl;
906  std::cerr << "lockname:         '" << this->lockname << "'" << std::endl;
907  std::cerr << "maxiter:          '" << this->maxiter << "'" << std::endl;
908  std::cerr << "path_link:        '" << this->path_link << "'" << std::endl;
909  std::cerr << "path_lock:        '" << this->path_lock << "'" << std::endl;
910  std::cerr << "path_lockdir:     '" << this->path_lockdir << "'" << std::endl;
911  std::cerr << "path_pool:        '" << this->path_pool << "'" << std::endl;
912  std::cerr << "pmarker:          '" << this->pmarker << "'" << std::endl;
913  std::cerr << "pmarkerlen:       '" << this->pmarkerlen << "'" << std::endl;
914  std::cerr << "pointerlen:       '" << this->pointerlen << "'" << std::endl;
915  std::cerr << "rc:               '" << this->rc << "'" << std::endl;
916  std::cerr << "rcname:           '" << this->rcname << "'" << std::endl;
917  std::cerr << "shelltype:        '" << this->shelltype << "'" << std::endl;
918  std::cerr << "status:           '" << this->status << "'" << std::endl;
919  std::cerr << "value:            '" << this->value << "'" << std::endl;
920  std::cerr << "valuename:        '" << this->valuename << "'" << std::endl;
921}
922
923void disparm::setarg(int argc, char*argv[])
924{
925  this->arg = argv[0];
926  for (int i=1; i<argc; i++)
927    this->arg += std::string(" ") + std::string(argv[i]);
928  this->arg += " pid:" + to_string(getpid());
929}
930
931//
932// Just to teach me again how to make an object
933// suitable for the << operator
934//
935std::ostream& operator <<(std::ostream &os,disparm &obj)
936{
937  stats sta;
938  sta = obj.getstats();
939  if ( sta.valid )
940  {
941    os << "Total:     " << sta.records   << "\n" 
942       << "Committed: " << sta.committed << "\n"
943       << "Ready:     " << sta.ready     << "\n"
944       << "Max:       " << sta.commax;
945  }
946  return os;
947}
948
Note: See TracBrowser for help on using the repository browser.