Skip to content
Snippets Groups Projects
Commit 12086678 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by root
Browse files

test: unit/popen -- provide a child process


Testing via plain C interface with a shell is not stable,
the shell might simply be misconfigured or not found and
we will simply stuck forever (the signal handling in libev
is tricky and requires at least idle cycles or similar to
pass event processing). Thus lets rather run a program we
know is presenting in the system (popen-child executable).

Fixes #4811

Signed-off-by: default avatarCyrill Gorcunov <gorcunov@gmail.com>
parent c6b8ed77
No related branches found
No related tags found
No related merge requests found
......@@ -92,6 +92,7 @@ test/unit/fiob
test/small
test/var
test/luajit-tap
test/unit/popen-child
third_party/luajit/src/luajit
third_party/luajit/lib/vmdef.lua
third_party/luajit/src/buildvm
......
......@@ -246,5 +246,9 @@ target_link_libraries(swim_errinj.test unit swim)
add_executable(merger.test merger.test.c)
target_link_libraries(merger.test unit core box)
#
# Client for popen.test
add_executable(popen-child popen-child.c)
add_executable(popen.test popen.c)
target_link_libraries(popen.test misc unit core)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
static ssize_t
read_safe(int pfd, char *dest, ssize_t bytes)
{
ssize_t left = bytes;
ssize_t off = 0;
while (left > 0) {
ssize_t nr = read(pfd, &dest[off], left);
if (nr < 0) {
if (errno == EAGAIN ||
errno == EWOULDBLOCK ||
errno == EINTR)
continue;
return nr;
} else if (nr == 0) {
break;
}
off += nr;
left -= nr;
}
return off;
}
static ssize_t
write_safe(int pfd, char *dest, ssize_t bytes)
{
ssize_t left = bytes;
ssize_t off = 0;
while (left > 0) {
ssize_t nr = write(pfd, &dest[off], left);
if (nr < 0) {
if (errno == EAGAIN ||
errno == EWOULDBLOCK ||
errno == EINTR)
continue;
return nr;
} else if (nr == 0) {
break;
}
off += nr;
left -= nr;
}
return off;
}
int
main(int argc, char *argv[])
{
char buf[1024];
if (argc < 2) {
fprintf(stderr, "Not enough args\n");
exit(1);
}
/* read -n X and the just echo data read */
if (!strcmp(argv[1], "read") &&
!strcmp(argv[2], "-n")) {
ssize_t nr = (ssize_t)atoi(argv[3]);
if (nr <= 0) {
fprintf(stderr, "Wrong number of args\n");
exit(1);
}
if (nr >= (ssize_t)sizeof(buf)) {
fprintf(stderr, "Too many bytes to read\n");
exit(1);
}
ssize_t n = read_safe(STDIN_FILENO, buf, nr);
if (n != nr) {
fprintf(stderr, "Can't read from stdin\n");
exit(1);
}
n = write_safe(STDOUT_FILENO, buf, nr);
if (n != nr) {
fprintf(stderr, "Can't write to stdout\n");
exit(1);
}
exit(0);
}
/* just echo the data */
if (!strcmp(argv[1], "echo")) {
ssize_t nr = (ssize_t)strlen(argv[2]) + 1;
if (nr <= 0) {
fprintf(stderr, "Wrong number of bytes\n");
exit(1);
}
ssize_t n = write_safe(STDOUT_FILENO, argv[2], nr);
if (n != nr) {
fprintf(stderr, "Can't write to stdout\n");
exit(1);
}
exit(0);
}
/* just sleep forever */
if (!strcmp(argv[1], "loop")) {
for (;;)
sleep(10);
exit(0);
}
fprintf(stderr, "Unknown command passed\n");
return 1;
}
......@@ -11,9 +11,10 @@
#include "popen.h"
#include "say.h"
static char popen_child_path[PATH_MAX];
#define TEST_POPEN_COMMON_FLAGS \
(POPEN_FLAG_SETSID | \
POPEN_FLAG_SHELL | \
POPEN_FLAG_RESTORE_SIGNALS)
/**
......@@ -40,8 +41,8 @@ popen_write_exit(void)
{
struct popen_handle *handle;
char *child_argv[] = {
"/bin/sh", "-c",
"prompt=''; read -n 5 prompt; echo $prompt",
popen_child_path,
"read", "-n", "5",
NULL,
};
......@@ -108,8 +109,8 @@ popen_read_exit(void)
{
struct popen_handle *handle;
char *child_argv[] = {
"/bin/sh", "-c",
"echo 1 2 3 4 5",
popen_child_path,
"echo", "1 2 3 4 5",
NULL,
};
......@@ -165,8 +166,8 @@ popen_kill(void)
{
struct popen_handle *handle;
char *child_argv[] = {
"/bin/sh", "-c",
"while [ 1 ]; do sleep 10; done",
popen_child_path,
"loop",
NULL,
};
......@@ -234,9 +235,20 @@ main_f(va_list ap)
int
main(int argc, char *argv[])
{
//say_logger_init(NULL, S_DEBUG, 0, "plain", 0);
#if 0
say_logger_init(NULL, S_DEBUG, 0, "plain", 0);
#endif
memory_init();
if (getenv("BUILDDIR") == NULL) {
size_t size = sizeof(popen_child_path);
strncpy(popen_child_path, "./test/unit/popen-child", size);
popen_child_path[size-1] = '\0';
} else {
snprintf(popen_child_path, sizeof(popen_child_path),
"%s/test/unit/popen-child", getenv("BUILDDIR"));
}
fiber_init(fiber_c_invoke);
popen_init();
coio_init();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment