#include <freeradius-devel/ident.h>
RCSID("$Id$")
-#include <freeradius-devel/autoconf.h>
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/rad_assert.h>
#include <sys/file.h>
-#include <stdlib.h>
-#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <signal.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
-
#define MAX_ARGV (256)
/*
* Execute a program on successful authentication.
return -1;
}
- strNcpy(mycmd, cmd, sizeof(mycmd));
+ strlcpy(mycmd, cmd, sizeof(mycmd));
/*
* Split the string into argv's BEFORE doing radius_xlat...
output_pairs = NULL;
}
- if ((pid = rad_fork(exec_wait)) == 0) {
+ if (exec_wait) {
+ pid = rad_fork(); /* remember PID */
+ } else {
+ pid = fork(); /* don't wait */
+ }
+
+ if (pid == 0) {
#define MAX_ENVP 1024
int devnull;
char *envp[MAX_ENVP];
if (n == T_OP_INVALID) {
DEBUG("Exec-Program-Wait: plaintext: %s", answer);
if (user_msg) {
- strNcpy(user_msg, answer, msg_len);
+ strlcpy(user_msg, answer, msg_len);
}
} else {
/*
* Call rad_waitpid (should map to waitpid on non-threaded
* or single-server systems).
*/
- for (n = 0; n < 10; n++) {
- child_pid = rad_waitpid(pid, &status, WNOHANG);
- if (child_pid == pid) {
- if (WIFEXITED(status)) {
- status = WEXITSTATUS(status);
- radlog(L_DBG, "Exec-Program: returned: %d", status);
- return status;
- }
- }
- if (child_pid < 0) {
- radlog(L_ERR|L_CONS, "Exec-Program: Failed to catch child return code");
- return 2;
+ child_pid = rad_waitpid(pid, &status);
+ if (child_pid == 0) {
+ radlog(L_DBG, "Exec-Program: Timeout waiting for child");
+ return 2;
+ }
+
+ if (child_pid == pid) {
+ if (WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
+ radlog(L_DBG, "Exec-Program: returned: %d", status);
+ return status;
}
- /*
- * If we haven't returned yet, the chile hasn't finished,
- * so sleep for 1 second then try again.
- */
- sleep(1);
}
- radlog(L_ERR|L_CONS, "Exec-Program: Child execution is taking too long. Giving up.");
- return 2;
+ radlog(L_ERR|L_CONS, "Exec-Program: Abnormal child exit: %s",
+ strerror(errno));
+ return 1;
}