пятница, 30 ноября 2018 г.

cd проверка статуса лотка привода

К сожалению, чистый bash не имеет возможности проверять открыт-ли лоток привода или нет, но это можно сделать 3 способами:

1. С помощью lshw
lshw -quiet 2>/dev/null | awk '/\*-cd/,/con/' | sed -e 's/^[ \t]*//' | grep configuration | cut -d ' ' -f3
2. С помощью крошечной программы trayopen
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h> // for open
#include <unistd.h> // for close
#include <linux/cdrom.h>

int main(int argc,char **argv) {
  int cdrom;
  int status=1;

  printf("Usage: trayopen [device]\n");
  printf("Result: Open tray exit code 0, closed tray exit code 1.\n");

  if ((cdrom = open(argv[1],O_RDONLY | O_NONBLOCK)) < 0) {
    printf("Unable to open device %s. Provide a device name (/dev/sr0, /dev/cdrom) as a parameter.\n",argv[1]);
    exit(1);
  }

  if (ioctl(cdrom,CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN) {
    status=0;
  }

  close(cdrom);
  exit(status);
}
Компиляция: gcc trayopen.c -o trayopen .
В найденной в сети программе trayopen не хватало строки
#include <unistd.h> // for close
И при компиляции без этой строки выводило:
implicit declaration of function «close»; did you mean «pclose»? [-Wimplicit-function-declaration]

Использовать программу можно через операции сравнения:
 ./trayopen /dev/sr0 && echo tray is open || echo tray is closed
3. Через программу cdstatus:
#include <sys/ioctl.h>
#include <linux/cdrom.h>
#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
int main(int argc, char **argv){
        int fd, s; int pt = -1;
        if(argc < 2)
                errx(1, "usage: %s /dev/srX [poll_secs] [verbose]", argv[0]);
        if((fd = open(argv[1], O_RDONLY|O_NONBLOCK)) == -1)
                err(1, "open %s", argv[1]);
        if(argc > 2 && ((pt = strtod(argv[2], 0) * 1000) < 1 || pt > 3600000))
                errx(1, "bad timeout '%s'", argv[2]);
redo:
        switch(s = ioctl(fd, CDROM_DRIVE_STATUS, 0)){
        case -1: err(1, "ioctl(CDROM_DRIVE_STATUS)");
        case CDS_NO_INFO: errx(1, "ioctl(CDROM_DRIVE_STATUS) not implemented");
        }
        if(pt < 0 || argc > 3)
                switch(s){
                case CDS_NO_DISC: printf("no_disc\n"); break;
                case CDS_TRAY_OPEN: printf("tray_open\n"); break;
                case CDS_DRIVE_NOT_READY: printf("drive_not_ready\n"); break;
                case CDS_DISC_OK: printf("disc_ok\n"); break;
                default: printf("status=%d\n", s); break;
                }
        if(pt > 0 && s != CDS_DISC_OK){
                if(poll(0, 0, pt) < 0) err(1, "poll");
                goto redo;
        }
        return s != CDS_DISC_OK;
}
cdstatus выводит результат не в true, а собственно в текстовый вывод: "no_disc", "tray_open", "drive_not_ready", "disc_ok".

 Спасибо авторам идей и тем на форумах:
Detect CD tray status 
problem using ioctl , CDROM_DRIVE_STATUS
Implicit declaration of function ‘close'

Комментарии: 0:

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.

Подпишитесь на каналы Комментарии к сообщению [Atom]

<< Главная страница