⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lock.c

📁 网络端口的服务程序
💻 C
字号:
/*
    Portserver - Use RTERM protocol to serve serial ports over a network
    Copyright (C) 1998 Kenn Humborg

    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 of the License, 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.
*/

/* These functions are derived from pppd (sys-linux.c) */

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <unistd.h>

#include "port.h"   /* for struct Port */

#ifndef LOCK_PREFIX
#define LOCK_PREFIX	"/var/lock/LCK.."
#endif

/* The pppd code doesn't define PID_BINARY, so make
   sure it's not defined here as well */

#ifdef PID_BINARY
#undef PID_BINARY
#endif


/*
 * LockPort - create a lock file for the named device.
 *
 * Returns 0 for success, -1 for failure
 */

int LockPort (struct Port *port)
  {
    char hdb_lock_buffer[12];
    int fd, n;
    int pid;
    char *p;
    char *dev;
    char *lock_file;

    dev = port->device_name;

    p = strrchr(dev, '/');
    if (p != NULL)
      {
	dev = ++p;
      }

    lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
    if (lock_file == NULL)
      {
        port->lock_file = NULL;
	return -1;
      }

    strcpy (lock_file, LOCK_PREFIX);
    strcat (lock_file, dev);
/*
 * Attempt to create the lock file at this point.
 */
    while (1)
      {
	fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
	if (fd >= 0)
	  {
	    pid = getpid();
#ifndef PID_BINARY
	    sprintf (hdb_lock_buffer, "%010d\n", pid);
	    write (fd, hdb_lock_buffer, 11);
#else
	    write(fd, &pid, sizeof (pid));
#endif
	    close(fd);
            port->lock_file = lock_file;
	    return 0;
	  }
/*
 * If the file exists then check to see if the pid is stale
 */
	if (errno == EEXIST)
	  {
	    fd = open(lock_file, O_RDONLY, 0);
	    if (fd < 0)
	      {
		if (errno == ENOENT) /* This is just a timing problem. */
		  {
		    continue;
		  }
		break;
	      }

	    /* Read the lock file to find out who has the device locked */
	    n = read (fd, hdb_lock_buffer, 11);
	    close (fd);
	    if (n < 0)
	      {
		syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
		break;
	      }

	    /* See the process still exists. */
	    if (n > 0)
	      {
#ifndef PID_BINARY
		hdb_lock_buffer[n] = '\0';
		sscanf (hdb_lock_buffer, " %d", &pid);
#else
		pid = ((int *) hdb_lock_buffer)[0];
#endif
		if (pid == 0 || (kill(pid, 0) == -1 && errno == ESRCH))
		  {
		    n = 0;
		  }
	      }

	    /* If the process does not exist then try to remove the lock */
	    if (n == 0 && unlink (lock_file) == 0)
	      {
		syslog (LOG_NOTICE, "Removed stale lock on %s (pid %d)",
			dev, pid);
		continue;
	      }

	    syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, pid);
	    break;
	  }

	syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
	break;
      }

    free(lock_file);
    port->lock_file = NULL;
    return -1;
}

/*
 * UnlockPort - remove our lockfile
 */

void UnlockPort(struct Port *port)
  {
    if (port->lock_file)
      {
	unlink(port->lock_file);
	free(port->lock_file);
	port->lock_file = NULL;
      }
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -