Skip to content

Instantly share code, notes, and snippets.

@iamahuman
Created May 22, 2017 08:35
Show Gist options
  • Save iamahuman/aa16d4c04f688cc3d7b031c5b5af8ab2 to your computer and use it in GitHub Desktop.
Save iamahuman/aa16d4c04f688cc3d7b031c5b5af8ab2 to your computer and use it in GitHub Desktop.
Linux: check CD-ROM tray status
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <libgen.h>
#include <linux/cdrom.h>
#define DEFAULT_CDROM_DEV "/dev/cdrom"
#define PROGNAME_TRAYOPEN "trayopen"
#define PROGNAME_TRAYCLOSED "trayclosed"
#define FATAL_ERROR_EXIT_CODE -1
#define UNKNOWN_EXIT_CODE -2
#if defined(__GNUC__) && !defined(DONT_EXPECT)
#define trayopen_unlikely(x) (__builtin_expect(!!(x), 0))
#define trayopen_likely(x) (__builtin_expect(!!(x), 1))
#else
#define trayopen_unlikely(x) (!!(x))
#define trayopen_likely(x) (!!(x))
#endif
const char name_trayopen[] = PROGNAME_TRAYOPEN;
const char name_trayclosed[] = PROGNAME_TRAYCLOSED;
int main(int argc, char **argv)
{
int expect_open, r, exit_code;
const char *dev, *invoked_name;
size_t prog_path_len;
char *program_path;
int fd;
if (trayopen_unlikely(argc < 1))
{
return FATAL_ERROR_EXIT_CODE;
}
prog_path_len = strlen(argv[0]);
program_path = malloc(prog_path_len + 1);
if (trayopen_unlikely(program_path == NULL))
{
return FATAL_ERROR_EXIT_CODE;
}
strncpy(program_path, argv[0], prog_path_len);
program_path[prog_path_len] = '\0';
invoked_name = basename(program_path);
if (strcmp(invoked_name, name_trayopen) == 0)
{
expect_open = 1;
}
else if (strcmp(invoked_name, name_trayclosed) == 0)
{
expect_open = 0;
}
else
{
free(program_path);
fprintf(stderr, "%s: this program must be invoked as either `%s` or `%s`.\n",
argv[0], name_trayopen, name_trayclosed);
return FATAL_ERROR_EXIT_CODE;
}
free(program_path);
if (trayopen_unlikely(argc > 2))
{
fprintf(stderr, "Usage:\n"
" %s [<name>] - determine if tray is opened.\n"
" %s [<name>] - determine if tray is closed.\n",
name_trayopen, name_trayclosed);
return FATAL_ERROR_EXIT_CODE;
}
dev = argc < 2 ? DEFAULT_CDROM_DEV : argv[1];
if ((fd = open(dev, O_RDONLY | O_NONBLOCK)) < 0)
{
perror("opening cd-rom device");
return FATAL_ERROR_EXIT_CODE;
}
if ((r = ioctl(fd, CDROM_DRIVE_STATUS)) < 0)
{
perror("ioctl CDROM_DRIVE_STATUS");
close(fd);
return FATAL_ERROR_EXIT_CODE;
}
close(fd);
if (r == CDS_NO_INFO)
{
fprintf(stderr, "%s: CDROM_DRIVE_STATUS not implemented\n", argv[0]);
fflush(stderr);
puts("unknown");
return UNKNOWN_EXIT_CODE;
}
else if (r == CDS_TRAY_OPEN)
{
exit_code = (expect_open ? EXIT_SUCCESS : EXIT_FAILURE);
}
else
{
exit_code = (expect_open ? EXIT_FAILURE : EXIT_SUCCESS);
}
return exit_code;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment