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) {
49  pclose(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) {
145  pclose(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 int hoc_retrieve_audit(int id) {
225 #if !OCSMALL
227  char buf[200];
228  char retdir[200];
230  /*printf("retrieve audit id=%d\n", id);*/
231  retrieve_audit.mode = 1;
232  retrieve_audit.id = id;
233 
234  Sprintf(buf, "%s/retrieve.sh %d %s", AUDIT_SCRIPT_DIR, id, AUDIT_DIR);
235  if ((retrieve_audit.pipe = popen(buf, "r")) == (FILE*) 0) {
236  hoc_execerror("Could not connect via pipe:", buf);
237  }
238  nrn_assert(fgets(retdir, 200, retrieve_audit.pipe));
239  xopen_audit();
240  nrn_assert(!fgets(buf, 200, retrieve_audit.pipe));
241  /* pclose(retrieve_audit.pipe);*/
243  fprintf(stderr, "should now delete %s", retdir);
244 #endif
245  return 1;
246 }
247 
248 void hoc_xopen_from_audit(const char* fname) {
249 #if !OCSMALL
250  char buf[200];
251  /* check the synchronization */
252  nrn_assert(fgets(buf, 200, retrieve_audit.pipe));
253  buf[strlen(buf) - 1] = '\0';
254  if (strncmp(buf, fname, strlen(fname)) != 0) {
255  fprintf(stderr, "Warning: xopen_from_audit files have different names %s %s\n", fname, buf);
256  }
257  xopen_audit();
258 #endif
259 }
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
void hoc_on_init_register(Pfrv pf)
Definition: code.cpp:462
#define id
Definition: md1redef.h:41
#define i
Definition: md1redef.h:19
double chkarg(int, double low, double high)
Definition: code2.cpp:626
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:248
int hoc_retrieving_audit(void)
Definition: audit.cpp:185
int hoc_saveaudit(void)
Definition: audit.cpp:161
void hoc_ret()
int hoc_pid(void)
Definition: hoc.cpp:773
void hoc_audit_from_xopen1(const char *fname, const char *rcs)
Definition: audit.cpp:130
int hoc_retrieve_audit(int id)
Definition: audit.cpp:224
void hoc_audit_from_final_exit(void)
Definition: audit.cpp:138
void hoc_audit_from_hoc_main1(int argc, const char **argv, const char **envp)
Definition: audit.cpp:56
static int argc
Definition: inithoc.cpp:45
static char ** argv
Definition: inithoc.cpp:46
void hoc_pushx(double)
Definition: code.cpp:779
int hoc_xopen1(const char *filename, const char *rcs)
Definition: fileio.cpp:166
printf
Definition: extdef.h:5
void hoc_execerror(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:39
void hoc_warning(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:44
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
Definition: wrap_sprintf.h:14
#define nrn_assert(x)
assert()-like macro, independent of NDEBUG status
Definition: nrn_assert.h:33
int const size_t const size_t n
Definition: nrngsl.h:10
s
Definition: multisend.cpp:521
int ifarg(int)
Definition: code.cpp:1607
short type
Definition: cabvars.h:10
static double save(void *v)
Definition: ocbox.cpp:344
FILE * pipe
Definition: audit.cpp:16