github.com/afumu/libc@v0.0.6/musl/src/stdio/freopen.c (about)

     1  #include "stdio_impl.h"
     2  #include <fcntl.h>
     3  #include <unistd.h>
     4  
     5  /* The basic idea of this implementation is to open a new FILE,
     6   * hack the necessary parts of the new FILE into the old one, then
     7   * close the new FILE. */
     8  
     9  /* Locking IS necessary because another thread may provably hold the
    10   * lock, via flockfile or otherwise, when freopen is called, and in that
    11   * case, freopen cannot act until the lock is released. */
    12  
    13  FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict f)
    14  {
    15  	int fl = __fmodeflags(mode);
    16  	FILE *f2;
    17  
    18  	FLOCK(f);
    19  
    20  	fflush(f);
    21  
    22  	if (!filename) {
    23  		if (fl&O_CLOEXEC)
    24  			__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
    25  		fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC);
    26  		if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0)
    27  			goto fail;
    28  	} else {
    29  		f2 = fopen(filename, mode);
    30  		if (!f2) goto fail;
    31  		if (f2->fd == f->fd) f2->fd = -1; /* avoid closing in fclose */
    32  		else if (__dup3(f2->fd, f->fd, fl&O_CLOEXEC)<0) goto fail2;
    33  
    34  		f->flags = (f->flags & F_PERM) | f2->flags;
    35  		f->read = f2->read;
    36  		f->write = f2->write;
    37  		f->seek = f2->seek;
    38  		f->close = f2->close;
    39  
    40  		fclose(f2);
    41  	}
    42  
    43  	FUNLOCK(f);
    44  	return f;
    45  
    46  fail2:
    47  	fclose(f2);
    48  fail:
    49  	fclose(f);
    50  	return NULL;
    51  }
    52  
    53  weak_alias(freopen, freopen64);