From 3120d2fecb926fedc4db4d44ff7df025b14355d4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 10 Jan 2004 22:41:31 +0000 Subject: many fixes git-svn-id: file:///home/lennart/svn/public/ivcall/trunk@13 e0b13411-74c3-0310-b366-a0654dd0340f --- src/ivcall.c | 11 ++--- src/lock.c | 154 ++++++++++++++++++++++++++++++++++++++++------------------- src/lock.h | 4 +- src/util.c | 4 ++ 4 files changed, 117 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/ivcall.c b/src/ivcall.c index 7e953f9..5aca741 100644 --- a/src/ivcall.c +++ b/src/ivcall.c @@ -18,6 +18,10 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -38,11 +42,6 @@ #include "util.h" #include "lock.h" -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - - // Those nifty DLE-sequences #define DLE 0x10 #define ETX 0x03 @@ -392,7 +391,7 @@ int go(void) { goto fail; } - snprintf(buf, sizeof(buf), "AT&E%s\n", source_msn); + snprintf(buf, sizeof(buf), "AT&L%s\n", source_msn); if (tty_command(fd, buf, "OK\r\n", COMMAND_TIMEOUT) < 0) { fprintf(stderr, "Initialisation failure.\n"); goto fail; diff --git a/src/lock.c b/src/lock.c index eb8a3cb..97dcd49 100644 --- a/src/lock.c +++ b/src/lock.c @@ -18,6 +18,11 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include #include #include @@ -29,6 +34,7 @@ #include #include #include +#include #include "lock.h" #include "util.h" @@ -40,69 +46,121 @@ static char* lockfile = NULL; -// Tries to lock a TTY-device, returns 0 on success -int device_lock(char *dev, char *appname) { - char buf[256], u[16]; - char path[PATH_MAX]; +static const char *get_lockfile(const char *dev) { + static char lockfile[PATH_MAX]; + snprintf(lockfile, sizeof(lockfile), "%s/LCK..%s", LOCK_DIR, basename((char*) dev)); + return lockfile; +} + +static const char *get_tempfile(const char *path) { + static char t[PATH_MAX]; + snprintf(t, sizeof(t), "%s.tmp.%lu", path, (unsigned long) getpid()); + return t; +} + + +int device_lock(const char *dev, const char *appname) { + struct stat st; int fd; - struct passwd *pwd; - char *username; + const char *path, *temp; + char buf[100]; + char uidbuf[32]; - assert(dev && !lockfile); - - if (access(LOCK_DIR, W_OK) < 0) + if (stat(LOCK_DIR, &st) != 0 || !S_ISDIR(st.st_mode)) { + fprintf(stderr, "Failed to lock device, directory "LOCK_DIR" not existent.\n"); return -1; + } + + path = get_lockfile(dev); + temp = get_tempfile(path); + + for (;;) { + mode_t u; + struct passwd* pw; + char *username; - snprintf(path, sizeof(path), "%s/LCK..%s", LOCK_DIR, basename(dev)); - - if ((fd = open(path, O_RDONLY)) >= 0) { - int n = loop_read(fd, buf, sizeof(buf) - 1); - close(fd); + if ((fd = open(path, O_RDONLY)) < 0) { + if (errno != ENOENT) { + fprintf(stderr, "Failed to open lock file: %s\n", strerror(errno)); + return -1; + } + } + + if (fd >= 0) { + ssize_t n; - if (n > 0) { - int pid; - - if (n == 4) - pid = *(int*) buf; - else { - buf[n] = 0; - sscanf(buf, "%d", &pid); + n = loop_read(fd, buf, sizeof(buf) - 1); + close(fd); + + if (n < 0) { + close(fd); + fprintf(stderr, "Failed to read from lock file: %s\n", strerror(errno)); + return -1; } - - if (pid > 0) { - if (kill((pid_t) pid, 0) < 0 && errno == ESRCH) { - fprintf(stderr, "Lockfile is stale. Overriding it.\n"); - unlink(path); - } else - return -1; + + if (n > 0) { + pid_t pid; + + if (n == 4) + pid = (pid_t) *((uint32_t*) buf); + else { + unsigned long v; + buf[n] = 0; + sscanf(buf, "%lu", &v); + pid = (pid_t) v; + } + + if (pid > 0) { + if (kill(pid, 0) < 0 && errno == ESRCH) { + fprintf(stderr, "Lockfile is stale. Overriding it.\n"); + /* Yes, here is a race condition */ + unlink(path); + } else + return 1; + } } } - } - if ((fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0) - return -1; - - if ((pwd = getpwuid(getuid()))) - username = pwd->pw_name; - else - snprintf(username = u, sizeof(u), "%u", getuid()); + u = umask(0033); + fd = open(temp, O_WRONLY | O_CREAT | O_EXCL, 0666); + umask(u); + + if (fd < 0) { + fprintf(stderr, "Failed to create temporary lock file: %s", strerror(errno)); + return -1; + } + + if ((pw = getpwuid(getuid()))) + username = pw->pw_name; + else + snprintf(username = uidbuf, sizeof(uidbuf), "%lu", (unsigned long) getuid()); + + snprintf(buf, sizeof(buf), "%10lu %s %.20s\n", (unsigned long) getpid(), appname, username); + if (loop_write(fd, buf, strlen(buf)) < 0) { + fprintf(stderr, "Failed to write to temporary lock file: %s", strerror(errno)); + close(fd); + return -1; + } - snprintf(buf, sizeof(buf), "%10ld %s %.20s\n", (long)getpid(), appname, username); - - if (loop_write(fd, buf, strlen(buf)) < 0) { close(fd); - return -1; - } - - close(fd); - lockfile = strdup(path); - - return 0; + if (link(temp, path) < 0) { + if (errno == EEXIST) + continue; + + fprintf(stderr, "Failed to link temporary lock file: %s", strerror(errno)); + } + + unlink(temp); + lockfile = strdup(path); + + return 0; + } } + // Tries to lock the first free device, returns 0 on success -int device_lock_first(char *appname, char *dev, size_t l) { +int device_lock_first(const char *appname, char *dev, size_t l) { int i, found = 0; for (i = 2; i <= 20; i++) { diff --git a/src/lock.h b/src/lock.h index a1847c9..4d6693e 100644 --- a/src/lock.h +++ b/src/lock.h @@ -21,8 +21,8 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -int device_lock(char *dev, char*appname); -int device_lock_first(char*appname, char *dev, size_t l); +int device_lock(const char *dev, const char*appname); +int device_lock_first(const char*appname, char *dev, size_t l); void device_unlock(void); #endif diff --git a/src/util.c b/src/util.c index 153a5c4..6dadea2 100644 --- a/src/util.c +++ b/src/util.c @@ -18,6 +18,10 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include -- cgit