Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

255
Views
Shell redirection doesn't move file position for stdout

I have a minimal complete example where the Linux API behavior seems to be a bit ambiguous. The stdout is closed, reopened and used as a regular file's descriptor:

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

int main(void) {
     system("echo > testfile");
     fclose(stdout);
     int fd = open("testfile", O_WRONLY);
     if (fd < 0) {
          perror("open():");
          return -1;
     }

     dprintf(fd, "Test\n");
     system("echo Test2");
     system("echo TestFFFFFFFFFFFF >> /proc/$$/fd/1"); // problem line
     sleep(5);
     dprintf(fd, "Test4\n");
     system("echo Test5");

     return 0;
}

Before sleep in testfile I see

Test
Test2
TestFFFFFFFFFFFF

But after sleep this line is overwritten:

Test
Test2
Test4
Test5
FFFF

It seems that for regular files this behavior is strange: if we write something to file - we change its position an appropriate way (to the end).
But for stdout it looks quite reasonable: if we write to stdout - we rewind its position back after finish writing (to the start).
Is this a bug or the right way?

P.S. Besides the bash I also tried dash and ksh - the same thing.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

The question is:

Is this a bug or the right way?

It is the right way.


/proc/$$/fd/1 is a symlink to testfile, so >> /proc/$$/fd/1 is the same as >> testfile. It is a separate child process that writes to testfile. When this child process terminates, you see the stuff it has written in the file. It has no effect on your parent process.

STDOUT_FILENO is not special, it's just like any other file descriptor.

Why child processes affect your parent process file descriptor position? Because duplicated file descriptors refer to the same open file description. Read it twice - "file descriptor" != "file description". It is like a double-mapping. We say, file descriptors are not copied, they are duplicated, they share the file offset and file status flags, because they share the file description. See man 2 dup and man 2 open.

When a separate process opens the same file, it has a separate file description, so it does not affect your process file description.

(It is so badly named. I mentally call "file descriptor" like "system handle" (because it can refer to anything kernel wants to) and call "file description" like "file data" (if it's a file, it can be anything kernel wants to). It's then clear - this "system handle" refers to this "file data" and "system handle" is duplicated between processes that means that two "system handles" refer to the same open "file data". And "file data" stores file position and file locks and such. Processes have "handles", not "data". "File data" are removed automatically, when the last "system handle" is getting removed (the confusing man 2 unlink).)

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!