aboutsummaryrefslogtreecommitdiffstats
path: root/pid.c
diff options
context:
space:
mode:
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2003-08-08 08:05:23 +0000
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2003-08-08 08:05:23 +0000
commita609eca5ec735091f7ed6e2d16edb45d492b6b0e (patch)
treed9085aee0f8ec93f5b6db97f93e501fc953e793a /pid.c
parent1934af04c445632c42de495e0ccdcb01e1b06c6e (diff)
downloadlcd4linux-a609eca5ec735091f7ed6e2d16edb45d492b6b0e.tar.gz
[lcd4linux @ 2003-08-08 08:05:23 by reinelt]
added PID file handling git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@208 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
Diffstat (limited to 'pid.c')
-rw-r--r--pid.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/pid.c b/pid.c
new file mode 100644
index 0000000..b7bfe3c
--- /dev/null
+++ b/pid.c
@@ -0,0 +1,143 @@
+/* $Id: pid.c,v 1.1 2003/08/08 08:05:23 reinelt Exp $
+ *
+ * PID file handling
+ *
+ * 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: pid.c,v $
+ * Revision 1.1 2003/08/08 08:05:23 reinelt
+ * added PID file handling
+ *
+ */
+
+/*
+ * exported functions:
+ *
+ * int pid_init (const char *pidfile)
+ * returns 0 if PID file could be successfully created
+ * returns PID of an already running process
+ * returns -1 in case of an error
+
+ * int pid_exit (const char *pidfile)
+ * returns 0 if PID file could be successfully deleted
+ * otherwise returns error from unlink() call
+ *
+ */
+
+
+#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 "debug.h"
+#include "pid.h"
+
+
+int pid_init (const char *pidfile)
+{
+ char tmpfile[256];
+ char buffer[16];
+ int fd, len, pid;
+
+ snprintf(tmpfile, sizeof(tmpfile), "%s.%s", pidfile, "XXXXXX");
+
+ if ((fd=mkstemp(tmpfile))==-1) {
+ error ("mkstemp(%s) failed: %s", tmpfile, strerror(errno));
+ return -1;
+ }
+
+ if (fchmod(fd,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)==-1) {
+ error ("fchmod(%s) failed: %s", tmpfile, strerror(errno));
+ close(fd);
+ unlink(tmpfile);
+ return -1;
+ }
+
+ snprintf (buffer, sizeof(buffer), "%d\n", (int)getpid());
+ if (write(fd, buffer, strlen(buffer))!=strlen(buffer)) {
+ error ("write(%s) failed: %s", tmpfile, strerror(errno));
+ close(fd);
+ unlink(tmpfile);
+ return -1;
+ }
+ close (fd);
+
+
+ while (link(tmpfile, pidfile)==-1) {
+
+ if (errno!=EEXIST) {
+ error ("link(%s, %s) failed: %s", tmpfile, pidfile, strerror(errno));
+ unlink(tmpfile);
+ return -1;
+ }
+
+ if ((fd=open(pidfile, O_RDONLY))==-1) {
+ if (errno==ENOENT) continue; // pidfile disappared
+ error ("open(%s) failed: %s", pidfile, strerror(errno));
+ unlink (tmpfile);
+ return -1;
+ }
+
+ len=read(fd, buffer, sizeof(buffer)-1);
+ if (len<0) {
+ error ("read(%s) failed: %s", pidfile, strerror(errno));
+ unlink (tmpfile);
+ return -1;
+ }
+
+ buffer[len]='\0';
+ if (sscanf(buffer, "%d", &pid)!=1 || pid==0) {
+ error ("scan(%s) failed.", pidfile);
+ unlink (tmpfile);
+ return -1;
+ }
+
+ if (pid==getpid()) {
+ error ("%s already locked by us. uh-oh...", pidfile);
+ unlink(tmpfile);
+ return 0;
+ }
+
+ if ((kill(pid, 0)==-1) && errno==ESRCH) {
+ error ("removing stale PID file %s", pidfile);
+ if (unlink(pidfile)==-1 && errno!=ENOENT) {
+ error ("unlink(%s) failed: %s", pidfile, strerror(errno));
+ unlink(tmpfile);
+ return pid;
+ }
+ continue;
+ }
+ unlink (tmpfile);
+ return pid;
+ }
+
+ unlink (tmpfile);
+ return 0;
+}
+
+
+int pid_exit (const char *pidfile)
+{
+ return unlink(pidfile);
+}