what would happen if a process wrote to its own stdin?

what would happen if a process wrote to its own stdin?

#include<unistd.h>
#include<fcntl.h>

int main()
{

    if((write(STDIN_FILENO,"arrgh!",6))==-1)
    {
        perror("error writing to file");
    }    

}

output:

[c_d@localhost C scratchpad]$ gcc temp.c
[c_d@localhost C scratchpad]$ ./a.out 
arrgh![c_d@localhost C scratchpad]$ 

apparently it wrote into its stdout...how and why? no asked to process to do so...

It wrote to stdin, aka file descriptor 0. You can add:
close(1);
close(2);
in front of your "if" statement to help prove it.

In this case, the shell opened /dev/tty for reading and writing and made all three initial fd's point to it.

Try:
echo hello > file
./a.out < file
echo who knows | ./a.out

i tried the exercise you suggested on

#include<unistd.h>
#include<fcntl.h>

int main()
{

    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    if((write(STDIN_FILENO,"arrgh!",6))==-1)
    {
        perror("error writing to file");
    }    

}

i get no output or error whatsoever
but when i perform the same exercise on my original code

i get

[c_d@localhost C scratchpad]$ ./a.out <file
error writing to file: Bad file descriptor
[c_d@localhost C scratchpad]$ echo watup | ./a.out
error writing to file: Bad file descriptor

i wanted to see that...but i m not able to make fcntl() work...

#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>

int main()
{
    int x=2,file,fd;
    
    if((file=open("fdvals",O_RDWR))==-1)
    {
        perror("error opening fdvals");
    }
    fd=fcntl(file,F_GETFD,0);
    printf("fd=%d",fd);
    fd=fcntl(STDOUT_FILENO,F_GETFD,0);
    printf("fd=%d",fd);
}

it tells fd=0fd=0 :frowning:

#include <stdio.h>

int main(void) {
    if ( fprintf(stdin, "A") < 1 )
        perror("fprintf");
    return 0;
}

OP:

[c_d@localhost C scratchpad]$ gcc temp.c
[c_d@localhost C scratchpad]$ ./a.out 
fprintf: Bad file descriptor

so...how come now stdin becomes an invalid fd?

now when i do this

#include <stdio.h>
#include <unistd.h>

int main(void) {
    FILE *fakestdin;
    fakestdin = fdopen(STDIN_FILENO, "a+");
    if(fakestdin!=NULL)
    {
        fprintf(fakestdin, "A\n");
         perror("fakestdin");
    }
    else
          printf("fakestdin is NULL");
    return 0;    
}

OP:

[c_d@localhost C scratchpad]$ gcc temp.c
[c_d@localhost C scratchpad]$ ./a.out <temp.c
fakestdin is NULL[c_d@localhost C scratchpad]$ ./a.out 
A
fakestdin: Success
[c_d@localhost C scratchpad]$

it opens and writes to /dev/tty...

so what does this mean?

does it mean that (STDIN_FILENO) points to /dev/tty under normal conditions, but stdin does not? then where does it point to?

why did i have to open "stdin"'s fd to write to it? because i never have to open "stdout"'s fd to write to it...

#include <stdio.h>

int main(void) {
     fprintf(stdout, "HELLO!");
        perror("fprintf");
    return 0;
}
[c_d@localhost C scratchpad]$ gcc temp.c
[c_d@localhost C scratchpad]$ ./a.out 
fprintf: Success
HELLO![c_d@localhost C scratchpad]$

Interesting!

I obtained file status flags of STDIN_FILENO, and it is open for O_RDWR.

Why then .\a.out < file.txt doesn't write "arghh!" to file.txt?

you cannot execute a file using \ ...it should be./a.out
and
< means you are redirecting the content of file.txt to stdin of a.out

to write "arghh!" to file.txt one would generally do ./a.out >file.txt

but in this case it will not write to file.txt because there is nothing in stdout of a.out process...

Hi

I know that a.out should be executed as "./a.out" , it was typing mistake.

file.txt is redircted as a.out's standard in put. In my program, I am writing to standard input (as shown in the first post)

yes, so the content of file.txt will be written to stdin of a.out

to demonstrate...

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>


int main(void) 
{
    struct stat st;
    char *whichtty;

    if ( !isatty(STDIN_FILENO) ) 
    {
	    (void) fprintf(stderr, "%s\n", "stdin is not connected to a tty device.");
    } 
    else 
    {
	    if ( (whichtty = ttyname(STDIN_FILENO)) == NULL ) 
	    {
	        perror("ttyname");
            return 1;
	    } 
	    else 
	    {
	        (void) fprintf(stderr, "stdin is connected to tty device %s.\n", whichtty);
	    }
    }

    if ( fstat(STDIN_FILENO, &st) == -1 ) 
    {
	    perror("file status");
	    return 1;
    } 
    else 
    {
	    if ( st.st_mode & S_IWUSR ) 
	    {
	        (void) fprintf(stderr, "%s\n", "stdin appears to be writeable by the user.");
	    } 
	    else 
	    {
	        (void) fprintf(stderr, "%s\n", "stdin does not appear to be writeable by the user.");
	    }
    }
    return 0;
}

OP:

[c_d@localhost C scratchpad]$ gcc temp.c
[c_d@localhost C scratchpad]$ ./a.out
stdin is connected to tty device /dev/pts/3.
stdin appears to be writeable by the user.
[c_d@localhost C scratchpad]$ ./a.out <temp.c        #this is what you are doing
stdin is not connected to a tty device.
stdin appears to be writeable by the user.
[c_d@localhost C scratchpad]$ chmod -w temp.c  #remove write perm
[c_d@localhost C scratchpad]$ ./a.out <temp.c
stdin is not connected to a tty device.
stdin does not appear to be writeable by the user.
[c_d@localhost C scratchpad]$ chmod +w temp.c

Can someone explain all this to me...or do you think its best I not dig into all this...???

Hi,

I know :slight_smile: May be I was not clear enough of what I am trying to do,

The program is as follows -

int main()
{
   if( write(STDIN_FILENO,"arghh!",6) == -1 )
  {
      fprintf(stderr,"Error in write\n");
      exit(2);
  }
  return 0;
}

I am doing following on shell command line -

$>file.txt (this create an empty file.txt)
$./a.out < file.txt (redirect standard input of a.out to file.txt, a.out is supposed to WRITE to(not READ from) file.txt(that is what it is programmed to do).

($ is not part of command but of shell command prompt)

STDIN_FILENO's file status flag is 2 (O_RDWR - both read write allowed).

I expected that a.out writes to standard input; which is file.txt. But file.txt remains empty.

I am trying to understand 'why'

Anybody. Please illuminate

[c_d@localhost cfiles]$ cat temp.c
#include<unistd.h>
#include<fcntl.h>

int main()
{

    if((write(STDIN_FILENO,"arrgh!",6))==-1)
    {
        perror("error writing to file");
    }    

}


[c_d@localhost cfiles]$ touch file     #create empty file
[c_d@localhost cfiles]$ cat file        #you can see, that the file is empty
[c_d@localhost cfiles]$ gcc temp.c  #compile temp.c
[c_d@localhost cfiles]$ ./a.out 0>file #redirection notice no "arrgh!" prints
[c_d@localhost cfiles]$ cat file         #because "arrgh!" is redirected to file
arrgh![c_d@localhost cfiles]$ rm file ; touch file  
[c_d@localhost cfiles]$ ./a.out <file      # :(
error writing to file: Bad file descriptor
[c_d@localhost cfiles]$ 

:slight_smile: i dunno...why that happens. probably because file connects to stdin of a.out first, so when write command executes, stdin is connected to file so it is not able to write into stdin, hence it returns -1.