]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2000-04-07 05:42:20 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 7 Apr 2000 05:42:20 +0000 (05:42 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 7 Apr 2000 05:42:20 +0000 (05:42 +0000)
UUCP style lockfiles for the serial port

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@41 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

Makefile.am
Makefile.in
MatrixOrbital.c
lcd4linux.c
lock.c [new file with mode: 0644]
lock.h [new file with mode: 0644]

index 1889b164dfce3afeaa664a737c701dbfeefba481..62d720ea57daeab7ba5771fc2a814dbb5e4c179e 100644 (file)
@@ -14,6 +14,7 @@ endif
 lcd4linux_SOURCES = \
 lcd4linux.c \
 cfg.c cfg.h \
+lock.c lock.h \
 parser.c parser.h \
 processor.c processor.h \
 system.c system.h \
index ccdca347a622cd0feadc4dcea241d5f44e238abe..722390ec0bec53b77c1c0b9324e98cbd2fb951b4 100644 (file)
@@ -73,7 +73,7 @@ AM_CFLAGS = $(X_CFLAGS) -Wall
 lcd4linux_LDFLAGS = $(X_LIBS)
 @WITH_X_TRUE@lcd4linux_LDADD = -lX11
 
-lcd4linux_SOURCES =  lcd4linux.c cfg.c cfg.h parser.c parser.h processor.c processor.h system.c system.h isdn.c isdn.h filter.c filter.h display.c display.h pixmap.c pixmap.h fontmap.c fontmap.h Skeleton.c MatrixOrbital.c Raster.c XWindow.c
+lcd4linux_SOURCES =  lcd4linux.c cfg.c cfg.h lock.c lock.h parser.c parser.h processor.c processor.h system.c system.h isdn.c isdn.h filter.c filter.h display.c display.h pixmap.c pixmap.h fontmap.c fontmap.h Skeleton.c MatrixOrbital.c Raster.c XWindow.c
 
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -89,9 +89,9 @@ X_CFLAGS = @X_CFLAGS@
 X_LIBS = @X_LIBS@
 X_EXTRA_LIBS = @X_EXTRA_LIBS@
 X_PRE_LIBS = @X_PRE_LIBS@
-lcd4linux_OBJECTS =  lcd4linux.o cfg.o parser.o processor.o system.o \
-isdn.o filter.o display.o pixmap.o fontmap.o Skeleton.o MatrixOrbital.o \
-Raster.o XWindow.o
+lcd4linux_OBJECTS =  lcd4linux.o cfg.o lock.o parser.o processor.o \
+system.o isdn.o filter.o display.o pixmap.o fontmap.o Skeleton.o \
+MatrixOrbital.o Raster.o XWindow.o
 @WITH_X_TRUE@lcd4linux_DEPENDENCIES = 
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -107,8 +107,8 @@ TAR = tar
 GZIP_ENV = --best
 DEP_FILES =  .deps/MatrixOrbital.P .deps/Raster.P .deps/Skeleton.P \
 .deps/XWindow.P .deps/cfg.P .deps/display.P .deps/filter.P \
-.deps/fontmap.P .deps/isdn.P .deps/lcd4linux.P .deps/parser.P \
-.deps/pixmap.P .deps/processor.P .deps/system.P
+.deps/fontmap.P .deps/isdn.P .deps/lcd4linux.P .deps/lock.P \
+.deps/parser.P .deps/pixmap.P .deps/processor.P .deps/system.P
 SOURCES = $(lcd4linux_SOURCES)
 OBJECTS = $(lcd4linux_OBJECTS)
 
index 833c7947fdb51541815459d49e20b4ffd8c9f6e7..fd77b85d00794930c4ec956a02b850d73576bde1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: MatrixOrbital.c,v 1.12 2000/03/26 18:46:28 reinelt Exp $
+/* $Id: MatrixOrbital.c,v 1.13 2000/04/07 05:42:20 reinelt Exp $
  *
  * driver for Matrix Orbital serial display modules
  *
  *
  *
  * $Log: MatrixOrbital.c,v $
+ * Revision 1.13  2000/04/07 05:42:20  reinelt
+ *
+ * UUCP style lockfiles for the serial port
+ *
  * Revision 1.12  2000/03/26 18:46:28  reinelt
  *
  * bug in pixmap.c that leaded to empty bars fixed
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
+#include <errno.h>
 #include <unistd.h>
+#include <signal.h>
 #include <termios.h>
 #include <fcntl.h>
-#include <string.h>
-#include <errno.h>
 
 #include "cfg.h"
+#include "lock.h"
 #include "display.h"
 
 #define SPEED 19200
@@ -122,8 +128,16 @@ static SEGMENT Segment[128] = {{ len1:0,   len2:0,   type:255, used:0, ascii:32
 static int MO_open (void)
 {
   int fd;
+  pid_t pid;
   struct termios portset;
   
+  if ((pid=lock_port(Port))!=0) {
+    if (pid==-1)
+      fprintf (stderr, "MatrixOrbital: port %s could not be locked\n", Port);
+    else
+      fprintf (stderr, "MatrixOrbital: port %s is locked by process %d\n", Port, pid);
+    return -1;
+  }
   fd = open(Port, O_RDWR | O_NOCTTY | O_NDELAY); 
   if (fd==-1) {
     fprintf (stderr, "MatrixOrbital: open(%s) failed: %s\n", Port, strerror(errno));
@@ -349,6 +363,8 @@ int MO_clear (void)
   return 0;
 }
 
+static void MO_quit (int signal); //forward decvlaration
+
 int MO_init (LCD *Self)
 {
   char *port;
@@ -391,6 +407,10 @@ int MO_init (LCD *Self)
   Device=MO_open();
   if (Device==-1) return -1;
 
+  signal(SIGINT,  MO_quit);
+  signal(SIGQUIT, MO_quit);
+  signal(SIGTERM, MO_quit);
+
   MO_clear();
   MO_contrast();
 
@@ -522,6 +542,14 @@ int MO_flush (void)
   return 0;
 }
 
+static void MO_quit (int signal)
+{
+  MO_clear();
+  MO_flush();
+  close (Device);
+  unlock_port(Port);
+  exit (0);
+}
 
 LCD MatrixOrbital[] = {
   { "LCD0821", 2,  8, XRES, YRES, BARS, MO_init, MO_clear, MO_put, MO_bar, MO_flush },
index 974f8eb643c892244857df584c8e510ae5830e40..6963609f288d07684c3de83940eec25f0cf7c152 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: lcd4linux.c,v 1.17 2000/04/03 17:31:52 reinelt Exp $
+/* $Id: lcd4linux.c,v 1.18 2000/04/07 05:42:20 reinelt Exp $
  *
  * LCD4Linux
  *
  *
  *
  * $Log: lcd4linux.c,v $
+ * Revision 1.18  2000/04/07 05:42:20  reinelt
+ *
+ * UUCP style lockfiles for the serial port
+ *
  * Revision 1.17  2000/04/03 17:31:52  reinelt
  *
  * suppress welcome message if display is smaller than 20x2
@@ -120,11 +124,35 @@ static void usage(void)
   printf ("usage: lcd4linux [-h] [-l] [-c key=value] [-f config-file] [-o output-file]\n");
 }
 
+static int hello (void)
+{
+  int x, y;
+  
+  lcd_query (&y, &x, NULL, NULL, NULL);
+  
+  if (x>=20) {
+    lcd_put (1, 1, "* LCD4Linux V" VERSION " *");
+    lcd_put (2, 1, " (c) 2000 M.Reinelt");
+  } else if (x >=16) {
+    lcd_put (1, 1, "LCD4Linux " VERSION);
+    lcd_put (2, 1, "(c) M.Reinelt");
+  } else if (x >=9) {
+    lcd_put (1, 1, "LCD4Linux");
+  } else if (x>=7) {
+    lcd_put (1, 1, "L4Linux");
+  } else return 0;
+  
+  lcd_put (1, 1, "* LCD4Linux V" VERSION " *");
+  lcd_put (2, 1, " (c) 2000 M.Reinelt");
+  lcd_flush();
+  return 1;
+}
+
 int main (int argc, char *argv[])
 {
   char *cfg="/etc/lcd4linux.conf";
   char *driver;
-  int c, x, y, smooth;
+  int c, smooth;
   
   while ((c=getopt (argc, argv, "c:f:hlo:"))!=EOF) {
     switch (c) {
@@ -182,15 +210,11 @@ int main (int argc, char *argv[])
   process_init();
   lcd_clear();
 
-  lcd_query (&y, &x, NULL, NULL, NULL);
-  if (x>=20 && y>=2) {
-    lcd_put (1, 1, "* LCD4Linux V" VERSION " *");
-    lcd_put (2, 1, " (c) 2000 M.Reinelt");
-    lcd_flush();
+  if (hello()) {
     sleep (3);
     lcd_clear();
   }
-
+  
   smooth=0;
   while (1) {
     process (smooth);
diff --git a/lock.c b/lock.c
new file mode 100644 (file)
index 0000000..dc83a10
--- /dev/null
+++ b/lock.c
@@ -0,0 +1,159 @@
+/* $Id: lock.c,v 1.1 2000/04/07 05:42:20 reinelt Exp $
+ *
+ * UUCP style locking
+ *
+ * Copyright 1999, 2000 by Michael Reinelt (reinelt@eunet.at)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: lock.c,v $
+ * Revision 1.1  2000/04/07 05:42:20  reinelt
+ *
+ * UUCP style lockfiles for the serial port
+ *
+ */
+
+/* 
+ * exported functions:
+ * 
+ * pid_t lock_port (char *port)
+ *   returns 0 if port could be successfully locked
+ *   otherwise returns PID of the process holding the lock
+ *
+ * pid_t unlock_port (char *port)
+ *   returns 0 if port could be successfully unlocked
+ *   otherwise returns PID of the process holding the lock
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+#include "lock.h"
+
+
+pid_t lock_port (char *port)
+{
+  char lockfile[256];
+  char tempfile[256];
+  char buffer[16];
+  char *p;
+  int fd, len, pid;
+
+  if ((p=strrchr (port, '/'))==NULL) 
+    p=port;
+  else
+    p++;
+  
+  snprintf(lockfile, sizeof(lockfile), LOCK, p);
+  snprintf(tempfile, sizeof(tempfile), LOCK, "TMP.XXXXXX");
+
+  if (mktemp(tempfile)==NULL) {
+    fprintf(stderr, "mktemp(%s) failed.\n", tempfile);
+    return -1;
+  }
+  
+  if ((fd=creat(tempfile, 0664))==-1) {
+    fprintf(stderr, "creat(%s) failed: %s\n", tempfile, strerror(errno));
+    return -1;
+  }
+  
+  snprintf (buffer, sizeof(buffer), "%10d\n", (int)getpid());
+  if (write(fd, buffer, strlen(buffer))!=strlen(buffer)) {
+    fprintf(stderr, "write(%s) failed: %s\n", tempfile, strerror(errno));
+    close(fd);
+    unlink(tempfile);
+    return -1;
+  }
+  close (fd);
+  
+
+  while (link(tempfile, lockfile)==-1) {
+
+    if (errno!=EEXIST) {
+      fprintf(stderr, "link(%s, %s) failed: %s\n", tempfile, lockfile, strerror(errno));
+      unlink(tempfile);
+      return -1;
+    }
+
+    if ((fd=open(lockfile, O_RDONLY))==-1) {
+      if (errno==ENOENT) continue; // lockfile disappared
+      fprintf (stderr, "open(%s) failed: %s\n", lockfile, strerror(errno));
+      unlink (tempfile);
+      return -1;
+    }
+
+    len=read(fd, buffer, sizeof(buffer)-1);
+    if (len<0) {
+      fprintf (stderr, "read(%s) failed: %s\n", lockfile, strerror(errno));
+      unlink (tempfile);
+      return -1;
+    }
+    
+    buffer[len]='\0';
+    if (sscanf(buffer, "%d", &pid)!=1 || pid==0) {
+      fprintf (stderr, "scan(%s) failed.\n", lockfile);
+      unlink (tempfile);
+      return -1;
+    }
+
+    if (pid==getpid()) {
+      fprintf (stderr, "%s already locked by us. uh-oh...\n", lockfile);
+      unlink(tempfile);
+      return 0;
+    }
+    
+    if ((kill(pid, 0)==-1) && errno==ESRCH) {
+      fprintf (stderr, "removing stale lockfile %s\n", lockfile);
+      if (unlink(lockfile)==-1 && errno!=ENOENT) {
+       fprintf (stderr, "unlink(%s) failed: %s\n", lockfile, strerror(errno));
+       unlink(tempfile);
+       return pid;
+      }
+      continue;
+    }
+    unlink (tempfile);
+    return pid;
+  }
+  
+  unlink (tempfile);
+  return 0;
+}
+
+
+pid_t unlock_port (char *port)
+{
+  char lockfile[256];
+  char *p;
+  
+  if ((p=strrchr (port, '/'))==NULL) 
+    p=port;
+  else
+    p++;
+  
+  snprintf(lockfile, sizeof(lockfile), LOCK, p);
+  unlink (lockfile);
+  return 0;
+}
diff --git a/lock.h b/lock.h
new file mode 100644 (file)
index 0000000..649cbfe
--- /dev/null
+++ b/lock.h
@@ -0,0 +1,37 @@
+/* $Id: lock.h,v 1.1 2000/04/07 05:42:20 reinelt Exp $
+ *
+ * UUCP style port locking
+ *
+ * Copyright 1999, 2000 by Michael Reinelt (reinelt@eunet.at)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: lock.h,v $
+ * Revision 1.1  2000/04/07 05:42:20  reinelt
+ *
+ * UUCP style lockfiles for the serial port
+ *
+ */
+
+#ifndef _LOCK_H_
+#define _LOCK_H_
+
+#define LOCK "/var/lock/LCK..%s"
+
+pid_t lock_port (char *port);
+pid_t unlock_port (char *port);
+
+#endif