1 /* Background Sound Library
2  *
3  * Copyright 1993 by Kurt Siegl <007@netrek.org> Permission to use,
4  * modify, copy and distribute this software without fee is hereby granted as
5  * long as this notice is left here.
6  *
7  */
8 
9 #include "config.h"
10 
11 #if defined(SOUND) && !defined(sgi)
12 #include <stdio.h>
13 #include INC_UNISTD
14 #include INC_STDLIB
15 #include INC_LIMITS
16 #include INC_FCNTL
17 #include INC_STRINGS
18 #include <signal.h>
19 #include <sys/ipc.h>
20 #include <sys/shm.h>
21 
22 #include "audio.h"
23 #include "defaults.h"
24 
25 static int snd_pid, SoundRet = -1, shmid;
26 
27 static struct shm_sound *shared_data;
28 
29 static  RETSIGTYPE
RetOk(int _dummy)30         RetOk(int _dummy)
31 {
32   SoundRet = 0;
33 }
34 
35 static  RETSIGTYPE
RetErr(int _dummy)36         RetErr(int _dummy)
37 {
38   SoundRet = -1;
39 }
40 
41 extern void
ExitSound(void)42         ExitSound(void)
43 {
44   kill(snd_pid, SIGINT);
45   shmctl(shmid, IPC_RMID, 0);
46 }
47 
InitSound(void)48 extern int InitSound(void) {
49 
50   char   *argv[5], shmids[10], mypid[10], *sound_player;
51   int     argc = 0;
52   int     pid, shmKey = IPC_PRIVATE;
53   struct shmid_ds smbuf;
54 
55   /* if ((shmid=shmget(shmKey, sizeof(struct shm_sound),0))>=0) { * *
56    * fprintf(stderr,"Killing Sound Shared Memory\n"); shmctl(shmid, IPC_RMID,
57    * * * 0); } */
58 
59   if ((shmid = shmget(shmKey, sizeof(struct shm_sound), (IPC_CREAT | 0777))) < 0)
60     {
61       perror("Can't open Sound Shared Memory\n");
62       return (-1);
63     }
64 
65   shmctl(shmid, IPC_STAT, &smbuf);
66   smbuf.shm_perm.uid = getuid();
67   smbuf.shm_perm.mode = 0777;
68   shmctl(shmid, IPC_SET, &smbuf);
69 
70   if ((shared_data = (struct shm_sound *) shmat(shmid, 0, 0)) == (void *) -1)
71     {
72       perror("shm attach failed");
73       return (-1);
74     }
75 
76   SoundRet = 1;
77   SIGNAL(SIGUSR1, RetOk);
78   SIGNAL(SIGUSR2, RetErr);
79   SIGNAL(SIGCHLD, RetErr);
80   sprintf(shmids, "%i", shmid);
81   sprintf(mypid, "%i", getpid());
82 
83   if ((pid = vfork()) == 0)
84     {
85 
86       /* setsid();  Make it independend of the main program */
87 
88       if ((sound_player = (char *) getdefault("soundplayer")) == NULL)
89 	sound_player = SOUNDPLAYER;
90       argv[argc++] = sound_player;
91       argv[argc++] = (char *) shmids;
92       argv[argc++] = (char *) mypid;
93       argv[argc] = NULL;
94 
95       SIGNAL(SIGINT, SIG_DFL);
96       execvp(sound_player, argv);
97       perror(sound_player);
98       fflush(stderr);
99       SoundRet = -2;
100       _exit(-1);
101     }
102 
103   if (pid == -1)
104     {
105       perror("forking");
106       return (-1);
107     }
108 
109   snd_pid = pid;
110   if (SoundRet >0 )
111     pause();
112   if (SoundRet)
113     ExitSound();
114   return (SoundRet);
115 
116 }
117 
118 extern void
StopSound(void)119         StopSound(void)
120 {
121   kill(snd_pid, SIGUSR1);
122 }
123 
StartSound(char * name)124 extern int StartSound(char *name) {
125   strcpy(shared_data->name, name);
126   kill(snd_pid, SIGUSR2);
127   return (0);
128 }
129 
130 extern int
SoundPlaying()131         SoundPlaying()
132 {
133   return (shared_data->play_sound);
134 }
135 #endif
136