enable unix socket and add test for it
This commit is contained in:
parent
9106bd46f2
commit
9797a64f06
@ -950,10 +950,10 @@ fn do_socket(domain: c_int, socket_type: c_int, protocol: c_int) -> Result<isize
|
||||
);
|
||||
|
||||
let file_ref: Arc<Box<File>> = match domain {
|
||||
// libc::AF_LOCAL => {
|
||||
// let unix_socket = UnixSocketFile::new(socket_type, protocol)?;
|
||||
// Arc::new(Box::new(unix_socket))
|
||||
// }
|
||||
libc::AF_LOCAL => {
|
||||
let unix_socket = UnixSocketFile::new(socket_type, protocol)?;
|
||||
Arc::new(Box::new(unix_socket))
|
||||
}
|
||||
_ => {
|
||||
let socket = SocketFile::new(domain, socket_type, protocol)?;
|
||||
Arc::new(Box::new(socket))
|
||||
@ -1022,7 +1022,7 @@ fn do_accept4(
|
||||
let new_file_ref: Arc<Box<File>> = Arc::new(Box::new(new_socket));
|
||||
let new_fd = proc.get_files().lock().unwrap().put(new_file_ref, false);
|
||||
|
||||
Ok(0)
|
||||
Ok(new_fd as isize)
|
||||
} else {
|
||||
errno!(EBADF, "not a socket")
|
||||
}
|
||||
@ -1147,14 +1147,19 @@ fn do_getpeername(
|
||||
let current_ref = process::get_current();
|
||||
let mut proc = current_ref.lock().unwrap();
|
||||
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
|
||||
let socket = file_ref.as_socket()?;
|
||||
|
||||
let ret = try_libc!(libc::ocall::getpeername(
|
||||
socket.fd(),
|
||||
addr,
|
||||
addr_len
|
||||
));
|
||||
Ok(ret as isize)
|
||||
if let Ok(socket) = file_ref.as_socket() {
|
||||
let ret = try_libc!(libc::ocall::getpeername(
|
||||
socket.fd(),
|
||||
addr,
|
||||
addr_len
|
||||
));
|
||||
Ok(ret as isize)
|
||||
} else if let Ok(unix_socket) = file_ref.as_unix_socket() {
|
||||
warn!("getpeername for unix socket is unimplemented");
|
||||
Ok(0)
|
||||
} else {
|
||||
errno!(EBADF, "not a socket")
|
||||
}
|
||||
}
|
||||
|
||||
fn do_sendto(
|
||||
|
@ -4,7 +4,7 @@ PROJECT_DIR := $(realpath $(CUR_DIR)/../)
|
||||
# Dependencies: need to be compiled but not to run by any Makefile target
|
||||
TEST_DEPS := dev_null
|
||||
# Tests: need to be compiled and run by test-% target
|
||||
TESTS := empty argv hello_world malloc file getpid spawn pipe time truncate readdir mkdir link tls pthread uname rlimit client server server_epoll
|
||||
TESTS := empty argv hello_world malloc file getpid spawn pipe time truncate readdir mkdir link tls pthread uname rlimit client server server_epoll unix_socket
|
||||
# Benchmarks: need to be compiled and run by bench-% target
|
||||
BENCHES := spawn_and_exit_latency pipe_throughput
|
||||
|
||||
|
5
test/unix_socket/Makefile
Normal file
5
test/unix_socket/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
include ../test_common.mk
|
||||
|
||||
EXTRA_C_FLAGS := -Wno-incompatible-pointer-types-discards-qualifiers
|
||||
EXTRA_LINK_FLAGS :=
|
||||
BIN_ARGS :=
|
117
test/unix_socket/main.c
Normal file
117
test/unix_socket/main.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <spawn.h>
|
||||
#include <string.h>
|
||||
|
||||
const char SOCK_PATH[] = "echo_socket";
|
||||
|
||||
int create_server_socket() {
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
printf("ERROR: failed to create a unix socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_un local;
|
||||
local.sun_family = AF_UNIX;
|
||||
strcpy(local.sun_path, SOCK_PATH);
|
||||
socklen_t len = strlen(local.sun_path) + sizeof(local.sun_family);
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&local, len) == -1) {
|
||||
printf("ERROR: failed to bind\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(fd, 5) == -1) {
|
||||
printf("ERROR: failed to listen\n");
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int create_client_socket() {
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
printf("ERROR: failed to create a unix socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_un remote;
|
||||
remote.sun_family = AF_UNIX;
|
||||
strcpy(remote.sun_path, SOCK_PATH);
|
||||
socklen_t len = strlen(remote.sun_path) + sizeof(remote.sun_family);
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&remote, len) == -1) {
|
||||
printf("ERROR: failed to connect\n");
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
// XXX: this is a hack! remove this in the future
|
||||
void* ptr = malloc(64);
|
||||
free(ptr);
|
||||
|
||||
int listen_fd = create_server_socket();
|
||||
if (listen_fd == -1) {
|
||||
printf("ERROR: failed to create server socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int socket_rd_fd = create_client_socket();
|
||||
if (socket_rd_fd == -1) {
|
||||
printf("ERROR: failed to create client socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_un remote;
|
||||
socklen_t len = sizeof(remote);
|
||||
int socket_wr_fd = accept(listen_fd, (struct sockaddr *)&remote, &len);
|
||||
if (socket_wr_fd == -1) {
|
||||
printf("ERROR: failed to accept socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// The following is same as 'pipe'
|
||||
|
||||
posix_spawn_file_actions_t file_actions;
|
||||
posix_spawn_file_actions_init(&file_actions);
|
||||
posix_spawn_file_actions_adddup2(&file_actions, socket_wr_fd, STDOUT_FILENO);
|
||||
posix_spawn_file_actions_addclose(&file_actions, socket_rd_fd);
|
||||
|
||||
const char* msg = "Echo!\n";
|
||||
const char* child_prog = "hello_world";
|
||||
const char* child_argv[3] = { child_prog, msg, NULL };
|
||||
int child_pid;
|
||||
if (posix_spawn(&child_pid, child_prog, &file_actions,
|
||||
NULL, child_argv, NULL) < 0) {
|
||||
printf("ERROR: failed to spawn a child process\n");
|
||||
return -1;
|
||||
}
|
||||
close(socket_wr_fd);
|
||||
|
||||
const char* expected_str = msg;
|
||||
size_t expected_len = strlen(expected_str);
|
||||
char actual_str[32] = {0};
|
||||
ssize_t actual_len;
|
||||
do {
|
||||
actual_len = read(socket_rd_fd, actual_str, sizeof(actual_str) - 1);
|
||||
} while (actual_len == 0);
|
||||
if (strncmp(expected_str, actual_str, expected_len) != 0) {
|
||||
printf("ERROR: received string is not as expected\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
if (wait4(child_pid, &status, 0, NULL) < 0) {
|
||||
printf("ERROR: failed to wait4 the child process\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user