]> git.sesse.net Git - vlc/blob - src/interface/intf_eject.c
* ./include/modules_inner.h: replaced _X with __VLC_SYMBOL because _X was
[vlc] / src / interface / intf_eject.c
1 /*****************************************************************************
2  * intf_eject.c: CD/DVD-ROM ejection handling functions
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: intf_eject.c,v 1.1 2002/01/09 02:01:14 sam Exp $
6  *
7  * Author: Julien Blache <jb@technologeek.org> for the Linux part
8  *               with code taken from the Linux "eject" command
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <string.h>
29
30 #include <videolan/vlc.h>
31
32 #ifdef SYS_LINUX
33
34 /* This code could be extended to support CD/DVD-ROM chargers */
35 #   include <linux/version.h>
36     /* handy macro found in 2.1 kernels, but not in older ones */
37 #   ifndef KERNEL_VERSION
38 #       define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
39 #   endif
40
41 #   include <sys/types.h>
42 #   include <sys/stat.h>
43 #   include <sys/ioctl.h>
44 #   include <fcntl.h>
45
46 #   include <sys/ioctl.h>
47 #   include <linux/cdrom.h>
48 #   if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
49 #       include <linux/ucdrom.h>
50 #   endif
51
52 #   include <sys/mount.h>
53 #   include <scsi/scsi.h>
54 #   include <scsi/sg.h>
55 #   include <scsi/scsi_ioctl.h>
56
57 #endif
58
59 static int EjectCdrom( int i_fd );
60 static int EjectScsi ( int i_fd );
61
62 /*
63  * Eject using CDROMEJECT ioctl. Return 0 if successful
64  */
65 static int EjectCdrom( int i_fd )
66 {
67     int i_status;
68   
69     i_status = ioctl( i_fd, CDROMEJECT );
70   
71     return i_status;
72 }
73
74
75 /*
76  * Eject using SCSI commands. Return 0 if successful
77  */
78 static int EjectScsi( int i_fd )
79 {
80     int i_status;
81
82     struct sdata
83     {
84         int  inlen;
85         int  outlen;
86         char cmd[256];
87     } scsi_cmd;
88
89     scsi_cmd.inlen  = 0;
90     scsi_cmd.outlen = 0;
91     scsi_cmd.cmd[0] = ALLOW_MEDIUM_REMOVAL;
92     scsi_cmd.cmd[1] = 0;
93     scsi_cmd.cmd[2] = 0;
94     scsi_cmd.cmd[3] = 0;
95     scsi_cmd.cmd[4] = 0;
96     scsi_cmd.cmd[5] = 0;
97     i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
98     if( i_status != 0 )
99     {
100         return 1;
101     }
102
103     scsi_cmd.inlen  = 0;
104     scsi_cmd.outlen = 0;
105     scsi_cmd.cmd[0] = START_STOP;
106     scsi_cmd.cmd[1] = 0;
107     scsi_cmd.cmd[2] = 0;
108     scsi_cmd.cmd[3] = 0;
109     scsi_cmd.cmd[4] = 1;
110     scsi_cmd.cmd[5] = 0;
111     i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
112     if( i_status != 0 )
113     {
114         return 1;
115     }
116   
117     scsi_cmd.inlen  = 0;
118     scsi_cmd.outlen = 0;
119     scsi_cmd.cmd[0] = START_STOP;
120     scsi_cmd.cmd[1] = 0;
121     scsi_cmd.cmd[2] = 0;
122     scsi_cmd.cmd[3] = 0;
123     scsi_cmd.cmd[4] = 2;
124     scsi_cmd.cmd[5] = 0;
125     i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
126     if( i_status != 0 )
127     {
128         return 1;
129     }
130   
131     /* Force kernel to reread partition table when new disc inserted */
132     i_status = ioctl( i_fd, BLKRRPART );
133   
134     return i_status;
135 }
136
137 /*
138  * returns 0 on success
139  * returns 1 on failure
140  * returns -1 if not implemented
141  *
142  * Modify eject_disc() prototype as needed for portability
143  */
144
145 int intf_Eject( const char *psz_device )
146 {
147   int i_ret;
148
149 #ifdef SYS_LINUX
150   int i_fd = 0;
151
152    i_fd = open( psz_device, O_RDONLY | O_NONBLOCK );
153    
154    if( i_fd == -1 )
155    {
156        intf_ErrMsg( "intf error: couldn't open device %s", psz_device );
157        return 1;
158    }
159
160    if( EjectCdrom(i_fd) == 0 )
161    {
162        i_ret = 0;
163    }
164    else if( EjectScsi(i_fd) == 0 )
165    {
166        i_ret = 0;
167    }
168    else
169    {
170        intf_ErrMsg( "intf error: couldn't eject %s", psz_device );
171        i_ret = 1;
172    }
173
174    close( i_fd );
175
176 #else
177    i_ret = -1;
178
179 #endif
180    return i_ret;
181 }
182