Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions atch.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,17 @@ int socket_with_chdir(char *path, int (*fn)(char *))
*slash = '\0';
s = chdir(path) >= 0 ? fn(slash + 1) : -1;
*slash = '/';
if (s >= 0 && fchdir(dirfd) < 0) {
close(s);
s = -1;
/* Always restore cwd, regardless of socket operation result */
{
int saved_errno = errno;
if (fchdir(dirfd) < 0) {
if (s >= 0) close(s);
close(dirfd);
return -1;
}
close(dirfd);
errno = saved_errno;
}
close(dirfd);
return s;
}

Expand Down Expand Up @@ -275,6 +281,10 @@ static void expand_sockname(void)
mkdir(dir, 0700);
fulllen = strlen(dir) + 1 + strlen(sockname);
full = malloc(fulllen + 1);
if (!full) {
printf("%s: out of memory\n", progname);
exit(1);
}
snprintf(full, fulllen + 1, "%s/%s", dir, sockname);
sockname = full;
}
Expand Down
22 changes: 18 additions & 4 deletions master.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ static void rotate_log(void)
char *buf;
ssize_t n;

if (log_fd < 0)
return;

size = lseek(log_fd, 0, SEEK_END);
if (size > (off_t) log_max_size) {
buf = malloc(log_max_size);
Expand All @@ -67,12 +70,18 @@ static void rotate_log(void)
if (n > 0) {
ftruncate(log_fd, 0);
lseek(log_fd, 0, SEEK_SET);
write(log_fd, buf, (size_t)n);
if (write(log_fd, buf, (size_t)n) < 0) {
close(log_fd);
log_fd = -1;
free(buf);
return;
}
}
free(buf);
}
}
lseek(log_fd, 0, SEEK_END);
if (log_fd >= 0)
lseek(log_fd, 0, SEEK_END);
}

/*
Expand All @@ -89,7 +98,7 @@ static int open_log(const char *path)

log_fd = fd;
rotate_log();
return fd;
return log_fd;
}

/* Write end marker to log, close it, and unlink the socket. */
Expand Down Expand Up @@ -388,7 +397,12 @@ static void pty_activity(int s)
}
scrollback_append(buf, (size_t)len);
if (log_fd >= 0) {
write(log_fd, buf, (size_t)len);
if (write(log_fd, buf, (size_t)len) < 0) {
close(log_fd);
log_fd = -1;
}
}
if (log_fd >= 0) {
log_written += (size_t)len;
if (log_written >= log_max_size) {
rotate_log();
Expand Down
15 changes: 15 additions & 0 deletions tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,21 @@ assert_contains "no args: shows Usage:" "Usage:" "$out"
run "$ATCH" --help
assert_contains "help: shows tail command" "tail" "$out"

# ── 23. cwd preserved after socket failure ─────────────────────────────────
# socket_with_chdir must restore cwd even when the socket operation fails.
# We create the parent dir so chdir succeeds, but the session path is bogus.

ORIG_PWD=$(pwd)
mkdir -p "$TESTDIR/sockdir"
"$ATCH" kill "$TESTDIR/sockdir/bogus" >/dev/null 2>&1
AFTER_PWD=$(pwd)
if [ "$ORIG_PWD" = "$AFTER_PWD" ]; then
ok "cwd: preserved after failed socket operation"
else
fail "cwd: preserved after failed socket operation" "$ORIG_PWD" "$AFTER_PWD"
cd "$ORIG_PWD"
fi

# ── summary ──────────────────────────────────────────────────────────────────

printf "\n1..%d\n" "$T"
Expand Down