Skip to content
Closed
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
62 changes: 43 additions & 19 deletions serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <limits.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <arpa/telnet.h>

#include "microcom.h"
Expand Down Expand Up @@ -177,29 +178,52 @@ struct ios_ops * serial_init(char *device)
exit(1);
}

fd = open(lockfile, O_RDONLY);
if (fd >= 0 && !opt_force) {
close(fd);
main_usage(3, "lockfile for port exists", device);
}
relock:
fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0444);
if (fd < 0) {
if (errno == EEXIST) {
char pidbuf[12];
ssize_t nbytes = 0;
if (opt_force) {
printf("lockfile for port exists, ignoring\n");
serial_unlock();
goto relock;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if serial_unlock() fails to delete the lockfile, this is an endless loop.

}

fd = open(lockfile, O_RDONLY);
if (fd < 0)
main_usage(3, "lockfile for port can't be opened", device);

do {
ret = read(fd, &pidbuf[nbytes], sizeof(pidbuf) - nbytes - 1);
nbytes += ret;
} while (ret > 0 && nbytes < sizeof (pidbuf) - 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense here to do some additional checks on the format? E.g. check you read the file completely? If the lockfile happens to be created by an older microcom with pid 33333333 you check for pid 3333 instead. (I think, didn't test.)


if (ret >= 0) {
pidbuf[nbytes] = '\0';
ret = sscanf(pidbuf, "%10ld\n", &pid);

if (ret == 1 && kill(pid, 0) < 0 && errno == ESRCH) {
printf("lockfile contains stale pid, ignoring\n");
serial_unlock();
goto relock;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same issue as with the first patch in this series (i.e. endless loop if serial_unlock fails to remove lockfile)

}
}

main_usage(3, "lockfile for port exists", device);
}

if (opt_force) {
printf("cannot create lockfile. ignoring\n");
lockfile = NULL;
goto force;
}

if (fd >= 0 && opt_force) {
close(fd);
printf("lockfile for port exists, ignoring\n");
serial_unlock();
main_usage(3, "cannot create lockfile", device);
}

fd = open(lockfile, O_RDWR | O_CREAT, 0444);
if (fd < 0 && opt_force) {
printf("cannot create lockfile. ignoring\n");
lockfile = NULL;
goto force;
}
if (fd < 0)
main_usage(3, "cannot create lockfile", device);
/* Kermit wants binary pid */
pid = getpid();
write(fd, &pid, sizeof(long));
dprintf(fd, "%10ld\n", (long)pid);
close(fd);
force:
/* open the device */
Expand Down