Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow logging to process #20

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
4 changes: 2 additions & 2 deletions commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ static int cmd_log(int argc, char *argv[])
if (argc < 2)
return MICROCOM_CMD_USAGE;

ret = logfile_open(argv[1]);
ret = log_open(argv);

return ret;
}
Expand Down Expand Up @@ -239,7 +239,7 @@ static struct cmd cmds[] = {
}, {
.name = "log",
.fn = cmd_log,
.info = "log to file",
.info = "log to file or |executable",
.help = "log <logfile>",
}, {
.name = "#",
Expand Down
2 changes: 1 addition & 1 deletion commands_fsl_imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ static int upload_file(uint32_t address, char *name, unsigned char type)
};
struct stat stat;

upfd = open(name, O_RDONLY);
upfd = open(name, O_RDONLY | O_CLOEXEC);
if (upfd < 0) {
perror("open");
return 1;
Expand Down
7 changes: 7 additions & 0 deletions microcom.1
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ microcom \- A minimalistic terminal program
.IR host : port ]
.RB [\| \-s
.IR speed \|]
.RB [ -l
.IR logfile ]
.br
.B microcom -c
.IB interface : rx_id : tx_id
Expand Down Expand Up @@ -65,6 +67,11 @@ work in telnet (rfc2217) mode.
.BI \-c\ interface\fB:\fIrx_id\fB:\fItx_id\fR,\ \fI \-\-can= interface\fB:\fIrx_id\fB:\fItx_id
work in CAN mode (default: \fBcan0:200:200\fR)
.TP
.BI \-l\ logfile \fR,\ \fB\-\-log= logfile
log output to \fIlogfile\fR. If \fIlogfile\fR starts with a pipe `\fB|\fR' character,
it's instead piped to an executable with that name in \fBPATH\fR. The executable receives
the microcom output over \fBstdin\fR with \fBstdout\fR closed and \fBstderr\fR connected to microcom's \fBstderr\fR.
.TP
.BR -h ", " \-\-help
Show help.

Expand Down
11 changes: 9 additions & 2 deletions microcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void main_usage(int exitcode, char *str, char *dev)
" default: (%s:%x:%x)\n"
" -f, --force ignore existing lock file\n"
" -d, --debug output debugging info\n"
" -l, --logfile=<logfile> log output to <logfile>\n"
" -l, --logfile=<logfile> log output to <logfile> or <|executable>\n"
" -o, --listenonly Do not modify local terminal, do not send input\n"
" from stdin\n"
" -a, --answerback=<str> specify the answerback string sent as response to\n"
Expand Down Expand Up @@ -297,7 +297,12 @@ int main(int argc, char *argv[])
exit(1);

if (logfile) {
ret = logfile_open(logfile);
char *args[MAXARGS + 1];
ret = parse_line(logfile, NULL, args);
if (ret < 0)
exit(1);

ret = log_open(args);
if (ret < 0)
exit(1);
}
Expand All @@ -324,6 +329,8 @@ int main(int argc, char *argv[])
sigaction(SIGPIPE, &sact, NULL);
sigaction(SIGTERM, &sact, NULL);
sigaction(SIGQUIT, &sact, NULL);
sact.sa_handler = SIG_IGN;
sigaction(SIGCHLD, &sact, NULL);
}

/* run the main program loop */
Expand Down
8 changes: 6 additions & 2 deletions microcom.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,12 @@ struct cmd {
char *help;
};

int logfile_open(const char *path);
void logfile_close(void);
#define MAXARGS 64

int parse_line(char *_line, int *argc, char *argv[]);

int log_open(char *argv[]);
void log_close(void);

int register_command(struct cmd *cmd);
#define MICROCOM_CMD_START 100
Expand Down
77 changes: 73 additions & 4 deletions mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <arpa/telnet.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <fcntl.h>

#define BUFSIZE 1024

Expand Down Expand Up @@ -366,26 +367,94 @@ static void cook_buf(struct ios_ops *ios, unsigned char *buf, int num)
} /* while - end of processing all the charactes in the buffer */
}

void logfile_close(void)
void log_close(void)
{
if (logfd >= 0)
close(logfd);

logfd = -1;
}

int logfile_open(const char *path)
static int logproc_open(const char *path, char *argv[])
{
int pipefd[2];
int ret;

ret = pipe(pipefd);
if (ret) {
fprintf(stderr, "Cannot open log pipe: %s\n", strerror(errno));
return -1;
}

ret = fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);
if (!ret)
ret = fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
if (ret) {
fprintf(stderr, "Cannot set FD_CLOEXEC on log pipe: %s\n",
strerror(errno));
return -1;
}

/* flush now, so we don't clone unflushed output buffers */
fflush(NULL);

ret = fork();
if (ret == 0) {
close(0);
close(1);
dup(pipefd[0]);

execvp(path, argv);
fprintf(stderr, "Cannot exec log process (%s): %s\n",
path, strerror(errno));
_Exit(1);
} else {
close(pipefd[0]);

if (ret < 0) {
close(pipefd[1]);
fprintf(stderr, "Cannot fork log process: %s\n",
strerror(errno));
return -1;
}
}

return pipefd[1];
}

static int logfile_open(const char *path)
{
int fd;

fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0644);
fd = open(path, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
if (fd < 0) {
fprintf(stderr, "Cannot open logfile '%s': %s\n", path, strerror(errno));
return fd;
}

if (logfd >= 0)
logfile_close();
log_close();

logfd = fd;

return 0;
}

int log_open(char *argv[])
{
const char *path = argv[0];
int fd;

if (*path == '|')
fd = logproc_open(++path, argv);
else
fd = logfile_open(path);

if (fd < 0)
return fd;

if (logfd >= 0)
log_close();

logfd = fd;

Expand Down
9 changes: 4 additions & 5 deletions parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
#include <readline/history.h>
#include "microcom.h"

#define MAXARGS 64

static int parse_line(char *_line, int *argc, char *argv[])
int parse_line(char *_line, int *argc, char *argv[])
{
char *line = _line;
int nargs = 0;
Expand Down Expand Up @@ -64,7 +62,8 @@ static int parse_line(char *_line, int *argc, char *argv[])
printf("Too many args (max. %d)\n", MAXARGS);
out:
argv[nargs] = NULL;
*argc = nargs;
if (argc)
*argc = nargs;

return line - _line + 1;
}
Expand Down Expand Up @@ -189,7 +188,7 @@ int do_commandline(void)

int do_script(char *script)
{
int fd = open(script, O_RDONLY);
int fd = open(script, O_RDONLY | O_CLOEXEC);
int stdin = dup(1);
int ret;

Expand Down
64 changes: 44 additions & 20 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,33 +178,56 @@ 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 | O_CLOEXEC, 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;
}

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);

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;
}
}

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 */
fd = open(device, O_RDWR | O_NONBLOCK);
fd = open(device, O_RDWR | O_NONBLOCK | O_CLOEXEC);
ops->fd = fd;

if (fd < 0) {
Expand Down