3331c3d3a02b36f8c8f735645b8a563ceab9cfef
[oweals/cde.git] / cde / lib / tt / mini_isam / iswrrec.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 libraries 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 /*%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                   */
24 /*%%  (c) Copyright 1993, 1994 International Business Machines Corp.     */
25 /*%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                    */
26 /*%%  (c) Copyright 1993, 1994 Novell, Inc.                              */
27 /*%%  $XConsortium: iswrrec.c /main/3 1995/10/23 11:46:30 rswiston $                                                     */
28 #ifndef lint
29 static char sccsid[] = "@(#)iswrrec.c 1.7 89/06/07 Copyr 1988 Sun Micro";
30 #endif
31 /*
32  * Copyright (c) 1988 by Sun Microsystems, Inc.
33  */
34
35 /*
36  * iswrrec.c
37  *
38  * Description:
39  *      Write a record to ISAM file. 
40  */
41
42 #include "isam_impl.h"
43 #include <sys/time.h>
44
45 static int _amwrrec();
46
47 /*
48  * isfd = iswrrec(isfd, recnum, record)
49  *
50  * Iswrrec() writes a record to ISAM file at specified recno position. 
51  * All indexes of the ISAM file are updated.
52  *
53  * Current record position is not changed.
54  * isrecnum is set to recnum.
55  *
56  * If the ISAM file is for variable length records, the isreclen variable
57  * must be set to indicate the actual length of the record, which must
58  * be between the minimum and maximum length, as specified in isbuild().
59  *
60  * Returns 0 if successful, or -1 of any error.
61  *
62  * Errors:
63  *      EDUPL   The write would result in a duplicate on a key that
64  *              does not allow duplicates.
65  *      ELOCKED The file has been locked by another process.
66  *      ENOTOPEN isfd does not correspond to an open ISAM file, or the
67  *              ISAM file was not opened with ISINOUT mode.
68  *      EKEXISTS Record with recnum already exists.
69  *      EBADARG recnum is negative.
70  */
71
72 int 
73 iswrrec(int isfd, long recnum, char *record)
74 {
75     Fab *fab;
76     int                 reclen;
77     int                 ret;
78
79     /*
80      * Get File Access Block.
81      */
82     if ((fab = _isfd_find(isfd)) == NULL) {
83         _setiserrno2(ENOTOPEN, '9', '0');
84         return (ISERROR);
85     }
86
87     /*
88      * Check that the open mode was  ISINOUT.
89      */
90     if (fab->openmode != OM_INOUT) {
91         _setiserrno2(ENOTOPEN, '9', '0');
92         return (ISERROR);
93     }
94
95     /*
96      * Determine record length. Check it against min and max record length.
97      */
98     reclen = (fab->varlength == TRUE) ? isreclen : fab->minreclen;
99     if (reclen < fab->minreclen || reclen > fab->maxreclen) {
100         _setiserrno2(EBADARG, '9' ,'0');
101         return (ISERROR);
102     }
103    
104     if ((ret = _amwrrec(&fab->isfhandle, record, reclen,
105                         recnum, &fab->errcode)) == ISOK) {
106         isrecnum = recnum;                   /* Set isrecnum */
107     }
108
109     _seterr_errcode(&fab->errcode);
110
111     return (ret);                            /* Successful write */
112 }
113
114 /*
115  * _amwrrec(isfhandle, record, reclen, recnum, errcode)
116  *
117  * _amwrrec() rewrites a record in ISAM file.
118  *
119  * Input params:
120  *      isfhandle       Handle of ISAM file
121  *      record          record
122  *      reclen          length of the record
123  *      recnum          record number of record to be deleted
124  *
125  * Output params:
126  *      errcode         error status of the operation
127  *
128  */
129
130 static int
131 _amwrrec(Bytearray *isfhandle, char *record, int reclen, Recno recnum,
132          struct errcode *errcode)
133 {
134     Fcb                 *fcb = NULL;
135     int                 err;
136     int                 (*rec_wrrec)();
137
138     _isam_entryhook();
139
140     /*
141      * Get FCB corresponding to the isfhandle handle.
142      */
143     if ((fcb = _openfcb(isfhandle, errcode)) == NULL) {
144         _isam_exithook();
145         return (ISERROR);
146     }
147
148     rec_wrrec = (fcb->varflag?_vlrec_wrrec:_flrec_wrrec);
149
150     /*
151      * Update information in FCB from CNTL page on the disk
152      */
153     (void)_isfcb_cntlpg_r2(fcb);
154
155     if ((err = rec_wrrec(fcb, record, recnum, reclen)) != ISOK) {
156         _amseterrcode(errcode, err);
157         goto ERROR;
158     }
159
160     /*
161      * Update all keys.
162      */
163     if ((err = _addkeys(fcb, record, recnum)) != ISOK) {
164         _amseterrcode(errcode, err);    
165         goto ERROR;
166     }
167
168     fcb->nrecords++;
169
170     _amseterrcode(errcode, ISOK);
171
172     _issignals_mask();
173     _isdisk_commit();
174     _isdisk_sync();
175     _isdisk_inval();
176
177     /*
178      * Update CNTL Page from the FCB.
179      */
180     (void)_isfcb_cntlpg_w2(fcb);
181     _issignals_unmask();
182
183     _isam_exithook();
184     return (ISOK);
185
186  ERROR:
187     _isdisk_rollback();
188     _isdisk_inval();
189
190     /*
191      * Restore FCB from CNTL page.
192      */
193     if (fcb) (void)_isfcb_cntlpg_r2(fcb);
194
195     _isam_exithook();
196     return (ISERROR);
197 }
198
199