From eb2d0288ece14df1e00709496bcc6e44c9983faf Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 9 Oct 2014 19:46:27 +0000 Subject: [PATCH] - Do nothing if FDs are identical (as per POSIX). - Deallocate new FD if it's already valid (as per POSIX). - Improved AutoDoc and added comments. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@49699 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- compiler/posixc/dup2.c | 57 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/compiler/posixc/dup2.c b/compiler/posixc/dup2.c index e8c17f5db7..53940e36a5 100644 --- a/compiler/posixc/dup2.c +++ b/compiler/posixc/dup2.c @@ -1,5 +1,5 @@ /* - Copyright © 1995-2012, The AROS Development Team. All rights reserved. + Copyright © 1995-2014, The AROS Development Team. All rights reserved. $Id$ POSIX.1-2008 function dup2(). @@ -14,7 +14,7 @@ NAME */ #include - int dup2 ( + int dup2( /* SYNOPSIS */ int oldfd, @@ -24,18 +24,29 @@ /* FUNCTION Duplicates a file descriptor. - The object referenced by the descriptor does not distinguish between oldd - and newd in any way. Thus if newd and oldd are duplicate references to - an open file, read(), write() and lseek() calls all move a single - pointer into the file, and append mode, non-blocking I/O and asynchronous - I/O options are shared between the references. If a separate pointer - into the file is desired, a different object reference to the file must be - obtained by issuing an additional open(2) call. The close-on-exec flag - on the new file descriptor is unset. + The object referenced by the descriptor does not distinguish between + oldfd and newfd in any way. Thus if newfd and oldfd are duplicate + references to an open file, read(), write() and lseek() calls all + move a single pointer into the file, and append mode, non-blocking + I/O and asynchronous I/O options are shared between the references. + If a separate pointer into the file is desired, a different object + reference to the file must be obtained by issuing an additional + open(2) call. + + The close-on-exec flag on the new file descriptor is unset. + + If oldfd is valid and has the same integer value as newfd, nothing is + done, and newfd is returned unchanged. + + If newfd is already valid when this function is called, its old + descriptor is deallocated before this function returns. + + This function fails gracefully if oldfd is invalid. INPUTS oldfd - The file descriptor to be duplicated - newfd - The value of the new descriptor we want the old one to be duplicated in + newfd - The value of the new descriptor we want the old one to be + duplicated in RESULT -1 for error or newfd on success @@ -56,9 +67,9 @@ ******************************************************************************/ { - fdesc *oldfdesc; - fdesc *newfdesc; + fdesc *oldfdesc, *newfdesc, *oldnewfdesc; + /* Fail if old FD is invalid */ oldfdesc = __getfdesc(oldfd); if (!oldfdesc) { @@ -66,20 +77,34 @@ return -1; } + /* Do nothing if FDs are identical */ + if (oldfd == newfd) + return newfd; + + /* Keep back-up of old "newfd" */ + oldnewfdesc = __getfdesc(newfd); + + /* Allocate new FD or fail */ newfdesc = __alloc_fdesc(); - if(!newfdesc) + if (!newfdesc) { errno = ENOMEM; return -1; } - + + /* Initialise new FD */ newfdesc->fdflags = 0; newfdesc->fcb = oldfdesc->fcb; - + newfd =__getfdslot(newfd); if (newfd != -1) { newfdesc->fcb->opencount++; + + /* Free old "newfd" (now that we've definitely succeeded) */ + if (oldnewfdesc) + __free_fdesc(oldnewfdesc); + __setfdesc(newfd, newfdesc); } -- 2.11.4.GIT