14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1985-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * Glenn Fowler <gsf@research.att.com> * 184887Schin * David Korn <dgk@research.att.com> * 194887Schin * Phong Vo <kpv@research.att.com> * 204887Schin * * 214887Schin ***********************************************************************/ 224887Schin #include "sfhdr.h" 234887Schin 244887Schin /* Change the file descriptor 254887Schin ** 264887Schin ** Written by Kiem-Phong Vo. 274887Schin */ 284887Schin 294887Schin #if __STD_C 30*8462SApril.Chin@Sun.COM static int _sfdup(int fd, int newfd) 314887Schin #else 324887Schin static int _sfdup(fd,newfd) 33*8462SApril.Chin@Sun.COM int fd; 34*8462SApril.Chin@Sun.COM int newfd; 354887Schin #endif 364887Schin { 374887Schin reg int dupfd; 384887Schin 394887Schin #ifdef F_DUPFD /* the simple case */ 404887Schin while((dupfd = sysfcntlf(fd,F_DUPFD,newfd)) < 0 && errno == EINTR) 414887Schin errno = 0; 424887Schin return dupfd; 434887Schin 444887Schin #else /* do it the hard way */ 454887Schin if((dupfd = sysdupf(fd)) < 0 || dupfd >= newfd) 464887Schin return dupfd; 474887Schin 484887Schin /* dup() succeeded but didn't get the right number, recurse */ 494887Schin newfd = _sfdup(fd,newfd); 504887Schin 514887Schin /* close the one that didn't match */ 524887Schin CLOSE(dupfd); 534887Schin 544887Schin return newfd; 554887Schin #endif 564887Schin } 574887Schin 584887Schin #if __STD_C 59*8462SApril.Chin@Sun.COM int sfsetfd(Sfio_t* f, int newfd) 604887Schin #else 614887Schin int sfsetfd(f,newfd) 62*8462SApril.Chin@Sun.COM Sfio_t *f; 63*8462SApril.Chin@Sun.COM int newfd; 644887Schin #endif 654887Schin { 664887Schin reg int oldfd; 67*8462SApril.Chin@Sun.COM SFMTXDECL(f); 684887Schin 69*8462SApril.Chin@Sun.COM SFMTXENTER(f, -1); 704887Schin 714887Schin if(f->flags&SF_STRING) 724887Schin SFMTXRETURN(f, -1); 734887Schin 744887Schin if((f->mode&SF_INIT) && f->file < 0) 754887Schin { /* restoring file descriptor after a previous freeze */ 764887Schin if(newfd < 0) 774887Schin SFMTXRETURN(f, -1); 784887Schin } 794887Schin else 804887Schin { /* change file descriptor */ 814887Schin if((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0) 824887Schin SFMTXRETURN(f, -1); 834887Schin SFLOCK(f,0); 844887Schin 854887Schin oldfd = f->file; 864887Schin if(oldfd >= 0) 874887Schin { if(newfd >= 0) 884887Schin { if((newfd = _sfdup(oldfd,newfd)) < 0) 894887Schin { SFOPEN(f,0); 904887Schin SFMTXRETURN(f, -1); 914887Schin } 924887Schin CLOSE(oldfd); 934887Schin } 944887Schin else 954887Schin { /* sync stream if necessary */ 964887Schin if(((f->mode&SF_WRITE) && f->next > f->data) || 974887Schin (f->mode&SF_READ) || f->disc == _Sfudisc) 984887Schin { if(SFSYNC(f) < 0) 994887Schin { SFOPEN(f,0); 1004887Schin SFMTXRETURN(f, -1); 1014887Schin } 1024887Schin } 1034887Schin 1044887Schin if(((f->mode&SF_WRITE) && f->next > f->data) || 1054887Schin ((f->mode&SF_READ) && f->extent < 0 && 1064887Schin f->next < f->endb) ) 1074887Schin { SFOPEN(f,0); 1084887Schin SFMTXRETURN(f, -1); 1094887Schin } 1104887Schin 1114887Schin #ifdef MAP_TYPE 1124887Schin if((f->bits&SF_MMAP) && f->data) 1134887Schin { SFMUNMAP(f,f->data,f->endb-f->data); 1144887Schin f->data = NIL(uchar*); 1154887Schin } 1164887Schin #endif 1174887Schin 1184887Schin /* make stream appears uninitialized */ 1194887Schin f->endb = f->endr = f->endw = f->data; 1204887Schin f->extent = f->here = 0; 1214887Schin f->mode = (f->mode&SF_RDWR)|SF_INIT; 1224887Schin f->bits &= ~SF_NULL; /* off /dev/null handling */ 1234887Schin } 1244887Schin } 1254887Schin 1264887Schin SFOPEN(f,0); 1274887Schin } 1284887Schin 1294887Schin /* notify changes */ 1304887Schin if(_Sfnotify) 131*8462SApril.Chin@Sun.COM (*_Sfnotify)(f, SF_SETFD, (void*)((long)newfd)); 1324887Schin 1334887Schin f->file = newfd; 1344887Schin 1354887Schin SFMTXRETURN(f,newfd); 1364887Schin } 137