|
|
d83c6e |
diff -up at-3.1.20/atd.c.lock-locks at-3.1.20/atd.c
|
|
|
d83c6e |
--- at-3.1.20/atd.c.lock-locks 2016-07-01 10:41:50.640867692 +0200
|
|
|
d83c6e |
+++ at-3.1.20/atd.c 2016-07-01 10:42:32.345844967 +0200
|
|
|
d83c6e |
@@ -74,6 +74,9 @@
|
|
|
d83c6e |
#include <syslog.h>
|
|
|
d83c6e |
#endif
|
|
|
d83c6e |
|
|
|
d83c6e |
+#include <sys/file.h>
|
|
|
d83c6e |
+#include <utime.h>
|
|
|
d83c6e |
+
|
|
|
d83c6e |
/* Local headers */
|
|
|
d83c6e |
|
|
|
d83c6e |
#include "privs.h"
|
|
|
d83c6e |
@@ -288,7 +291,7 @@ run_file(const char *filename, uid_t uid
|
|
|
d83c6e |
* mail to the user.
|
|
|
d83c6e |
*/
|
|
|
d83c6e |
pid_t pid;
|
|
|
d83c6e |
- int fd_out, fd_in;
|
|
|
d83c6e |
+ int fd_out, fd_in, fd_std;
|
|
|
d83c6e |
char jobbuf[9];
|
|
|
d83c6e |
char *mailname = NULL;
|
|
|
d83c6e |
int mailsize = 128;
|
|
|
d83c6e |
@@ -410,6 +413,10 @@ run_file(const char *filename, uid_t uid
|
|
|
d83c6e |
|
|
|
d83c6e |
fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);
|
|
|
d83c6e |
|
|
|
d83c6e |
+ if (flock(fd_in, LOCK_EX | LOCK_NB) != 0)
|
|
|
d83c6e |
+ perr("Somebody already locked the job %8lu (%.500s) - "
|
|
|
d83c6e |
+ "aborting", jobno, filename);
|
|
|
d83c6e |
+
|
|
|
d83c6e |
/*
|
|
|
d83c6e |
* If the spool directory is mounted via NFS `atd' isn't able to
|
|
|
d83c6e |
* read from the job file and will bump out here. The file is
|
|
|
d83c6e |
@@ -553,10 +560,7 @@ run_file(const char *filename, uid_t uid
|
|
|
d83c6e |
PRIV_END
|
|
|
d83c6e |
}
|
|
|
d83c6e |
/* We're the parent. Let's wait.
|
|
|
d83c6e |
- */
|
|
|
d83c6e |
- close(fd_in);
|
|
|
d83c6e |
-
|
|
|
d83c6e |
- /* We inherited the master's SIGCHLD handler, which does a
|
|
|
d83c6e |
+ We inherited the master's SIGCHLD handler, which does a
|
|
|
d83c6e |
non-blocking waitpid. So this blocking one will eventually
|
|
|
d83c6e |
return with an ECHILD error.
|
|
|
d83c6e |
*/
|
|
|
d83c6e |
@@ -573,14 +577,14 @@ run_file(const char *filename, uid_t uid
|
|
|
d83c6e |
/* some sendmail implementations are confused if stdout, stderr are
|
|
|
d83c6e |
* not available, so let them point to /dev/null
|
|
|
d83c6e |
*/
|
|
|
d83c6e |
- if ((fd_in = open("/dev/null", O_WRONLY)) < 0)
|
|
|
d83c6e |
+ if ((fd_std = open("/dev/null", O_WRONLY)) < 0)
|
|
|
d83c6e |
perr("Could not open /dev/null.");
|
|
|
d83c6e |
- if (dup2(fd_in, STDOUT_FILENO) < 0)
|
|
|
d83c6e |
+ if (dup2(fd_std, STDOUT_FILENO) < 0)
|
|
|
d83c6e |
perr("Could not use /dev/null as standard output.");
|
|
|
d83c6e |
- if (dup2(fd_in, STDERR_FILENO) < 0)
|
|
|
d83c6e |
+ if (dup2(fd_std, STDERR_FILENO) < 0)
|
|
|
d83c6e |
perr("Could not use /dev/null as standard error.");
|
|
|
d83c6e |
- if (fd_in != STDOUT_FILENO && fd_in != STDERR_FILENO)
|
|
|
d83c6e |
- close(fd_in);
|
|
|
d83c6e |
+ if (fd_std != STDOUT_FILENO && fd_std != STDERR_FILENO)
|
|
|
d83c6e |
+ close(fd_std);
|
|
|
d83c6e |
|
|
|
d83c6e |
if (unlink(filename) == -1)
|
|
|
d83c6e |
syslog(LOG_WARNING, "Warning: removing output file for job %li failed: %s",
|
|
|
d83c6e |
@@ -588,7 +592,12 @@ run_file(const char *filename, uid_t uid
|
|
|
d83c6e |
|
|
|
d83c6e |
/* The job is now finished. We can delete its input file.
|
|
|
d83c6e |
*/
|
|
|
d83c6e |
- chdir(ATJOB_DIR);
|
|
|
d83c6e |
+ if (chdir(ATJOB_DIR) != 0)
|
|
|
d83c6e |
+ perr("Somebody removed %s directory from under us.", ATJOB_DIR);
|
|
|
d83c6e |
+
|
|
|
d83c6e |
+ /* This also removes the flock */
|
|
|
d83c6e |
+ (void)close(fd_in);
|
|
|
d83c6e |
+
|
|
|
d83c6e |
unlink(newname);
|
|
|
d83c6e |
free(newname);
|
|
|
d83c6e |
|
|
|
d83c6e |
@@ -723,16 +732,18 @@ run_loop()
|
|
|
d83c6e |
|
|
|
d83c6e |
/* Skip lock files */
|
|
|
d83c6e |
if (queue == '=') {
|
|
|
d83c6e |
- /* FIXME: calhariz */
|
|
|
d83c6e |
- /* I think the following code is broken, but commenting
|
|
|
d83c6e |
- may haven unknow side effects. Make a release and see
|
|
|
d83c6e |
- in the wild how it works. For more information see:
|
|
|
d83c6e |
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=818508/*
|
|
|
d83c6e |
-
|
|
|
d83c6e |
- /* if ((buf.st_nlink == 1) && (run_time + CHECK_INTERVAL <= now)) { */
|
|
|
d83c6e |
- /* /\* Remove stale lockfile FIXME: lock the lockfile, if you fail, it's still in use. *\/ */
|
|
|
d83c6e |
- /* unlink(dirent->d_name); */
|
|
|
d83c6e |
- /* } */
|
|
|
d83c6e |
+ if ((buf.st_nlink == 1) && (run_time + CHECK_INTERVAL <= now)) {
|
|
|
d83c6e |
+ int fd;
|
|
|
d83c6e |
+
|
|
|
d83c6e |
+ fd = open(dirent->d_name, O_RDONLY);
|
|
|
d83c6e |
+ if (fd != -1) {
|
|
|
d83c6e |
+ if (flock(fd, LOCK_EX | LOCK_NB) == 0) {
|
|
|
d83c6e |
+ unlink(dirent->d_name);
|
|
|
d83c6e |
+ syslog(LOG_NOTICE, "removing stale lock file %s\n", dirent->d_name);
|
|
|
d83c6e |
+ }
|
|
|
d83c6e |
+ (void)close(fd);
|
|
|
d83c6e |
+ }
|
|
|
d83c6e |
+ }
|
|
|
d83c6e |
continue;
|
|
|
d83c6e |
}
|
|
|
d83c6e |
/* Skip any other file types which may have been invented in
|