open vim from C system command - c

I am noobie with C.
I've seen system() and fork() and execv() stuff, but I do not think they are what I need ( or they just do not work )
I just want to my C program to open vim immediately of a file path to edit, then i can quit vim and the program continues, in my case it will just exit.
Think like git commit, it opens vim for me then when I save+exit it sends the commit.
Any ideas?

System(3) will do the work, but beware that if you call your program with the input/output redirected not to a terminal, this will propagate to the execution of vim and it will not work.
vim(3) requires that the input and output are directed to a terminal line, it cannot work on redirected input, so the best way to call it should be (with system()):
system("/usr/bin/vim file </dev/tty >/dev/tty");
The redirection clauses specify that the input and the output be redirected to the session controlling terminal, so you'll get it working even if you have redirected standard input/output in the main program.

system() is what I was looking for, I was using it incorrectly, but it's simple just use:
system("vim path/to/file.txt");
will open vim of current directy and work like expected ( like git commit )

Related

Disallowing printf in child process

I've got a cmd line app in C under Linux that has to run another process, the problem is that the child process prints a lot in a comand line and the whole app gets messy.
Is it possible to disallow child process to print anything in cmd line from parent process? It would be very helpful to for example being able to define a command that allows or disallows printing by a child process.
There's the time-honoured tradition of just redirecting the output to the bit bucket(a), along the lines of:
system("runChild >/dev/null 2>&1");
Or, if you're doing it via fork/exec, simply redirect the file handles using dup2 between the fork and exec.
It won't stop a determined child from outputting to your standard output but it will have to be very tricky to do that.
(a) I'm not usually a big fan of that, just in case something goes wrong. I'd prefer to redirect it to a real file which can be examined later if need be (and deleted eventually if not).
Read Advanced Linux Programming then syscalls(2).
On recent Linux, every executable is in ELF format (except init or systemd; play with pstree(1) or proc(5)) is running in a process started by fork(2) (or clone(2)...) and execve(2).
You might use cleverly dup2(2) with open(2) to redirect STDOUT_FILENO to /dev/null (see null(4), stdout(3), fileno(3))
I've got a cmd line app in C under Linux that has to run another process, the problem is that the child process prints a lot in a comand line
I would instead provide a way to selectively redirect the child process' output. You could use program arguments or environment variables (see getenv(3) and/or environ(7)) to provide such an option to your user.
An example of such a command program starting and redirecting subprocesses and redirecting them is your GCC compiler (see gcc(1); it runs cc1 and as(1) and ld(1)...). Consider downloading and studying its source code.
Study also -for inspiration- the source code of some shell (e.g. sash), or write your own one.

How do I copy everything from my terminal to a file including the stdout and the prompt using C?

I know how to get the stdout into a file using dup/dup2 system calls, but how do I get the entire output that would be normally shown on my terminal(including the prompt that says my username along with the $ symbol and the current working directory) to a file?
Yes you can, but this may be difficult in many details (depending on your expert level). For the shell to behave normally (I would mean exactly as in a terminal), then it needs to interact with a terminal (special system object). So you need to create a program that behave like a terminal, this what pseudo-terminals devices (/dev) are intended for. Read documentation about this to implement it but roughly, your application should behave like the user so should be connected to the slave side of the pseudo-terminal, and the shell to the master side of the pseudo-terminal. Then you can easily log real inputs made by the user and catch outputs made by the shell.
Can't comment cause of low reputation.
I would say there is no way to do that inside a code in C. Instead, you could use bash for example to redirect everything to a file, and leave the code in C as it is.
In this way you have all the info you want to save: prompt, current directory, call to the program (including flags), and of course the output of the program.
Well, you can do:
-For bash prompt PS1: Echo expanded PS1 (in case you want it expanded, if not there is a simple way to do it just echong PS1)
- For executed command: https://unix.stackexchange.com/questions/169259/how-to-capture-command-line-input-into-logfile-and-execute-it-at-the-same-time
- Standard output and error output: Redirect stderr and stdout in a Bash script
And that's all you want to capture, I think.
Look up the script command in Unix systems. If you want to capture all keyboard and std in/out for a command, use the script executable. If you want to see how it's done, look up the source.

Where does stderr file dumps its content to?

I wanted to know like where does the stderr dumps its content.
I have a question like whether it dumps to syslog?
Please explain.
stderr is just another output stream, just like stdout.
Where it's hooked up depends on how the application is called.
For example if I run foo.exe 2> errors.txt then stderr will write to the specified file.
Stderr output is dumped whenever you decide to redirect it.
If you run a program in a GUI enviroment, by clicking on an icon or something, look for .xsession-errors in your $HOME.
If you run a program from a shell and don't redirect stderr, you just see it on your terminal (and it is not saved anywhere else).
That depends on the environment.
By default, stderr is typically connected to the same place as stdout, i.e. the current terminal.
Otherwise, you wouldn't see the errors which would be kind of annoying.
Here is a blog post about redirecting stderr to the system's logging mechanism.
stderr is a stream. It's managed by and output to by the owning process. Where it 'goes' is defined by how the process is invoked. The parent process can gather it and write it to a file, ignore it, redirect it to /dev/null (esssentially binning it) etc.
Whilst stderr can be redirected elsewhere, it typically outputs to the same place as stdout. To make it into syslog, you'd definitely have to work a bit. This link:
With bash, how can I pipe standard error into another process?
shows how you pipe stderr to a pipe, and if the other process is a process that writes to "syslog", it would do what you want. But for most cases, it's probably easier to just add syslog functionality to your own program.

Make C Program for Interactive Mode

Here I have one command which is like interactive mode:
obex_test -b $BD_ADDR $CH_NUM
This command is from a script but I want to run this command through a system call in a C program.
obex_test is nothing but obex file transfer library.
Here I want to receive a file from remote device to local device through bluetooth.
This is the manual page of obex_test
Please can anybody tell me how can I put my C program in interactive mode like this command, and I want to use this command also.
I used popen(command,"r") but its not useful; it does not take input from the user.
If I used "w" mode then I don't know what happens; I directly get a message like >Unknown Command. It's the error this command gives when we give different options. So it's taken something as a write mode.
You could have two pairs of pipes (created with the pipe(2) system call); one for data from your program to obex_test's stdin and one from obex_test's stdout to your program. Then you would fork and execve... Beware of deadlocks (your program blocked on writing to obex_test stdin when its output pipe is full and blocking it), you might need to call poll(2) or select(2)...
However, as it man pages explain, "obex_test is a test application for the libopenobex library". So why don't call directly functions inside this libopenobex library, which you would link to your program?
You can use the system command. Check the manual page for more details.
For e.g. system( "obex_test -b 172.16.7.1 1234" );

How to access the default stdin while using file redirection?

I need to run a script and have access to the default stdin (terminal input) in my program. I could do ./program "script", opening and parsing the script through the program, but I want to make it POSIX style, accepting input from pipes or from redirection.
I mean, since my program is a parser, I could run ./program, type the script and still use stdin (in a scanf, for example). But I'd like to run ./program < script and still be able to use stdin (in a scanf).
My program is a simplified Pascal interpreter, that's why I need to run read(x) and write(x) in my scripts.
Yes, it's homework (the intepreter), but the doubt just popped up in the brainstorming process.
The current controlling terminal can be accessed using /dev/tty, even if stdin has been redirected.
ttyname(0) will return the filename of the current terminal associated with stdin. You can then open that and read from it.
If I understand what you're asking, you're asking for the ability to take in interactive input from a user when using file redirection, like the ./program < script bit above.
I don't believe there's a way to do that. A POSIX system will feed the script in via stdin and that's that. No interaction from the user.
It's also worth noting that you don't have to do anything special to realize that. Just treat stdin like you normally would. You don't have to think about whether it's coming in interactively or from a file, which is really quite nice.

Resources