4

I'm developing on SGS2 api v.16

I have two applications: native and Java

From the native app I open a Unix pipe with mkfifo() function and write some string to it.

And in the java app I'm trying to read the string, but somehow the app blocks and I don't know why, no indication in the logcat for why it blocked.

The 2 apps have android:sharedUserId="my.Id" in the manifest, and the share worked for sure.

In the logcat I can see the "opening input stream" log, but no log after that.. Is there a recommended way to read from a pipe file in Java? NOTE: if I open a regular file with open(...) instead of using mkfifo(...) I succeed to read from the file, the problem is only when I open a pipe file with mkfifo()

Here is the function runs from the native app:

jint Java_com_example_ndkfoo_NdkFooActivity_writeToPipe(JNIEnv* env, jobject javaThis) {
   const char* PATH = "/data/data/com.example.ndkfoo/v_pipe8";
   char* line = "Hello Pipe!";
   int pipe;
   errno = 0;

   // open a named pipe
   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
   pipe = mkfifo(PATH, mode);
   if(errno != 0) {
        __android_log_write(ANDROID_LOG_ERROR, "NDK_FOO_TAG", strerror(errno));
        return errno;
    }
    __android_log_write(ANDROID_LOG_DEBUG, "NDK_FOO_TAG", "file opened successfully");

   // actually write out the data and close the pipe
   int err = write(pipe, line, strlen(line));

    // close the pipe
   close(pipe);
   return err;

}

And here is the java that tries to read from the pipe

package com.example.secondparty;

import java.io.FileDescriptor;
import java.io.FileInputStream;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {
     private static final String TAG = MainActivity.class.getSimpleName();
     //public final static String PATH2 = "/sdcard/fifo9001";
     public final static String PATH = "/data/data/com.example.ndkfoo/v_pipe8";

     @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        readFromPipe();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private void readFromPipe() {
        Log.i(TAG, "Attempt started");
        FileInputStream fis;
        String message = "";
        byte buffer[] = new byte[256];

        try {
            Log.i(TAG, "openning input stream");
            fis = new FileInputStream(PATH);
            Log.i(TAG, "input stream opened");
            FileDescriptor fd =  fis.getFD();
            int len = 0;
            do {
                len = fis.read(buffer);
                if(len > 0) {
                    String newmessage = new String(buffer,0, len, "US-ASCII");
                    message += newmessage;
                }
            } while (len == buffer.length);
            Log.i(TAG, "message: "+message);
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}
Bush
  • 2,433
  • 5
  • 34
  • 57

2 Answers2

1

Use BufferedReader instead `FileInputStream

Bush
  • 2,433
  • 5
  • 34
  • 57
0

here a very helpful consideration over the case, with some examples and explanations. http://www.jonathanbeard.io/tutorials/CtoJava

Jonathan
  • 595
  • 5
  • 10
  • please don't post links as answers. Overtime, the link may become broken. Please include all of the detail in your answer. Also, keep in mind that this question already has an accepted answer – SaggingRufus Mar 21 '17 at 10:04