I'm writing a text editor in gtk+ 2.0 & gtksourceview 2.0. Currently I'm using gtk_text_buffer_get_text and g_file_set_contents to save the textbuffer to a file. I see in the docs for g_file_set_contents that it says:
Also since the file is recreated, existing permissions, access control lists, metadata etc. may be lost.
I looked around devhelp and Google and can't find an alternative way to save the textbuffer to a file while preserving file permissions. Any ideas on how to accomplish this? Thanks.
As #ptomato suggested using a method that truncates the file, then writing out the text buffer worked as desired. Here is a snippet of code which worked for me:
gtk_text_buffer_get_end_iter(tbuffer,&end_iter);
gtk_text_buffer_get_start_iter(tbuffer,&start_iter);
text = gtk_text_buffer_get_text(tbuffer,&start_iter,&end_iter,FALSE);
FILE *fp;
fp=fopen(path, "w");
fprintf(fp, "%s", text);
fclose(fp);
Related
I am developing a command line application in C (linux environment) to edit a particular file format. This file format is a plain XML file, which is compressed, then encrypted, then cryptographically signed.
I'd like to offer an option to the user to edit this kind of file in an easy way, without the hassle of manualy extracting the file, editing it, and then compressing, encrypting and signing it.
Ideally, when called, my application should do the following:
Open the encrypted/compressed file and extract it to a temporary location (like /tmp)
Call an external text editor like nano or sublime-text or gedit depending on which is installed and maybe the user preferences. Wait until the user have edited the file and closed the text editor.
Read the modified temporary file and encrypt/compress it, replacing the old encrypted/compressed file
How can I achieve point no. 2?
I thought about calling nano with system() and waiting for it to return, or placing an inotify() on the temp file to know when it is modified by the graphical text editor.
Which solution is better?
How can i call the default text editor of the user?
Anything that can be done in a better way?
First, consider not writing an actual application or wrapper yourself, which calls another editor, but rather writing some kind of plugin for some existing editor which is flexible enough to support additional formats and passing its input through decompression.
That's not the only solution, of course, but it might be easier for you.
With your particular approach, you could:
Use the EDITOR and/or VISUAL command-line variables (as also pointed out by #KamilCuk) to determine which editor to use.
Run the editor as a child process so that you know when it ends execution, rather than having to otherwise communicate with it. Being notified of changes to the file, or even to its opening or closing, is not good enough, since the editor may make changes multiple files, and some editors don't even keep the file open while you work on it in them.
Remember to handle the cases of the editor failing to come up; or hanging; or you getting some notification to stop waiting for the editor; etc.
Call an external text editor like nano or sublime-text or gedit depending on which is installed and maybe the user preferences. Wait until the user have edited the file and closed the text editor.
Interesting question. One way to open the xml file with the user's default editor is using the xdg-open, but it doesn't give the pid of the application, in which user will edit the file.
You can use xdg-mime query default application/xml to find out the .desktop file of the default editor, but then you have to parse this file to figure out the executable path of the program - this is exactly how xdg-open actually works, in the search_desktop_file() function the line starting with Exec= entry is simply extracted from the *.desktop to call the editor executable and pass the target file as argument... What I am trying to say, is, after you find the editor executable, you can start it, and wait until it's closed, and then check if the file content has been changed. Well, this looks like a lot of unnecessary work...
Instead, you can try a fixed well-known editor, such as gedit, to achieve the desired workflow. You can also provide user a way (i.e. a prompt or config file) to set a default xml editor, i.e. /usr/bin/sublime_text, which then can be used in your programm on next run.
However, the key is here to open an editor that blocks the calling process, until user closes the editor. After the editor is closed, you can simply check if the file has been changed and if so, perform further operations.
To find out, if the file contents have been modified, you can use the stat system call to get the inode change time of the file, before you open the file, and then compare the timestamp value with the current one once it is closed.
i.e.:
stat -c %Z filename
Output: 1558650334
Wrapping up:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void execute_command(char* cmd, char* result) {
FILE *fp;
fp = popen(cmd, "r");
fscanf (fp, "%s" , result);
}
int get_changetime(char* filename) {
char cmd[4096];
char output[10];
sprintf(cmd, "stat -c %%Z %s", filename);
execute_command(cmd, output);
return atoi(output);
}
int main() {
char cmd[4096];
char* filename = "path/to/xml-file.xml";
uint ctime = get_changetime(filename);
sprintf(cmd, "gedit %s", filename);
execute_command(cmd, NULL);
if (ctime != get_changetime(filename)) {
printf("file modified!");
// do your work here...
}
return 0;
}
I am using "UNIX" (on my virtual machine) and generating ".docx" file there using "C", after getting the file into Windows, when I am opening the file it's saying "the file is corrupted, can't be opened" and then its not opening.
I am using MS-Word 2010.
Here is the piece of code I am using:-
Write_to_file(){
FILE *fp;
if((fp=fopen("hello.docx","w"))==(FILE*)NULL){
printf("Error opening file");
return 0;
}
fprintf(fp,"Hello World");
fclose(fp);
}
Just with an extension name (doc docx) does not make the file a MS word file. Your code is only writing a text file. You can dectect this by file command under Linux.
Please reference this http://msdn.microsoft.com/en-us/library/cc313105(v=office.12).aspx, and write the REAL MS document file.
A doc file is not a simple text file. You'd want to use the txt format:
fopen("hello.txt", "w");
To actually read/write a doc file, you'd need to use a library designed specifically to read them and write them.
The spec for MS-DOC files is pretty lengthy, so I wouldn't implement my own reader/writer if I were you.
How to clear a file in J2ME so that it becomes empty (no content)?
All output streams (OutputStream, DataOutputStream, PrintStream...)
can only write() and add the content to the file while I see no way to delete a byte/bytes in a file.
I use Netbeams 7.0.1
Thanks for any help
Call your write() method like this:
.write((new String()).getBytes());
This will make your file empty.
You can also delete your file and create a new one. This will also results into an empty file having the same file name.
I've been wondering about this one. Most books I've read shows that when you open a file and you found that the file is not existing, you should put an error that there's no such file then exit the system...
FILE *stream = NULL;
stream = fopen("student.txt", "rt");
if (stream==NULL) {
printf(“Cannot open input file\n”);
exit(1);
else {printf("\nReading the student list directory. Wait a moment please...");
But I thought that instead of doing that.. why not automatically create a new one when you found that the file you are opening is not existing. Even if you will not be writing on the file upon using the program (but will use it next time). I'm not sure if this is efficient or not. I'm just new here and have no programming experience whatsoever so I'm asking your opinion what are the advantages and disadvantages of creating a file upon trying to open it instead of exiting the system as usually being exampled on the books.
FILE *stream = NULL;
stream = fopen("student.txt", "rt");
if (stream == NULL) stream = fopen("student.txt", "wt");
else {
printf("\nReading the student list directory. Wait a moment please...");
Your opinion will be highly appreciated. Thank you.
Because from your example, it seems like it's an input file, if it doesn't exist, no point creating it.
For example if the program is supposed to open a file, then count how many vowels in it, then I don't see much sense of creating the file if it doesn't exist.
my $0.02 worth.
Argument mode:
``r'' Open text file for reading.
``r+'' Open for reading and writing.
``w'' Truncate file to zero length or create text file for writing.
``w+'' Open for reading and writing. The file is created if it does not
exist, otherwise it is truncated.
``a'' Open for writing. The file is created if it does not exist.
``a+'' Open for reading and writing. The file is created if it does not
exist.
Your question is a simple case. Read above description, when you call fopen(), you should decide which mode shall be used. Please consider why a file is not created for "r" and "r+", and why a file is truncated for "w" and "w+", etc. All of these are reasonable designs.
If your program expects a file to exist and it doesn't, then creating one yourself doesn't make much sense, since it's going to be empty.
If OTOH, your program is OK with a file not existing and knows how to populate one from scratch, then it's perfectly fine to do so.
Either is fine as long as it makes sense for your program. Don't worry about efficiency here -- it's negligible. Worry about correctness first.
You may not have permission to create/write to a file in the directory that the user chooses. You will have to handle that error condition.
I would like to add logs at the end of a file for each event, and create a new one when its size up to 255 Mo.
For example, the current file could be /var/log/foo.2:
/var/log/foo.0.log (full log file)
/var/log/foo.1.log (full log file)
/var/log/foo.2.log
Have you got an idea of C source to do so?
Thank you
When opening the file with
File *fopen(const char *filename, const char *mode);
choose "a" as mode. Which will open or create a text file for writing at the end of file.
Basic c file code: http://c-programming.suite101.com/article.cfm/c_tutorial_file_handling_commands
If you just want to have the functionality, look at log4c.
If you want to know how that works, you can look at its code as well.
If you need specially tailored code for your application...
Basically you need to use fopen with the "a" option, where a stands for append.
To determine size of a file, use ftell or another platform specific function because there is no file size information method in the C standard as far as I can remember. Or you go the long way and just read all the bytes from the file and count them...