File: pidfile.c

package info (click to toggle)
ypserv 4.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,184 kB
  • sloc: ansic: 10,161; xml: 1,872; sh: 915; makefile: 263; awk: 21
file content (91 lines) | stat: -rw-r--r-- 2,436 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* Copyright (c) 2009, 2011 Thorsten Kukuk
   Author: Thorsten Kukuk <kukuk@suse.de>

   The YP Server 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 of the
   License, or (at your option) any later version.

   The YP Server 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 the YP Server; see the file COPYING. If
   not, write to the Free Software Foundation, Inc., 51 Franklin Street,
   Suite 500, Boston, MA 02110-1335, USA. */

#include "pidfile.h"
#include "log_msg.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>

void
create_pidfile (const char *filename, const char *daemonname)
{
  int fd, left, written;
  pid_t pid;
  char pbuf[50], *ptr;
  struct flock lock;

  fd = open (filename, O_CREAT | O_RDWR | O_CLOEXEC,
	     S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  if (fd < 0)
    {
      log_msg ("cannot create pidfile %s", filename);
      if (debug_flag)
	log_msg ("\n");
      exit (1);
    }

  lock.l_type = F_WRLCK;
  lock.l_start = 0;
  lock.l_whence = SEEK_SET;
  lock.l_len = 0;

  /* Is the pidfile locked by another daemon ? */
  if (fcntl (fd, F_GETLK, &lock) < 0)
    {
      log_msg ("fcntl error");
      if (debug_flag)
	log_msg ("\n");
      exit (1);
    }
  if (lock.l_type == F_UNLCK)
    pid = 0;	        /* false, region is not locked by another proc */
  else
    pid = lock.l_pid;	/* true, return pid of lock owner */

  if (0 != pid)
    {
      log_msg ("%s already running (pid %d) - exiting", daemonname, pid);
      if (debug_flag)
	log_msg ("\n");
      exit (1);
    }

  /* write lock */
  lock.l_type = F_WRLCK;
  lock.l_start = 0;
  lock.l_whence = SEEK_SET;
  lock.l_len = 0;
  if (0 != fcntl (fd, F_SETLK, &lock))
    log_msg ("cannot lock pidfile");
  sprintf (pbuf, "%ld\n", (long) getpid ());
  left = strlen (pbuf);
  ptr = pbuf;
  while (left > 0)
    {
      if ((written = write (fd, ptr, left)) <= 0)
	return;			/* error */
      left -= written;
      ptr += written;
    }
  return;
}