0

I have a c code which is using pthread and specifically pthread_cond_wait. My problem is that if I am calling this c executable from my python code using subprocess.Popen it's not working correctly, it looks like it's buffering data instead of printing in real time. Following is my c code:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <pthread.h>
#include "linux_nfc_api.h"

pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

nfcTagCallback_t g_TagCB;
nfc_tag_info_t g_tagInfos;

void onTagArrival(nfc_tag_info_t *pTagInfo){
    printf("Tag detected\n");
    int i = 0;
    for(i = 0x00; i < (*pTagInfo).uid_length; i++){
        printf("%02X ", (unsigned char) (*pTagInfo).uid[i]);
    }
    g_tagInfos = *pTagInfo;
    pthread_cond_signal(&condition);
}

void onTagDeparture(void){
    printf("Tag removed\n");
}

int main(int argc, char ** argv) {
    g_TagCB.onTagArrival = onTagArrival;
    g_TagCB.onTagDeparture = onTagDeparture;
    nfcManager_doInitialize();
    nfcManager_registerTagCallback(&g_TagCB);
    nfcManager_enableDiscovery(DEFAULT_NFA_TECH_MASK, 0x01, 0, 0);

    unsigned char page = 0x00;
    int i;
    int res = 0x00;
    unsigned char cmd_send[3] = {0x02, 0x20, 0x00};
    unsigned char cmd_response[255];
    printf("Waiting for tag...\n");
    do{
        pthread_cond_wait(&condition, &mutex); //problem

        memset(cmd_response, 0x00, 255);

        printf("SEND APDU: ");
        for(i=0; i < sizeof(cmd_send); i++){
            printf("%02X ",cmd_send[i]);
        }

        res = nfcTag_transceive(g_tagInfos.handle, cmd_send, 3, cmd_response, 255, 500);
        printf("RECV APDU (%d): ",res);
        for(i=0; i<res; i++){
            printf("%02X ",cmd_response[i]);
        }
    }while(1);
    nfcManager_doDeinitialize();
}

I found out that problem is due to pthread_cond_wait. My python keeps on buffering and it prints all data after python program is closed instead of real time. Following is my python code:

import sys
from subprocess import Popen, PIPE, call

proc = Popen(['App'], stdout=PIPE)
for line in iter(proc.stdout.readline, ''):
    print line

Thus is there any way to handle this situation considering the fact I will not be able to change my c code?

prattom
  • 1,625
  • 11
  • 42
  • 67

1 Answers1

0

Try:

import sys
from subprocess import Popen, PIPE, call

proc = Popen(['App'], stdout=PIPE, stderr=PIPE)
output, errors = proc.communicate()
print output.decode()

Why:

See python docs:

Warning - Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

Montmons
  • 1,416
  • 13
  • 44