summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak2012-03-27 17:36:47 +0200
committerKarel Zak2012-03-27 17:38:28 +0200
commit1abc33266f3e6806c0c9637bd498b1ad0de6c50d (patch)
treed79f28433cd7976e72bf5fed17556bc6c30ab431
parenteject: add --manualeject from fedora (diff)
downloadkernel-qcow2-util-linux-1abc33266f3e6806c0c9637bd498b1ad0de6c50d.tar.gz
kernel-qcow2-util-linux-1abc33266f3e6806c0c9637bd498b1ad0de6c50d.tar.xz
kernel-qcow2-util-linux-1abc33266f3e6806c0c9637bd498b1ad0de6c50d.zip
eject: add -X from Fedora
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--include/pathnames.h1
-rw-r--r--misc-utils/eject.117
-rw-r--r--misc-utils/eject.c103
3 files changed, 118 insertions, 3 deletions
diff --git a/include/pathnames.h b/include/pathnames.h
index 70c6ecfb3..28f8d6f4f 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -81,6 +81,7 @@
#define _PATH_PROC_DEVICES "/proc/devices"
#define _PATH_PROC_MOUNTINFO "/proc/self/mountinfo"
#define _PATH_PROC_LOCKS "/proc/locks"
+#define _PATH_PROC_CDROMINFO "/proc/sys/dev/cdrom/info"
#define _PATH_SYS_BLOCK "/sys/block"
#define _PATH_SYS_DEVBLOCK "/sys/dev/block"
diff --git a/misc-utils/eject.1 b/misc-utils/eject.1
index 26a427dbf..4839152a8 100644
--- a/misc-utils/eject.1
+++ b/misc-utils/eject.1
@@ -25,6 +25,8 @@ eject [-vn] -T [<name>]
.br
eject [\-vn] \-x <speed> [<name>]
.br
+eject [\-vn] \-X [<name>]
+.br
eject \-V
.SH DESCRIPTION
@@ -111,6 +113,15 @@ of. Every time the media is changed this option is cleared. This
option can be used alone, or with the \-t and \-c options.
.TP 0.5i
+.B \-X
+With this option the CD-ROM drive will be probed to detect the
+available speeds. The output is a list of speeds which can be used as
+an argument of the \-x option. This only works with Linux 2.6.13 or
+higher, on previous versions solely the maximum speed will be
+reported. Also note that some drive may not correctly report the speed
+and therefore this option does not work with them.
+
+.TP 0.5i
.B \-n
With this option the selected device is displayed but no action is
performed.
@@ -311,10 +322,12 @@ The \-x option was added by Nobuyuki Tsuchimura (tutimura@nn.iij4u.or.jp),
with thanks to Roland Krivanek (krivanek@fmph.uniba.sk) and his
cdrom_speed command.
-The -T option was added by Sybren Stuvel (sybren@thirdtower.com), with
+The \-T option was added by Sybren Stuvel (sybren@thirdtower.com), with
big thanks to Benjamin Schwenk (benjaminschwenk@yahoo.de).
- .SH SEE ALSO
+The \-X option was added by Eric Piel (Eric.Piel@tremplin-utc.net).
+
+.SH SEE ALSO
mount(2), umount(2), mount(8), umount(8)
diff --git a/misc-utils/eject.c b/misc-utils/eject.c
index daa9b0630..c37930177 100644
--- a/misc-utils/eject.c
+++ b/misc-utils/eject.c
@@ -49,6 +49,7 @@
#include "strutils.h"
#include "xalloc.h"
#include "canonicalize.h"
+#include "pathnames.h"
#define EJECT_DEFAULT_DEVICE "/dev/cdrom"
@@ -71,6 +72,7 @@ static int r_option;
static int s_option;
static int t_option;
static int T_option;
+static int X_option;
static int v_option;
static int x_option;
static int p_option;
@@ -142,6 +144,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
" -t, --trayclose close tray\n"
" -T, --traytoggle toggle tray\n"
" -x, --cdspeed set CD-ROM max speed\n"
+ " -X, --listspeed list CD-ROM available speeds\n"
" -v, --verbose enable verbose output\n"
" -n, --noop don't eject, just show device found\n"
" -r, --cdrom eject CD-ROM\n"
@@ -173,6 +176,7 @@ static void parse_args(int argc, char **argv, char **device)
{"trayclose", no_argument, NULL, 't'},
{"traytoggle", no_argument, NULL, 'T'},
{"cdspeed", required_argument, NULL, 'x'},
+ {"listspeed", no_argument, NULL, 'X'},
{"noop", no_argument, NULL, 'n'},
{"cdrom", no_argument, NULL, 'r'},
{"scsi", no_argument, NULL, 's'},
@@ -186,7 +190,7 @@ static void parse_args(int argc, char **argv, char **device)
int c;
while ((c = getopt_long(argc, argv,
- "a:c:i:x:dfhnqrstTvVpm", long_opts, NULL)) != -1) {
+ "a:c:i:x:dfhnqrstTXvVpm", long_opts, NULL)) != -1) {
switch (c) {
case 'a':
a_option = 1;
@@ -247,6 +251,9 @@ static void parse_args(int argc, char **argv, char **device)
case 'T':
T_option = 1;
break;
+ case 'X':
+ X_option = 1;
+ break;
case 'v':
v_option = 1;
break;
@@ -413,6 +420,92 @@ static void select_speed(int fd, int speed)
}
/*
+ * Read Speed of CD-ROM drive. From Linux 2.6.13, the current speed
+ * is correctly reported
+ */
+static int read_speed(const char *devname)
+{
+ int drive_number = -1;
+ char *name;
+ FILE *f;
+
+ f = fopen(_PATH_PROC_CDROMINFO, "r");
+ if (!f)
+ err(EXIT_FAILURE, _("%s: open failed"), _PATH_PROC_CDROMINFO);
+
+ name = rindex(devname, '/') + 1;
+
+ while (!feof(f)) {
+ char line[512];
+ char *str;
+
+ if (!fgets(line, sizeof(line), f))
+ break;
+
+ /* find drive number in line "drive name" */
+ if (drive_number == -1) {
+ if (strncmp(line, "drive name:", 11) == 0) {
+ str = strtok(&line[11], "\t ");
+ drive_number = 0;
+ while (strncmp(name, str, strlen(name)) != 0) {
+ drive_number++;
+ str = strtok(NULL, "\t ");
+ if (!str)
+ errx(EXIT_FAILURE,
+ _("%s: failed to finding CD-ROM name"),
+ _PATH_PROC_CDROMINFO);
+ }
+ }
+ /* find line "drive speed" and read the correct speed */
+ } else {
+ if (strncmp(line, "drive speed:", 12) == 0) {
+ int i;
+ char *str;
+
+ str = strtok(&line[12], "\t ");
+ for (i = 1; i < drive_number; i++)
+ str = strtok(NULL, "\t ");
+
+ if (!str)
+ errx(EXIT_FAILURE,
+ _("%s: failed to read speed"),
+ _PATH_PROC_CDROMINFO);
+ return atoi(str);
+ }
+ }
+ }
+
+ errx(EXIT_FAILURE, _("failed to read speed"));
+}
+
+/*
+ * List Speed of CD-ROM drive.
+ */
+static void list_speeds(const char *name, int fd)
+{
+#ifdef CDROM_SELECT_SPEED
+ int max_speed, curr_speed = 0, prev_speed;
+
+ select_speed(fd, 0);
+ max_speed = read_speed(name);
+
+ while (curr_speed < max_speed) {
+ prev_speed = curr_speed;
+ select_speed(fd, prev_speed + 1);
+ curr_speed = read_speed(name);
+ if (curr_speed > prev_speed)
+ printf("%d ", curr_speed);
+ else
+ curr_speed = prev_speed + 1;
+ }
+
+ printf("\n");
+#else
+ warnx(_("CD-ROM select speed command not supported by this kernel"));
+#endif
+}
+
+/*
* Eject using CDROMEJECT ioctl. Return 1 if successful, 0 otherwise.
*/
static int eject_cdrom(int fd)
@@ -787,6 +880,14 @@ int main(int argc, char **argv)
exit(0);
}
+ /* handle -X option */
+ if (X_option) {
+ verbose(_("%s: listing CD-ROM speed"), device);
+ fd = open_device(device);
+ list_speeds(device, fd);
+ exit(0);
+ }
+
/* handle -x option only */
if (!c_option)
set_device_speed(device);