mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
184 lines
5.1 KiB
C
184 lines
5.1 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $XConsortium: sfwrite.c /main/3 1995/11/01 18:39:07 rswiston $ */
|
|
/***************************************************************
|
|
* *
|
|
* AT&T - PROPRIETARY *
|
|
* *
|
|
* THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
|
|
* AT&T CORP. *
|
|
* *
|
|
* Copyright (c) 1995 AT&T Corp. *
|
|
* All Rights Reserved *
|
|
* *
|
|
* This software is licensed by AT&T Corp. *
|
|
* under the terms and conditions of the license in *
|
|
* http://www.research.att.com/orgs/ssr/book/reuse *
|
|
* *
|
|
* This software was created by the *
|
|
* Software Engineering Research Department *
|
|
* AT&T Bell Laboratories *
|
|
* *
|
|
* For further information contact *
|
|
* gsf@research.att.com *
|
|
* *
|
|
***************************************************************/
|
|
#include "sfhdr.h"
|
|
|
|
/* Write data out to the file system
|
|
** Note that the reg declarations below must be kept in
|
|
** their relative order so that the code will configured
|
|
** correctly on Vaxes to use "asm()".
|
|
**
|
|
** Written by Kiem-Phong Vo (06/27/90)
|
|
*/
|
|
|
|
#if __STD_C
|
|
int sfwrite(reg Sfio_t* f, const Void_t* buf, reg int n)
|
|
#else
|
|
sfwrite(f,buf,n)
|
|
reg Sfio_t* f; /* write to this stream. r11 on Vax */
|
|
Void_t* buf; /* buffer to be written. */
|
|
reg int n; /* number of bytes. r10 on Vax */
|
|
#endif
|
|
{
|
|
reg char* s; /* r9 on Vax */
|
|
reg uchar* next; /* r8 on Vax */
|
|
reg int w; /* r7 on Vax */
|
|
reg char* begs;
|
|
reg int local;
|
|
|
|
GETLOCAL(f,local);
|
|
|
|
/* release peek lock */
|
|
if(f->mode&SF_PEEK)
|
|
{ if(!(f->mode&SF_WRITE) && (f->flags&SF_RDWR) != SF_RDWR)
|
|
return -1;
|
|
|
|
if((uchar*)buf != f->next)
|
|
{ reg Sfrsrv_t* frs = _sfrsrv(f,0);
|
|
if((uchar*)buf != frs->data)
|
|
return -1;
|
|
}
|
|
|
|
f->mode &= ~SF_PEEK;
|
|
|
|
if(f->mode&SF_PKRD)
|
|
{ /* read past peeked data */
|
|
char buf[16];
|
|
reg int r;
|
|
|
|
for(w = n; w > 0; )
|
|
{ if((r = w) > sizeof(buf))
|
|
r = sizeof(buf);
|
|
if((r = read(f->file,buf,r)) <= 0)
|
|
{ n -= w;
|
|
break;
|
|
}
|
|
else w -= r;
|
|
}
|
|
|
|
f->mode &= ~SF_PKRD;
|
|
f->endb = f->data + n;
|
|
f->here += n;
|
|
}
|
|
|
|
if((f->mode&SF_READ) && (f->flags&SF_PROCESS))
|
|
f->next += n;
|
|
}
|
|
|
|
s = begs = (char*)buf;
|
|
for(;; f->mode &= ~SF_LOCK)
|
|
{ /* check stream mode */
|
|
if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0 )
|
|
return s > begs ? s-begs : -1;
|
|
|
|
if(n <= 0)
|
|
break;
|
|
|
|
SFLOCK(f,local);
|
|
|
|
/* current available buffer space */
|
|
if((w = f->endb - f->next) > n)
|
|
w = n;
|
|
|
|
if((uchar*)s == f->next)
|
|
{ /* fast write after sfreserve() */
|
|
f->next += w;
|
|
s += w;
|
|
n = 0;
|
|
break;
|
|
}
|
|
|
|
if(w > 0 && ((f->flags&SF_STRING) || w != (f->endb-f->data)) )
|
|
{ /* copy into buffer */
|
|
next = f->next;
|
|
|
|
#if _vax_asm /* s is r9, next is r8, w is r7 */
|
|
asm( "movc3 r7,(r9),(r8)" );
|
|
s += w;
|
|
next += w;
|
|
#else
|
|
MEMCPY(next,s,w);
|
|
#endif
|
|
f->next = next;
|
|
if((n -= w) <= 0)
|
|
break;
|
|
}
|
|
else if(!(f->flags&SF_STRING) && f->next > f->data)
|
|
{ if(SFFLSBUF(f,-1) < 0)
|
|
break;
|
|
}
|
|
else if((w = SFWR(f,s,n,f->disc)) == 0)
|
|
break;
|
|
else if(w > 0)
|
|
{ s += w;
|
|
if((n -= w) <= 0)
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* always flush buffer for share streams */
|
|
if(f->extent < 0 && (f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC) )
|
|
(void)SFFLSBUF(f,-1);
|
|
|
|
/* check to see if buffer should be flushed */
|
|
else if(n == 0 && (f->flags&SF_LINE) && !(f->flags&SF_STRING))
|
|
{ if((n = f->next-f->data) > (w = s-begs))
|
|
n = w;
|
|
if(n > 0 && n < HIFORLINE)
|
|
{ w = *(next = f->next-n); *next = '\n'; next += n;
|
|
while(*--next != '\n')
|
|
;
|
|
f->next[-n] = w;
|
|
if(*next == '\n')
|
|
n = HIFORLINE;
|
|
}
|
|
if(n >= HIFORLINE)
|
|
(void)SFFLSBUF(f,-1);
|
|
}
|
|
|
|
SFOPEN(f,local);
|
|
|
|
return s-begs;
|
|
}
|