Download | Plain Text | Line Numbers


/*
 * simple taskset -> cpuset converter
 */
 
#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
 
void usage()
{
  printf("Usage: taskset mask cmd [args...]\n");
  exit(EXIT_FAILURE);
}
 
int main(int argc, char *argv[])
{
  int query[2];
  int numcpu = 0;
  size_t length = sizeof(numcpu);
  int i;
  long mask;
  char *endptr;
  /* fixed buffers -> buffer overflow */
  char csarg[255] = "-l";
  char buf[10];
 
  if (argc < 3)
    usage();
 
  query[0] = CTL_HW;
  query[1] = HW_NCPU;
  if (sysctl(query, 2, &numcpu, &length, NULL, 0) == -1)
  {
    printf("Unable to query cpus: %s\n", strerror(errno));
    return EXIT_FAILURE;
  }
 
  mask = strtol(argv[1], &endptr, 16);
  if ((errno == ERANGE && (mask == LONG_MAX || mask == LONG_MIN))
    || (errno != 0 && mask == 0))
  {
    printf("Invalid mask value\n");
    exit(EXIT_FAILURE);
  }
 
  if (*endptr != '\0' || mask < 0)
  {
    printf("Invalid mask value. Only positive numbers allowed.\n");
    exit(EXIT_FAILURE);
  }
 
  if (mask == 0)
  {
    printf("Mask value 0 not allowed.\n");
    exit(EXIT_FAILURE);
  }
 
  for(i = 0; i < numcpu; ++i)
  {
    long cpuval = pow(2, i);
    if (mask & cpuval)
    {
      sprintf(buf, "%d,", i);
      strcat(csarg, buf);
    }
  }
 
  argv[0] = "cpuset";
  argv[1] = csarg;
  return execvp(argv[0], argv);
}