void do_shutdown(shutop_t op) { touch(SYNC_SHUTDOWN); if (sdown) run_interactive(sdown, "Calling shutdown hook: %s", sdown); /* Update UTMP db */ utmp_set_halt(); /* * Tell all remaining non-monitored processes to exit, give them * some time to exit gracefully, 2 sec is customary. */ do_kill(SIGTERM); do_sleep(2); do_kill(SIGKILL); /* Exit plugins and API gracefully */ plugin_exit(); api_exit(); /* Reap 'em */ while (waitpid(-1, NULL, WNOHANG) > 0) ; /* Close all local non-console descriptors */ for (int fd = 3; fd < 128; fd++) close(fd); if (vfork()) { /* * Put PID 1 aside and let child perform reboot/halt * kernel may exit child and we don't want to exit PID 1 * ... causing "aiii killing init" during reboot ... */ return; } /* Unmount any tmpfs before unmounting swap ... */ unmount_tmpfs(); run("/sbin/swapoff -e -a"); /* ... unmount remaining regular file systems. */ unmount_regular(); /* We sit on / so we must remount it ro, try all the things! */ sync(); run("/bin/mount -n -o remount,ro -t dummytype dummydev /"); run("/bin/mount -n -o remount,ro dummydev /"); run("/bin/mount -n -o remount,ro /"); /* Call mdadm to mark any RAID array(s) as clean before halting. */ mdadm_wait(); /* Reboot via watchdog or kernel, or shutdown? */ if (op == SHUT_REBOOT) { if (wdogpid) { int timeout = 10; /* Wait here until the WDT reboots, or timeout with fallback */ print(kill(wdogpid, SIGPWR) == 1, "Pending watchdog reboot"); while (timeout--) do_sleep(1); } _d("Rebooting ..."); reboot(RB_AUTOBOOT); } else if (op == SHUT_OFF) { _d("Powering down ..."); reboot(RB_POWER_OFF); } /* Also fallback if any of the other two fails */ _d("Halting ..."); reboot(RB_HALT_SYSTEM); }
int plugin_run(struct playerHandles *ph, char *key, int *totaltime){ size_t size; size_t len; int mret=MPG123_NEED_MORE; int retval=DEC_RET_SUCCESS; struct outputdetail *details=ph->outdetail; unsigned char *out; int outsize; if(mp3Init(ph)<0)return DEC_RET_ERROR; details->totaltime=*totaltime>0?*totaltime:-1; details->percent=-1; ph->dechandle=&h; pthread_mutex_lock(&dechandle_lock); new_format(ph); outsize=mpg123_outblock(h.m); pthread_mutex_unlock(&dechandle_lock); h.tcarry=0; h.total=0; h.accuracy=1000; if(!(out=malloc(sizeof(unsigned char)*outsize))){ fprintf(stderr,"Malloc failed (out decoder buffer)."); plugin_exit(ph); return DEC_RET_ERROR; } do{ /* Read and write until everything is through. */ //if outbuff isn't big enough to hold all decoded data from inbuff, keep going if(mret != MPG123_NEED_MORE){ pthread_mutex_lock(&dechandle_lock); mret=mpg123_read(h.m,out,outsize,&len); pthread_mutex_unlock(&dechandle_lock); } else{ pthread_mutex_lock(&dechandle_lock); mret=mpg123_read(h.m,out,outsize,&len); pthread_mutex_unlock(&dechandle_lock); if(mret==MPG123_DONE || mret==MPG123_ERR){ // EOF (or read error) retval=DEC_RET_SUCCESS; break; } } if(mret==MPG123_NEW_FORMAT){ //fprintf(stderr,"Should have reformatted here."); pthread_mutex_lock(&dechandle_lock); new_format(ph); pthread_mutex_unlock(&dechandle_lock); } if(len==0)continue; size=len; pthread_mutex_lock(&dechandle_lock); details->curtime=h.total; details->percent=(details->curtime*100)/details->totaltime; h.tcarry+=size; if(h.tcarry>=h.samptime){ h.total+=h.tcarry/h.samptime; h.tcarry%=h.samptime; } pthread_mutex_unlock(&dechandle_lock); #if WITH_ALSA==1 if(writei_snd(ph,(char *)out,size/h.framesize)<0)break; #else if(writei_snd(ph,(char *)out,size)<0)break; #endif /* if(metacount++>2000){ printf("1\n"); metacount=0; pthread_mutex_lock(&dechandle_lock); metaret=mpg123_meta_check(h.m); if(metaret & MPG123_NEW_ICY){ mpg123_icy(h.m,&icymeta); printf("%s\n",icymeta); } pthread_mutex_unlock(&dechandle_lock); }*/ if(ph->pflag->exit!=DEC_RET_SUCCESS){ retval=ph->pflag->exit; break; } }while(mret != MPG123_ERR && mret!=MPG123_DONE); if(mret == MPG123_ERR){ fprintf(stderr, "decoder error: %s", mpg123_strerror(h.m)); if(mpg123_errcode(h.m)!=28) // Common error. quick fix retval=DEC_RET_ERROR; } writei_snd(ph,(char *)out,0); // drain sound buffer /* Done decoding, now just clean up and leave. */ plugin_exit(ph); free(out); *totaltime=details->curtime; return retval; }