diff --git a/Kernel/sync.sh b/Kernel/sync.sh index 34b60f83cd..440bb946f3 100755 --- a/Kernel/sync.sh +++ b/Kernel/sync.sh @@ -76,6 +76,7 @@ cp -v ../Userland/env mnt/bin/env cp -v ../Userland/stat mnt/bin/stat cp -v ../Userland/ping mnt/bin/ping cp -v ../Userland/uc mnt/bin/uc +cp -v ../Userland/tc mnt/bin/tc chmod 4755 mnt/bin/su cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor diff --git a/LibC/sys/socket.cpp b/LibC/sys/socket.cpp index d9db65f010..e92f3d9744 100644 --- a/LibC/sys/socket.cpp +++ b/LibC/sys/socket.cpp @@ -41,6 +41,11 @@ ssize_t sendto(int sockfd, const void* data, size_t data_length, int flags, cons __RETURN_WITH_ERRNO(rc, rc, -1); } +ssize_t send(int sockfd, const void* data, size_t data_length, int flags) +{ + return sendto(sockfd, data, data_length, flags, nullptr, 0); +} + ssize_t recvfrom(int sockfd, void* buffer, size_t buffer_length, int flags, struct sockaddr* addr, socklen_t* addr_length) { Syscall::SC_recvfrom_params params { sockfd, buffer, buffer_length, flags, addr, addr_length }; @@ -48,6 +53,11 @@ ssize_t recvfrom(int sockfd, void* buffer, size_t buffer_length, int flags, stru __RETURN_WITH_ERRNO(rc, rc, -1); } +ssize_t recv(int sockfd, void* buffer, size_t buffer_length, int flags) +{ + return recvfrom(sockfd, buffer, buffer_length, flags, nullptr, nullptr); +} + int getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size) { Syscall::SC_getsockopt_params params { sockfd, level, option, value, value_size }; diff --git a/LibC/sys/socket.h b/LibC/sys/socket.h index eb6b93ad0c..a7aa1e26b6 100644 --- a/LibC/sys/socket.h +++ b/LibC/sys/socket.h @@ -56,7 +56,9 @@ int bind(int sockfd, const sockaddr* addr, socklen_t); int listen(int sockfd, int backlog); int accept(int sockfd, sockaddr*, socklen_t*); int connect(int sockfd, const sockaddr*, socklen_t); +ssize_t send(int sockfd, const void*, size_t, int flags); ssize_t sendto(int sockfd, const void*, size_t, int flags, const struct sockaddr*, socklen_t); +ssize_t recv(int sockfd, void*, size_t, int flags); ssize_t recvfrom(int sockfd, void*, size_t, int flags, struct sockaddr*, socklen_t*); int getsockopt(int sockfd, int level, int option, void*, socklen_t*); int setsockopt(int sockfd, int level, int option, const void*, socklen_t); diff --git a/Userland/.gitignore b/Userland/.gitignore index 3f492418c4..65bc7283b9 100644 --- a/Userland/.gitignore +++ b/Userland/.gitignore @@ -39,3 +39,4 @@ chown stat ping uc +tc diff --git a/Userland/Makefile b/Userland/Makefile index 2af1bdaa27..84d425e40b 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -35,6 +35,7 @@ OBJS = \ stat.o \ ping.o \ uc.o \ + tc.o \ rm.o APPS = \ @@ -75,6 +76,7 @@ APPS = \ stat \ ping \ uc \ + tc \ rm ARCH_FLAGS = @@ -208,6 +210,8 @@ ping: ping.o uc: uc.o $(LD) -o $@ $(LDFLAGS) $< -lc +tc: tc.o + $(LD) -o $@ $(LDFLAGS) $< -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Userland/tc.cpp b/Userland/tc.cpp new file mode 100644 index 0000000000..711b4fc3f1 --- /dev/null +++ b/Userland/tc.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + const char* addr_str = "127.0.0.1"; + if (argc > 1) + addr_str = argv[1]; + + int fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + perror("socket"); + return 1; + } + + struct timeval timeout { 3, 0 }; + int rc = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + if (rc < 0) { + perror("setsockopt"); + return 1; + } + rc = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); + if (rc < 0) { + perror("setsockopt"); + return 1; + } + + struct sockaddr_in dst_addr; + memset(&dst_addr, 0, sizeof(dst_addr)); + + dst_addr.sin_family = AF_INET; + dst_addr.sin_port = htons(8080); + rc = inet_pton(AF_INET, addr_str, &dst_addr.sin_addr); + if (rc < 0) { + perror("inet_pton"); + return 1; + } + + rc = connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr)); + if (rc < 0) { + perror("connect"); + return 1; + } + + char buffer[BUFSIZ]; + const char* msg = "Test message"; + + send(fd, (const char*)msg, strlen(msg), 0); + printf("Message sent.\n"); + + struct sockaddr_in src_addr; + socklen_t src_addr_len = sizeof(src_addr); + ssize_t nrecv = recv(fd, buffer, sizeof(buffer), 0); + if (nrecv < 0) { + perror("recvfrom"); + return 1; + } + buffer[nrecv] = '\0'; + printf("Server: %s\n", buffer); + + rc = close(fd); + if (rc < 0) { + perror("close"); + return 1; + } + return 0; +}