1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 /* Change the file descriptor
26 ** Written by Kiem-Phong Vo.
30 static int _sfdup(int fd
, int newfd
)
32 static int _sfdup(fd
,newfd
)
39 #ifdef F_DUPFD /* the simple case */
40 while((dupfd
= sysfcntlf(fd
,F_DUPFD
,newfd
)) < 0 && errno
== EINTR
)
44 #else /* do it the hard way */
45 if((dupfd
= sysdupf(fd
)) < 0 || dupfd
>= newfd
)
48 /* dup() succeeded but didn't get the right number, recurse */
49 newfd
= _sfdup(fd
,newfd
);
51 /* close the one that didn't match */
59 int sfsetfd(Sfio_t
* f
, int newfd
)
71 if(f
->flags
&SF_STRING
)
74 if((f
->mode
&SF_INIT
) && f
->file
< 0)
75 { /* restoring file descriptor after a previous freeze */
80 { /* change file descriptor */
81 if((f
->mode
&SF_RDWR
) != f
->mode
&& _sfmode(f
,0,0) < 0)
88 { if((newfd
= _sfdup(oldfd
,newfd
)) < 0)
95 { /* sync stream if necessary */
96 if(((f
->mode
&SF_WRITE
) && f
->next
> f
->data
) ||
97 (f
->mode
&SF_READ
) || f
->disc
== _Sfudisc
)
104 if(((f
->mode
&SF_WRITE
) && f
->next
> f
->data
) ||
105 ((f
->mode
&SF_READ
) && f
->extent
< 0 &&
112 if((f
->bits
&SF_MMAP
) && f
->data
)
113 { SFMUNMAP(f
,f
->data
,f
->endb
-f
->data
);
114 f
->data
= NIL(uchar
*);
118 /* make stream appears uninitialized */
119 f
->endb
= f
->endr
= f
->endw
= f
->data
;
120 f
->extent
= f
->here
= 0;
121 f
->mode
= (f
->mode
&SF_RDWR
)|SF_INIT
;
122 f
->bits
&= ~SF_NULL
; /* off /dev/null handling */
131 (*_Sfnotify
)(f
, SF_SETFD
, (void*)((long)newfd
));
135 SFMTXRETURN(f
,newfd
);