[man] dup, dup2

숭글·2022년 11월 1일
0

dup is used for duplicate a file descriptor.

#include <unistd.h>

dup

int dup(int oldfd);

The dup() system call allocates a new file descriptor that refers to the same open file description as the descriptor oldfd.
(The new file descriptor number is guaranteed to be the lowest-numbered file descriptor that was unused in the calling process.)

The two file descriptors refer to the same open file description. so the old and new file descriptors may be used interchangeably.

The two file descriptors share file offset and file status flags.

The two file descriptors do not share file descriptor flags.

RETURN VALUE

: On success, these system calls return the new file descriptor.
On error, -1 is returned, and errno is set to indicate the error.

dup examples

🏊‍ example 1

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

int main(){
	int new;
	char buff[5];

	new = dup(STDIN_FILENO);
	read(STDIN_FILENO, buff, 5);
	printf("from fd %d : %s \n", STDIN_FILENO, buff);
	read(new, buff, 5);
	printf("from fd %d : %s \n", new, buff);
}


--terminal--

INPUT	1234567890

OUTPUT	from fd 0 : 12345 
		from fd 3 : 67890 

After using read func successfully, file offset is changed.
STDIN_FILENO and new file description are using same file offset. so when one of them changes the file offset, the other file descriptor read file with changed file offset.

🏊‍ example 2

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

int main(){
	int	old_fd = open("test.txt", O_RDONLY);
	int new_fd = dup(old_fd);
	char buff[5];

	read(old_fd, buff, 5);
	printf("from fd %d : %s \n", old_fd, buff);
	close(old_fd);
	read(new_fd, buff, 5);
	printf("from fd %d : %s \n", new_fd, buff);
    close(new_fd);
}


-file test.txt-

1234567890
2345678901

--terminal--

OUTPUT	from fd 3 : 12345 
		from fd 4 : 67890  

The two file descriptors do not share file descriptor flags.
old_fd is cloesed, new_fd works well though.


dup2

int dup2(int oldfd, int newfd);

The dup2() system call allocates a new file descriptor that refers to the same open file description as the descriptor oldfd.
it uses the file descriptor number specified in newfd.

If the file descriptor newfd was previously open, it is closed before being reused; the close is performed silently (i.e., any errors during the close are not reported by dup2()).

If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed.

If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd.

RETURN VALUE

: On success, these system calls return the new file descriptor.
On error, -1 is returned, and errno is set to indicate the error.

dup2 examples

🏊‍ example 1

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

int main(){
	int	used_fd = dup(STDOUT_FILENO);
	
	write(used_fd, "TEST 1\n", 7);

	int old_fd = open("test.txt", O_RDONLY);
	int new_fd = dup2(old_fd, used_fd);

	char buff[5];

	printf("used_fd : %d new_fd : %d\n", used_fd, new_fd);

	read(old_fd, buff, 5);
	printf("from fd %d : %s \n", old_fd, buff);

	read(new_fd, buff, 5);
	printf("from fd %d : %s \n", new_fd, buff);

	write(used_fd, "TEST 2\n", 7);
    
    close(old_fd);
    close(new_fd);
}

-file test.txt-

1234567890
2345678901

--terminal--

OUTPUT	TEST 1
		used_fd : 3 new_fd : 3
		from fd 4 : 12345 
		from fd 3 : 67890

As explained earlier, since new_fd duplicates the old file descriptor with new number which same as open_fd's number by using dup2, open_fd is closed. so second write isn't wokring.

🏊‍ example 2

int main(){
	int open_fd = open("test.txt", O_RDONLY);
	char buff[6];

	if (read(open_fd, buff, 5) < 0){
			printf("open_fd read 1 fail\n");
    }
	else {
		printf("from fd %d : %s \n", open_fd, buff);
    }
        
	close(open_fd);
    
	if (read(open_fd, buff, 5) < 0){
			printf("open_fd read 2 fail\n");
    }
	else {
		printf("from fd %d : %s \n", open_fd, buff);
    }
    printf("%s\n", strerror(errno));
}

--terminal--

OUTPUT	from fd 3 : 12345 
		open_fd read 2 fail
		Bad file descriptor
        

↑ for checking what error occurs when using closed file descriptor.

int main(){
	int new_fd = dup2(-1, 5);
	printf("new_fd : %d\n\n", new_fd);

	char buff[6];

	if (read(new_fd, buff, 5) < 0)
		printf("read fail\n");
	else
		printf("from fd %d : %s \n", new_fd, buff);

	printf("%s\n", strerror(errno));
}


--terminal--

OUTPUT	new_fd : -1

		read fail
		Bad file descriptor

set up the oldfd with not a valid file descriptor, dup2 returns -1. read's return value is also -1 so everything isn't working.

📝 note

The steps of closing and reusing the file descriptor newfd are performed atomically. This is important, because trying to implement equivalent functionality using close(2) and dup() would be subject to race conditions, whereby newfd might be reused between the two steps. Such reuse could happen because the main program is interrupted by a signal handler that allocates a file descriptor, or because a parallel thread allocates a file descriptor.


📖 dup, dup2

profile
Hi!😁 I'm Soongle. Welcome to my Velog!!!

0개의 댓글