drv_pipe.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:4k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* MikMod sound library
  2. (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for
  3. complete list.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of
  7. the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  17. 02111-1307, USA.
  18. */
  19. /*==============================================================================
  20.   $Id: drv_pipe.c,v 1.3 2004/01/31 22:39:40 raph Exp $
  21.   Driver for output via a pipe to another command
  22. ==============================================================================*/
  23. /*
  24. Written by Simon Hosie <gumboot@clear.net.nz>
  25. */
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include "mikmod_internals.h"
  30. #ifdef DRV_PIPE
  31. #ifdef HAVE_UNISTD_H
  32. #include <unistd.h>
  33. #endif
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #if defined unix || (defined __APPLE__ && defined __MACH__)
  37. #include <errno.h>
  38. #include <sys/wait.h>
  39. #endif
  40. #ifdef SUNOS
  41. extern int fclose(FILE *);
  42. #endif
  43. #define BUFFERSIZE 32768
  44. static MWRITER *pipeout=NULL;
  45. static FILE *pipefile=NULL;
  46. #if defined unix || (defined __APPLE__ && defined __MACH__)
  47. static int pipefd[2]={-1,-1};
  48. static pid_t pid;
  49. #endif
  50. static SBYTE *audiobuffer=NULL;
  51. static CHAR *target=NULL;
  52. static void pipe_CommandLine(CHAR *cmdline)
  53. {
  54. CHAR *ptr=MD_GetAtom("pipe",cmdline,0);
  55. if(ptr) {
  56. _mm_free(target);
  57. target=ptr;
  58. }
  59. }
  60. static BOOL pipe_IsThere(void)
  61. {
  62. return 1;
  63. }
  64. static BOOL pipe_Init(void)
  65. {
  66. if(!target) {
  67. _mm_errno=MMERR_OPENING_FILE;
  68. return 1;
  69. }
  70. #if !defined unix && (!defined __APPLE__ || !defined __MACH__)
  71. #ifdef __EMX__
  72. _fsetmode(stdout, "b");
  73. #endif
  74. #ifdef __WATCOMC__
  75. pipefile = _popen(target, "wb");
  76. #else
  77. pipefile = popen(target, "wb");
  78. #endif
  79. if (!pipefile) {
  80. _mm_errno=MMERR_OPENING_FILE;
  81. return 1;
  82. }
  83. #else
  84. /* poor man's popen() */
  85. if (pipe(pipefd)) {
  86. _mm_errno = MMERR_OPENING_FILE;
  87. return 1;
  88. }
  89. switch (pid=fork()) {
  90. case -1:
  91. close(pipefd[0]);
  92. close(pipefd[1]);
  93. pipefd[0]=pipefd[1]=-1;
  94. _mm_errno=MMERR_OPENING_FILE;
  95. return 1;
  96. case 0:
  97. if (pipefd[0]) {
  98. dup2(pipefd[0],0);
  99. close(pipefd[0]);
  100. }
  101. close(pipefd[1]);
  102. if (!MD_DropPrivileges())
  103. execl("/bin/sh","sh","-c",target,NULL);
  104. exit(127);
  105. }
  106. close(pipefd[0]);
  107. if (!(pipefile=fdopen(pipefd[1],"wb"))) {
  108. _mm_errno=MMERR_OPENING_FILE;
  109. return 1;
  110. }
  111. #endif
  112. if(!(pipeout=_mm_new_file_writer(pipefile)))
  113. return 1;
  114. if(!(audiobuffer=(SBYTE*)_mm_malloc(BUFFERSIZE)))
  115. return 1;
  116. md_mode|=DMODE_SOFT_MUSIC|DMODE_SOFT_SNDFX;
  117. return VC_Init();
  118. }
  119. static void pipe_Exit(void)
  120. {
  121. #if defined unix || (defined __APPLE__ && defined __MACH__)
  122. int pstat;
  123. pid_t pid2;
  124. #endif
  125. VC_Exit();
  126. _mm_free(audiobuffer);
  127. if(pipeout) {
  128. _mm_delete_file_writer(pipeout);
  129. pipeout=NULL;
  130. }
  131. if(pipefile) {
  132. #if !defined unix && (!defined __APPLE__ || !defined __MACH__)
  133. #ifdef __WATCOMC__
  134. _pclose(pipefile);
  135. #else
  136. pclose(pipefile);
  137. #endif
  138. #ifdef __EMX__
  139. _fsetmode(stdout,"t");
  140. #endif
  141. #else
  142. fclose(pipefile);
  143. do {
  144. pid2=waitpid(pid,&pstat,0);
  145. } while (pid2==-1 && errno==EINTR);
  146. #endif
  147. pipefile=NULL;
  148. }
  149. }
  150. static void pipe_Update(void)
  151. {
  152. _mm_write_UBYTES(audiobuffer,VC_WriteBytes(audiobuffer,BUFFERSIZE),pipeout);
  153. }
  154. MIKMODAPI MDRIVER drv_pipe={
  155. NULL,
  156. "Piped writer",
  157. "Piped Output driver v0.2",
  158. 0,255,
  159. "pipe",
  160. "pipe:t::Pipe commandn",
  161. pipe_CommandLine,
  162. pipe_IsThere,
  163. VC_SampleLoad,
  164. VC_SampleUnload,
  165. VC_SampleSpace,
  166. VC_SampleLength,
  167. pipe_Init,
  168. pipe_Exit,
  169. NULL,
  170. VC_SetNumVoices,
  171. VC_PlayStart,
  172. VC_PlayStop,
  173. pipe_Update,
  174. NULL,
  175. VC_VoiceSetVolume,
  176. VC_VoiceGetVolume,
  177. VC_VoiceSetFrequency,
  178. VC_VoiceGetFrequency,
  179. VC_VoiceSetPanning,
  180. VC_VoiceGetPanning,
  181. VC_VoicePlay,
  182. VC_VoiceStop,
  183. VC_VoiceStopped,
  184. VC_VoiceGetPosition,
  185. VC_VoiceRealVolume
  186. };
  187. #else
  188. MISSING(drv_pipe);
  189. #endif
  190. /* ex:set ts=4: */