Skip to content

Commit

Permalink
BEEPCMD
Browse files Browse the repository at this point in the history
Add option to run arbitrary shell command instead of X bell

Command does not run from gui thread.  Command will not
be run concurrently.
  • Loading branch information
Michael Davidsaver committed Oct 9, 2012
1 parent 41635f2 commit 039f535
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 1 deletion.
33 changes: 33 additions & 0 deletions alConfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,37 @@ int context,int caConnect,struct mainGroup *pmainGroup)
return;
}

if (strncmp(&buf[1],"BEEPCMD",7)==0) {
unsigned int start=8, end = strlen(buf) - 1;

/* skip leading whitespace to find start of command */
for(; start<=end && (buf[start]=='\t' || buf[start]==' '); start++) {}

if(start>end) {
print_error(buf, "expected argument after BEEPCMD");
return;
}

/* back track to trim trailing whitespace */
for(; end>=start && (buf[end]=='\0' || isspace(buf[end])); end--) {}

if(end>start) {
if(psetup.beepCmd)
free(psetup.beepCmd);
psetup.beepCmd = malloc(end-start+2);
if(!psetup.beepCmd) {
print_error(buf, "Not enough memory for BEEPCMD");
} else {
memcpy(psetup.beepCmd, &buf[start], end-start+1);
psetup.beepCmd[end-start+1] = '\0';
}
} else {
print_error(buf, "Missing argument for BEEPCMD");
}

return;
}

if (strncmp(&buf[1],"HEARTBEATPV",11)==0) { /*HEARTBEATPV*/

if (pmainGroup->heartbeatPV.name) return;
Expand Down Expand Up @@ -774,6 +805,8 @@ void alWriteConfig(char *filename,struct mainGroup *pmainGroup)
if (!fw) return;
if (psetup.beepSevr > 1)
fprintf(fw,"$BEEPSEVERITY %s\n",alhAlarmSeverityString[psetup.beepSevr]);
if (psetup.beepCmd)
fprintf(fw,"$BEEPCMD %s\n", psetup.beepCmd);
/*alWriteGroupConfig(fw,(SLIST *)&(pmainGroup->p1stgroup));*/
alWriteGroupConfig(fw,(SLIST *)pmainGroup);
fclose(fw);
Expand Down
1 change: 1 addition & 0 deletions alh.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ struct setup {
char logFile[NAMEDEFAULT_SIZE]; /* alarm log file name */
char opModFile[NAMEDEFAULT_SIZE]; /* opMod log file name */
char saveFile[NAMEDEFAULT_SIZE]; /* save config file name */
char *beepCmd; /* Optional command in place of X bell*/
Boolean silenceForever; /* 1 - beepoff forever is true */
short silenceOneHour; /* 1 - beepoff one hour is true */
short silenceCurrent; /* 1 - current beep on 0 - off */
Expand Down
97 changes: 96 additions & 1 deletion os/default/alAudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,114 @@
*
*/

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#include "alh.h"

static pthread_mutex_t beep_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t beep_wake = PTHREAD_COND_INITIALIZER;
static pthread_once_t beep_setup = PTHREAD_ONCE_INIT;
/* states: -2 done, -1 shutdown, 0 idle, 1 playing, 2 request play */
static int beeping = 0;
static pthread_t beeper;

#define LOCK() assert(pthread_mutex_lock(&beep_lock)==0)
#define UNLOCK() assert(pthread_mutex_unlock(&beep_lock)==0)

static void beeper_shutdown(void)
{
/* request shutdown and spin until beeper thread stops */
LOCK();
beeping = -1;
while(beeping!=-2) {
UNLOCK();
pthread_cond_broadcast(&beep_wake);
usleep(10000); /* 10ms */
LOCK();
}
/* thread is stopped now */
free(psetup.beepCmd);
psetup.beepCmd = NULL;

UNLOCK();
}

static void* beeper_thread(void* junk)
{
LOCK();

atexit(&beeper_shutdown);

while(beeping>=0) {

assert(pthread_cond_wait(&beep_wake, &beep_lock)==0);

if(beeping==2) {
beeping=1;
UNLOCK();

system(psetup.beepCmd);

LOCK();
/* be careful not to overwrite the shutdown command */
if(beeping==1)
beeping=0;
}
}
UNLOCK();
beeping=-2;
return NULL;
}

static void setup(void)
{
if(!psetup.beepCmd)
return;

if(pthread_create(&beeper, NULL, &beeper_thread, NULL)) {
printf("Error creating beeper thread!\n");
/* clear beepCmd so that future calls to alBeep() will
* call XBell().
*/
free(psetup.beepCmd);
psetup.beepCmd = NULL;
return;
}
}

/* Audio device not implemented */

/******************************************************
alBeep
******************************************************/
int alBeep(Display *displayBB)
{
/* system("play /path/to/beep.wav"); */
pthread_once(&beep_setup, &setup);

if(!psetup.beepCmd) {
XBell(displayBB,0);
return 0;

} else {
LOCK();

/* wakeup for new command.
* also if still waiting for wakeup
* if beeper didn't start fast enough
* on the previous call.
*/
if(beeping==0 || beeping==2) {
beeping=2;
pthread_cond_broadcast(&beep_wake);
}

UNLOCK();
return 0;
}
}


1 change: 1 addition & 0 deletions test.alhConfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
$BEEPCMD sleep 5;date -R >> alhtest
$BEEPSEVERITY MAJOR
GROUP NULL JBA_TEST_MAIN_GROUP
$COMMAND xload
Expand Down

0 comments on commit 039f535

Please sign in to comment.