1 /*
2 Cmp3 works by spawning a manager process that takes care of playing the
3 songs while the regular process worries about the actual playlist.
4 This file contains the manager process.
5 */
6
7 #include"cmp3manager.h"
8
9 FILE *debugfile;
10
11
12 /* XXX - debug stuff */
startdebug()13 void startdebug()
14 {
15 #ifdef CMP3_DEBUG
16 debugfile = fopen(CMP3_LOGFILE, "a");
17 setbuf(debugfile, NULL);
18 #else /* CMP3_DEBUG */
19 debugfile = fopen("/dev/null", "w");
20 return;
21 #endif /* CMP3_DEBUG */
22 }
23
24
25 /**************************
26 MANAGEIT
27 runs in a separate forked process,
28 manages the mp3 process
29 **************************/
manageit()30 void manageit()
31 {
32 /* setpgrp(); */
33 shmptr = (shmdata_t*) shmat(shmid,NULL,0);
34 if (shmptr < 0) {
35 perror("can't attach shared memory");
36 dienow(1);
37 }
38 shmptr->managpid = getpid();
39 shmptr->listlen = 0;
40 shmptr->pid = 0;
41 shmptr->pltail = shmptr->plhead;
42 signal(SIGUSR1,listnext); /* why is this not Signal?? */
43 Signal(SIGCHLD,listnext);
44 Signal(SIGINT,dienow);
45 Signal(SIGTERM,dienow);
46
47 startdebug();
48 if (debugfile)
49 fprintf(debugfile, "Initialized manager process %d\n", getpid());
50
51 while (1)
52 /* oh, oh, oh, oh, stayin' alive, stayin' alive */
53 /* FIXME: what happens if there IS no stdin? i.e. tty goes away? */
54 select(0,NULL,NULL,NULL,NULL);
55 exit(0);
56 }
57
58 /******************************************
59 LISTNEXT
60 plays the next file in the list.
61 *******************************************/
listnext(int signum)62 void listnext(int signum)
63 {
64 int pid;
65
66 /* first reap dead pid's (HACK!) */
67 if(kill(shmptr->pid,0)){
68 shmptr->pid = 0;
69 }
70
71 if (shmptr->pause)
72 return;
73
74 if (signum==SIGCHLD) {
75 while(waitpid(-1,NULL,WNOHANG) > 0)
76 ;
77 if ((shmptr->listlen > 1)) {
78
79 if (shmptr->repeat == 1) {
80 pl_addentry(shmptr->plhead);
81 }
82 pl_delentry(shmptr->plhead);
83 } else {
84 if (shmptr->repeat != 1) {
85 if (shmptr->using == 0) {
86 dienow(1);
87 } else {
88 shmptr->listlen = 0;
89 shmptr->pltail = shmptr->plhead;
90 return;
91 }
92 } else {
93 /* In repeat mode, keep playing */
94 }
95 }
96 shmptr->pid=0;
97 /* old sysv style, must reset this here */
98 Signal(SIGCHLD,listnext);
99 } else {
100 /* FIXME: ok, this must be where it is returning cause pid full? */
101 if (shmptr->pid) {
102 if(kill(shmptr->pid, 0) ){
103 shmptr->pid = 0;
104 }
105 return;
106 }
107 /* old sysv style, must reset this here */
108 signal(SIGUSR1,listnext);
109 }
110 if (shmptr->listlen > 0) {
111 /* check for file type, launch either mpg123 or ogg123 */
112 if (Strcmp(shmptr->plhead+(strlen(shmptr->plhead)-4),".mp3") == 0){
113 pid = fork();
114 if (pid == -1) {
115 perror("Cant fork");
116 exit(0);
117 }
118 if (pid==0) {
119 int returned=0;
120
121 sleep(1);
122 fclose(stdin);
123
124 /* Route all mpg123 output from stderr to logfile */
125 if (debugfile) {
126 dup2(fileno(debugfile), fileno(stderr));
127 dup2(fileno(debugfile), fileno(stdout));
128 } else {
129 fclose(stderr);
130 }
131
132 returned = execlp(EXEC_LOC,
133 "mpg123",
134 EXEC_PARAMS
135 shmptr->plhead, 0);
136
137
138
139 if (returned != 0) {
140 fprintf(debugfile, "execlp failed on %s with errno = %d\n",
141 shmptr->plhead, errno);
142 }
143
144 exit(0);
145 }
146 shmptr->pid=pid;
147 } else if (Strcmp(shmptr->plhead+(strlen(shmptr->plhead)-4),".ogg") == 0){
148 pid = fork();
149 if (pid == -1) {
150 perror("Cant fork");
151 exit(0);
152 }
153 if (pid==0) {
154 int returned=0;
155
156 sleep(1);
157 fclose(stdin);
158
159 /* Route all mpg123 output from stderr to logfile */
160 if (debugfile) {
161 dup2(fileno(debugfile), fileno(stderr));
162 dup2(fileno(debugfile), fileno(stdout));
163 } else {
164 fclose(stderr);
165 }
166
167
168 returned = execlp(OGG_LOC,
169 "ogg123",
170 OGG_PARAMS
171 shmptr->plhead, 0);
172
173
174 if (returned != 0) {
175 fprintf(debugfile, "execlp failed on %s with errno = %d\n",
176 shmptr->plhead, errno);
177 }
178
179 exit(0);
180 }
181 shmptr->pid=pid;
182 } else {
183 fprintf(debugfile, "listnext: %s is not an mp3 or ogg file\n",
184 shmptr->plhead);
185 return;
186 } /* end ogg/mp3 contingencies */
187 } /* end listlen > 0 */
188 } /* END LISTNEXT */
189
dienow(int diedude)190 void dienow(int diedude)
191 {
192 if (shmptr->pause == 1)
193 kill(shmptr->pid, SIGCONT);
194 if (shmptr->pid)
195 kill(shmptr->pid,SIGINT);
196
197 fprintf(debugfile, "Exiting manager process %d\n", getpid());
198 fclose(debugfile);
199
200 if (shmdt((char*)shmptr) < 0)
201 perror("can't detach shared memory");
202 if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0) < 0)
203 perror("can't remove shared memory");
204
205 exit(1);
206 }
207
208 /* EOF */
209