Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / sfio / sfwrite.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: sfwrite.c /main/3 1995/11/01 18:39:07 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46 #include        "sfhdr.h"
47
48 /*      Write data out to the file system
49 **      Note that the reg declarations below must be kept in
50 **      their relative order so that the code will configured
51 **      correctly on Vaxes to use "asm()".
52 **
53 **      Written by Kiem-Phong Vo (06/27/90)
54 */
55
56 #if __STD_C
57 sfwrite(reg Sfio_t* f, const Void_t* buf, reg int n)
58 #else
59 sfwrite(f,buf,n)
60 reg Sfio_t*     f;      /* write to this stream. r11 on Vax     */
61 Void_t*         buf;    /* buffer to be written.                */
62 reg int         n;      /* number of bytes. r10 on Vax          */
63 #endif
64 {
65         reg char*       s;      /* r9 on Vax    */
66         reg uchar*      next;   /* r8 on Vax    */
67         reg int         w;      /* r7 on Vax    */
68         reg char*       begs;
69         reg int         local;
70
71         GETLOCAL(f,local);
72
73         /* release peek lock */
74         if(f->mode&SF_PEEK)
75         {       if(!(f->mode&SF_WRITE) && (f->flags&SF_RDWR) != SF_RDWR)
76                         return -1;
77
78                 if((uchar*)buf != f->next)
79                 {       reg Sfrsrv_t*   frs = _sfrsrv(f,0);
80                         if((uchar*)buf != frs->data)
81                                 return -1;
82                 }
83
84                 f->mode &= ~SF_PEEK;
85
86                 if(f->mode&SF_PKRD)
87                 {       /* read past peeked data */
88                         char    buf[16];
89                         reg int r;
90
91                         for(w = n; w > 0; )
92                         {       if((r = w) > sizeof(buf))
93                                         r = sizeof(buf);
94                                 if((r = read(f->file,buf,r)) <= 0)
95                                 {       n -= w;
96                                         break;
97                                 }
98                                 else    w -= r;
99                         }
100
101                         f->mode &= ~SF_PKRD;
102                         f->endb = f->data + n;
103                         f->here += n;
104                 }
105
106                 if((f->mode&SF_READ) && (f->flags&SF_PROCESS))
107                         f->next += n;
108         }
109
110         s = begs = (char*)buf;
111         for(;; f->mode &= ~SF_LOCK)
112         {       /* check stream mode */
113                 if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0 )
114                         return s > begs ? s-begs : -1;
115
116                 if(n <= 0)
117                         break;
118
119                 SFLOCK(f,local);
120
121                 /* current available buffer space */
122                 if((w = f->endb - f->next) > n)
123                         w = n;
124
125                 if((uchar*)s == f->next)
126                 {       /* fast write after sfreserve() */
127                         f->next += w;
128                         s += w;
129                         n = 0;
130                         break;
131                 }
132
133                 if(w > 0 && ((f->flags&SF_STRING) || w != (f->endb-f->data)) )
134                 {       /* copy into buffer */
135                         next = f->next;
136
137 #if _vax_asm            /* s is r9, next is r8, w is r7 */
138                         asm( "movc3     r7,(r9),(r8)" );
139                         s += w;
140                         next += w;
141 #else
142                         MEMCPY(next,s,w);
143 #endif
144                         f->next = next;
145                         if((n -= w) <= 0)
146                                 break;
147                 }
148                 else if(!(f->flags&SF_STRING) && f->next > f->data)
149                 {       if(SFFLSBUF(f,-1) < 0)
150                                 break;
151                 }
152                 else if((w = SFWR(f,s,n,f->disc)) == 0)
153                         break;
154                 else if(w > 0)
155                 {       s += w;
156                         if((n -= w) <= 0)
157                                 break;
158                 }
159         }
160
161         /* always flush buffer for share streams */
162         if(f->extent < 0 && (f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC) )
163                 (void)SFFLSBUF(f,-1);
164
165         /* check to see if buffer should be flushed */
166         else if(n == 0 && (f->flags&SF_LINE) && !(f->flags&SF_STRING))
167         {       if((n = f->next-f->data) > (w = s-begs))
168                         n = w;
169                 if(n > 0 && n < HIFORLINE)
170                 {       w = *(next = f->next-n); *next = '\n'; next += n;
171                         while(*--next != '\n')
172                                 ;
173                         f->next[-n] = w;
174                         if(*next == '\n')
175                                 n = HIFORLINE;
176                 }
177                 if(n >= HIFORLINE)
178                         (void)SFFLSBUF(f,-1);
179         }
180
181         SFOPEN(f,local);
182
183         return s-begs;
184 }