I am developing an application in WinCE7. The application includes a serial com port and file IO operations. There is an embedded device connected the serial port. I need to check the status of inputs on the device and save their details in file. Lets say, if input 1 is high then I need to write Input 1 HIGH on the serial port, and save the same in file.
Now to write data in file I am using fprintf & fopen functions. Code looks like below:
main()
{
// some code to initialize serial port
FILE * fp;
fp= fopen ("Logs.txt", "w+"); //-------> create a file named as Logs.txt
while(1)
{
if(Input1 == TRUE)
{
serialPort.Send("Input 1 HIGH");
fprintf(fp,"%s","Input 1 HIGH"); //-------> saving data in file
}
if(Input2 == TRUE)
{
serialPort.Send("Input 2 HIGH");
fprintf(fp,"%s","Input 2 HIGH"); //-------> saving data in file
}
//same goes for rest of the inputs
}
fclose(fp); //----------> closing the file
}
Now after writing data to the file using fprintf, we need to use fclose() to close the file. But as I have to continuously monitor the input status I have used while(1) due to which my control doesn't reaches at fclose(fp). Thus the file is not closed and it becomes corrupted. When I open the file to see the saved data it gave me below error:
How can I properly use flcose() and fprintf() to write data in file.?
There is nothing wrong with opening log file and closing each time you want to do the logging. It might cause problems if your while loop is being executed with very high frequency - it may slow down your application. This is why you should consider a way to somehow close your application, now as I understand you copy your log file while your application is being executed - this can cause all sort of problems - among others that your file will be corrupted.
btw. you can also use windows-ce native logging api like: CeLog, see here:
https://msdn.microsoft.com/en-us/library/ee479601.aspx
https://msdn.microsoft.com/en-us/library/ee488587.aspx
When would your loop start, and when would it end? I mean, not programatically, but theoretically? The simplest thing seems to be to modify the while condition. As of now, it will be endlessly stuck in the while loop!
Lets assume that your program is running, and it keeps on running for as long as your device remains connected. So you need to monitor some message or look for some event that signifies that the device has disconnected or stopped (or whatever is appropriate). This event or situation can be used as a flag (for eg., TRUE while the device is connected and active, FALSE when the device is disconnected or inactive) and then use that as a condition to open/write/close the file.
Further more, instead of a loop, you could use a timer or a periodic event to poll your device input. You can adjust your polling rate as high as you like, depending on the accuracy of your timer. This will ensure that your code doesn't get stuck in a loop. Say, you call your function to monitor the input at every timer tick. So each time the tick event fires, the input will be read. And you can check the condition of the device's connection before calling the polling function.
the flow would go something like:
Start->Device connected, flag TRUE->fOpen->Start timer
=>timer tick->flag == TRUE?->poll device->write to file=> (repeats for each tick unless the below scenario happens.)
Device disconnected, flag FALSE
=>timer tick->flag == TRUE? NO->fClose->Stop timer->Stop
This would assume that you had some way of detecting the device connect/active vs disconnect/inactive situations. Maybe the device SDK has some form of message or event that signifies this.
Related
I am working on terminal based text editor and stuck at a point where I need to differentiate whether the input text from read() function is a clipboard paste text or a keyboard text input.
#include <unistd.h>
char read_key_input() {
char ch;
int read_count;
while ((read_count = read(STDIN_FILENO, &ch, 1)) != 1)
{
// Handle error if any
}
return ch;
}
...
Edit: Here's what I ended up doing.
void read_key_input(void (*callback)(int)) {
char* text = malloc(UINT8_MAX);
int read_count;
while ((read_count = read(STDIN_FILENO, text, UINT8_MAX)) == -1)
{
// Handle error if any
}
// Handle escape sequences if found and return early
...
if (read_count > 1) {
// It's probably a clipboard text. So change the editor mode to input and loop through all the characters one by one.
else {
// It's a user keyboard text input
}
// Revert back to the original editor mode if changed
}
I updated the code to retrieve more than one byte at a time (as suggested by #AnttiHaapala) and process each byte. Seems to be sufficient for my text editor's need for now. Will post back if I update.
Usually you can differentiate this by counting the number of characters you've received in rapid succession. So if you get the keypresses more rapidly than say 1000 characters per minute, then it is likely a clipboard paste... or nonsense.
Furthermore, if you've set the terminal to raw mode, then you can easily monitor individual keypresses. Also make read accept more than one byte at once - with read that is the maximum number of bytes to receive without blocking when available anyway.
One example of such an interactive terminal program would be IPython - here two lines typed separately:
In [1]: print("Hello")
Hello
In [2]: print("World")
World
And here pasted in one go:
In [3]: print("Hello")
...: print("World")
...:
Hello
World
Notice how the prompt is different, and the program runs only after there has been a separate Enter key hit after a small delay.
AFAIK, you cannot do what you want (reliably).
The clipboard is related (usually) to some display server, e.g. Xorg or Wayland server (Weston). And X11 might have distant clients (hence, a clipboard operation could be slow, if crossing some ocean).
Some Linux machines (perhaps the web server at Stackoverflow) do not run any display server.
You could code a GUI application, e.g. using GTK or Qt.
You could test if your standard input is a terminal with termios(3) functions or isatty(3) (i.e. with isatty(STDIN_FILENO) or isatty(STDOUT_FILENO) for standard output)
If your program is run inside a crontab(1) job, or a unix pipeline, the standard input won't be a terminal, and there might not even be any display server running.
You could take inspiration from the source code of GNU emacs, which does detect when a display server is available (probably using environ(7), e.g. getenv(3) of "DISPLAY"...)
On Linux you might open(2) /dev/tty (see tty(4)) to access your terminal. In some cases, it does not exist.
Hey #jiten not sure if you checked like
its key input detect and check wether it's input is one by one key
or its instant bulk input.
I know how to do basic file operations in C, but what I'd like to do if it is possible is somehow create a variable that represents a live running file (for example, an access_log from apache that updates every second). Then I want to be able to read the last line that is entered into the file as it happens regardless of whether any other process currently has the file open or not.
I'm thinking of code like this:
int main(){
FILE *live=fattachto("/path/to/apaches/access_log");
long lastupdated=live->lastwrite();
while(1){
if(live->lastwrite() != lastupdated){printf("File was just updated now\n");}
sleep(1);
}
}
Yes I did put in sleep in my code because I want to ensure my code doesn't oveheat the cpu.
and the code above as-is won't execute because I'm looking for the correct set of functions to use to produce the end result.
Any idea?
Why don't you just set line buffering or use small buffer read size, once you've seeked to the end of the log file? Then simply do blocking reads on the lines from the file as they're added?
Then when the read returns, you can signal, set flags or initiate processing, on any interesting input.
I'm using FileStream to read files in two computers that are connected in a Local Area Network (LAN).
I have no problem to read the files when the others computers are connected. I'm checking if the directory exists before writing the file
I'm checking if the directory AND the file exists before reading the file.
file_pc1 = new File("//OTHER-PC/Folder/file.csv");
directory = new File("//OTHER-PC/Folder");
if (directory_pc1.exists)
{
stream.open(file_pc1, FileMode.WRITE);
stream.writeUTFBytes(csv.data);
stream.close();
}
if (directory_pc1.exists && file_pc1.exists)
{
stream.open(file_pc1, FileMode.READ);
stream.writeUTFBytes(csv.data);
stream.close();
}
All this works great but if the other computer is not connected, the statements directory_pc1.exists and file_pc1.exists takes a very long time and the app freezes, sometime even sending the "Application is not responding" message from Windows, but it finally responds after a long time.
Is there a fastest way to check if i'm connected to another PC?
While I don't know of a method to make File.exists() perform faster (likely there is no way as it's more of an OS issue), you can at least mitigate the issue by using asynchronous operations instead - thus avoiding locking the UI.
You can skip the exists operation, and just attempt to open the file async, if it errors, then you know the file doesn't exist and it will likely take about the same amount of time as using File.exists.
So something like this:
stream.addEventListener(IOErrorEvent.IO_ERROR, fileIOError);
stream.addEventListener(Event.COMPLETE, loadComplete);
stream.openAsync(file_pc1, FileMode.UPDATE);
function loadComplete(e:Event):void {
stream.writeUTFBytes(csv.data);
stream.close();
}
function fileIOError(e:IOErrorEvent):void {
//file doesn't exist, do something
}
That all said, since your just writing a file, it doesn't actually make sense to even check if it exists or not (unless you need to use the current data in that file as part of your write operation) - if you used FileMode.WRITE, it doesn't matter if the file exists or not it will attempt to save the file. You'll need to wrap it in a try catch though in case the network location is unavailable.
I am new in programming C language, but I have to do a project with three micro-controllers, each using a bluetooth device. The micro-controllers have to access a text file on my computer where they update their activity in order to have one of them measuring temperature (Activity1), another controlling a motor (Activity2) and the other waiting (Activity3) or doing something else (Activity4), but not two of them doing the same activity.
I need to program "something" to make this file available to all micro-controllers. For instance, the text file shows:
Line 1- Activity1 //for micro1
Line 2- Activity3 //for micro2
Line 3- Activity2 //for micro3
After some event, micro1 had to change its activity and update the file
Line 1- Activity4 //for micro1
Line 2- Activity3 //for micro2
Line 3- Activity2 //for micro3
Here, micro1 only have the Activity4 as a free choice to change, but it knew that through reading the file.
I need you tell me what is that "something"? Do I need a server?
I'm writing an inotify watcher in C for a Minecraft server. Basically, it watches server.log, gets the latest line, parses it, and if it matches a regex; performs some actions.
The program works fine normally through "echo string matching the regex >> server.log", it parses and does what it should. However, when the string is written to the file automatically via Minecraft server, it doesn't work until I shut down the server or (sometimes) log out.
I would post code, but I'm wondering if it doesn't have something to do with ext4 flushing data to disk or something along those lines; a filesystem problem. It would be odd if that were the case though, because "tail -f server.log" updates whenever the file does.
Solved my own problem. It turned out the server was writing to the log file faster than the watcher could read from it; so the watcher was getting out of sync.
I fixed it by adding a check after it processes the event saying "if the number of lines currently in the log file is more than the recorded length of the log, reprocess the file until the two are equal."
Thanks for your help!
Presumably that is because you are watching for IN_CLOSE events, which may not occur until the server shuts down (and closes the log file handle). See man inotify(7) for valid mask parameters for the inotify_add_watch() call. I expect you'll want to use IN_WRITE.
Your theory is more than likely correct, the log file is being buffered by the OS, and the log writer has no flushing of that buffer, so everything will remain in the buffer till the file is closed or the buffer is full. A fast way to test is to start up the log to the point where you know it would have written events to the log, then forcibly close it so it cannot close the handle, if the log is empty is definitly the buffer. If you can get hold of the file handle/descriptor, you can use setbuf to remove buffering, at the cost of performance.