why ftell( stdin ) causes illegal seek error - c

The following code outputs "Illegal seek":
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main() {
errno = 0;
getchar();
getchar();
getchar();
ftell( stdin );
printf( "%s\n", strerror(errno) );
}
This occurs when I run cat script | ./a.out as well as when I just run ./a.out. The problem is with ftell, of course. My question is: why does this occur? I would think stdin can be seekable. fseek also causes the same error. If stdin is not seekable, is there some way I can do the same sort of thing?
Thank you for your replies.

Fifos aren't seekable. They are simply a buffer. Once data has been read() from a fifo buffer, it can never be retrieved.
Note that if you ran your program:
./a.out < script
then standard input would be a file and not a fifo, so ftell() will then do what you expect.

Related

realtime redirecting stdout to file in linux c

I am trying to implement following bash line in c.
while true; do echo Hello; done > out.log
I can collect log in log file .
But logs are written only when executable finishes execution.
my test case which uses non exiting executable fails.
how do I write log file realtime ?
here is hello.c
#include <stdio.h>
#include <unistd.h>
int main(){
// while(1){
for(int i=0; i<10;i++){
printf("Hello World\n");
sleep(1);
}
return 0;
}
here is helloExec.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
char *cmd[] = {"./hello", NULL};
int fd = -1;
if(fork() == 0){
fd=open("log.out", O_RDWR | O_CREAT | O_APPEND, 0666);
dup2(fd,1);
execv(cmd[0],cmd);
}
return 0;
}
compiled with make hello and make helloExec
When I use for loop I do see logs collected after 10 sec.
Whereas If while is used then logs are not written to file.
using tail -f log.out to follow log file.
Any inputs about this are welcome.
NOTE: unsuccessful trying to resolve this using pipe.
Piped output is buffered even aggressively than line-buffered terminal output, \n is not enough to flush it.
Use fflush(stdout) after printf()

C - fprintf isn't writing to file

C - fprintf isn't writing to file, any idea why?
#include <stdio.h>
#include <stdlib.h>
int main(void){
FILE* pfile=fopen("/home/user-vlad/Programming/C-other/meme.txt","r");
if(pfile==NULL){
printf("ERROR: Stream is equal to NULL\n");
exit(1);
}
fprintf(pfile,"Hello");
fclose(pfile);
return 0;
}
Compiler: clang, OS: FreeBSD
Assuming the file opens can be because you called fopen() with the argument "r", that means read.
To write you can use the argument "w"
fopen("/home/user-vlad/Programming/C-other/meme.txt","w");
Or if the file already exists "r+"
fopen("/home/user-vlad/Programming/C-other/meme.txt","r+");
Or if the file already exists and you want to append you can use "a"
fopen("/home/user-vlad/Programming/C-other/meme.txt","a");
You can learn more on fopen() here.

creating a getchar function with read( , , ) error

I wrote read this code from the K&R book. But i compile it i get an error:
gcc: error: getchar.c: No such file or directory
gcc: fatal error: no input files
compilation terminated.
Code:
#include <sys/syscall.h>
#include <stdio.h>
int getchar(void)
{
char c;
return (read(0, &c,1) == 1) ? (unsigned char) c : EOF ;
}
main()
{
printf("\nEnter the character you want to getchar: \n");
getchar();
return 0;
}
The error message is telling you that there is no file called getchar.c in the current directory to compile. That might mean that you accidentally called it getchar.c or getchar.c instead, so you should look carefully at what you called it -- it might look like it is correct, but have extra invisible characters in it.
The easiest fix is probably to open the file in your editor, and then "save as" and type in a name that has no invisible characters in it.
If you're just compiling it in the Windows environment
try
#include <sys/syscall.h>
change to
#include <io.h>

Setting C program to line buffer won't work

I'm trying to force my C program to line buffer (stdout is going to be captured by a java program), but it always seems to fully buffer instead. Here is some sample code:
#include <stdio.h>
#include <stdlib.h>
int main(){
char c;
setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
printf("Hello world\n");
c = getchar();
printf("got char: %c\n", c);
}
If I specify _IOLBF or _IOFBF, then I don't see an output until I input a char. Only if I use _IONBF will I see output before the getchar(). Shouldn't _IOLBF do the same since "Hello World\n" contains a '\n'?
I am using visual c++ 2005.
Thanks
According to this Microsoft documentation:
_IOLBF:
For some systems, this provides line buffering. However, for Win32, the behavior is the same as _IOFBF - Full Buffering.

Why does the following program not generate any visible output?

The following C program doesn't printing anything on the screen.
I compiled the program with gcc:
#include<stdio.h>
main()
{
printf("hai");
for(;;);
}
Most likely, stdout is line buffered. Your program does not call fflush or send a newline so the buffer does not get written out.
#include <stdio.h>
int main(void) {
printf("hai\n");
for(;;)
;
return 0;
}
See also question 12.4 and What's the correct declaration of main()? in the C FAQ.
This is caused by the buffering which takes place in stdio (i.e. it is not output immediately unless you tell it to by including a \n or fflush). Please refer to Write to stdout and printf output not interleaved which explains this.
(p.s. or the compiler is not happy about the typo in #include)
Standard output tends to be line buffered by default so the reason you're not seeing anything is because you haven't flushed the line.
This will work:
#include <stdio.h>
int main (int argC, char *argV[])
{
printf("hai\n");
for(;;)
;
return 0;
}
Alternatively, you could fflush standard out or just get rid of the infinite loop so the program exits:
#include <stdio.h>
int main (int argC, char *argV[])
{
printf("hai");
return 0;
}
but you probably want the newline there anyway.
Your for(;;) loop stops the stream from being flushed. As others have suggested, add a newline to the string being output, or flush the stream explicitly:
fflush( stdout );
after your printf. And correct the spelling of #include.

Resources