Example #1
0
int main(int argc, char **argv)
{
	int fd;
	int ret;
	enum usb_controller state = atoi(argv[1]);

	int val = atoi(argv[2]);

	fd = open("/dev/usb_accessory_debug",O_RDWR);
	err_chk(fd, open);

	switch (state) {
		case USB_CMD_SND:	
			ret = ioctl(fd, USBCMDS, &val);
			err_chk(ret, ioctl);
			break;

		case USB_CMD_RCV:	
			ret = ioctl(fd, USBCMDR, &val);
			err_chk(ret, ioctl);
			printf("The value = %d\n", val);	
			break;

		default:
			printf("Currently not handled\n");
	}
		
	return 0;
}
Example #2
0
/***********************************************************************
* new_region_list - initialize a new region_list                       *
*                                                                      *
* Given a pid, new_region_list crawls through /proc/<pid>/maps and     *
* produces a linked list called region_list which contains the         *
* addresses for all the memory regions in the pid's address space.     *
*                                                                      *
* The flag RL_FLAG_ANON specifies whether it should include all the    *
* segments it can read in this list or just the interesting ones.      *
***********************************************************************/
struct region_list * new_region_list(pid_t pid, int flags)
{
    /* Variables */
    char * path = NULL;
    int maps_fd = -1;
    int maps_len;
    char * maps = NULL;
    int i = 0;
    off_t offset = 0;
    char i_hate_proc;
    struct region_list * head;
    struct region_list * cur;
    char * tok/*en_of_my_appreciation*/;
    int chk;

    /* Initialize */
    path = calloc(1, 25);
    err_chk(path == NULL);
    head = calloc(sizeof(struct region_list), 1);
    err_chk(head == NULL);
    cur = head;

    /* Open maps */
    snprintf(path, 24, "%s%d%s", "/proc/", (int) pid, "/maps");
    maps_fd = open(path, O_RDONLY);
    err_chk(maps_fd == -1);

    /* read maps into memory */
    for(maps_len = 0; (chk = read(maps_fd, &i_hate_proc, 1)) == 1; maps_len++); /* find length because files in proc are silly */
    err_chk(chk == -1);
    lseek(maps_fd, 0, SEEK_SET);
    maps = calloc(maps_len + 1, 1);
    err_chk(maps == NULL);
    while(offset != maps_len)
    {
        chk = read(maps_fd, maps + offset, maps_len - offset);
        err_chk(chk == -1);
        offset += chk;
    }

    /* parse */
    while(1)
    {
        cur->next = calloc(sizeof(struct region_list), 1);
        err_chk(cur->next == NULL);
        cur->next->begin = (void *) strtol(maps + i, &tok, 16);
        cur->next->end = (void *) strtol(tok + 1, &tok, 16);
        for(;maps[i] != '\n';i++);
        if(flags & RL_FLAG_RWANON)
        {
            if(tok[1] != 'r' || tok[2] != 'w' || tok[21] != '0' || tok[22] != ' ')
            {
                free(cur->next);
                cur->next = NULL;
                i++;
                if(i == maps_len)
                    break;
                else
                    continue;
            }
        }
        else
        {
            if(tok[1] != 'r')
            {
                free(cur->next);
                cur->next = NULL;
                i++;
                if(i == maps_len)
                    break;
                else
                    continue;
            }
        }
        if(i+1 == maps_len)
            break;
        else
            i++;
        cur = cur->next;
    }

    /* clean up */
    cur = head->next;
    free(head);
    free(path);
    free(maps);
    close(maps_fd);
    return cur;

err: /* Error handling */
    /* perror("new_region_list"); */
    if(path)
        free(path);
    if(maps)
        free(maps);
    if(maps_fd != -1)
        close(maps_fd);
    return NULL;
}
/* Main program logic */
int main(int argc, char * argv[])
{
    int event = 0;
    int umask = 0;
    pid_t pid = 0;
    int freq = DEFAULT_FREQ;
    int mmap_region = DEFAULT_BUFFER_SIZE;
    char * default_filename = DEFAULT_FILENAME;
    char * out = default_filename;
    int interval_ms = DEFAULT_INTERVAL;
    bool exit_error = false;

    /* Argument parsing */
    char opt;
    char * strerr = NULL;
    long arg;
    struct stat chkstat;
    int chk;
    while((opt = getopt(argc, argv, "+hre:u:f:p:o:m:k:i:")) != -1)
    {
        switch(opt)
        {
            /* Set realtime mode (UNIMPLEMENTED) */
            case 'r':
                err_msg("-r is unimplemented in this release.\n\n");
                break; /* unreached */

            /* Specify event code */
            case 'e':
                if(OPT_E)
                    err_msg("This program only monitors one event at a time for now, but two -e args specified!\n\n");
                OPT_E = true;
                arg = strtol(optarg, &strerr, 16);
                if(strerr[0] != 0)
                    err_msg("Unable to parse -e argument correctly, should be event code in hexadecimal\n\n");
                if(arg < 0 || arg > 0xFFF)
                    err_msg("Unable to parse -e argument, event code out of range 0x00-0xFFF\n\n");
                event = arg;
                optarg = NULL;
                break;
            
            /* Specify event code */
            case 'u':
                if(OPT_U)
                    err_msg("This version only monitors one event at a time for now, but two -u args specified!\n\n");
                OPT_U = true;
                arg = strtol(optarg, &strerr, 16);
                if(strerr[0] != 0)
                    err_msg("Unable to parse -u argument correctly, should be umask in hexadecimal\n\n");
                if(arg < 0 || arg > 0xFF)
                    err_msg("Unable to parse -u argument, umask out of range 0x00-0xFF\n\n");
                umask = arg;
                optarg = NULL;
                break;
    
            /* Specify pid to snapshot */
            case 'p':
                if(OPT_P)
                    err_msg("This version does not support more than one -p argument\n\n");
                OPT_P = true;
                arg = strtol(optarg, &strerr, 10);
                if(arg > INT_MAX || arg < 0 || strerr[0] != 0)
                    err_msg("Unable to parse -p argument correctly, should be a pid\n\n");
                pid = arg;
                optarg = NULL;
                break;
    
            /* Specify frequency */
            case 'f':
                if(OPT_F)
                    fprintf(stderr, "-f already specified, ignoring previous value...\n\n");
                OPT_F = true;
                arg = strtol(optarg, &strerr, 10);
                if(strerr[0] != 0)
                    err_msg("Unable to parse -f argument correctly, should be a frequency in whole numbers of hz\n\n");
                if(arg < 1)
                    err_msg("Unable to parse -f argument correctly, frequency must be greater than 1\n\n");
                if(arg < 2000)
                    fprintf(stderr, "Warning: frequencies below 2000hz miss samples often in our testing.\n\n");
                if(arg > 1000000000)
                    err_msg("Unable to parse -f argument correctly, frequencies above 1ghz are unsupported\n\n");
                freq = arg;
                optarg = NULL;
                break;
    
            /* Specify output file */
            case 'o':
                if(OPT_O)
                    err_msg("-o already specified\n\n");
                OPT_O = true;
                arg = stat(dirname(optarg), &chkstat);
                if(arg == -1 && errno == ENOENT)
                    err_msg("Unable to parse -o argument correctly, invalid path to file\n\n");
                if(arg == -1)
                    perr_msg("Unable to parse -o argument correctly: ");
                out = optarg;
                optarg = NULL;
                break;
    
            /* Specify mmap() region in megabytes or kilobytes */
            case 'm':
            case 'k':
                if(OPT_MK)
                    fprintf(stderr, "mmap region size already specified in previous -m or -k, ignoring previous...\n\n");
                OPT_MK = true;
                arg = strtol(optarg, &strerr, 10);
                if(arg > INT_MAX || arg < 0 || strerr[0] != 0)
                {
                    if(opt == 'm')
                        err_msg("Unable to parse -m argument correctly, should be mmap buffer size in megabytes\n\n");
                    else
                        err_msg("Unable to parse -k argument correctly, should be mmap buffer size in kilobytes\n\n");
                }
                if(opt == 'm')
                    arg *= 1024;
                if(arg > 128 * 1024)
                    err_msg("mmap buffer specified is larger than 128mb.  That seems large, don't you think?  I refuse to be party to this.\n\n");
                if(arg < 8)
                    err_msg("mmap buffer must be at least 8kb.\n\n");
                arg *= 1024;
                mmap_region = getpagesize();
                while(mmap_region < arg)
                    mmap_region <<= 1;
                if(mmap_region != arg)
                    err_msg("mmap buffer must be specified as a power of two.\n\n");
                optarg = NULL;
                break;

            /* Specify interval between data collection, in milliseconds */
            case 'i':
                if(OPT_I)
                    fprintf(stderr, "-i already specified, ignoring previous value...\n\n");
                OPT_I = true;
                arg = strtol(optarg, &strerr, 10);
                if(strerr[0] != 0)
                    err_msg("Unable to parse -i argument correctly, should be number of milliseconds\n\n");
                if(arg < 0)
                    err_msg("Unable to parse -i argument, must be a positive number\n\n");
                interval_ms = arg * 1000;
                optarg = NULL;
                break;
    
            /* Print usage */
            case 'h':
            default:
                print_usage();
                return 0;
        }
    }

    /* Option validity checks */
    if(!OPT_E)
        err_msg("No event code specified!\n\n");
    if(!OPT_U)
        err_msg("No umask specified!\n\n");

    /* Start a process if specified on the command line */
    if(argc > optind)
    {
        if(OPT_P)
            err_msg("pid already specified, cannot also specify a process to run!\n\n");

        /* Fork */
        pid_t ret = 0;
        ret = fork();
        err_chk(ret == -1);

        /* Which side of the fork are we on? */
        if(ret == 0) /* We are the child */
        {
            int i;
            char ** arglist;
            arglist = calloc((argc - optind) + 1, sizeof(char *)); /* Enough for all the args, plus a null */
            for(i = optind;i <= argc;i++)
                arglist[i - optind] = argv[i];
            arglist[argc - optind] = NULL;
            chk = execvp(argv[optind], arglist); /* Never returns */
            err_chk(chk == -1);
            sleep(1); //XXX: Remove me?
        }
        else /* We are the parent */
        {
            pid = ret;
            OPT_P = true;
        }
    }

    /* Check for pid */
    if(!OPT_P)
        err_msg("No process specified!\n\n");

    /* Configure perf_event_attr */
    struct perf_event_attr e;
    memset(&e, 0, sizeof(struct perf_event_attr));
    e.type = PERF_TYPE_RAW;
    e.size = sizeof(struct perf_event_attr);
    e.config = event | umask << 8;
    e.freq = 1;
    e.sample_freq = freq;
    e.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_READ;
    e.pinned = 1;
    e.exclude_user = 0;
    e.exclude_kernel = 0;
    e.exclude_hv = 1;

    /* Initialize performance events */
    int pe_fd;
    pe_fd = perf_event_open(&e, pid, -1, -1, 0);
    err_chk(pe_fd == -1);

    /* mmap buffer */
    void * pem = NULL;
    void * events = NULL;
    int tail = 0;
    struct perf_event_mmap_page * hdr = NULL;
    pem = mmap(NULL, mmap_region + getpagesize(), PROT_READ, MAP_SHARED, pe_fd, 0); /* Failing point */
    err_chk(pem == MAP_FAILED);

    hdr = pem;
    events = (char *) pem + getpagesize();

    /* Open output file */
    int outfd = 0;
    void * outbuf = NULL;
    FILE * output = NULL;
    outfd = open(out, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
    err_chk(outfd == -1);
    outbuf = calloc(1, mmap_region);
    err_chk(outbuf == NULL);
    output = fdopen(outfd, "w");
    err_chk(output == NULL);

    while(1) /* Main Loop */
    {
        usleep(interval_ms);

        int head = hdr->data_head;
        rmb();

        if(head == tail)
            continue;

        if(head - tail > mmap_region)
            fprintf(stderr, "Missed samples!  Enlarge mmap region!\n");

        /* Copy into buffer */
        if(head % mmap_region < tail % mmap_region)
        {
            memcpy(outbuf, (char *) events + (tail % mmap_region), mmap_region - (tail % mmap_region));
            memcpy((char *) outbuf + (mmap_region - (tail % mmap_region)), events, head % mmap_region);
        }
        else
            memcpy(outbuf, (char *) events + (tail % mmap_region), head - tail);

        chk = fwrite(outbuf, 1, head - tail, output);
        err_chk(chk != head - tail);

        tail += head - tail;

    }

    /* Cleanup and exit cleanly */
    goto cleanup;

/* Error handler */
err:
    perror("event_count");
    exit_error = true;

/* Cleanup anything that needs to be cleaned up */
cleanup:
    if(pem && pem != MAP_FAILED)
        munmap(pem, mmap_region + getpagesize());
    if(pe_fd && pe_fd != -1)
        close(pe_fd);
    if(output != NULL)
        fclose(output);
    if(outfd && outfd != -1 && output == NULL)
        close(outfd);
    if(outbuf)
        free(outbuf);

/* Exit */
    if(exit_error)
        exit(EXIT_FAILURE);
    exit(EXIT_SUCCESS);
}
Example #4
0
int
main ( /* int argc, char * argv[] */ )
{
  int pipe_d[2], pipe_u[2];

  // Open two pipes
  err_chk (pipe (pipe_d) == -1, "pipe: failed to open pipe_d");
  err_chk (pipe (pipe_u) == -1, "pipe: failed to open pipe_u");
  printf ("Opened pipe_d (r:%d, w:%d)\n", pipe_d[PIPE_READ],
	  pipe_d[PIPE_WRITE]);
  printf ("Opened pipe_u (r:%d, w:%d)\n", pipe_u[PIPE_READ],
	  pipe_u[PIPE_WRITE]);


  // Create a child process
  pid_t pID = fork ();

  switch (pID)
    {

      /* FAILURE */
    case -1:
      perror ("fork");
      exit (EXIT_FAILURE);


      /* CHILD PROCESS */
    case 0:

      // close write end of downstream pipe
      err_chk (close (pipe_d[PIPE_WRITE]) == -1, "close: dw");

      // close read end of upstream pipe
      err_chk (close (pipe_u[PIPE_READ]) == -1, "close: ur");



      // Message testing
      char c_msg_out[BUFSIZ] = "uw";
      char c_msg_in[BUFSIZ];


      // get message from parent
      ssize_t r_bytes_c = read (pipe_d[PIPE_READ], &c_msg_in, BUFSIZ);
      err_chk (r_bytes_c == 0, "read: unexpected EOF");
      err_chk (r_bytes_c == -1, "read");
      printf ("CHILD:  writing on %d OK\n", pipe_d[PIPE_WRITE]);

      if (strcmp (c_msg_in, "dw") == 0)
	{
	  printf ("CHILD:  reading on %d OK\n", pipe_d[PIPE_READ]);
	  fflush (stdout);
	}
      else
	{
	  printf ("CHILD:  unexpected message from parent\n");
	  exit (EXIT_FAILURE);
	}


      // send a response
      ssize_t w_bytes_c = write (pipe_u[PIPE_WRITE], &c_msg_out, BUFSIZ);
      err_chk (w_bytes_c == 0 || w_bytes_c == -1, "write");


      // redirect stdout and stdin
      printf
	("CHILD:  duplicating downstream read (%d) onto stdin (%d)\n",
	 pipe_d[PIPE_READ], STDIN_FILENO);

      dup2 (pipe_d[PIPE_READ], STDIN_FILENO);

      printf
	("CHILD:  duplicating upstream write (%d) onto stdout (%d)\n",
	 pipe_u[PIPE_WRITE], STDOUT_FILENO);

      dup2 (pipe_u[PIPE_WRITE], STDOUT_FILENO);

      printf ("ready");
      fflush (stdout);



      // starting sort
      execlp ("sort", "sort", "-k3,3", "-k1,1", NULL);


      // something went wrong if we got this far
      perror ("returned from execlp unexpectedly");
      exit (EXIT_FAILURE);


      /* PARENT PROCESS */
    default:

      // close read end of downstream pipe
      err_chk (close (pipe_d[PIPE_READ]) == -1, "close: dr");

      // close write end of upstream pipe
      err_chk (close (pipe_u[PIPE_WRITE]) == -1, "close: uw");



      // Message testing
      char p_msg_out[BUFSIZ] = "dw";
      char p_msg_in[BUFSIZ];


      // send message to child
      ssize_t w_bytes_p = write (pipe_d[PIPE_WRITE], &p_msg_out, BUFSIZ);
      err_chk (w_bytes_p == 0 || w_bytes_p == -1, "write");


      // get response from child
      ssize_t r_bytes_p = read (pipe_u[PIPE_READ], &p_msg_in, BUFSIZ);
      err_chk (r_bytes_p == 0, "read: unexpected EOF");
      err_chk (r_bytes_p == -1, "read");
      printf ("PARENT: writing on %d OK\n", pipe_u[PIPE_WRITE]);

      if (strcmp (p_msg_in, "uw") == 0)
	{
	  printf ("PARENT: reading on %d OK\n", pipe_u[PIPE_READ]);
	  fflush (stdout);
	}
      else
	{
	  perror ("PARENT: unexpected message from child");
	  exit (EXIT_FAILURE);
	}



      // see if stdout was redirected successfully
      char buffer[BUFSIZ];
      r_bytes_p = read (pipe_u[PIPE_READ], &buffer, BUFSIZ);
      err_chk (r_bytes_p == 0, "read: unexpected EOF");
      err_chk (r_bytes_p == -1, "read");
      printf ("PARENT: child reports: %s\n", buffer);
      fflush (stdout);


      // ready to start sending data for sorting
      FILE *sort_data = fopen ("cs308a2_sort_data", "r");
      while (fgets (buffer, BUFSIZ, sort_data) != NULL)	// get one line
	{
	  // send line of data to child running sort
	  w_bytes_p = write (pipe_d[PIPE_WRITE], &buffer, strlen (buffer));
	  err_chk (w_bytes_p == 0 || w_bytes_p == -1, "write");
	}


      // once fgets returns null, we hit EOF.
      // we'll close the pipe to child to trigger an EOF downstream.
      err_chk (close (pipe_d[PIPE_WRITE]) == -1, "close: dw");

      // don't need the input file handle anymore
      fclose (sort_data);


      // now we'll await results and print them
      int prev_ac = 0, ac_count = 0;
      char name1[BUFSIZ], name2[BUFSIZ];
      int ac, p1, p2;

      FILE *fp = fdopen (pipe_u[PIPE_READ], "r");

      printf ("\n");
      while (fgets (buffer, BUFSIZ, fp) != NULL)
	{
	  buffer[strlen (buffer) - 1] = '\0';
	  sscanf (buffer, "%511s %511s %3d %3d %4d", name1, name2, &ac, &p1,
		  &p2);
	  ac_count++;

	  if (ac != prev_ac)
	    {
	      printf ("  Area code %d: %d instances\n", ac, ac_count);
	      ac_count = 0;
	    }

	  prev_ac = ac;
	}

      printf ("\n");

      // clean up
      err_chk (close (pipe_u[PIPE_READ]) == -1, "close: ur");
      printf ("PARENT: waiting for child process to terminate\n");
      wait (NULL);
      printf ("PARENT: all done, exiting\n");
      exit (EXIT_SUCCESS);
    }

  // if we get here, something went wrong
  printf ("We shouldn't be here...\n");
  exit (EXIT_FAILURE);
}