/* Cmp3 works by spawning a manager process that takes care of playing the songs while the regular process worries about the actual playlist. This file contains the manager process. */ #include"cmp3manager.h" FILE *debugfile; /* XXX - debug stuff */ void startdebug() { #ifdef CMP3_DEBUG debugfile = fopen(CMP3_LOGFILE, "a"); setbuf(debugfile, NULL); #else /* CMP3_DEBUG */ debugfile = fopen("/dev/null", "w"); return; #endif /* CMP3_DEBUG */ } /************************** MANAGEIT runs in a separate forked process, manages the mp3 process **************************/ void manageit() { /* setpgrp(); */ shmptr = (shmdata_t*) shmat(shmid,NULL,0); if (shmptr < 0) { perror("can't attach shared memory"); dienow(1); } shmptr->managpid = getpid(); shmptr->listlen = 0; shmptr->pid = 0; shmptr->pltail = shmptr->plhead; signal(SIGUSR1,listnext); /* why is this not Signal?? */ Signal(SIGCHLD,listnext); Signal(SIGINT,dienow); Signal(SIGTERM,dienow); startdebug(); if (debugfile) fprintf(debugfile, "Initialized manager process %d\n", getpid()); while (1) /* oh, oh, oh, oh, stayin' alive, stayin' alive */ /* FIXME: what happens if there IS no stdin? i.e. tty goes away? */ select(0,NULL,NULL,NULL,NULL); exit(0); } /****************************************** LISTNEXT plays the next file in the list. *******************************************/ void listnext(int signum) { int pid; /* first reap dead pid's (HACK!) */ if(kill(shmptr->pid,0)){ shmptr->pid = 0; } if (shmptr->pause) return; if (signum==SIGCHLD) { while(waitpid(-1,NULL,WNOHANG) > 0) ; if ((shmptr->listlen > 1)) { if (shmptr->repeat == 1) { pl_addentry(shmptr->plhead); } pl_delentry(shmptr->plhead); } else { if (shmptr->repeat != 1) { if (shmptr->using == 0) { dienow(1); } else { shmptr->listlen = 0; shmptr->pltail = shmptr->plhead; return; } } else { /* In repeat mode, keep playing */ } } shmptr->pid=0; /* old sysv style, must reset this here */ Signal(SIGCHLD,listnext); } else { /* FIXME: ok, this must be where it is returning cause pid full? */ if (shmptr->pid) { if(kill(shmptr->pid, 0) ){ shmptr->pid = 0; } return; } /* old sysv style, must reset this here */ signal(SIGUSR1,listnext); } if (shmptr->listlen > 0) { /* check for file type, launch either mpg123 or ogg123 */ if (Strcmp(shmptr->plhead+(strlen(shmptr->plhead)-4),".mp3") == 0){ pid = fork(); if (pid == -1) { perror("Cant fork"); exit(0); } if (pid==0) { int returned=0; sleep(1); fclose(stdin); /* Route all mpg123 output from stderr to logfile */ if (debugfile) { dup2(fileno(debugfile), fileno(stderr)); dup2(fileno(debugfile), fileno(stdout)); } else { fclose(stderr); } returned = execlp(EXEC_LOC, "mpg123", EXEC_PARAMS shmptr->plhead, 0); if (returned != 0) { fprintf(debugfile, "execlp failed on %s with errno = %d\n", shmptr->plhead, errno); } exit(0); } shmptr->pid=pid; } else if (Strcmp(shmptr->plhead+(strlen(shmptr->plhead)-4),".ogg") == 0){ pid = fork(); if (pid == -1) { perror("Cant fork"); exit(0); } if (pid==0) { int returned=0; sleep(1); fclose(stdin); /* Route all mpg123 output from stderr to logfile */ if (debugfile) { dup2(fileno(debugfile), fileno(stderr)); dup2(fileno(debugfile), fileno(stdout)); } else { fclose(stderr); } returned = execlp(OGG_LOC, "ogg123", OGG_PARAMS shmptr->plhead, 0); if (returned != 0) { fprintf(debugfile, "execlp failed on %s with errno = %d\n", shmptr->plhead, errno); } exit(0); } shmptr->pid=pid; } else { fprintf(debugfile, "listnext: %s is not an mp3 or ogg file\n", shmptr->plhead); return; } /* end ogg/mp3 contingencies */ } /* end listlen > 0 */ } /* END LISTNEXT */ void dienow(int diedude) { if (shmptr->pause == 1) kill(shmptr->pid, SIGCONT); if (shmptr->pid) kill(shmptr->pid,SIGINT); fprintf(debugfile, "Exiting manager process %d\n", getpid()); fclose(debugfile); if (shmdt((char*)shmptr) < 0) perror("can't detach shared memory"); if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0) < 0) perror("can't remove shared memory"); exit(1); } /* EOF */