+/*
+ * static to localize to this compilation unit; volatile to avoid register
+ * optimization which would prevent modification by a signal handler.
+ */
+static volatile int my_err;
+
+/*
+ * Handler; used by memory_tests() child to reset my_err so that it will
+ * exit normally following a SIGBUS, rather than triggering a crash report;
+ * this depends on setting the error non-zero before triggering the condition
+ * that would trigger a SIGBUS. To avoid confusion, this is most easily done
+ * right before the test in question, and if there are subsequent tests, then
+ * undone immediately after to avoid false test negatives.
+ */
+void
+bus_handler(int sig, siginfo_t *si, void *mcontext)
+{
+ /* Reset global error value when we see a SIGBUS */
+ if (sig == SIGBUS)
+ my_err = 0;
+}
+
+/*
+ * Count the number of crashes for us in /Library/Logs/CrashReporter/
+ *
+ * XXX Assumes that CrashReporter uses our name as a prefix
+ * XXX Assumes no one lese has the same prefix as our name
+ */
+int
+crashcount(char *namebuf1, char *namebuf2)
+{
+ char *crashdir1 = "/Library/Logs/CrashReporter";
+ char *crashdir2 = "/Library/Logs/DiagnosticReports";
+ char *crash_file_pfx = "xnu_quick_test";
+ int crash_file_pfxlen = strlen(crash_file_pfx);
+ struct stat sb;
+ DIR *dirp1, *dirp2;
+ struct dirent *dep1, *dep2;
+ int count = 0;
+
+ /* If we can't open the directory, it hasn't been created */
+ if ((dirp1 = opendir(crashdir1)) == NULL) {
+ return( 0 );
+ }
+
+ while((dep1 = readdir(dirp1)) != NULL) {
+ if (strncmp(crash_file_pfx, dep1->d_name, crash_file_pfxlen))
+ continue;
+ /* record each one to get the last one */
+ if (namebuf1) {
+ strcpy(namebuf1, crashdir1);
+ strcat(namebuf1, "/");
+ strcat(namebuf1, dep1->d_name);
+ }
+ count++;
+ }
+
+ closedir(dirp1);
+
+ /* If we can't open the directory, it hasn't been created */
+ if ((dirp2 = opendir(crashdir2)) == NULL) {
+ return( 0 );
+ }
+
+ while((dep2 = readdir(dirp2)) != NULL) {
+ if (strncmp(crash_file_pfx, dep2->d_name, crash_file_pfxlen))
+ continue;
+ /* record each one to get the last one */
+ if (namebuf2) {
+ strcpy(namebuf2, crashdir2);
+ strcat(namebuf2, "/");
+ strcat(namebuf2, dep2->d_name);
+ }
+ count++;
+ }
+
+ closedir(dirp2);
+
+ return( count/2 );
+}
+
+