/* * amg_zombie_check.c - Part of AFD, an automatic file distribution program. * Copyright (c) 1995 - 2022 Deutscher Wetterdienst (DWD), * Holger Kiehl * * 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. */ #include "afddefs.h" DESCR__S_M3 /* ** NAME ** amg_zombie_check - checks if any process terminated that was ** started by the AMG ** ** SYNOPSIS ** int amg_zombie_check(pid_t *proc_id, int option) ** ** DESCRIPTION ** The function amg_zombie_check() checks if any process is finished ** (zombie), if this is the case it is killed with waitpid(). ** ** RETURN VALUES ** Returns YES when the status of a process has changed (except ** when it has been put to sleep). Otherwise NO is returned. ** ** AUTHOR ** H.Kiehl ** ** HISTORY ** 10.08.1995 H.Kiehl Created ** 27.03.1998 H.Kiehl Put this function into a separate file. ** 08.04.2002 H.Kiehl Added saving of old core files. ** */ DESCR__E_M3 #include /* rename() */ #include /* strerror() */ #include #ifdef HAVE_STATX # include /* Definition of AT_* constants */ #endif #include #include /* waitpid() */ #include #include #include "amgdefs.h" #define NO_OF_SAVED_CORE_FILES 5 #ifdef NO_OF_SAVED_CORE_FILES extern char *p_work_dir; #endif /*########################## amg_zombie_check() #########################*/ int amg_zombie_check(pid_t *proc_id, int option) { int status, table_changed = NO; /* Is process a zombie? */ if (waitpid(*proc_id, &status, option) > 0) { int exit_status = 0; if (WIFEXITED(status)) { exit_status = WEXITSTATUS(status); if (exit_status == 0) { exit_status = NOT_RUNNING; } else { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("Process returned %d"), exit_status); exit_status = DIED; } } else if (WIFSIGNALED(status)) { /* Abnormal termination. */ #ifdef NO_OF_SAVED_CORE_FILES static int no_of_saved_cores = 0; if (no_of_saved_cores < NO_OF_SAVED_CORE_FILES) { char core_file[MAX_PATH_LENGTH]; # ifdef HAVE_STATX struct statx stat_buf; # else struct stat stat_buf; # endif (void)snprintf(core_file, MAX_PATH_LENGTH, "%s/core", p_work_dir); # ifdef HAVE_STATX if (statx(0, core_file, AT_STATX_SYNC_AS_STAT, 0, &stat_buf) != -1) # else if (stat(core_file, &stat_buf) != -1) # endif { char new_core_file[MAX_PATH_LENGTH + 43]; (void)snprintf(new_core_file, MAX_PATH_LENGTH + 43, # if SIZEOF_TIME_T == 4 "%s.%s.%ld.%d", # else "%s.%s.%lld.%d", # endif core_file, DC_PROC_NAME, (pri_time_t)time(NULL), no_of_saved_cores); if (rename(core_file, new_core_file) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("Failed to rename() `%s' to `%s' : %s"), core_file, new_core_file, strerror(errno)); } else { no_of_saved_cores++; } } } #endif /* NO_OF_SAVED_CORE_FILES */ system_log(DEBUG_SIGN, __FILE__, __LINE__, _("Abnormal termination caused by signal %d"), WTERMSIG(status)); exit_status = DIED; } else if (WIFSTOPPED(status)) { /* Child stopped. */ exit_status = STOPPED; } /* Update table. */ if (exit_status < STOPPED) { table_changed = YES; *proc_id = exit_status; } } return(table_changed); }