1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
cde/cde/programs/dtksh/ksh93/src/lib/libast/sfio/sfwrite.c
2019-08-20 12:52:43 +02:00

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;
}