source: roaraudio/libroar/cdrom.c @ 4708:c9d40761088a

Last change on this file since 4708:c9d40761088a was 4708:c9d40761088a, checked in by phi, 13 years ago

updated copyright statements

File size: 6.0 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 = fork()) == -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 // new 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, char * device) {
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
130 cdrom->stream     = -1;
131 cdrom->play_local =  1;
132 cdrom->player     = -1;
133
134 if ( (cdrom->fh = open(cdrom->device, O_RDONLY, 0644)) == -1 )
135  return -1;
136
137#ifndef ROAR_TARGET_WIN32
138 if ( (flags = fcntl(cdrom->fh, F_GETFL, 0)) == -1 ) {
139  close(cdrom->fh);
140  cdrom->fh  = -1;
141  return -1;
142 }
143
144 flags |= FD_CLOEXEC;
145
146 if ( fcntl(cdrom->fh, F_SETFL, flags) == -1 ) {
147  close(cdrom->fh);
148  cdrom->fh = -1;
149  return -1;
150 }
151#endif
152
153 return 0;
154#else
155 return -1;
156#endif
157}
158
159int roar_cdrom_close(struct roar_cdrom * cdrom) {
160#ifdef ROAR_HAVE_CDROM
161 if ( cdrom == NULL )
162  return -1;
163
164 roar_cdrom_stop(cdrom); // stop on close
165
166 if ( cdrom->fh != -1 )
167  close(cdrom->fh);
168
169 memset((void*)cdrom, 0, sizeof(struct roar_cdrom));
170
171 return 0;
172#else
173 return -1;
174#endif
175}
176
177int roar_cdrom_stop (struct roar_cdrom * cdrom) {
178#ifdef ROAR_HAVE_CDROM
179 int ret;
180
181 if ( cdrom == NULL )
182  return -1;
183
184 if ( cdrom->con == NULL )
185  return -1;
186
187 if ( cdrom->stream == -1 )
188  return -1;
189
190 if ( (ret = roar_kick(cdrom->con, ROAR_OT_STREAM, cdrom->stream)) == -1 ) {
191  return -1;
192 }
193
194#ifndef ROAR_TARGET_WIN32
195 if ( cdrom->player != -1 )
196  kill(cdrom->player, SIGINT);
197#else
198 if ( cdrom->player != -1 ) {
199  ROAR_ERR("roar_cdrom_stop(*): Can not kill player with pid %i, not supported on win32", cdrom->player);
200 }
201#endif
202
203 cdrom->player = -1;
204 cdrom->stream = -1;
205
206 return ret;
207#else
208 return -1;
209#endif
210}
211
212int roar_cdrom_play (struct roar_cdrom * cdrom, int track) {
213#ifdef ROAR_HAVE_CDROM
214 int stream_fh;
215 struct roar_stream stream[1];
216
217 if ( cdrom == NULL )
218  return -1;
219
220 if ( cdrom->con == NULL )
221  return -1;
222
223 if ( cdrom->stream != -1 ) {
224  if ( roar_cdrom_stop(cdrom) == -1 )
225   return -1;
226 }
227
228 if ( cdrom->play_local ) {
229
230  if ( (stream_fh = roar_simple_new_stream_obj(cdrom->con, stream, ROAR_CDROM_STREAMINFO, ROAR_DIR_PLAY)) == -1 ) {
231   return -1;
232  }
233
234  if ( (cdrom->player = roar_cdrom_run_cdparanoia(cdrom->fh, stream_fh, track, NULL)) != -1 ) {
235   cdrom->stream = stream->id;
236   return 0;
237  }
238
239  close(stream_fh);
240
241  return -1;
242 } else {
243  // no support for remote playback yet
244  return -1;
245 }
246#else
247 return -1;
248#endif
249}
250
251//ll
Note: See TracBrowser for help on using the repository browser.