NEURON
audit.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <hocdec.h>
6 #include "hocassrt.h"
7 
8 
9 static int doaudit;
10 static FILE* faudit;
11 static FILE* audit_pipe;
12 
13 typedef struct RetrieveAudit {
14  int mode;
15  int id;
16  FILE* pipe;
18 
20 
21 static void pipesend(int type, const char* s);
22 
23 /*
24 Notes:
25 
26 The goal is to support easy reconstruction of a simulation while realizing
27 that the user may not know whether to save the information til she sees
28 something that she feels is worth saving. If he does want to save then
29 a saveaudit() command is issued.
30 
31 RCS checking of files
32 In order to not delay the main process while managing rcs files (deciding
33 whether a file needs to be checked in with rcsdiff and ci) we merely
34 send the file name through a pipe to another process which will asynchronously
35 maintain a list of xopen statements with the proper rcs version number.
36 */
37 
38 #define AUDIT_SCRIPT_DIR "$NEURONHOME/lib/auditscripts"
39 #define AUDIT_DIR "AUDIT"
40 
41 
42 static void hoc_audit_init(void) {
43 #if !OCSMALL
44  if (retrieve_audit.mode) {
45  /* clean up. there must have been an execerror */
46  retrieve_audit.mode = 0;
47  retrieve_audit.id = 0;
48  if (retrieve_audit.pipe) {
50  retrieve_audit.pipe = (FILE*) 0;
51  }
52  }
53 #endif
54 }
55 
56 void hoc_audit_from_hoc_main1(int argc, const char** argv, const char** envp) {
57 #if !OCSMALL
58  /*ARGSUSED*/
59  int i;
60  char buf[200];
61 
63 
64 #if 0
65  if (getenv("HOCAUDIT")) {
66  doaudit = 1;
67  printf("auditing\n");
68  }else{
69  doaudit = 0;
70  printf("no auditing\n");
71  }
72 #endif
73 
74  if (!doaudit) {
75  return;
76  }
77  /* since file open for entire session will have to make the name unique*/
78  sprintf(buf, "if [ ! -d %s ] ; then mkdir %s ; fi", AUDIT_DIR, AUDIT_DIR);
79  nrn_assert(system(buf) >= 0);
80  sprintf(buf, "mkdir %s/%d", AUDIT_DIR, hoc_pid());
81  nrn_assert(system(buf) >= 0);
82  sprintf(buf, "%s/hocaudit.sh %d %s", AUDIT_SCRIPT_DIR, hoc_pid(), AUDIT_DIR);
83  if ((audit_pipe = popen(buf, "w")) == (FILE*) 0) {
84  hoc_warning("Could not connect to hocaudit.sh via pipe:", buf);
85  doaudit = 0;
86  return;
87  }
88  if (hoc_saveaudit() == 0) {
89  return;
90  }
91  fprintf(faudit, "/*\n");
92  for (i = 0; i < argc; ++i) {
93  fprintf(faudit, " %s", argv[i]);
94  }
95  fprintf(faudit, "\n*/\n");
96  fflush(faudit);
97  for (i = 1; i < argc; ++i) {
98  if (argv[i][0] != '-') {
99  fprintf(faudit, "xopen(\"%s\")\n", argv[i]);
100  hoc_audit_from_xopen1(argv[i], (char*) 0);
101  }
102  }
103  fprintf(faudit, "\n");
104 #endif
105 }
106 
107 #if !OCSMALL
108 static void pipesend(int type, const char* s) {
109  int err;
110  if (audit_pipe) {
111  err = fprintf(audit_pipe, "%d %s\n", type, s);
112  if (err == EOF) {
113  hoc_warning("auditing failed in pipesend", "turning off");
114  doaudit = 0;
115  audit_pipe = 0;
116  return;
117  }
118  fflush(audit_pipe);
119  }
120 }
121 #endif
122 void hoc_audit_command(const char* buf) {
123 #if !OCSMALL
124  if (doaudit) {
125  fprintf(faudit, "%s", buf);
126  }
127 #endif
128 }
129 
130 void hoc_audit_from_xopen1(const char* fname, const char* rcs) {
131 #if !OCSMALL
132  if (!hoc_retrieving_audit() && doaudit && !rcs) {
133  pipesend(1, fname);
134  }
135 #endif
136 }
137 
139 #if !OCSMALL
140  if (faudit) {
141  fclose(faudit);
142  faudit = 0;
143  }
144  if (audit_pipe) {
146  audit_pipe = 0;
147  }
148  doaudit = 0;
149 #endif
150 }
151 
152 void hoc_Saveaudit(void) {
153  int err;
154 #if !OCSMALL
155  err = hoc_saveaudit();
156 #endif
157  hoc_ret();
158  hoc_pushx((double) err);
159 }
160 
161 int hoc_saveaudit(void) {
162 #if !OCSMALL
163  static int n = 0;
164  char buf[200];
165  if (hoc_retrieving_audit() || !doaudit) {
166  return 0;
167  }
168  if (faudit) {
169  fclose(faudit);
170  faudit = 0;
171  sprintf(buf, "hocaudit%d", n);
172  pipesend(3, buf);
173  ++n;
174  }
175  sprintf(buf, "%s/%d/hocaudit%d", AUDIT_DIR, hoc_pid(), n);
176  if ((faudit = fopen(buf, "w")) == (FILE*) 0) {
177  hoc_warning("NO audit. fopen failed for:", buf);
178  doaudit = 0;
179  return 0;
180  }
181 #endif
182  return 1;
183 }
184 
186 #if !OCSMALL
187  return retrieve_audit.mode;
188 #else
189  return 0;
190 #endif
191 }
192 
193 void hoc_Retrieveaudit(void) {
194  int err, id;
195 #if !OCSMALL
196  if (ifarg(1)) {
197  id = (int) chkarg(1, 0., 1e7);
198  } else {
199  id = 0;
200  }
201 #endif
202  err = hoc_retrieve_audit(id);
203  hoc_ret();
204  hoc_pushx((double) err);
205 }
206 
207 static void xopen_audit(void) {
208 #if !OCSMALL
209  char buf[200], *bp;
210  constexpr auto rm_str = "rm ";
211  strcpy(buf, rm_str);
212  bp = buf + strlen(buf);
213  /* get the temporary file name */
214  nrn_assert(fgets(bp, 200 - strlen(rm_str), retrieve_audit.pipe));
215  /*printf("xopen_audit: %s", bp);*/
216  bp[strlen(bp) - 1] = '\0';
217  hoc_xopen1(bp, "");
218 #if 1
219  nrn_assert(system(buf) >= 0);
220 #endif
221 #endif
222 }
223 
224 #ifdef NeXT
225 int hoc_retrieve_audit(int id) /* I have no idea why... CMC */
226 #else
228 
229 #endif
230 {
231 #if !OCSMALL
233  char buf[200];
234  char retdir[200];
236  /*printf("retrieve audit id=%d\n", id);*/
237  retrieve_audit.mode = 1;
238  retrieve_audit.id = id;
239 
240  sprintf(buf, "%s/retrieve.sh %d %s", AUDIT_SCRIPT_DIR, id, AUDIT_DIR);
241  if ((retrieve_audit.pipe = popen(buf, "r")) == (FILE*) 0) {
242  hoc_execerror("Could not connect via pipe:", buf);
243  }
244  nrn_assert(fgets(retdir, 200, retrieve_audit.pipe));
245  xopen_audit();
246  nrn_assert(!fgets(buf, 200, retrieve_audit.pipe));
247  /* pclose(retrieve_audit.pipe);*/
249  fprintf(stderr, "should now delete %s", retdir);
250 #endif
251  return 1;
252 }
253 
254 void hoc_xopen_from_audit(const char* fname) {
255 #if !OCSMALL
256  char buf[200];
257  /* check the synchronization */
258  nrn_assert(fgets(buf, 200, retrieve_audit.pipe));
259  buf[strlen(buf) - 1] = '\0';
260  if (strncmp(buf, fname, strlen(fname)) != 0) {
261  fprintf(stderr, "Warning: xopen_from_audit files have different names %s %s\n", fname, buf);
262  }
263  xopen_audit();
264 #endif
265 }
static void hoc_audit_init(void)
Definition: audit.cpp:42
static int doaudit
Definition: audit.cpp:9
#define AUDIT_SCRIPT_DIR
Definition: audit.cpp:38
struct RetrieveAudit RetrieveAudit
static RetrieveAudit retrieve_audit
Definition: audit.cpp:19
void hoc_Saveaudit(void)
Definition: audit.cpp:152
void hoc_Retrieveaudit(void)
Definition: audit.cpp:193
static FILE * audit_pipe
Definition: audit.cpp:11
static FILE * faudit
Definition: audit.cpp:10
static void xopen_audit(void)
Definition: audit.cpp:207
#define AUDIT_DIR
Definition: audit.cpp:39
static void pipesend(int type, const char *s)
Definition: audit.cpp:108
short type
Definition: cabvars.h:9
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
double chkarg(int, double low, double high)
Definition: code2.cpp:638
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
char buf[512]
Definition: init.cpp:13
void hoc_audit_command(const char *buf)
Definition: audit.cpp:122
void hoc_xopen_from_audit(const char *fname)
Definition: audit.cpp:254
void hoc_audit_from_xopen1(const char *fname, const char *rcs)
Definition: audit.cpp:130
int hoc_retrieve_audit(int id)
Definition: audit.cpp:227
int hoc_saveaudit(void)
Definition: audit.cpp:161
void hoc_ret()
void hoc_warning(const char *, const char *)
int hoc_retrieving_audit(void)
Definition: audit.cpp:185
void hoc_on_init_register(Pfrv pf)
Definition: code.cpp:393
void hoc_audit_from_hoc_main1(int argc, const char **argv, const char **envp)
Definition: audit.cpp:56
void hoc_audit_from_final_exit(void)
Definition: audit.cpp:138
int hoc_pid(void)
Definition: hoc.cpp:877
static int argc
Definition: inithoc.cpp:53
static char ** argv
Definition: inithoc.cpp:54
int ifarg(int)
Definition: code.cpp:1581
void hoc_pushx(double)
int hoc_xopen1(const char *filename, const char *rcs)
Definition: fileio.cpp:207
pclose(FILE *p)
Definition: macprt.cpp:107
char * getenv(const char *s)
Definition: macprt.cpp:67
FILE * popen(char *s1, char *s2)
Definition: macprt.cpp:102
#define id
Definition: md1redef.h:33
#define i
Definition: md1redef.h:12
#define printf
Definition: mwprefix.h:26
#define fprintf
Definition: mwprefix.h:30
#define nrn_assert(ex)
Definition: nrnassrt.h:53
int const size_t const size_t n
Definition: nrngsl.h:11
static double save(void *v)
Definition: ocbox.cpp:346
FILE * fopen()
FILE * pipe
Definition: audit.cpp:16
static const char * fname(const char *name)
Definition: nrnbbs.cpp:113