/*
* Copyright (c) 2020 YuQing <384681@qq.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the Lesser GNU General Public License, version 3
* or later ("LGPL"), as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include "shared_func.h"
#include "logger.h"
#include "process_ctrl.h"
int get_pid_from_file(const char *pidFilename, pid_t *pid)
{
char buff[32];
int64_t file_size;
int result;
if (access(pidFilename, F_OK) != 0) {
return errno != 0 ? errno : EPERM;
}
file_size = sizeof(buff);
if ((result=getFileContentEx(pidFilename, buff, 0, &file_size)) != 0) {
return result;
}
*pid = strtol(buff, NULL, 10);
if (*pid == 0) {
return EINVAL;
}
return 0;
}
int write_to_pid_file(const char *pidFilename)
{
char buff[32];
int len;
len = sprintf(buff, "%d", (int)getpid());
return writeToFile(pidFilename, buff, len);
}
int delete_pid_file(const char *pidFilename)
{
int result;
pid_t pid;
if ((result=get_pid_from_file(pidFilename, &pid)) != 0) {
return result;
}
if (pid != getpid()) {
fprintf(stderr, "pid file: %s not mine, pid: %d != mine: %d",
pidFilename, (int)pid, (int)getpid());
return ESRCH;
}
if (unlink(pidFilename) == 0) {
return 0;
}
else {
fprintf(stderr, "unlink file: %s fail, "
"errno: %d, error info: %s!\n",
pidFilename, errno, strerror(errno));
return errno != 0 ? errno : ENOENT;
}
}
static int do_stop(const char *pidFilename, const bool bShowError, pid_t *pid)
{
int result;
if ((result=get_pid_from_file(pidFilename, pid)) != 0) {
if (bShowError) {
if (result == ENOENT) {
fprintf(stderr, "pid file: %s not exist!\n", pidFilename);
}
else {
fprintf(stderr, "get pid from file: %s fail, " \
"errno: %d, error info: %s\n",
pidFilename, result, strerror(result));
}
}
return result;
}
if (kill(*pid, SIGTERM) == 0) {
return 0;
}
else {
result = errno != 0 ? errno : EPERM;
if (bShowError || result != ESRCH) {
fprintf(stderr, "kill pid: %d fail, errno: %d, error info: %s\n",
(int)*pid, result, strerror(result));
}
return result;
}
}
int process_stop_ex(const char *pidFilename, const bool bShowError)
{
#define MAX_WAIT_COUNT 300
pid_t pid;
int result;
int sig;
int i;
if ((result=do_stop(pidFilename, bShowError, &pid)) != 0) {
return result;
}
fprintf(stderr, "waiting for pid [%d] exit ...\n", (int)pid);
for (i=0; i