📄 server.c
字号:
*/ strcpy(svr.path,RECORD_PATH); /* Always record to same place */ msg.msg_type = ToClnt_Path; strcpy(msg.u.toclnt_path.path,svr.path); msg.bytes = strlen(msg.u.toclnt_path.path); MsgToClient(clntIPC,&msg,0); /* Send back our path */ /* * Try to acquire the record lock on the device: */ if ( svr.lockIPCID >= 0 && LockDSP(svr.lockIPCID,1,x_erf,RECDLOCK_SECS) ) return 0; /* No lock acquired */ /* * Now attempt to open for write: */ svr.wfile = WavOpenForWrite(svr.path, pmsg->u.tosvr_record.Channels, pmsg->u.tosvr_record.SamplingRate, pmsg->u.tosvr_record.DataBits, 999999, x_erf); /* * Send back error info if we fail open: */ if ( svr.wfile == NULL ) { msg.u.toclnt_stat.Errno = errno == 0 ? EINVAL : errno; msg.msg_type = ToClnt_Stat; /* We're sending stat info back */ msg.bytes = sizeof msg.u.toclnt_stat; MsgToClient(clntIPC,&msg,0); /* * Release the record lock on the device: */ if ( svr.lockIPCID >= 0 ) UnlockDSP(svr.lockIPCID,1,x_erf); return 1; } /* * Clear all overrides: */ svr.opts.SamplingRate.optChar = 0; svr.opts.Channels.optChar = 0; svr.opts.DataBits.optChar = 0; /* * Start recording: */ svr_work_proc = ServerWorkProc; wavrecd(&svr.opts,NULL,x_erf); /* Record file */ svr_work_proc = NULL; /* * Release the record lock on the device: */ if ( svr.lockIPCID >= 0 ) UnlockDSP(svr.lockIPCID,1,x_erf); goto updt; /* Update client */ } else if ( pmsg->msg_type == ToSvr_Debug ) { cmdopt_x = pmsg->u.tosvr_debug.bDebugMode ? 1 : 0; return 0; /* Continue biz as usual */ } else if ( pmsg->msg_type == ToSvr_SemReset ) { /* * Remove old semaphore set : */ if ( semctl(svr.lockIPCID,0,IPC_RMID,NULL) < 0 ) { toclnt_fatal(0,"%s: Unable to remove old locking semaphores.",sys_errlist[errno]); exit(13); } /* * Open new semaphore set: */ if ( (svr.lockIPCID = OpenDSPLocks(svr.IPCKey,1,x_erf)) < 0 ) { toclnt_fatal(0,"%s:\nAttempting to obtain new locking\nsemaphores.", sys_errlist[errno]); exit(13); } /* * Provide reset feedback to client program: */ ClntMsg("Old semaphores have been released.\n" "The new semaphore set for IPC Key 0x%08lX (%lu)\n" "is now IPC ID %d.", (unsigned long)svr.IPCKey, (unsigned long)svr.IPCKey, (int)svr.lockIPCID); } else { ClntMsg("Unknown server request type %u\n",(unsigned)pmsg->msg_type); return 1; } return 1; /* Unknown request */}/* * This process is called during a "Playing/Recording" of a WAV file. If we return * TRUE, this process will stop. */intServerWorkProc(DSPFILE *dfile) { SVRMSG msg; int z; if ( MsgFromClient(clntIPC,&msg,IPC_NOWAIT) != 0 ) return 0; /* No messages from client */ /* * Shut the DSP up right away if we hit pause: */ if ( msg.msg_type == ToSvr_Pause ) ioctl(dfile->fd,SNDCTL_DSP_RESET,0); /* * If we get a Pause request, we block here indefinitely until * another message from the client arrives: */ while ( msg.msg_type == ToSvr_Pause ) { /* * During a "pause", we block on a client request message get: */ if ( MsgFromClient(clntIPC,&msg,0) ) return -1; /* Failed msg read */ } /* * Non pause message received: */ z = Serve(&msg,1); /* Server from within work procedure */ if ( z ) /* Shut up DSP if we're stopping */ ioctl(dfile->fd,SNDCTL_DSP_RESET,0); return z;}/* * This is the main server loop: */intServer(key_t IPCKey) { SVRMSG msg; uid_t uid; int z; memset(&svr,0,sizeof svr); /* Initialize server state */ svr.opts.ipc = -1; *svr.path = 0; /* No pathname yet */ svr.wfile = NULL; /* No open file yet */ svr.IPCKey = IPCKey; svr.lockIPCID = OpenDSPLocks(svr.IPCKey,1,x_erf);#ifdef SCHED_PRIORITY /* * Set real time scheduling parameters: */ { struct sched_param rtp; pid_t pid = getpid(); rtp.sched_priority = SCHED_PRIORITY; if ( sched_setscheduler(pid,SCHED_FIFO,&rtp) != 0 ) { z = errno; fprintf(stderr,"WARNING; %s: sched_setscheduler(%ld,SCHED_FIFO,) // priority=%d;\n", sys_errlist[z],(long)pid,(int)SCHED_PRIORITY); if ( z == EPERM && rtp.sched_priority > 0 ) fputs("You need setuid root to use sched_setscheduler()\n",stderr); fflush(stderr); } }#endif if ( (uid = geteuid()) == 0 ) setuid(getuid()); toclnt_ready(0); /* Tell client we're ready */ while ( !bExit && !MsgFromClient(clntIPC,&msg,0) ) Serve(&msg,0); exit(0);}/* * Server -> Client * * Tell client that server is ready: * Returns 0 if message sent. flags can be IPC_NOWAIT. */voidtoclnt_ready(int flags) { SVRMSG msg; msg.msg_type = ToClnt_Ready; msg.bytes = 0; if ( MsgToClient(clntIPC,&msg,flags) != 0 ) { /* Send to client */ ClntMsg("%s: toclnt_ready(flags=0%o;ipc=%d)\n",sys_errlist[errno],flags,clntIPC); exit(13); }}/* * Server -> Client * * Tell client that server is ready: */voidtoclnt_bits(int flags,int bits) { SVRMSG msg; msg.msg_type = ToClnt_Bits; msg.bytes = sizeof msg.u.toclnt_bits; msg.u.toclnt_bits.DataBits = bits; if ( MsgToClient(clntIPC,&msg,flags) != 0 ) { /* Send to client */ ClntMsg("%s: toclnt_ready(flags=0%o;ipc=%d)\n",sys_errlist[errno],flags,clntIPC); exit(13); }}/* * Sever -> Client * * Tell client many of the current server settings: */inttoclnt_settings(int flags,WAVFILE *wfile,WavPlayOpts *wavopts) { SVRMSG msg; int z; memset(&msg,0,sizeof msg); msg.msg_type = ToClnt_Settings; if ( wfile != NULL ) { /* * We have a WAV file open: */ WavReadOverrides(wfile,wavopts); /* Apply current overrides */ msg.u.toclnt_settings.SamplingRate = wfile->wavinfo.SamplingRate; msg.u.toclnt_settings.Channels = wfile->wavinfo.Channels; msg.u.toclnt_settings.Samples = wfile->wavinfo.Samples; msg.u.toclnt_settings.DataBits = wfile->wavinfo.DataBits; msg.u.toclnt_settings.bOvrSampling = wfile->wavinfo.bOvrSampling; msg.u.toclnt_settings.bOvrMode = wfile->wavinfo.bOvrMode; msg.u.toclnt_settings.bOvrBits = wfile->wavinfo.bOvrBits; } else { /* * No WAV file open: */ if ( (msg.u.toclnt_settings.bOvrSampling = wavopts->SamplingRate.optChar ? 1 : 0) != 0 ) msg.u.toclnt_settings.SamplingRate = wavopts->SamplingRate.optValue; else msg.u.toclnt_settings.SamplingRate = 8000; if ( (msg.u.toclnt_settings.bOvrMode = wavopts->Channels.optChar ? 1 : 0) != 0 ) msg.u.toclnt_settings.Channels = wavopts->Channels.optValue; else msg.u.toclnt_settings.Channels = Mono; if ( (msg.u.toclnt_settings.bOvrBits = wavopts->DataBits.optChar ? 1 : 0) != 0 ) msg.u.toclnt_settings.DataBits = wavopts->DataBits.optValue; else msg.u.toclnt_settings.DataBits = 8; } /* For now: */ strcpy(msg.u.toclnt_settings.WavType,"PCM"); msg.bytes = sizeof msg.u.toclnt_settings; if ( (z = MsgToClient(clntIPC,&msg,flags)) != 0 && flags && errno != EAGAIN ) { toclnt_fatal(0,"%s: toclnt_settings(flags=0%o;ipc=%d)\n",sys_errlist[errno],flags,clntIPC); exit(13); } return z >= 0 ? 0 : -1;}/* * Tell client about fatal server error: */ inttoclnt_fatal(int flags,const char *format,...) { SVRMSG msg; va_list ap; char buf[2048]; msg.msg_type = ToClnt_Fatal; /* Fatal server error */ msg.bytes = sizeof msg.u.toclnt_fatal; /* Message bytes */ msg.u.toclnt_fatal.Errno = errno; /* Pass back errno value */ va_start(ap,format); vsprintf(buf,format,ap); va_end(ap); strncpy(msg.u.toclnt_fatal.msg,buf,sizeof msg.u.toclnt_fatal.msg)[sizeof msg.u.toclnt_fatal.msg-1] = 0; return MsgToClient(clntIPC,&msg,flags); /* Send message to client */}/* * Send an error message back to the client process: */static voidtoclnt_errmsg(int msg_errno,const char *message,int flags) { SVRMSG msg; msg.msg_type = ToClnt_ErrMsg; msg.bytes = sizeof msg.u.toclnt_errmsg; msg.u.toclnt_errmsg.Errno = msg_errno; strncpy(msg.u.toclnt_errmsg.msg,message,sizeof msg.u.toclnt_errmsg.msg) [sizeof msg.u.toclnt_errmsg.msg - 1] = 0; if ( MsgToClient(clntIPC,&msg,flags) != 0 ) { /* Send to client */ fprintf(stderr,"%s: toclnt_errmsg(...)\n",sys_errlist[errno]); exit(13); }}/* $Source: /home/cvs/wavplay/server.c,v $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -