Import Upstream version 1.2.2
[quagga-debian.git] / lib / pid_output.c
1 /*
2  * Process id output.
3  * Copyright (C) 1998, 1999 Kunihiro Ishiguro
4  *
5  * This file is part of GNU Zebra.
6  *
7  * GNU Zebra is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2, or (at your option) any
10  * later version.
11  *
12  * GNU Zebra is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
19  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20  * 02111-1307, USA.  
21  */
22
23 #include <zebra.h>
24 #include <fcntl.h>
25 #include <log.h>
26 #include "version.h"
27
28 #define PIDFILE_MASK 0644
29 #ifndef HAVE_FCNTL
30
31 pid_t
32 pid_output (const char *path)
33 {
34   FILE *fp;
35   pid_t pid;
36   mode_t oldumask;
37
38   pid = getpid();
39
40   oldumask = umask(0777 & ~PIDFILE_MASK);
41   fp = fopen (path, "w");
42   if (fp != NULL) 
43     {
44       fprintf (fp, "%d\n", (int) pid);
45       fclose (fp);
46       umask(oldumask);
47       return pid;
48     }
49   /* XXX Why do we continue instead of exiting?  This seems incompatible
50      with the behavior of the fcntl version below. */
51   zlog_warn("Can't fopen pid lock file %s (%s), continuing",
52             path, safe_strerror(errno));
53   umask(oldumask);
54   return -1;
55 }
56
57 #else /* HAVE_FCNTL */
58
59 pid_t
60 pid_output (const char *path)
61 {
62   int tmp;
63   int fd;
64   pid_t pid;
65   char buf[16];
66   struct flock lock;  
67   mode_t oldumask;
68
69   pid = getpid ();
70
71   oldumask = umask(0777 & ~PIDFILE_MASK);
72   fd = open (path, O_RDWR | O_CREAT, PIDFILE_MASK);
73   if (fd < 0)
74     {
75       zlog_err("Can't create pid lock file %s (%s), exiting",
76                path, safe_strerror(errno));
77       umask(oldumask);
78       exit(1);
79     }
80   else
81     {
82       size_t pidsize;
83
84       umask(oldumask);
85       memset (&lock, 0, sizeof(lock));
86
87       lock.l_type = F_WRLCK;
88       lock.l_whence = SEEK_SET;
89
90       if (fcntl(fd, F_SETLK, &lock) < 0)
91         {
92           zlog_err("Could not lock pid_file %s, exiting", path);
93           exit(1);
94         }
95
96       sprintf (buf, "%d\n", (int) pid);
97       pidsize = strlen(buf);
98       if ((tmp = write (fd, buf, pidsize)) != (int)pidsize)
99         zlog_err("Could not write pid %d to pid_file %s, rc was %d: %s",
100                  (int)pid,path,tmp,safe_strerror(errno));
101       else if (ftruncate(fd, pidsize) < 0)
102         zlog_err("Could not truncate pid_file %s to %u bytes: %s",
103                  path,(u_int)pidsize,safe_strerror(errno));
104     }
105   return pid;
106 }
107
108 #endif /* HAVE_FCNTL */