/* * com.c - Part of AFD, an automatic file distribution program. * Copyright (c) 1995 - 2023 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 ** com - sends a command to the dir_check or fr command fifo ** ** SYNOPSIS ** int com(char action, char *file, int line) ** ** DESCRIPTION ** ** RETURN VALUES ** SUCCESS when transmission of command was successful, ** otherwise INCORRECT is returned. ** ** AUTHOR ** H.Kiehl ** ** HISTORY ** 10.08.1995 H.Kiehl Created ** 26.03.1998 H.Kiehl Put this function into a separate file. ** 27.09.2017 H.Kiehl Allow other process to send a BUSY_WORKING, ** meaning we will not timeout and instead ** keep waiting. ** 08.12.2023 H.Kiehl Show file and line of calling process if ** there is an error. ** */ DESCR__E_M3 #include #include /* exit() */ #include #include #include #include /* read(), write(), close() */ #ifdef HAVE_FCNTL_H # include #endif #include #include "amgdefs.h" /* External global variables. */ extern char *p_work_dir; /*################################ com() ################################*/ int com(char action, char *file, int line) { int write_fd, read_fd, ret; char buffer[10], com_fifo[MAX_PATH_LENGTH], *ptr; fd_set rset; struct timeval timeout; /* Build the fifo names. */ (void)strcpy(com_fifo, p_work_dir); (void)strcat(com_fifo, FIFO_DIR); ptr = com_fifo + strlen(com_fifo); /* Open fifo to send command to job. */ (void)strcpy(ptr, DC_CMD_FIFO); if ((write_fd = open(com_fifo, O_RDWR)) == -1) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not open fifo %s : %s [%s %d]", com_fifo, strerror(errno), file, line); exit(INCORRECT); } /* Open fifo to wait for answer from job. */ (void)strcpy(ptr, DC_RESP_FIFO); if ((read_fd = open(com_fifo, (O_RDONLY | O_NONBLOCK))) == -1) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not open fifo %s : %s [%s %d]", com_fifo, strerror(errno), file, line); exit(INCORRECT); } /* Write command to command fifo. */ if (write(write_fd, &action, 1) != 1) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not write to fifo %s : %s [%s %d]", DC_CMD_FIFO, strerror(errno), file, line); exit(INCORRECT); } /* Initialise descriptor set and timeout. */ FD_ZERO(&rset); for (;;) { FD_SET(read_fd, &rset); timeout.tv_usec = 0L; timeout.tv_sec = JOB_TIMEOUT; /* Wait for message x seconds and then continue. */ ret = select((read_fd + 1), &rset, NULL, NULL, &timeout); if ((ret > 0) && (FD_ISSET(read_fd, &rset))) { if ((ret = read(read_fd, buffer, 10)) > 0) { if (buffer[ret - 1] == BUSY_WORKING) { #ifdef _MAINTAINER_LOG maintainer_log(DEBUG_SIGN, NULL, 0, "com() received BUSY_WORKING."); #endif continue; } if (buffer[ret - 1] != ACKN) { system_log(WARN_SIGN, __FILE__, __LINE__, "Received garbage (%d) while reading from fifo. [%s %d]", buffer[ret - 1], file, line); } ret = SUCCESS; } else { system_log(WARN_SIGN, __FILE__, __LINE__, "Read problems (%d) : %s [%s %d]", ret, strerror(errno), file, line); ret = INCORRECT; } break; } else if (ret < 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, "select() error : %s [%s %d]", strerror(errno), file, line); exit(INCORRECT); } else if (ret == 0) { /* The other side does not answer. */ system_log(WARN_SIGN, __FILE__, __LINE__, "Did not receive any reply from %s for the command %s (%d). [%s %d]", DC_PROC_NAME, get_com_action_str(action), action, file, line); ret = INCORRECT; break; } else /* Impossible! Unknown error. */ { system_log(FATAL_SIGN, __FILE__, __LINE__, "Ouch! What now? [%s %d] @!$(%.", file, line); exit(INCORRECT); } } if ((close(write_fd) == -1) || (close(read_fd) == -1)) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "close() error : %s [%s %d]", strerror(errno), file, line); } return(ret); }