Cocoa system() progress? - c

I am creating an application that must use the system(const char*) function to do some "heavy lifting", and I need to be able to give the user a rough progress percentage. For example, if the OS is moving files for you, it gives you a progress bar with the amount of data moved and the amount of data to move displayed on the window. I need something like that. How can this be done?
Edit: Basically, I give the user the option to save files in a compressed format. If they do so, it saves normally then runs this code:
char* command = (char*)[[NSString stringWithFormat:#"tar -jcvf %#.tar.bz2 %#", saveurl.path, filename] cStringUsingEncoding:NSUTF8StringEncoding];
system(command);
Sometimes this takes a little while (the app deals with video files), so I want to be able to give them an estimated completion time.

I am creating an application that must use the system(const char*)
function to do some "heavy lifting"
No, it doesn't have to use system() as such. In fact, it shouldn't. There are plenty of other APIs for running subprocesses, almost all of which will be better. In Cocoa, the most obvious better option is NSTask.
In any case, there's nothing that can tell how much progress a subprocess is making except that subprocess itself. If the program you're running doesn't provide a means for reporting progress, there's little hope. Nothing else can even divine what the purpose or goal of the subprocess is, let alone judge how far along it is to meeting that goal.
Even if the program does report progress, you'll need a means to receive that information. system() doesn't allow for that. NSTask does, as would popen() or manually forking and execing the program.

You would need a command line program that has a way of communicating progress information back to your application (or perhaps simply write progress info to a log file that you parse in your cocoa app). Are you sure you really need to do this?
For your edited example, you might consider just putting up some sort of spinner or hourglass type UI indicator to show them that the write is in progress, while allowing them to continue with other work. You can't predict archive creation time, especially when you add compression to it.

Related

How to write a tail -f like C program

I want to implement a C program in Linux (Ubuntu distro) that mimics tail -f. Note that I do not want to actually call tail -f from my C code, rather implement its behaviour. At the moment I can think of two ways to implement it.
When the program is called, I seek to the end of file. Afterwards, I would read to the end of file periodically and print whatever I read if it is not empty.
The second method which can potentially be more efficient is to again, seek to the end of file. But, this time I "somehow" listen for changes to that file and read to the end of file, only if I it is changed.
With that being said, my question is how to implement the second approach and if someone can share if it is worth the effort. Also, are these the only two options?
NOTE: Thanks for the comments, the question is changed based on them.
There is no standardized mechanism for monitoring changes to a file, so you'll need to implement a "polling" solution anyway (that is, when you hit the end of file, wait a short amount of time and try again.)
On Linux, you can use the inotify family of system calls, but be aware that it won't always work. It doesn't work for special files or remote filesystems, for example, and it may not work for some local filesystems. It is complicated in the case of symlinks. And so on. There is a Windows equivalent, but I believe it suffers from some of the same issues.
So even if you use a notification system, you'll need the polling solution as a backup, and since OS notifications are not guaranteed to be reliable (that is, if the system is under load, notifications might be dropped), you'll need to poll on timeout even if you are using a notification system.
You might want to take a look at the implementation of the GNU tail utility (http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tail.c) to see how the special cases are handled.
You can implement the requirement by following steps:
1) fopen with 'a+' mode;
2) select the file discriptor opened (need do convert from FILE * to file descriptor) and do the read.

Linux terminal - printing lots of data

I am writing application in C programming language that enables to monitor remote computers system information, number of logged users, free memory and so on.
I will write gathered info to standard output. But usually there will be more information then one single window of terminal, so I will need to implement some sort of 'scrolling' through results.
The easiest solution is I think to print for example first 25 rows, and then wait for user to push up or down and rewrite all rows accordingly.
Is there some easier/more elegant way to handle such output on terminal?
EDIT: forgot to mention, I would like to refresh the data if some new input comes from some remote computer, for example: number of processes changes.
Sounds like you need curses.
Here's a guide to the ncurses library.
It's an old school GUI library for terminals. Things like top and make menuconfig use it, so it's on every system. It allows you to stop thinking in terms of "print 25 lines and refresh" and more in terms of "put data in the text area which is scrollable".
Use an external pager, such as more (or less) to paginate the output. The strength of Unix is in combining simple commands, creating pipelines instead of reinventing functionality that already exists.

Getting a pointer to my XDisplay (Linux) (X)?

I need to be able to access the X Event Loop to add clipboard support for a game API. The problem is the game API does not know which API it will use for display (It could use SDL or other). As a result, I do not have direct access to the X event loop. Is there a function in XLib to get a pointer to my display so that I can process messages and add clipboard support?
Thanks
If it runs on X11, there has to be a Display pointer in the graphics object somewhere. You can allocate a new one with XOpenDisplay(NULL); but that's not likely to achieve what you want. You'd still have to find the Windows and other info which is tricky enough when a program does it once.
You really need to dig through the existing code to find the X11 module. There's likely to be a single function that performs on iteration of the "Event Loop" as a subroutine of the real "main Processing Loop". If you can't simply add your new code there, you can at least see how the program already accesses this information.
If you're using OpenGL for graphics, you can exploit that. At some point in the program where you know, the OpenGL context is made current call glXGetCurrentDisplay. However you should be carefull not to interfere with the programs main event loop.

How to trap read write system calls?

Whenever i attempt to write anything on my pendrive, a write system call is generated. What i want to do is, this write call should be trapped and and the user should be requested to input predecided password( which i can define during coding itself).
Please tell me whether this is possible or not? and if yes than how should i do it?
The windows DDK has an example of hooking the file reads/writes/copies in filesys\minifilter, with both pre and post op callbacks, that should have you set for the kernel side of things. For the gui part you'll need something to do a non-blocking spin till the drives signals an event, you'll probably also want a pipe or mapped memory view to pass data around
EasyHook is supposed to give you the ability to hook kernel functions. I have not tried it, so your mileage may vary. Be sure to hook functions cautiously - you may degrade the performance of your machine to a point where it's unusable. What you want is to interact with the user, meaning that you must put the hooked function on hold, and issue a callback into user space. This is probably not an exercise for mere mortals.
At any rate, good luck!

Program communicating with itself between executions

I want to write a C program that will sample something every second (an extension to screen). I can't do it in a loop since screen waits for the program to terminate every time, and I have to access the previous sample in every execution. Is saving the value in a file really my best bet?
You could use a named pipe (if available), which might allow the data to remain "in flight", i.e. not actually hit disk. Still, the code isn't any simpler, and hitting disk twice a second won't break the bank.
You could also use a named shared memory region (again, if available). That might result in simpler code.
You're losing some portability either way.
Is saving the value in a file really my best bet?
Unless you want to write some complicated client/server model communicating with another instance of the program just for the heck of it. Reading and writing a file is the preferred method.

Resources