Code owners
Assign users and groups as approvers for specific file changes. Learn more.
pb_submitter.c 2.29 KiB
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#define PB_SET_PLAN 0x1337
typedef struct {
pid_t pid;
uint64_t *inst_cnt;
size_t num_tasks;
} pb_plan_t;
static void usage(void)
{
puts("Usage: ./pb_submitter <prog_name> <plan_file>");
}
static size_t count_lines(FILE *fp)
{
char c;
size_t lines = 0;
while (!feof(fp)) {
c = fgetc(fp);
if (c == '\n') {
lines++;
}
}
rewind(fp);
return lines;
}
int main(int argc, char** argv)
{
if (argc < 0x3) {
usage();
return -1;
}
int ret;
pb_plan_t plan = { 0 };
FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t cnt;
int pipes[0x2];
ret = pipe(pipes);
if (ret < 0) {
perror("pipe");
return -1;
}
fp = fopen(argv[2], "r");
if (fp == NULL) {
usage();
return -1;
}
plan.num_tasks = count_lines(fp);
uint64_t* inst_cnt = calloc(plan.num_tasks, sizeof(uint64_t));
if (inst_cnt == NULL) {
perror("calloc");
return -1;
}
size_t i;
for (i = 0; i < plan.num_tasks; i++) {
cnt = getline(&line, &len, fp);
if (cnt < 0) {
perror("getline");
return -1;
}
uint64_t cnt = strtoull(line, NULL, 10);
if (inst_cnt == 0) {
puts("Inst_cnt conversion failure");
return -1;
}
inst_cnt[i] = cnt;
}
plan.inst_cnt = inst_cnt;
pid_t pid = fork();
if (pid == 0x0) {
char *const args[] = {argv[1], NULL};
char *const env[] = {NULL};
write(pipes[0x1], "a", sizeof("a"));
ret = execve(argv[1], args, env);
if (ret < 0) {
perror("execve");
return -1;
}
}
else {
/**
* Wait for execve of child to finish else pb cycles are wasted inside
* the execve function.
*
* todo: find better method to do this
*/
sleep(0x1);
char c;
read(pipes[0x0], &c, sizeof(char));
plan.pid = pid;
ret = syscall(PB_SET_PLAN, &plan);
if (ret < 0) {
puts("PB_SET_PLAN failed");
return -1;
}
}
return 0;
}