source: roaraudio/libroar/cdrom.c @ 5376:c8f94c6ad2a3

Last change on this file since 5376:c8f94c6ad2a3 was 5373:8da157c10483, checked in by phi, 12 years ago
  • Updated config structure
  • Added a flag to ask libroar to only connect to local servers
  • Added a way to override fork()
  • added support for +internal
File size: 6.3 KB
Line 
1//cdrom.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2011
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38#define ROAR_CDROM_ERROR_NORETURN(format, args...) ROAR_ERR(format, ## args); _exit(3)
39
40#if BYTE_ORDER == BIG_ENDIAN
41#define ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT "--output-raw-big-endian"
42#elif BYTE_ORDER == LITTLE_ENDIAN
43#define ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT "--output-raw-little-endian"
44#endif
45
46#ifdef ROAR_TARGET_WIN32
47#undef ROAR_HAVE_BIN_CDPARANOIA
48#endif
49
50pid_t roar_cdrom_run_cdparanoia (int cdrom, int data, int track, char * pos) {
51#if defined(ROAR_HAVE_BIN_CDPARANOIA) && defined(ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT) && defined(ROAR_HAVE_CDROM)
52 char my_pos[32] = {0};
53 pid_t pid;
54 int fh[2];
55
56 ROAR_DBG("roar_cdrom_run_cdparanoia(cdrom=%i, data=%i, track=%i, pos='%s') = ?", cdrom, data, track, pos);
57
58 if ( cdrom == -1 || data == -1 || (track == -1 && pos == NULL) || (track != -1 && pos != NULL) )
59  return -1;
60
61 if ( track != -1 ) {
62  pos = my_pos;
63  snprintf(pos, 32, "%i", track);
64 }
65
66 if ( (pid = roar_fork(NULL)) == (pid_t)-1 ) {
67  return -1;
68 }
69
70 if ( pid )
71  return pid;
72
73 fh[0] = dup(cdrom);
74 fh[1] = dup(data);
75
76 if ( fh[0] == -1 || fh[1] == -1 ) {
77  ROAR_CDROM_ERROR_NORETURN("Can not dup(): %s", strerror(errno));
78 }
79
80 close(ROAR_STDIN);
81 close(ROAR_STDOUT);
82
83 // TODO: should I close some other handles?
84
85 if ( dup2(fh[0], ROAR_STDIN) == -1 || dup2(fh[1], ROAR_STDOUT) == -1 ) {
86  ROAR_CDROM_ERROR_NORETURN("Can not dup2(): %s", strerror(errno));
87 }
88
89 // now close our backups:
90 close(fh[0]);
91 close(fh[1]);
92
93 execl(ROAR_HAVE_BIN_CDPARANOIA, "cdparanoia", "--force-cdrom-device", "/dev/stdin", "-q",
94                ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT, pos, "-", NULL);
95
96 ROAR_CDROM_ERROR_NORETURN("We are still alive after exec()!, very bad!, error was: %s", strerror(errno));
97 return -1;
98#else
99#ifndef ROAR_HAVE_BIN_CDPARANOIA
100 ROAR_ERR("roar_cdrom_run_cdparanoia(*): ROAR_HAVE_BIN_CDPARANOIA not defined!");
101#endif
102#ifndef ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT
103 ROAR_ERR("roar_cdrom_run_cdparanoia(*): ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT not defined!");
104#endif
105 ROAR_ERR("roar_cdrom_run_cdparanoia(cdrom=%i, data=%i, track=%i, pos='%s') = -1 // no cdparanoia support compiled in",
106             cdrom, data, track, pos);
107 return -1;
108#endif
109}
110
111int roar_cdrom_open (struct roar_connection * con, struct roar_cdrom * cdrom, const char * device, int mixer) {
112#ifdef ROAR_HAVE_CDROM
113 int flags;
114
115 if ( cdrom == NULL )
116  return -1;
117
118 memset((void*)cdrom, 0, sizeof(struct roar_cdrom));
119
120 if ( device == NULL )
121  device = roar_cdromdevice();
122
123 if ( device == NULL )
124  return -1;
125
126 strncpy(cdrom->device, device, ROAR_CDROM_MAX_DEVLEN);
127
128 cdrom->con        = con; // we do not care here if it is set or not as we can operate in local only mode
129 cdrom->mixer      = mixer;
130
131 cdrom->stream     = -1;
132 cdrom->play_local =  1;
133 cdrom->player     = -1;
134
135 if ( (cdrom->fh = open(cdrom->device, O_RDONLY, 0644)) == -1 )
136  return -1;
137
138#ifndef ROAR_TARGET_WIN32
139 if ( (flags = fcntl(cdrom->fh, F_GETFL, 0)) == -1 ) {
140  close(cdrom->fh);
141  cdrom->fh  = -1;
142  return -1;
143 }
144
145 flags |= FD_CLOEXEC;
146
147 if ( fcntl(cdrom->fh, F_SETFL, flags) == -1 ) {
148  close(cdrom->fh);
149  cdrom->fh = -1;
150  return -1;
151 }
152#endif
153
154 return 0;
155#else
156 return -1;
157#endif
158}
159
160int roar_cdrom_close(struct roar_cdrom * cdrom) {
161#ifdef ROAR_HAVE_CDROM
162 if ( cdrom == NULL )
163  return -1;
164
165 roar_cdrom_stop(cdrom); // stop on close
166
167 if ( cdrom->fh != -1 )
168  close(cdrom->fh);
169
170 memset((void*)cdrom, 0, sizeof(struct roar_cdrom));
171
172 return 0;
173#else
174 return -1;
175#endif
176}
177
178int roar_cdrom_stop (struct roar_cdrom * cdrom) {
179#ifdef ROAR_HAVE_CDROM
180 int ret;
181
182 if ( cdrom == NULL )
183  return -1;
184
185 if ( cdrom->con == NULL )
186  return -1;
187
188 if ( cdrom->stream == -1 )
189  return -1;
190
191 if ( (ret = roar_kick(cdrom->con, ROAR_OT_STREAM, cdrom->stream)) == -1 ) {
192  return -1;
193 }
194
195#ifndef ROAR_TARGET_WIN32
196 if ( cdrom->player != -1 )
197  kill(cdrom->player, SIGINT);
198#else
199 if ( cdrom->player != -1 ) {
200  ROAR_ERR("roar_cdrom_stop(*): Can not kill player with pid %i, not supported on win32", cdrom->player);
201 }
202#endif
203
204 cdrom->player = -1;
205 cdrom->stream = -1;
206
207 return ret;
208#else
209 return -1;
210#endif
211}
212
213int roar_cdrom_play (struct roar_cdrom * cdrom, int track) {
214#ifdef ROAR_HAVE_CDROM
215 struct roar_vio_calls vio;
216 struct roar_stream stream[1];
217 int stream_fh;
218
219 if ( cdrom == NULL )
220  return -1;
221
222 if ( cdrom->con == NULL )
223  return -1;
224
225 if ( cdrom->stream != -1 ) {
226  if ( roar_cdrom_stop(cdrom) == -1 )
227   return -1;
228 }
229
230 if ( cdrom->play_local ) {
231
232  if ( roar_vio_simple_new_stream_obj(&vio, cdrom->con, stream, ROAR_CDROM_STREAMINFO, ROAR_DIR_PLAY, cdrom->mixer) == -1 ) {
233   return -1;
234  }
235
236  if ( roar_vio_ctl(&vio, ROAR_VIO_CTL_GET_WRITE_FH, &stream_fh) == -1 ) {
237   roar_vio_close(&vio);
238   return -1;
239  }
240
241  if ( (cdrom->player = roar_cdrom_run_cdparanoia(cdrom->fh, stream_fh, track, NULL)) != -1 ) {
242   cdrom->stream = stream->id;
243   return 0;
244  }
245
246  roar_vio_close(&vio);
247
248  return -1;
249 } else {
250  // no support for remote playback yet
251  return -1;
252 }
253#else
254 return -1;
255#endif
256}
257
258//ll
Note: See TracBrowser for help on using the repository browser.