Redirect printf/printk message to file - c

I want to duplicate messages called via printf/printk to a file, keeping the original behavior of printf/printk the same. Environment contains multiple processes running and printf/printk functional calls called.
I want to achieve the above said, with minimal change to each binary as possible.

Don't do it in your program, do it in the console when you run your program instead.
Then you can use the tee program to redirect standard output to a file:
./your_program | tee some_file
That will cause the output of your program to be written to both the file and standard output.

Related

Output to terminal different than I redirect output to file AND output to terminal

So for some reason when I run my script and have it output to the terminal just as it would, I get my intended output. Yet when I redirect the output to a file, I don't receive full output.
Let's say I have an executable named "filename" and run it "./filename", the output on the terminal is, let's say :
a
b
c
Yet if I do "./filename > output.txt" or "./filename |& tee output.txt", the output on the terminal AND the output.txt text file is just, let's say:
a
b
I know this isn't very specific, but my output is huge. I was thinking this would be general enough to provide general solutions/ possible problems.
I'm using a program someone else made, so I don't know where this additional output is called. Yet, it shouldn't matter since the functionality of the program doesn't change, just what's being output.
Without a minimal code sample to reproduce, it's very hard to guess what's going on.
But some things you could try:
Redirect all output streams to your file, i.e. your-script &> output.txt
Run it through strace and look for write and open calls to see what's going on
Read and debug the source code to figure out what's going on

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.

Executing more with "exec()" function corrupts line breaking in bash

I had an exercise to write a program that will do the following pipe processing:
ls -la | grep "^d" | more
After executing my program however, the bash interpreter would not break line nor display commands correctly, however after executing them the result is showed, it looks like the input for the console is not getting on stdout but somewhere else and i cant find the reason of this behavior.
I am using 3 child process with stdio redirected to connect the pipe between them.
The program finishes successfully it shows the good result, no errors are showed or whatever, also when i am using the cat instead of more everything works normally after execution, is it possible that more changes some system values and does not change them back?
It's likely that more is turning off echo and canonical mode on your TTY (see man 3 termios), and never switching them back on before it exits (either because it gets killed without a chance to, or because it doesn't think it's attached to a TTY). You can attach to more with gdb to find out why that's ahppening, or you could simply reset the terminal yourself before exiting.

Potential Dangers of Running Code in Parallel

I am working in OSX and using bash for my shell. I have a script which calls an executable hundreds of times, and each call is independent of the other. Therefore I am going to run this code in parallel. However, each call to the executable appends output to a community text file on a new line.
The ordering of the text file is not of importance (although it would be nice, but totally not worth over complicating since I can just use unix sort command), but what is, is that every call of the executable properly printed to the file. My concern is that if I run the script in parallel that the by some freak accident, two threads will check out the text file, print to it and then save different copies back to the original directory of the text file. Thus nullifying one of the writes to the file.
Does this actually happen, or is my understanding of printing to a file flawed? I don't fully know if this would also be a case by case bases so I will provide some mock code of what is being done in my program below.
Script:
#!/bin/sh
abs=$1
input=$(echo "$abs" | awk '{print 0.004 + 0.005*$1 }')
./program input
"./program":
~~Normal .c file stuff here~~
~~VALUE magically calculated here~~
~~run number is pulled out of input and assigned to index for sorting~~
FILE *fpp;
fpp = fopen("Doc.txt","a");
fprintf(fpp,"%d, %.3f\n", index, VALUE);
fclose(fpp);
~Closing events of program.c~~
Commands to run script in parallel in bash:
printf "%s\n" {0..199} | xargs -P 8 -n 1 ./program
Thanks for any help you guys can offer.
A write() call (like fwrite()) with the append flag set in open() (like during fopen()) is guaranteed to avoid the race condition you describe.
O_APPEND
If set, the file offset shall be set to the end of the file prior to each write.
From: POSIX specifications for open:
opengroup.org open
Race conditions are what you are thinking of.
Not 100% sure but if you simple append to the end of the file rather than opening it and editing it should be right
If you have the option, make your program write to standard output instead of directly to a file. Then you can let the shell merge the output of your programs:
printf "%s\n" {0..199} | parallel -P 8 -n 1 ./program > merged_output.txt
Yeah, that looks like a recipe for disaster. If those processes both hit opening the file at the roughly the same time, only one will "take".
I suggest either (easier) writing to separate files then catting them together when the processing is done, or (harder) sending all results to a consumer process that will write the file for everyone.

How to printf part of command line command

Hello I am currently trying to printf a certain part of the command line when i run my program. I currently run my program as follows
zcat gcc | sim
What i am trying to accomplish is print out to a seperate file the 'gcc' part of the command line. Is there any way to accomplish this. Thanks for the help
I forgot to mention this is in c not C++
The 'sim' program only knows that it has data from stdin. It doesn't know what is handing the data to stdin - it may be another program, or redirected input, or from a device.
From 'sim' POV, there's only data from stdin.
IF you can guarantee that you will always receive data from another process via a pipe, you can start looking for process headers matching the 'sim' process, and from then extracting process info from associated processes. However, I suspect that this is more than you're willing to go.
You are passing output of zcat (through pipe) to your program, it doesn't know details of arguments passed to zcat.
You can explicitly pass it as a part of input stream though,
(echo 'zcat gcc'; zcat gcc ) | sim
but that is a hack. It may be Ok if you are planning to run your
program this way only.

Resources