Rewrite in Rust

This commit is contained in:
Alex Kotov 2021-11-17 22:43:30 +05:00
parent f5addd1a53
commit 7c701d1e7d
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
9 changed files with 88 additions and 129 deletions

4
.gitignore vendored
View file

@ -1,3 +1 @@
*.o
/polytree-session
/target/

16
Cargo.lock generated Normal file
View file

@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "libc"
version = "0.2.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
[[package]]
name = "polytree-session"
version = "0.0.0"
dependencies = [
"libc",
]

16
Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "polytree-session"
version = "0.0.0"
authors = ["Alex Kotov <kotovalexarian@gmail.com>"]
edition = "2021"
description = "Polytree session manager"
readme = true
homepage = "https://github.com/PolytreeWM/polytree-session"
repository = "https://github.com/PolytreeWM/polytree-session.git"
license = "MIT"
keywords = ["gui"]
categories = ["gui"]
publish = true
[dependencies]
libc = "0.2.107"

View file

@ -1,33 +1,17 @@
# Polytree Session - session manager
all: target/debug/polytree-session
include config.mk
SRC = status.c main.c
HDR = status.h
OBJ = $(SRC:.c=.o)
SRC = Cargo.toml src/main.rs
all: options polytree-session
options:
@echo Polytree Session build options:
@echo "CFLAGS = $(CFLAGS)"
@echo "LDFLAGS = $(LDFLAGS)"
@echo "CC = $(CC)"
%.o: %.c
$(CC) -c $< -o $@ $(CFLAGS)
OBJ: config.mk $(HDR)
polytree-session: $(OBJ)
$(CC) -o $@ $(OBJ) $(LDFLAGS)
clean:
rm -f polytree-session $(OBJ)
target/debug/polytree-session: $(SRC)
cargo build
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f polytree-session $(DESTDIR)$(PREFIX)/bin
cp -f target/debug/polytree-session $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/polytree-session
xinstall: install
@ -45,4 +29,4 @@ uninstall:
$(DESTDIR)$(ICONSPREFIX)/polytree.png \
$(DESTDIR)$(XSESSIONSPREFIX)/polytree.desktop
.PHONY: all options clean install xinstall uninstall
.PHONY: all install xinstall uninstall

View file

@ -6,18 +6,3 @@ SYSPREFIX = /usr
ICONSPREFIX = $(SYSPREFIX)/share/icons
XSESSIONSPREFIX = $(SYSPREFIX)/share/xsessions
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# FreeBSD (uncomment)
#X11INC = /usr/local/include
#X11LIB = /usr/local/lib
INCS = -I${X11INC}
LIBS = -L${X11LIB} -lX11 -lpthread
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\"
CFLAGS = -std=c99 -pedantic -Wall -Wextra -Os $(INCS) $(CPPFLAGS)
LDFLAGS = $(LIBS)
CC = cc

35
main.c
View file

@ -1,35 +0,0 @@
#include "status.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
const pid_t wm_pid = fork();
if (wm_pid == -1) {
perror("polytree-session: WM fork");
exit(EXIT_FAILURE);
}
if (wm_pid == 0) {
char *const args[] = { "polytreewm", NULL };
execvp(args[0], args);
perror("polytree-session: WM exec");
exit(EXIT_FAILURE);
}
status_start();
int wm_status;
waitpid(wm_pid, &wm_status, 0);
status_stop();
exit(WEXITSTATUS(wm_status));
}

48
src/main.rs Normal file
View file

@ -0,0 +1,48 @@
use std::ffi::CString;
use std::thread;
fn main() {
unsafe { unsafe_main() }
}
unsafe fn unsafe_main() {
let wm_pid = libc::fork();
if wm_pid == -1 {
let msg = CString::new(b"polytree-session: WM fork" as &[u8]).unwrap();
libc::perror(msg.as_ptr());
libc::exit(libc::EXIT_FAILURE);
}
if wm_pid == 0 {
let arg0 = CString::new(b"polytreewm" as &[u8]).unwrap();
let args = vec![arg0.as_ptr(), std::ptr::null()];
libc::execvp(arg0.as_ptr(), args.as_ptr());
let msg = CString::new(b"polytree-session: WM exec" as &[u8]).unwrap();
libc::perror(msg.as_ptr());
libc::exit(libc::EXIT_FAILURE);
}
let status_thread = thread::spawn(move || {
let pid = libc::fork();
if pid == -1 { return };
if pid == 0 {
let arg0 = CString::new(b"slstatus" as &[u8]).unwrap();
let args = vec![arg0.as_ptr(), std::ptr::null()];
libc::execvp(arg0.as_ptr(), args.as_ptr());
let msg = CString::new(b"polytree-session: slstatus exec" as &[u8])
.unwrap();
libc::perror(msg.as_ptr());
libc::exit(libc::EXIT_FAILURE);
}
});
let wm_status: i32 = 0;
libc::waitpid(wm_pid, wm_status as *mut i32, 0);
status_thread.join().unwrap();
libc::exit(libc::WEXITSTATUS(wm_status));
}

View file

@ -1,44 +0,0 @@
#include "status.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static bool running = false;
static pid_t pid = 0;
bool status_start()
{
// TODO: maybe we should assert
if (running) return false;
running = true;
pid = fork();
if (pid == -1) {
status_stop();
return false;
}
if (pid == 0) {
char *const args[] = { "slstatus", NULL };
execvp(args[0], args);
perror("polytree-session: slstatus exec");
exit(EXIT_FAILURE);
}
return true;
}
void status_stop()
{
// TODO: maybe we should assert
if (!running) return;
running = false;
kill(pid, SIGKILL);
waitpid(pid, NULL, 0);
}

View file

@ -1,9 +0,0 @@
#ifndef _STATUS_H
#define _STATUS_H
#include <stdbool.h>
bool status_start();
void status_stop();
#endif // _STATUS_H