0

This question was closed and the message instructs me to edit it or delete it, and possibly post a new question; however, the system won't permit me to delete it and states others have put in too much effort for it to be deleted.

That's fine. If interested, @jfs provided the answer in a comment here. I appreciate the comments and the answer in this post, but should point out that browsers can exchange messages with C programs through the native messaging API alone. Nothing else is required by the developer apart from that in the OS-specific set up instructions provided in this MDN document and this MDN document. Even I got that part to work, although my C question was quite novice.

Thanks.


I'm trying to set up native messaging between a browser extension and a native c program. I'm pretty sure I understand the extension side and have it ready to test; but I haven't used C since Borland Turbo C was popular.

Would you please point me to information on how the stdin and stdout in C are used to receive and post messages from the browser? I'm sure I'm just looking in the wrong places but all I've come across relate to the keyboard and files, but not input from another program. I think I can manipulate the information once I get it, but I'm stuck on the first step of the equivalent of setting up a communication port listener.

Thank you.


I'd like to do something like this done in C# but I don't follow what the equivalent is in C for the code below in public static JObject Read():

var stdin = Console.OpenStandardInput();
var lengthBytes = new byte[4];
stdin.Read(lengthBytes, 0, 4);

This question is similar to what is taking place. The browser is functioning as this poster's Java program, in that it opens the C progam and passes it data. I've just been confused on whether or not stdin has to redirected from the keyboard to something related to this pasing of data or if it will just pickup any data sent to it. And, how is the keyboard input not picked up in the interim?

Gary
  • 2,393
  • 12
  • 31
  • 1
    Regardless where the input is coming from you read from a file in C. `stdin` is the standard file number `0`. You can use *character-oriented* input `getchar()`, `fgetc()`, etc.., you can use *line-oriented* input, `fgets()` or POSIX `getline()`, or you can use *formatted-input*, such as `scanf()` or `fscanf()`. (though here you are better reading with `fgets()` and then using `sscanf()` to parse values from the buffer) If it is binary data, then you would use `fread()` or the lower-level syscall `read()`, the difference being whether you are using the file-stream or file descriptor. – David C. Rankin Oct 17 '20 at 05:38
  • 1
    For completion, `stdout` is the stream which corresponds to standard file number `1` and `stderr` file number `2`. From a file descriptor standpoint it is `STDIN_FILENO`, `STDOUT_FILENO` and`STDERR_FILENO`. – David C. Rankin Oct 17 '20 at 05:41
  • Thank you. I read about these methods and tried them on other input, but must be missing something obvious. All the examples and my books start off by opening a file to read. I'm missing how to get the standard file number 0 associated with input from the browser message? – Gary Oct 17 '20 at 05:53
  • Please [edit](https://stackoverflow.com/posts/64399326/edit) your question to give a lot more details: what computer, what operating system, what C compiler. Also provide some [mre] in your question here. – Basile Starynkevitch Oct 17 '20 at 06:09
  • @Basile Starynkevitch I want to do this but in C rather than C#. https://stackoverflow.com/questions/30880709/c-sharp-native-host-with-chrome-native-messaging, But I couldn't understand how `stdin` was going to read the incoming message but I think I understand now. – Gary Oct 17 '20 at 06:20
  • Generally, whatever your browser extension is writing to -- that is the file you need to read. It can write directly to `stdout` (though that would be strange, as the browser extension has no concept of what device that would be attached to), but more likely it is writing to a *port* or perhaps a Unix *socket*, both of which can be read in C. That is handled with basic networking. For that your Go-To guide is [Beej's Guide to Network Programming](https://beej.us/guide/bgnet/) which is kept current and probably the most up to date Networking tutorial out there. – David C. Rankin Oct 17 '20 at 06:43
  • Do you need help in implementing something like [native-messaging-example-host](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/docs/examples/api/nativeMessaging/host/native-messaging-example-host) in C (instead of Python in the example) or do you need help with making any native-messaging example to run (how to write manifest, where to put it, etc)? (or both?) – jfs Oct 17 '20 at 07:00
  • @jfs Implementing the Python example in C. – Gary Oct 17 '20 at 07:02
  • the essence of the example is to read 4 bytes from stdin, interpret them as a native integer to get the length of the message, then read given number of bytes to get utf-8 encoded json text. To read 4 bytes from stdin and get an integer in C is just: `fread(&n, sizeof(n), 1, stdin)` where `uint32_t n;` – jfs Oct 17 '20 at 07:12
  • @jfs Thank you. Does `stdin` ever have to be redirected? I mean will `stdin` in `fread` always read the extension's serialized object passed in the communication port? That's the part that I've been not understanding. – Gary Oct 17 '20 at 07:21
  • If all you do is fread/fwrite, It shouldn't matter where `stdin` is connected to. For unit testing, you could read input from a file (`your_program < test.file`). If `native-messaging-example-host` works for you, then it is enough to replace the Python script with your compiled C program. – jfs Oct 17 '20 at 07:44
  • @jfs Thanks for your help. I reposted this question a little differently since it was closed for lack of details or clarity; and you're the only one that understood what i was trying to ask. The question is here https://stackoverflow.com/questions/64400254/how-to-use-stdin-in-a-native-c-application-with-web-extension-native-messaging. If you want to answer it, I'll accept the answer. Thanks again. – Gary Oct 17 '20 at 08:03

1 Answers1

1

I am trying to set up native messaging between a browser extension and a native c program

A C program does not interact with a browser (for example, a C program running on Arduino don't, and the Linux kernel sometimes don't, and the C program inside my computer mouse don't).

Read about CGI and FastCGI and HTTP if you want to code a program interacting with some web browser.

Read more about the C programming language, e.g. Modern C then the C11 draft standard n1570.

On some operating systems (e.g. POSIX or Linux), you could use HTTP server libraries such as libonion (for Linux, see also syscalls(2)...). But If you use Windows, read its documentation.

Read the documentation of your C compiler (e.g. GCC) and debugger (e.g. GDB). Consider using static analysis tools like Frama-C or the Clang static analyzer.

On Linux, you may want to read socket(7) and tcp(7) and consider using popen(3) and/or dlopen(3). Then read also Advanced Linux Programming and syscalls(2).

On FreeBSD, things are slightly different. On Windows things are very different, and also on IBM/Series Z or OpenVMS or GNU Hurd or L4 or Plan9. Read also this PhD thesis about exokernels and see this list of open source operating systems.

You could want to read some textbook about operating systems.

Of course, some browsers -in particular firefox- are coded (mostly) in C++ (with some parts coded in Rust). You could even download its source code (since Firefox is open source). That code uses operating system specific APIs.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Are you certain that this method won't work if the native app. is written in C? https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging – Gary Oct 17 '20 at 05:47
  • @Gary: No, I am not certain because, not being a native English speaker, I don't understand what you mean by "native app". [n1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) don't mention them. – Basile Starynkevitch Oct 17 '20 at 05:48
  • I see. I mean a program installed on the user's computer. There is a language drop down in that Mozilla document but I don't know if it will have your native language. The objective is to have the extension communicate with the locally installed program. The document doesn't mention that the native-messaging API cannot work with C programs, although the examples use Python and node.js. I don't know enough about it, but there are SO questins where this is done using C#. Thanks for all the links. – Gary Oct 17 '20 at 06:00
  • If the user's computer run Android, or Windows, or FreeBSD, or Linux things are *very* different. If it is a [top500](http://top500.org/) supercomputer, things are even more different. AFAIK, supercomputers don't run browsers. – Basile Starynkevitch Oct 17 '20 at 06:01
  • I'm very much a novice and I'm sure the links you provided are well beyond my limited capacity. I'm not trying to be rude but I'm not sure what you thought I asked. A C program can interact with a browser. Perhaps we have a different understanding of "interact." Nonetheless, browser's provide a native-messaging API, as linked in my first comment above. @jfs provided me the information I was struggling to understand and it works. Please see https://stackoverflow.com/questions/64400254/how-to-use-stdin-in-a-native-c-application-with-web-extension-native-messaging. – Gary Oct 19 '20 at 02:56
  • According to the C11 standard n1570 a C program does not interact with a browser. However a POSIX program does. For example, my computer mouse contains a microcontroller programmed in C. But that does not interact with a browser – Basile Starynkevitch Oct 19 '20 at 04:17
  • I don't know about all of that but I compiled a C program in minGW-W64 to an .exe file and, using the native messaging API in Firefox browser, the browser extension can open the program and exchange messages with it. Thus, it can invoke functions in the C program, running in that execution context, and return the output to the extension. That's what the API is designed to do and it works. I'm just a novice, but what is surprising about a browser, which is at least in part written in C/C++, giving access via APIs to permit an extension to communciate with another C program? – Gary Oct 19 '20 at 05:52