Hoi,
Ich nutze das Forum mal kurz als Zwischenspeicher für Quick'n'Dirty-Code. Habe sled etwas umgeschrieben, damit ich mit der gleichen Hardware bei Bedarf ein Programm starten und stoppen kann.
Soll akut für einen VDR-Server und Deluge gut sein (keine Tastatur und Fernbedienung am Rechner).
C
/* vim: set sw=8 ts=8 si : */
/*
* Serial line daemon program for shutdown of your server.
* A blinking LED indicates the server is running.
* The program uses the serial interface lines
* DTR (output: data terminal ready), RTS (output:request to send)
* and CD (input: carrier detect)
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License.
* See http://www.gnu.org/copyleft/ for details.
*
* Written by Guido Socher <guido@linuxfocus.org>
*
* Some ideas were taken from an earlier progam called
* cpanel written by Mirko Dölle <dg2fer@qsl.net>
*/
#define VERINFO "version 0.1"
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
static int fd = 0;
enum led {rts_red,dtr_yellow,all};
/* Signal handler: all led off then exit */
void offandexit(int code)
{
int state = 0;
ioctl(fd, TIOCMSET, &state);
close(fd);
exit(0);
}
/* Switch the LEDs on or off */
int setled( enum led whichled, int fd, int onoff, int *ledstate){
int bitpat;
/* the blinking LED first */
if (whichled == rts_red){
bitpat=TIOCM_RTS;
}else if (whichled == dtr_yellow){
bitpat=TIOCM_DTR;
}else if (whichled == all){
bitpat=(TIOCM_RTS | TIOCM_DTR);
}
if (onoff){
/* on */
*ledstate |= bitpat;
}else{
*ledstate &= ~bitpat;
}
ioctl(fd, TIOCMSET, ledstate);
return *ledstate;
}
/* get the current state of the push button
* and return it. */
int getpushbutton(int fd)
{
int state;
ioctl(fd, TIOCMGET, &state); /* read interface */
if (state & TIOCM_CAR) {
return (1);
}
return (0);
}
void help()
{
printf("sled -- serial line pushbutton and LED control daemon\n\
USAGE: sled serial-device\n\
\n\
EXAMPLE:\n\
sled /dev/ttyS0\n\
\n\
Use command setserial -g /dev/ttyS* to see available ttyS devices.\n\
This program forks it self to background. It must have permissions\n\
to execute /sbin/shutdown\n\
");
#ifdef VERINFO
puts(VERINFO);
#endif
exit(0);
}
int main(int argc, char **argv)
{
int lstate = 0;
int progrunning = 0;
int progrunning_old;
int i;
pid_t pid;
/* exactly one argument must be given */
if (argc != 2)
help();
/* open device */
fd = open(argv[1], O_RDWR | O_NDELAY);
if (fd < 0) {
fprintf(stderr, "ERROR: can not open \"%s\"\n", argv[1]);
exit(2);
}
/* catch signals INT and TERM and switch of LEDs before
* terminating */
signal(SIGINT, offandexit);
signal(SIGTERM, offandexit);
/* first set a defined state, all off */
ioctl(fd, TIOCMSET, &lstate);
/* switch on the yellow LED to indicate that the
* shutdown pushbutton is active */
setled(dtr_yellow, fd, 1, &lstate);
/* now we fork to background */
if ((pid = fork())<0){
perror("sled server fork");
exit(1);
}else if (pid > 0){
/* parent dies */
exit(0);
}
/* we are the child and run as a daemon */
while(1){
progrunning_old=progrunning; /*pruefen, ob Programm extern gestartet wurde; evtl. LED anpassen*/
if (system("pgrep sled > /dev/null") == 0) progrunning=1;
else progrunning=0;
if (progrunning != progrunning_old) setled(rts_red, fd, progrunning, &lstate);
setled(dtr_yellow, fd, 0, &lstate); usleep(100000); setled(dtr_yellow, fd, 1, &lstate);
if (getpushbutton(fd)) /*wenn Knopf gedrueckt, blitzen:*/
{
for (i=1; i<=3; i++)
{
setled( rts_red, fd, 1, &lstate);
usleep(100000);
setled( rts_red, fd, 0, &lstate);
usleep(100000);
} /*anschließend Programm starten/stoppen:*/
if (progrunning==1) system("killall sled");
else system("~/sled/sled /dev/ttyS1");
if (system("pgrep sled > /dev/null") == 0) progrunning=1; /*LEDs setzen:*/
else progrunning=0;
setled(rts_red, fd, progrunning, &lstate);
}
sleep(2);
}
/* we never get here */
return (2);
}
Alles anzeigen
Code ist noch recht unschön, wird noch mal überholt. Läuft aber schon.
Als Lesezeichen für mich hier noch ein paar nützliche Links mit Befehlen für die ser. Schnittstelle:
http://makelinux.com/ldd3/chp-18-sect-3.shtml
http://linux.die.net/man/4/tty_ioctl
Gruß, Bartho