/*
* Process id output.
* Copyright (C) 1998, 1999 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
*
* GNU Zebra 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.
*
* GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <zebra.h>
#include <fcntl.h>
#include <log.h>
#include "version.h"
#define PIDFILE_MASK 0644
int pidfile_acquire (const char *path)
{
int fd;
mode_t oldumask;
fd = open (path, O_RDWR | O_CREAT, PIDFILE_MASK);
if (fd < 0)
{
zlog_err ("Can't create pid lock file %s (%s), exiting",
path, safe_strerror (errno));
exit (1);
}
umask (oldumask);
#ifdef HAVE_FCNTL
{
struct flock lock;
memset (&lock, 0, sizeof (lock));
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
if (fcntl (fd, F_SETLK, &lock) < 0)
{
zlog_err ("Could not lock pid_file %s, exiting", path);
exit (1);
}
}
#endif
return fd;
}
void pidfile_fill (const int fd)
{
int tmp;
char buf[BUFSIZ];
size_t pidsize;
pidsize = snprintf (buf, BUFSIZ, "%u\n", getpid());
if ((tmp = write (fd, buf, pidsize)) != (int)pidsize)
zlog_err ("Could not write pid %u to FD %d, rc was %d: %s",
getpid(), fd, tmp, safe_strerror(errno));
else if (ftruncate(fd, pidsize) < 0)
zlog_err ("Could not truncate FD %d to %u bytes: %s",
fd, pidsize, safe_strerror (errno));
/* Do not close the pidfile, let the lock remain. */
}
pid_t pid_output (const char *path)
{
pidfile_fill (pidfile_acquire (path));
/* There is little sense in returning the PID (especially when no other
* function really uses returned value), but to keep function spec
* unchanged let's just do it.
*/
return getpid();
}