Ctrl K
ComunidadGuías…

std/process.zc

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot

import "./core.zc";
import "./vec.zc";
import "./mem.zc";
import "./string.zc";
import "./option.zc";

import "sys/process.zc";

extern struct FILE;

struct Output {
    std_out: String;
    exit_code: int;
}

struct Command {
    program: String;
    args: Vec<String>;
}

impl Command {
    /// Creates a new process builder.
    fn new(program: char*) -> Command {
        return Command {
            program: String::from(program),
            args: Vec<String>::new()
        };
    }
    
    /// Adds a command-line argument.
    fn arg(self, arg: char*) -> Command* {
        self.args.push(String::from(arg));
        return &self;
    }
    
    fn _build_cmd(self) -> String {
        let cmd_str = self.program.substring(0, self.program.length());
        
        for arg in &self.args {
            let space = String::from(" ");
            cmd_str.append(&space);
            space.free();
            
            cmd_str.append(arg);
        }
        
        return cmd_str;
    }
    
    /// Returns the captured stdout.
    fn output(self) -> Output {
        let cmd_str = self._build_cmd();
        let cmd_c = cmd_str.c_str();
        
        let fp = popen(cmd_c, "r");
        
        if (fp == NULL) {
            cmd_str.free();
            return Output { 
                std_out: String::from(""), 
                exit_code: -1 
            };
        }
        
        let out = String::from("");
        let buf_size: usize = 1024;
        let buf = alloc_n<char>(buf_size);
        
        while (true) {
            let fgets_res = fgets(buf, (c_int)buf_size, fp);
            if (fgets_res == NULL) break;
            
            let chunk = String::from(buf);
            out.append(&chunk);
            chunk.free();
        }
        
        let code = pclose(fp);
        dealloc<char>(buf);
        cmd_str.free();
        
        return Output {
            std_out: out,
            exit_code: code
        };
    }
    
    fn status(self) -> int {
        let cmd_str = self._build_cmd();
        let code = system(cmd_str.c_str());
        cmd_str.free();
        return code;
    }

    /// Frees the process resources.
    fn free(self) {
        self.program.free();
        
        for s in &self.args {
            s.free();
        }
        self.args.free();
    }
}