Beispiel #1
0
static void *simple_sink_thread (void *param)
{
	char		*name = (char *) param;
	int		status;
	char		buf [USB_BUFSIZE];

	status = sink_open (name);
	if (status < 0)
		return 0;
	sink_fd = status;

	/* synchronous reads of endless streams of data */
	pthread_cleanup_push (close_fd, &sink_fd);
	do {
		/* original LinuxThreads cancelation didn't work right
		 * so test for it explicitly.
		 */
		pthread_testcancel ();
		errno = 0;
		status = read (sink_fd, buf, sizeof buf);

		if (status < 0)
			break;
		status = empty_out_buf (buf, status);
	} while (status > 0);
	if (status == 0) {
		if (verbose)
			fprintf (stderr, "done %s\n", __FUNCTION__);
	} else if (verbose > 2 || errno != ESHUTDOWN) /* normal disconnect */
		perror ("read");
	fflush (stdout);
	fflush (stderr);
	pthread_cleanup_pop (1);

	return 0;
}
Beispiel #2
0
static void *aio_out_thread (void *param)
{
	char		*name = (char *) param;
	int		status;
	io_context_t	ctx = 0;
	struct iocb	*queue, *iocb;
	unsigned	i;

	status = sink_open (name);
	if (status < 0)
		return 0;
	sink_fd = status;
	pthread_cleanup_push (close_fd, &sink_fd);

	/* initialize i/o queue */
	status = io_setup (aio_out, &ctx);
	if (status < 0) {
		perror ("aio_out_thread, io_setup");
		return 0;
	}
	pthread_cleanup_push (queue_release, &ctx);

	if (aio_out == 0)
		aio_out = 1;
	queue = alloca (aio_out * sizeof *iocb);

	/* populate and (re)run the queue */
	for (i = 0, iocb = queue; i < aio_out; i++, iocb++) {
		char *buf = malloc (iosize);

		if (!buf) {
			fprintf(stderr, "%s can't get buffer[%d]\n",
				__FUNCTION__, i);
			return 0;
		}

		/* data can be processed in out_complete() */
		io_prep_pread (iocb, sink_fd, buf, iosize, 0);
		io_set_callback (iocb, out_complete);
		iocb->key = USB_DIR_OUT;

		status = io_submit (ctx, 1, &iocb);
		if (status < 0) {
			perror (__FUNCTION__);
			break;
		}
		aio_out_pending++;
		if (verbose > 2)
			fprintf(stderr, "%s submit uiocb %p\n",
				__FUNCTION__, iocb);
	}

	status = io_run (ctx, &aio_out_pending);
	if (status < 0)
		perror ("aio_out_thread, io_run");

	/* clean up */
	fflush (stderr);
	pthread_cleanup_pop (1);
	pthread_cleanup_pop (1);

	return 0;
}
Beispiel #3
0
/* ccid thread, forwards ccid requests to pcsc and returns results  */
static void *ccid (void *param)
{
    char	**names      = (char **) param;
    char	*source_name = names[0];
    char	*sink_name   = names[1];
    int		result;
    size_t      bufsize = sizeof(PC_to_RDR_XfrBlock_t) + CCID_EXT_APDU_MAX;
    __u8        inbuf[bufsize];

    source_fd = source_open (source_name);
    if (source_fd < 0) {
        if (verbose > 1)
            perror("source_fd");
        goto error;
    }
    pthread_cleanup_push (close_fd, &source_fd);

    sink_fd   = sink_open (sink_name);
    if (sink_fd   < 0) {
        if (verbose > 1)
            perror("sink_fd");
        goto error;
    }
    pthread_cleanup_push (close_fd, &sink_fd);

    pthread_cleanup_push (close_ccid, NULL);

    __u8 *outbuf = NULL;
    pthread_cleanup_push (free, outbuf);

    do {

        /* original LinuxThreads cancelation didn't work right
         * so test for it explicitly.
         */
        pthread_testcancel ();

        if (verbose > 1)
            fprintf(stderr, "bulk loop: reading %lu bytes... ", (long unsigned) bufsize);
        result = read(sink_fd, inbuf, bufsize);
        if (result < 0) break;
        if (verbose > 1)
            fprintf(stderr, "bulk loop: got %d, done.\n", result);
        if (!result) break;

        result = ccid_parse_bulkout(inbuf, result, &outbuf);
        if (result < 0) break;

        if (verbose > 1)
            fprintf(stderr, "bulk loop: writing %d bytes... ", result);
        result = write(source_fd, outbuf, result);
        if (verbose > 1)
            fprintf(stderr, "done (%d written).\n", result);
    } while (result >= 0);

    if (errno != ESHUTDOWN || result < 0) {
        perror ("ccid loop aborted");
        pthread_cancel(ep0);
    }

    pthread_cleanup_pop (1);
    pthread_cleanup_pop (1);
    pthread_cleanup_pop (1);
    pthread_cleanup_pop (1);

    fflush (stdout);
    fflush (stderr);

    return 0;

error:
    pthread_cancel(ep0);
    pthread_exit(0);
}