1 /* Fortran-callable routines to read and write characther (bacio) and */
2 /* numeric (banio) data byte addressably */
3 /* Robert Grumbine 16 March 1998 */
4 /* v1.1: Put diagnostic output under control of define VERBOSE or QUIET */
5 /* Add option of non-seeking read/write */
6 /* Return code for fewer data read/written than requested */
7 /* v1.2: Add cray compatibility 20 April 1998 */
10 #include <sys/types.h>
15 #include <sys/malloc.h>
22 /* Include the C library file for definition/control */
23 /* Things that might be changed for new systems are there. */
24 /* This source file should not (need to) be edited, merely recompiled */
30 /* -1 Tried to open read only _and_ write only */
31 /* -2 Tried to read and write in the same call */
32 /* -3 Internal failure in name processing */
33 /* -4 Failure in opening file */
34 /* -5 Tried to read on a write-only file */
35 /* -6 Failed in read to find the 'start' location */
36 /* -7 Tried to write to a read only file */
37 /* -8 Failed in write to find the 'start' location */
38 /* -9 Error in close */
39 /* -10 Read or wrote fewer data than requested */
41 /* Note: In your Fortran code, call bacio, not bacio_. */
42 /*int bacio_(int * mode, int * start, int * size, int * no, int * nactual, */
43 /* int * fdes, const char *fname, char *data, int namelen, */
44 /* int datanamelen) */
46 /* Mode is the integer specifying operations to be performed */
47 /* see the clib.inc file for the values. Mode is obtained */
48 /* by adding together the values corresponding to the operations */
49 /* The best method is to include the clib.inc file and refer to the */
50 /* names for the operations rather than rely on hard-coded values */
51 /* Start is the byte number to start your operation from. 0 is the first */
52 /* byte in the file, not 1. */
53 /* Newpos is the position in the file after a read or write has been */
54 /* performed. You'll need this if you're doing 'seeking' read/write */
55 /* Size is the size of the objects you are trying to read. Rely on the */
56 /* values in the locale.inc file. Types are CHARACTER, INTEGER, REAL, */
57 /* COMPLEX. Specify the correct value by using SIZEOF_type, where type */
58 /* is one of these. (After having included the locale.inc file) */
59 /* no is the number of things to read or write (characters, integers, */
61 /* nactual is the number of things actually read or written. Check that */
62 /* you got what you wanted. */
63 /* fdes is an integer 'file descriptor'. This is not a Fortran Unit Number */
64 /* You can use it, however, to refer to files you've previously opened. */
65 /* fname is the name of the file. This only needs to be defined when you */
66 /* are opening a file. It must be (on the Fortran side) declared as */
67 /* CHARACTER*N, where N is a length greater than or equal to the length */
68 /* of the file name. CHARACTER*1 fname[80] (for example) will fail. */
69 /* data is the name of the entity (variable, vector, array) that you want */
70 /* to write data out from or read it in to. The fact that C is declaring */
71 /* it to be a char * does not affect your fortran. */
72 /* namelen - Do NOT specify this. It is created automagically by the */
73 /* Fortran compiler */
74 /* datanamelen - Ditto */
78 (int * mode
, int * start
, int *newpos
, int * size
, int * no
,
79 int * nactual
, int * fdes
, const char *fname
, char *datary
,
80 int namelen
, int datanamelen
)
82 int i
, j
, jret
, seekret
;
83 char *realname
, *tempchar
;
87 /* Initialization(s) */
90 /* Check for illegal combinations of options */
91 if (( BAOPEN_RONLY
& *mode
) &&
92 ( (BAOPEN_WONLY
& *mode
) || (BAOPEN_WONLY_TRUNC
& *mode
) || (BAOPEN_WONLY_APPEND
& *mode
) ) ) {
94 printf("illegal -- trying to open both read only and write only\n");
98 if ( (BAREAD
& *mode
) && (BAWRITE
& *mode
) ) {
100 printf("illegal -- trying to both read and write in the same call\n");
105 /* This section handles Fortran to C translation of strings so as to */
106 /* be able to open the files Fortran is expecting to be opened. */
108 namelen
= _fcdlen(fcd_fname
);
109 fname
= _fcdtocp(fcd_fname
);
112 realname
= (char *) malloc( (namelen
+1) * sizeof(char) ) ;
113 if (realname
== NULL
) {
115 printf("failed to mallocate realname %d = namelen\n", namelen
);
121 if ( (BAOPEN_RONLY
& *mode
) || (BAOPEN_WONLY
& *mode
) ||
122 (BAOPEN_WONLY_TRUNC
& *mode
) || (BAOPEN_WONLY_APPEND
& *mode
) ||
123 (BAOPEN_RW
& *mode
) ) {
125 printf("Will be opening a file %s %d\n", fname
, namelen
); fflush(stdout
);
126 printf("Strlen %d namelen %d\n", strlen(fname
), namelen
); fflush(stdout
);
128 tempchar
= (char *) malloc(sizeof(char) * 1 ) ;
131 *tempchar
= fname
[i
];
132 tcharval
= *tempchar
;
133 while (i
== j
&& i
< namelen
) {
135 if ( isgraph(tcharval
) ) {
136 realname
[j
] = fname
[i
];
140 *tempchar
= fname
[i
];
141 tcharval
= *tempchar
;
144 printf("i,j = %d %d\n",i
,j
); fflush(stdout
);
150 /* Open files with correct read/write and file permission. */
151 if (BAOPEN_RONLY
& *mode
) {
153 printf("open read only %s\n", realname
);
155 *fdes
= open(realname
, O_RDONLY
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
157 else if (BAOPEN_WONLY
& *mode
) {
159 printf("open write only %s\n", realname
);
161 *fdes
= open(realname
, O_WRONLY
| O_CREAT
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
163 else if (BAOPEN_WONLY_TRUNC
& *mode
) {
165 printf("open write only with truncation %s\n", realname
);
167 *fdes
= open(realname
, O_WRONLY
| O_CREAT
| O_TRUNC
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
169 else if (BAOPEN_WONLY_APPEND
& *mode
) {
171 printf("open write only with append %s\n", realname
);
173 *fdes
= open(realname
, O_WRONLY
| O_CREAT
| O_APPEND
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
175 else if (BAOPEN_RW
& *mode
) {
177 printf("open read-write %s\n", realname
);
179 *fdes
= open(realname
, O_RDWR
| O_CREAT
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
183 printf("no openings\n");
188 printf("error in file descriptor! *fdes %d\n", *fdes
);
194 printf("file descriptor = %d\n",*fdes
);
199 /* Read data as requested */
200 if (BAREAD
& *mode
&&
201 ( (BAOPEN_WONLY
& *mode
) || (BAOPEN_WONLY_TRUNC
& *mode
) || (BAOPEN_WONLY_APPEND
& *mode
) ) ) {
203 printf("Error, trying to read while in write only mode!\n");
207 else if (BAREAD
& *mode
) {
208 /* Read in some data */
209 if (! (*mode
& NOSEEK
) ) {
210 seekret
= lseek(*fdes
, *start
, SEEK_SET
);
213 printf("error in seeking to %d\n",*start
);
219 printf("Seek successful, seek ret %d, start %d\n", seekret
, *start
);
224 datary
= _fcdtocp(fcd_datary
);
226 if (datary
== NULL
) {
227 printf("Massive catastrophe -- datary pointer is NULL\n");
231 printf("file descriptor, datary = %d %d\n", *fdes
, (int) datary
);
233 count
= (size_t) *no
;
234 jret
= read(*fdes
, (void *) datary
, count
);
237 printf("did not read in the requested number of bytes\n");
238 printf("read in %d bytes instead of %d \n",jret
, *no
);
243 printf("read in %d bytes requested \n", *no
);
247 *newpos
= *start
+ jret
;
249 /* Done with reading */
251 /* See if we should be writing */
252 if ( BAWRITE
& *mode
&& BAOPEN_RONLY
& *mode
) {
254 printf("Trying to write on a read only file \n");
258 else if ( BAWRITE
& *mode
) {
259 if (! (*mode
& NOSEEK
) ) {
260 seekret
= lseek(*fdes
, *start
, SEEK_SET
);
263 printf("error in seeking to %d\n",*start
);
269 datary
= _fcdtocp(fcd_datary
);
271 if (datary
== NULL
) {
272 printf("Massive catastrophe -- datary pointer is NULL\n");
276 printf("write file descriptor, datary = %d %d\n", *fdes
, (int) datary
);
278 count
= (size_t) *no
;
279 jret
= write(*fdes
, (void *) datary
, count
);
282 printf("did not write out the requested number of bytes\n");
283 printf("wrote %d bytes instead\n", jret
);
286 *newpos
= *start
+ jret
;
290 printf("wrote %d bytes \n", jret
);
293 *newpos
= *start
+ jret
;
296 /* Done with writing */
299 /* Close file if requested */
300 if (BACLOSE
& *mode
) {
304 printf("close failed! jret = %d\n",jret
);
313 /* Check that if we were reading or writing, that we actually got what */
314 /* we expected, else return a -10. Return 0 (success) if we're here */
315 /* and weren't reading or writing */
316 if ( (*mode
& BAREAD
|| *mode
& BAWRITE
) && (*nactual
!= *no
) ) {
324 (int * mode
, int * start
, int *newpos
, int * size
, int * no
,
325 int * nactual
, int * fdes
, const char *fname
, char *datary
,
328 int i
, j
, jret
, seekret
;
329 char *realname
, *tempchar
;
332 /* Initialization(s) */
335 /* Check for illegal combinations of options */
336 if (( BAOPEN_RONLY
& *mode
) &&
337 ( (BAOPEN_WONLY
& *mode
) || (BAOPEN_WONLY_TRUNC
& *mode
) || (BAOPEN_WONLY_APPEND
& *mode
) ) ) {
339 printf("illegal -- trying to open both read only and write only\n");
343 if ( (BAREAD
& *mode
) && (BAWRITE
& *mode
) ) {
345 printf("illegal -- trying to both read and write in the same call\n");
350 /* This section handles Fortran to C translation of strings so as to */
351 /* be able to open the files Fortran is expecting to be opened. */
353 namelen
= _fcdlen(fcd_fname
);
354 fname
= _fcdtocp(fcd_fname
);
356 if ( (BAOPEN_RONLY
& *mode
) || (BAOPEN_WONLY
& *mode
) ||
357 (BAOPEN_WONLY_TRUNC
& *mode
) || (BAOPEN_WONLY_APPEND
& *mode
) ||
358 (BAOPEN_RW
& *mode
) ) {
360 printf("Will be opening a file %s %d\n", fname
, namelen
); fflush(stdout
);
361 printf("Strlen %d namelen %d\n", strlen(fname
), namelen
); fflush(stdout
);
363 realname
= (char *) malloc( (namelen
+1) * sizeof(char) ) ;
364 if (realname
== NULL
) {
366 printf("failed to mallocate realname %d = namelen\n", namelen
);
371 tempchar
= (char *) malloc(sizeof(char) * 1 ) ;
374 *tempchar
= fname
[i
];
375 tcharval
= *tempchar
;
376 while (i
== j
&& i
< namelen
) {
378 if ( isgraph(tcharval
) ) {
379 realname
[j
] = fname
[i
];
383 *tempchar
= fname
[i
];
384 tcharval
= *tempchar
;
387 printf("i,j = %d %d\n",i
,j
); fflush(stdout
);
392 /* Open files with correct read/write and file permission. */
393 if (BAOPEN_RONLY
& *mode
) {
395 printf("open read only %s\n", realname
);
397 *fdes
= open(realname
, O_RDONLY
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
399 else if (BAOPEN_WONLY
& *mode
) {
401 printf("open write only %s\n", realname
);
403 *fdes
= open(realname
, O_WRONLY
| O_CREAT
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
405 else if (BAOPEN_WONLY_TRUNC
& *mode
) {
407 printf("open write only with truncation %s\n", realname
);
409 *fdes
= open(realname
, O_WRONLY
| O_CREAT
| O_TRUNC
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
411 else if (BAOPEN_WONLY_APPEND
& *mode
) {
413 printf("open write only with append %s\n", realname
);
415 *fdes
= open(realname
, O_WRONLY
| O_CREAT
| O_APPEND
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
417 else if (BAOPEN_RW
& *mode
) {
419 printf("open read-write %s\n", realname
);
421 *fdes
= open(realname
, O_RDWR
| O_CREAT
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
425 printf("no openings\n");
430 printf("error in file descriptor! *fdes %d\n", *fdes
);
436 printf("file descriptor = %d\n",*fdes
);
441 /* Read data as requested */
442 if (BAREAD
& *mode
&&
443 ( (BAOPEN_WONLY
& *mode
) || (BAOPEN_WONLY_TRUNC
& *mode
) || (BAOPEN_WONLY_APPEND
& *mode
) ) ) {
445 printf("Error, trying to read while in write only mode!\n");
449 else if (BAREAD
& *mode
) {
450 /* Read in some data */
451 if (! (*mode
& NOSEEK
) ) {
452 seekret
= lseek(*fdes
, *start
, SEEK_SET
);
455 printf("error in seeking to %d\n",*start
);
461 printf("Seek successful, seek ret %d, start %d\n", seekret
, *start
);
465 jret
= read(*fdes
, datary
, *no
*(*size
) );
466 if (jret
!= *no
*(*size
) ) {
468 printf("did not read in the requested number of items\n");
469 printf("read in %d items of %d \n",jret
/(*size
), *no
);
471 *nactual
= jret
/(*size
);
472 *newpos
= *start
+ jret
;
475 printf("read in %d items \n", jret
/(*size
));
477 *nactual
= jret
/(*size
);
478 *newpos
= *start
+ jret
;
480 /* Done with reading */
482 /* See if we should be writing */
483 if ( BAWRITE
& *mode
&& BAOPEN_RONLY
& *mode
) {
485 printf("Trying to write on a read only file \n");
489 else if ( BAWRITE
& *mode
) {
490 if (! (*mode
& NOSEEK
) ) {
491 seekret
= lseek(*fdes
, *start
, SEEK_SET
);
494 printf("error in seeking to %d\n",*start
);
500 printf("Seek successful, seek ret %d, start %d\n", seekret
, *start
);
504 jret
= write(*fdes
, datary
, *no
*(*size
));
505 if (jret
!= *no
*(*size
)) {
507 printf("did not write out the requested number of items\n");
508 printf("wrote %d items instead\n", jret
/(*size
) );
510 *nactual
= jret
/(*size
) ;
511 *newpos
= *start
+ jret
;
515 printf("wrote %d items \n", jret
/(*size
) );
517 *nactual
= jret
/(*size
) ;
518 *newpos
= *start
+ jret
;
521 /* Done with writing */
524 /* Close file if requested */
525 if (BACLOSE
& *mode
) {
529 printf("close failed! jret = %d\n",jret
);
536 /* Check that if we were reading or writing, that we actually got what */
537 /* we expected, else return a -10. Return 0 (success) if we're here */
538 /* and weren't reading or writing */
539 if ( (*mode
& BAREAD
|| *mode
& BAWRITE
) && (*nactual
!= *no
) ) {