Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/webm/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 823 B image not shown  

Quelle  actions.c   Sprache: unbekannt

 
// SPDX-License-Identifier: GPL-2.0
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>

#include "actions.h"
#include "trace.h"
#include "utils.h"

/*
 * actions_init - initialize struct actions
 */

void
actions_init(struct actions *self)
{
 self->size = action_default_size;
 self->list = calloc(self->size, sizeof(struct action));
 self->len = 0;
 self->continue_flag = false;

 memset(&self->present, 0sizeof(self->present));

 /* This has to be set by the user */
 self->trace_output_inst = NULL;
}

/*
 * actions_destroy - destroy struct actions
 */

void
actions_destroy(struct actions *self)
{
 /* Free any action-specific data */
 for (struct action *action = self->list; action < self->list + self->len; action++) {
  if (action->type == ACTION_SHELL)
   free(action->command);
  if (action->type == ACTION_TRACE_OUTPUT)
   free(action->trace_output);
 }

 /* Free action list */
 free(self->list);
}

/*
 * actions_new - Get pointer to new action
 */

static struct action *
actions_new(struct actions *self)
{
 if (self->len >= self->size) {
  self->size *= 2;
  self->list = realloc(self->list, self->size * sizeof(struct action));
 }

 return &self->list[self->len++];
}

/*
 * actions_add_trace_output - add an action to output trace
 */

int
actions_add_trace_output(struct actions *self, const char *trace_output)
{
 struct action *action = actions_new(self);

 self->present[ACTION_TRACE_OUTPUT] = true;
 action->type = ACTION_TRACE_OUTPUT;
 action->trace_output = calloc(strlen(trace_output) + 1sizeof(char));
 if (!action->trace_output)
  return -1;
 strcpy(action->trace_output, trace_output);

 return 0;
}

/*
 * actions_add_trace_output - add an action to send signal to a process
 */

int
actions_add_signal(struct actions *self, int signal, int pid)
{
 struct action *action = actions_new(self);

 self->present[ACTION_SIGNAL] = true;
 action->type = ACTION_SIGNAL;
 action->signal = signal;
 action->pid = pid;

 return 0;
}

/*
 * actions_add_shell - add an action to execute a shell command
 */

int
actions_add_shell(struct actions *self, const char *command)
{
 struct action *action = actions_new(self);

 self->present[ACTION_SHELL] = true;
 action->type = ACTION_SHELL;
 action->command = calloc(strlen(command) + 1sizeof(char));
 if (!action->command)
  return -1;
 strcpy(action->command, command);

 return 0;
}

/*
 * actions_add_continue - add an action to resume measurement
 */

int
actions_add_continue(struct actions *self)
{
 struct action *action = actions_new(self);

 self->present[ACTION_CONTINUE] = true;
 action->type = ACTION_CONTINUE;

 return 0;
}

/*
 * actions_parse - add an action based on text specification
 */

int
actions_parse(struct actions *self, const char *trigger)
{
 enum action_type type = ACTION_NONE;
 char *token;
 char trigger_c[strlen(trigger) + 1];

 /* For ACTION_SIGNAL */
 int signal = 0, pid = 0;

 /* For ACTION_TRACE_OUTPUT */
 char *trace_output;

 strcpy(trigger_c, trigger);
 token = strtok(trigger_c, ",");

 if (strcmp(token, "trace") == 0)
  type = ACTION_TRACE_OUTPUT;
 else if (strcmp(token, "signal") == 0)
  type = ACTION_SIGNAL;
 else if (strcmp(token, "shell") == 0)
  type = ACTION_SHELL;
 else if (strcmp(token, "continue") == 0)
  type = ACTION_CONTINUE;
 else
  /* Invalid trigger type */
  return -1;

 token = strtok(NULL, ",");

 switch (type) {
 case ACTION_TRACE_OUTPUT:
  /* Takes no argument */
  if (token == NULL)
   trace_output = "timerlat_trace.txt";
  else {
   if (strlen(token) > 5 && strncmp(token, "file="5) == 0) {
    trace_output = token + 5;
   } else {
    /* Invalid argument */
    return -1;
   }

   token = strtok(NULL, ",");
   if (token != NULL)
    /* Only one argument allowed */
    return -1;
  }
  return actions_add_trace_output(self, trace_output);
 case ACTION_SIGNAL:
  /* Takes two arguments, num (signal) and pid */
  while (token != NULL) {
   if (strlen(token) > 4 && strncmp(token, "num="4) == 0) {
    signal = atoi(token + 4);
   } else if (strlen(token) > 4 && strncmp(token, "pid="4) == 0) {
    if (strncmp(token + 4"parent"7) == 0)
     pid = -1;
    else
     pid = atoi(token + 4);
   } else {
    /* Invalid argument */
    return -1;
   }

   token = strtok(NULL, ",");
  }

  if (!signal || !pid)
   /* Missing argument */
   return -1;

  return actions_add_signal(self, signal, pid);
 case ACTION_SHELL:
  if (token == NULL)
   return -1;
  if (strlen(token) > 8 && strncmp(token, "command="8) == 0)
   return actions_add_shell(self, token + 8);
  return -1;
 case ACTION_CONTINUE:
  /* Takes no argument */
  if (token != NULL)
   return -1;
  return actions_add_continue(self);
 default:
  return -1;
 }
}

/*
 * actions_perform - perform all actions
 */

int
actions_perform(struct actions *self)
{
 int pid, retval;
 const struct action *action;

 for (action = self->list; action < self->list + self->len; action++) {
  switch (action->type) {
  case ACTION_TRACE_OUTPUT:
   retval = save_trace_to_file(self->trace_output_inst, action->trace_output);
   if (retval) {
    err_msg("Error saving trace\n");
    return retval;
   }
   break;
  case ACTION_SIGNAL:
   if (action->pid == -1)
    pid = getppid();
   else
    pid = action->pid;
   retval = kill(pid, action->signal);
   if (retval) {
    err_msg("Error sending signal\n");
    return retval;
   }
   break;
  case ACTION_SHELL:
   retval = system(action->command);
   if (retval)
    return retval;
   break;
  case ACTION_CONTINUE:
   self->continue_flag = true;
   return 0;
  default:
   break;
  }
 }

 return 0;
}

Messung V0.5 in Prozent
C=94 H=90 G=91

[Dauer der Verarbeitung: 0.19 Sekunden, vorverarbeitet 2026-06-07]