<commit_before>#define KL_LOG KL_SYSCALL
#include <klog.h>
#include <sysent.h>
#include <systm.h>
#include <errno.h>
#include <thread.h>
#include <mman.h>
#include <vfs.h>
#include <vnode.h>
#include <fork.h>
#include <sbrk.h>
#include <signal.h>
#include <proc.h>
#include <stat.h>
#include <systm.h>
#include <wait.h>
#include <exec.h>
#include <time.h>
#include <proc.h>
#include <pipe.h>
#include <malloc.h>
#include <syslimits.h>

/* Empty syscall handler, for unimplemented and deprecated syscall numbers. */
int sys_nosys(thread_t *td, syscall_args_t *args) {
  klog("unimplemented system call %ld", args->code);
  return -ENOSYS;
};

static int sys_sbrk(thread_t *td, syscall_args_t *args) {
  intptr_t increment = (size_t)args->args[0];

  klog("sbrk(%d)", increment);

  return sbrk_resize(td->td_proc, increment);
}

static int sys_exit(thread_t *td, syscall_args_t *args) {
  int status = args->args[0];
  klog("exit(%d)", status);
  proc_exit(MAKE_STATUS_EXIT(status));
  __unreachable();
}

static int sys_fork(thread_t *td, syscall_args_t *args) {
  klog("fork()");
  return do_fork();
}

static int sys_getpid(thread_t *td, syscall_args_t *args) {
  klog("getpid()");
  return td->td_proc->p_pid;
}

static int sys_getppid(thread_t *td, syscall_args_t *args) {
  klog("getppid()");
  assert(td->td_proc->p_parent);
  return td->td_proc->p_parent->p_pid;
}

/* Moves the process to the process group with ID specified by pgid.
 * If pid is zero, then the PID of the calling process is used.
 * If pgid is zero, then the process is moved to process group
 * with ID equal to the PID of the process. */
static int sys_setpgid(thread_t *td, syscall_args_t *args) {
  pid_t pid = args->args[0];
  pgid_t pgid = args->args[1];

  klog("setpgid(%d, %d)", pid, pgid);

  proc_t *p = td->td_proc;

  if (pgid < 0)
    return -EINVAL;

  if (pid == 0)
    pid = p->p_pid;
  if (pgid == 0)
    pgid = pid;

  /* TODO Allow process to call setpgid on its children.
   * TODO Make setpgid accepts pgid equal to ID of any existing process group */
  if (pid != p->p_pid || pgid != p->p_pid)
    return -ENOTSUP;

  return pgrp_enter(p, pgid);
}

/* Gets process group ID of the process with ID specified by pid.
 * If pid equals zero then process ID of the calling process is used. */
static int sys_getpgid(thread_t *td, syscall_args_t *args) {
  pid_t pid = args->args[0];
  proc_t *p = td->td_proc;

  if (pid < 0)
    return -EINVAL;

  if (pid == 0)
    pid = p->p_pid;

  return proc_getpgid(pid);
}

static int sys_kill(thread_t *td, syscall_args_t *args) {
  pid_t pid = args->args[0];
  signo_t sig = args->args[1];
  klog("kill(%lu, %d)", pid, sig);
  return proc_sendsig(pid, sig);
}

static int sys_killpg(thread_t *td, syscall_args_t *args) {
  pgid_t pgid = args->args[0];
  signo_t sig = args->args[1];
  klog("killpg(%lu, %d)", pgid, sig);
  return -ENOTSUP;
}

static int sys_sigaction(thread_t *td, syscall_args_t *args) {
  int signo = args->args[0];
  char *p_newact = (char *)args->args[1];
  char *p_oldact = (char *)args->args[2];

  klog("sigaction(%d, %p, %p)", signo, p_newact, p_oldact);

  sigaction_t newact;
  sigaction_t oldact;
  int error;
  if ((error = copyin_s(p_newact, newact)))
    return error;

  int res = do_sigaction(signo, &newact, &oldact);
  if (res < 0)
    return res;

  if (p_oldact != NULL)
    if ((error = copyout_s(oldact, p_oldact)))<commit_msg>killpg system call implementation (#547)<commit_after>#define KL_LOG KL_SYSCALL
#include <klog.h>
#include <sysent.h>
#include <systm.h>
#include <errno.h>
#include <thread.h>
#include <mman.h>
#include <vfs.h>
#include <vnode.h>
#include <fork.h>
#include <sbrk.h>
#include <signal.h>
#include <proc.h>
#include <stat.h>
#include <systm.h>
#include <wait.h>
#include <exec.h>
#include <time.h>
#include <proc.h>
#include <pipe.h>
#include <malloc.h>
#include <syslimits.h>

/* Empty syscall handler, for unimplemented and deprecated syscall numbers. */
int sys_nosys(thread_t *td, syscall_args_t *args) {
  klog("unimplemented system call %ld", args->code);
  return -ENOSYS;
};

static int sys_sbrk(thread_t *td, syscall_args_t *args) {
  intptr_t increment = (size_t)args->args[0];

  klog("sbrk(%d)", increment);

  return sbrk_resize(td->td_proc, increment);
}

static int sys_exit(thread_t *td, syscall_args_t *args) {
  int status = args->args[0];
  klog("exit(%d)", status);
  proc_exit(MAKE_STATUS_EXIT(status));
  __unreachable();
}

static int sys_fork(thread_t *td, syscall_args_t *args) {
  klog("fork()");
  return do_fork();
}

static int sys_getpid(thread_t *td, syscall_args_t *args) {
  klog("getpid()");
  return td->td_proc->p_pid;
}

static int sys_getppid(thread_t *td, syscall_args_t *args) {
  klog("getppid()");
  assert(td->td_proc->p_parent);
  return td->td_proc->p_parent->p_pid;
}

/* Moves the process to the process group with ID specified by pgid.
 * If pid is zero, then the PID of the calling process is used.
 * If pgid is zero, then the process is moved to process group
 * with ID equal to the PID of the process. */
static int sys_setpgid(thread_t *td, syscall_args_t *args) {
  pid_t pid = args->args[0];
  pgid_t pgid = args->args[1];

  klog("setpgid(%d, %d)", pid, pgid);

  proc_t *p = td->td_proc;

  if (pgid < 0)
    return -EINVAL;

  if (pid == 0)
    pid = p->p_pid;
  if (pgid == 0)
    pgid = pid;

  /* TODO Allow process to call setpgid on its children.
   * TODO Make setpgid accepts pgid equal to ID of any existing process group */
  if (pid != p->p_pid || pgid != p->p_pid)
    return -ENOTSUP;

  return pgrp_enter(p, pgid);
}

/* Gets process group ID of the process with ID specified by pid.
 * If pid equals zero then process ID of the calling process is used. */
static int sys_getpgid(thread_t *td, syscall_args_t *args) {
  pid_t pid = args->args[0];
  proc_t *p = td->td_proc;

  if (pid < 0)
    return -EINVAL;

  if (pid == 0)
    pid = p->p_pid;

  return proc_getpgid(pid);
}

static int sys_kill(thread_t *td, syscall_args_t *args) {
  pid_t pid = args->args[0];
  signo_t sig = args->args[1];
  klog("kill(%lu, %d)", pid, sig);
  return proc_sendsig(pid, sig);
}

/* Sends signal sig to process group with ID equal to pgid. */
static int sys_killpg(thread_t *td, syscall_args_t *args) {
  pgid_t pgid = args->args[0];
  signo_t sig = args->args[1];
  klog("killpg(%lu, %d)", pgid, sig);

  if (pgid == 1 || pgid < 0)
    return -EINVAL;

  /* pgid == 0 => sends signal to our process group
   * pgid  > 1 => sends signal to the process group with ID equal pgid */
  return proc_sendsig(-pgid, sig);
}

static int sys_sigaction(thread_t *td, syscall_args_t *args) {
  int signo = args->args[0];
  char *p_newact = (char *)args->args[1];
  char *p_oldact = (char *)args->args[2];

  klog("sigaction(%d, %p, %p)", signo, p_newact, p_oldact);

  sigaction_t newact;
  sigaction_t oldact;
  int error;
  if ((error = copyin_s(p_newact, newact)))
    return error;

  int res = do_sigaction(signo, &newact, &oldact);
  if (res < 0)
    return res;

  if (p_oldact != NULL)
    if ((error = copyout_s(oldact, p_oldact)))
{'fraction_non_alphanumeric': 0.15122020031033998, 'fraction_numerical': 0.0060657356467766965, 'mean_word_length': 4.0, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 102, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6220754', 'n_tokens_mistral': 2901, 'n_tokens_neox': 2781, 'n_words': 784}