1 /*
2  * Copyright (C) 2000-2011 the xine project,
3  *
4  * This file is part of xine, a free video player.
5  *
6  * xine is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * xine is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  */
21 
22 /* Standard includes */
23 #include "config.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <sys/types.h>
30 
31 #ifndef WIN32
32 #include <sys/wait.h>
33 #include <sys/ioctl.h>
34 #endif
35 
36 #include <unistd.h>
37 #include <string.h>
38 
39 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD_kernel__)
40 #include <sys/cdio.h> /* CDIOCALLOW etc... */
41 #elif defined(HAVE_LINUX_CDROM_H)
42 #include <linux/cdrom.h>
43 #elif defined(HAVE_SYS_CDIO_H)
44 #include <sys/cdio.h>
45 #elif WIN32
46 #else
47 #warning "This might not compile due to missing cdrom ioctls"
48 #endif
49 
50 #include "media_helper.h"
51 
52 #define LOG_MEDIA_EJECT
53 
54 #ifndef WIN32
media_umount_media(const char * device)55 static int media_umount_media(const char *device)
56 {
57   pid_t pid;
58   int status;
59 
60   pid=fork();
61   if (pid == 0) {
62     execl("/bin/umount", "umount", device, NULL);
63     exit(127);
64   }
65   do {
66     if(waitpid(pid, &status, 0) == -1) {
67       if (errno != EINTR)
68 	return -1;
69     }
70     else {
71       return WEXITSTATUS(status);
72     }
73   } while(1);
74 
75   return -1;
76 }
77 #endif
78 
media_eject_media(xine_t * xine,const char * device)79 int media_eject_media (xine_t *xine, const char *device)
80 {
81 #if defined (__sun)
82 
83   if (fork() == 0) {
84     execl("/usr/bin/eject", "eject", device, NULL);
85     _exit(EXIT_FAILURE);
86   }
87 
88   return 1;
89 
90 #elif defined (WIN32)
91 
92   return 0;
93 
94 #else
95 
96   int fd;
97 
98   /* printf("input_dvd: Eject Device %s current device %s opened=%d handle=%p trying...\n",device, this->current_dvd_device, this->opened, this->dvdnav); */
99   media_umount_media(device);
100   /* printf("input_dvd: umount result: %s\n", strerror(errno)); */
101 
102   if ((fd = xine_open_cloexec(device, O_RDONLY|O_NONBLOCK)) > -1) {
103 
104 #if defined (__linux__)
105     int ret, status;
106 
107     if((status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) {
108       switch(status) {
109       case CDS_TRAY_OPEN:
110         if((ret = ioctl(fd, CDROMCLOSETRAY)) != 0) {
111 #ifdef LOG_MEDIA_EJECT
112           printf("input_dvd: CDROMCLOSETRAY failed: %s\n", strerror(errno));
113 #endif
114         }
115         break;
116       case CDS_DISC_OK:
117         if((ret = ioctl(fd, CDROMEJECT)) != 0) {
118 #ifdef LOG_MEDIA_EJECT
119           printf("input_dvd: CDROMEJECT failed: %s\n", strerror(errno));
120 #endif
121         }
122         break;
123       }
124     }
125     else {
126 #ifdef LOG_MEDIA_EJECT
127       printf("input_dvd: CDROM_DRIVE_STATUS failed: %s\n", strerror(errno));
128 #endif
129       close(fd);
130       return 0;
131     }
132 
133 #elif defined (__NetBSD__) || defined (__OpenBSD__) || defined (__FreeBSD_kernel__)
134 
135     if (ioctl(fd, CDIOCALLOW) == -1) {
136       xprintf(xine, XINE_VERBOSITY_DEBUG, "ioctl(cdromallow): %s\n", strerror(errno));
137     } else {
138       if (ioctl(fd, CDIOCEJECT) == -1) {
139         xprintf(xine, XINE_VERBOSITY_DEBUG, "ioctl(cdromeject): %s\n", strerror(errno));
140       }
141     }
142 
143 #endif
144 
145     close(fd);
146   }
147   else {
148     xprintf(xine, XINE_VERBOSITY_LOG, _("input_dvd: Device %s failed to open during eject calls\n"), device);
149   }
150 
151   return 1;
152 
153 #endif
154 }
155 
156