PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/WPS/ungrib/src/ngl/w3/bacio.v1.3.c

http://github.com/jbeezley/wrf-fire
C | 571 lines | 455 code | 27 blank | 89 comment | 118 complexity | 38edc87c650bc1ce56df97979a4b8810 MD5 | raw file
Possible License(s): AGPL-1.0
  1. /* Fortran-callable routines to read and write characther (ba_cio) 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 */
  8. #include <stdio.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #ifndef _WIN32
  13. # include <unistd.h>
  14. #else
  15. # define S_IRWXU 00700
  16. # define S_IRWXG 00070
  17. # define S_IRWXO 00007
  18. #endif
  19. #ifdef MACOS
  20. #include <malloc/malloc.h>
  21. #else
  22. #include <malloc.h>
  23. #endif
  24. #include <ctype.h>
  25. #include <string.h>
  26. /* Include the C library file for definition/control */
  27. /* Things that might be changed for new systems are there. */
  28. /* This source file should not (need to) be edited, merely recompiled */
  29. #include "clib.h"
  30. /* Return Codes: */
  31. /* 0 All was well */
  32. /* -1 Tried to open read only _and_ write only */
  33. /* -2 Tried to read and write in the same call */
  34. /* -3 Internal failure in name processing */
  35. /* -4 Failure in opening file */
  36. /* -5 Tried to read on a write-only file */
  37. /* -6 Failed in read to find the 'start' location */
  38. /* -7 Tried to write to a read only file */
  39. /* -8 Failed in write to find the 'start' location */
  40. /* -9 Error in close */
  41. /* -10 Read or wrote fewer data than requested */
  42. /* Note: In your Fortran code, call ba_cio, not ba_cio_. */
  43. /*int ba_cio_(int * mode, int * start, int * size, int * no, int * nactual, */
  44. /* int * fdes, const char *fname, char *data, int namelen, */
  45. /* int datanamelen) */
  46. /* Arguments: */
  47. /* Mode is the integer specifying operations to be performed */
  48. /* see the clib.inc file for the values. Mode is obtained */
  49. /* by adding together the values corresponding to the operations */
  50. /* The best method is to include the clib.inc file and refer to the */
  51. /* names for the operations rather than rely on hard-coded values */
  52. /* Start is the byte number to start your operation from. 0 is the first */
  53. /* byte in the file, not 1. */
  54. /* Newpos is the position in the file after a read or write has been */
  55. /* performed. You'll need this if you're doing 'seeking' read/write */
  56. /* Size is the size of the objects you are trying to read. Rely on the */
  57. /* values in the locale.inc file. Types are CHARACTER, INTEGER, REAL, */
  58. /* COMPLEX. Specify the correct value by using SIZEOF_type, where type */
  59. /* is one of these. (After having included the locale.inc file) */
  60. /* no is the number of things to read or write (characters, integers, */
  61. /* whatever) */
  62. /* nactual is the number of things actually read or written. Check that */
  63. /* you got what you wanted. */
  64. /* fdes is an integer 'file descriptor'. This is not a Fortran Unit Number */
  65. /* You can use it, however, to refer to files you've previously opened. */
  66. /* fname is the name of the file. This only needs to be defined when you */
  67. /* are opening a file. It must be (on the Fortran side) declared as */
  68. /* CHARACTER*N, where N is a length greater than or equal to the length */
  69. /* of the file name. CHARACTER*1 fname[80] (for example) will fail. */
  70. /* data is the name of the entity (variable, vector, array) that you want */
  71. /* to write data out from or read it in to. The fact that C is declaring */
  72. /* it to be a char * does not affect your fortran. */
  73. /* namelen - Do NOT specify this. It is created automagically by the */
  74. /* Fortran compiler */
  75. /* datanamelen - Ditto */
  76. /* What is going on here is that although the Fortran caller will always */
  77. /* be calling ba_cio, the called C routine name will change from system */
  78. /* to system. */
  79. #if defined _UNDERSCORE
  80. int ba_cio_
  81. (int * mode, int * start, int *newpos, int * size, int * no,
  82. int * nactual, int * fdes, const char *fname, char *datary,
  83. int namelen, int datanamelen) {
  84. #elif defined _DOUBLEUNDERSCORE
  85. int ba_cio__
  86. (int * mode, int * start, int *newpos, int * size, int * no,
  87. int * nactual, int * fdes, const char *fname, char *datary,
  88. int namelen, int datanamelen) {
  89. #else
  90. int ba_cio
  91. (int * mode, int * start, int *newpos, int * size, int * no,
  92. int * nactual, int * fdes, const char *fname, char *datary,
  93. int namelen, int datanamelen) {
  94. #endif
  95. int i, j, jret, seekret;
  96. char *realname, *tempchar;
  97. int tcharval;
  98. size_t count;
  99. /* Initialization(s) */
  100. *nactual = 0;
  101. /* Check for illegal combinations of options */
  102. if (( BAOPEN_RONLY & *mode) &&
  103. ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
  104. #ifdef VERBOSE
  105. printf("illegal -- trying to open both read only and write only\n");
  106. #endif
  107. return -1;
  108. }
  109. if ( (BAREAD & *mode ) && (BAWRITE & *mode) ) {
  110. #ifdef VERBOSE
  111. printf("illegal -- trying to both read and write in the same call\n");
  112. #endif
  113. return -2;
  114. }
  115. /* This section handles Fortran to C translation of strings so as to */
  116. /* be able to open the files Fortran is expecting to be opened. */
  117. #ifdef CRAY90
  118. namelen = _fcdlen(fcd_fname);
  119. fname = _fcdtocp(fcd_fname);
  120. #endif
  121. if ( (BAOPEN_RONLY & *mode) || (BAOPEN_WONLY & *mode) ||
  122. (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ||
  123. (BAOPEN_RW & *mode) ) {
  124. #ifdef VERBOSE
  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);
  127. #endif
  128. realname = (char *) malloc( namelen * sizeof(char) ) ;
  129. if (realname == NULL) {
  130. #ifdef VERBOSE
  131. printf("failed to mallocate realname %d = namelen\n", namelen);
  132. fflush(stdout);
  133. #endif
  134. return -3;
  135. }
  136. tempchar = (char *) malloc(sizeof(char) * 1 ) ;
  137. i = 0;
  138. j = 0;
  139. *tempchar = fname[i];
  140. tcharval = *tempchar;
  141. while (i == j && i < namelen ) {
  142. fflush(stdout);
  143. if ( isgraph(tcharval) ) {
  144. realname[j] = fname[i];
  145. j += 1;
  146. }
  147. i += 1;
  148. *tempchar = fname[i];
  149. tcharval = *tempchar;
  150. }
  151. #ifdef VERBOSE
  152. printf("i,j = %d %d\n",i,j); fflush(stdout);
  153. #endif
  154. realname[j] = '\0';
  155. }
  156. /* Open files with correct read/write and file permission. */
  157. if (BAOPEN_RONLY & *mode) {
  158. #ifdef VERBOSE
  159. printf("open read only %s\n", realname);
  160. #endif
  161. *fdes = open(realname, O_RDONLY , S_IRWXU | S_IRWXG | S_IRWXO );
  162. }
  163. else if (BAOPEN_WONLY & *mode ) {
  164. #ifdef VERBOSE
  165. printf("open write only %s\n", realname);
  166. #endif
  167. *fdes = open(realname, O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  168. }
  169. else if (BAOPEN_WONLY_TRUNC & *mode ) {
  170. #ifdef VERBOSE
  171. printf("open write only with truncation %s\n", realname);
  172. #endif
  173. *fdes = open(realname, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU | S_IRWXG | S_IRWXO );
  174. }
  175. else if (BAOPEN_WONLY_APPEND & *mode ) {
  176. #ifdef VERBOSE
  177. printf("open write only with append %s\n", realname);
  178. #endif
  179. *fdes = open(realname, O_WRONLY | O_CREAT | O_APPEND , S_IRWXU | S_IRWXG | S_IRWXO );
  180. }
  181. else if (BAOPEN_RW & *mode) {
  182. #ifdef VERBOSE
  183. printf("open read-write %s\n", realname);
  184. #endif
  185. *fdes = open(realname, O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  186. }
  187. else {
  188. #ifdef VERBOSE
  189. printf("no openings\n");
  190. #endif
  191. }
  192. if (*fdes < 0) {
  193. #ifdef VERBOSE
  194. printf("error in file descriptor! *fdes %d\n", *fdes);
  195. #endif
  196. return -4;
  197. }
  198. else {
  199. #ifdef VERBOSE
  200. printf("file descriptor = %d\n",*fdes );
  201. #endif
  202. }
  203. /* Read data as requested */
  204. if (BAREAD & *mode &&
  205. ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
  206. #ifdef VERBOSE
  207. printf("Error, trying to read while in write only mode!\n");
  208. #endif
  209. return -5;
  210. }
  211. else if (BAREAD & *mode ) {
  212. /* Read in some data */
  213. if (! (*mode & NOSEEK) ) {
  214. seekret = lseek(*fdes, *start, SEEK_SET);
  215. if (seekret == -1) {
  216. #ifdef VERBOSE
  217. printf("error in seeking to %d\n",*start);
  218. #endif
  219. return -6;
  220. }
  221. #ifdef VERBOSE
  222. else {
  223. printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
  224. }
  225. #endif
  226. }
  227. #ifdef CRAY90
  228. datary = _fcdtocp(fcd_datary);
  229. #endif
  230. if (datary == NULL) {
  231. printf("Massive catastrophe -- datary pointer is NULL\n");
  232. return -666;
  233. }
  234. #ifdef VERBOSE
  235. printf("file descriptor, datary = %d %d\n", *fdes, (int) datary);
  236. #endif
  237. count = (size_t) *no;
  238. jret = read(*fdes, (void *) datary, count);
  239. if (jret != *no) {
  240. #ifdef VERBOSE
  241. printf("did not read in the requested number of bytes\n");
  242. printf("read in %d bytes instead of %d \n",jret, *no);
  243. #endif
  244. }
  245. else {
  246. #ifdef VERBOSE
  247. printf("read in %d bytes requested \n", *no);
  248. #endif
  249. }
  250. *nactual = jret;
  251. *newpos = *start + jret;
  252. }
  253. /* Done with reading */
  254. /* See if we should be writing */
  255. if ( BAWRITE & *mode && BAOPEN_RONLY & *mode ) {
  256. #ifdef VERBOSE
  257. printf("Trying to write on a read only file \n");
  258. #endif
  259. return -7;
  260. }
  261. else if ( BAWRITE & *mode ) {
  262. if (! (*mode & NOSEEK) ) {
  263. seekret = lseek(*fdes, *start, SEEK_SET);
  264. if (seekret == -1) {
  265. #ifdef VERBOSE
  266. printf("error in seeking to %d\n",*start);
  267. #endif
  268. return -8;
  269. }
  270. }
  271. #ifdef CRAY90
  272. datary = _fcdtocp(fcd_datary);
  273. #endif
  274. if (datary == NULL) {
  275. printf("Massive catastrophe -- datary pointer is NULL\n");
  276. return -666;
  277. }
  278. #ifdef VERBOSE
  279. printf("write file descriptor, datary = %d %d\n", *fdes, (int) datary);
  280. #endif
  281. count = (size_t) *no;
  282. jret = write(*fdes, (void *) datary, count);
  283. if (jret != *no) {
  284. #ifdef VERBOSE
  285. printf("did not write out the requested number of bytes\n");
  286. printf("wrote %d bytes instead\n", jret);
  287. #endif
  288. *nactual = jret;
  289. *newpos = *start + jret;
  290. }
  291. else {
  292. #ifdef VERBOSE
  293. printf("wrote %d bytes \n", jret);
  294. #endif
  295. *nactual = jret;
  296. *newpos = *start + jret;
  297. }
  298. }
  299. /* Done with writing */
  300. /* Close file if requested */
  301. if (BACLOSE & *mode ) {
  302. jret = close(*fdes);
  303. if (jret != 0) {
  304. #ifdef VERBOSE
  305. printf("close failed! jret = %d\n",jret);
  306. #endif
  307. return -9;
  308. }
  309. }
  310. /* Done closing */
  311. /* Check that if we were reading or writing, that we actually got what */
  312. /* we expected, else return a -10. Return 0 (success) if we're here */
  313. /* and weren't reading or writing */
  314. if ( (*mode & BAREAD || *mode & BAWRITE) && (*nactual != *no) ) {
  315. return -10;
  316. }
  317. else {
  318. return 0;
  319. }
  320. }
  321. #if defined _UNDERSCORE
  322. int banio_
  323. (int * mode, int * start, int *newpos, int * size, int * no,
  324. int * nactual, int * fdes, const char *fname, char *datary,
  325. int namelen ) {
  326. #elif defined _DOUBLEUNDERSCORE
  327. int banio__
  328. (int * mode, int * start, int *newpos, int * size, int * no,
  329. int * nactual, int * fdes, const char *fname, char *datary,
  330. int namelen ) {
  331. #else
  332. int banio
  333. (int * mode, int * start, int *newpos, int * size, int * no,
  334. int * nactual, int * fdes, const char *fname, char *datary,
  335. int namelen ) {
  336. #endif
  337. int i, j, jret, seekret;
  338. char *realname, *tempchar;
  339. int tcharval;
  340. /* Initialization(s) */
  341. *nactual = 0;
  342. /* Check for illegal combinations of options */
  343. if (( BAOPEN_RONLY & *mode) &&
  344. ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
  345. #ifdef VERBOSE
  346. printf("illegal -- trying to open both read only and write only\n");
  347. #endif
  348. return -1;
  349. }
  350. if ( (BAREAD & *mode ) && (BAWRITE & *mode) ) {
  351. #ifdef VERBOSE
  352. printf("illegal -- trying to both read and write in the same call\n");
  353. #endif
  354. return -2;
  355. }
  356. /* This section handles Fortran to C translation of strings so as to */
  357. /* be able to open the files Fortran is expecting to be opened. */
  358. #ifdef CRAY90
  359. namelen = _fcdlen(fcd_fname);
  360. fname = _fcdtocp(fcd_fname);
  361. #endif
  362. if ( (BAOPEN_RONLY & *mode) || (BAOPEN_WONLY & *mode) ||
  363. (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ||
  364. (BAOPEN_RW & *mode) ) {
  365. #ifdef VERBOSE
  366. printf("Will be opening a file %s %d\n", fname, namelen); fflush(stdout);
  367. printf("Strlen %d namelen %d\n", strlen(fname), namelen); fflush(stdout);
  368. #endif
  369. realname = (char *) malloc( namelen * sizeof(char) ) ;
  370. if (realname == NULL) {
  371. #ifdef VERBOSE
  372. printf("failed to mallocate realname %d = namelen\n", namelen);
  373. fflush(stdout);
  374. #endif
  375. return -3;
  376. }
  377. tempchar = (char *) malloc(sizeof(char) * 1 ) ;
  378. i = 0;
  379. j = 0;
  380. *tempchar = fname[i];
  381. tcharval = *tempchar;
  382. while (i == j && i < namelen ) {
  383. fflush(stdout);
  384. if ( isgraph(tcharval) ) {
  385. realname[j] = fname[i];
  386. j += 1;
  387. }
  388. i += 1;
  389. *tempchar = fname[i];
  390. tcharval = *tempchar;
  391. }
  392. #ifdef VERBOSE
  393. printf("i,j = %d %d\n",i,j); fflush(stdout);
  394. #endif
  395. realname[j] = '\0';
  396. }
  397. /* Open files with correct read/write and file permission. */
  398. if (BAOPEN_RONLY & *mode) {
  399. #ifdef VERBOSE
  400. printf("open read only %s\n", realname);
  401. #endif
  402. *fdes = open(realname, O_RDONLY , S_IRWXU | S_IRWXG | S_IRWXO );
  403. }
  404. else if (BAOPEN_WONLY & *mode ) {
  405. #ifdef VERBOSE
  406. printf("open write only %s\n", realname);
  407. #endif
  408. *fdes = open(realname, O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  409. }
  410. else if (BAOPEN_WONLY_TRUNC & *mode ) {
  411. #ifdef VERBOSE
  412. printf("open write only with truncation %s\n", realname);
  413. #endif
  414. *fdes = open(realname, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU | S_IRWXG | S_IRWXO );
  415. }
  416. else if (BAOPEN_WONLY_APPEND & *mode ) {
  417. #ifdef VERBOSE
  418. printf("open write only with append %s\n", realname);
  419. #endif
  420. *fdes = open(realname, O_WRONLY | O_CREAT | O_APPEND , S_IRWXU | S_IRWXG | S_IRWXO );
  421. }
  422. else if (BAOPEN_RW & *mode) {
  423. #ifdef VERBOSE
  424. printf("open read-write %s\n", realname);
  425. #endif
  426. *fdes = open(realname, O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  427. }
  428. else {
  429. #ifdef VERBOSE
  430. printf("no openings\n");
  431. #endif
  432. }
  433. if (*fdes < 0) {
  434. #ifdef VERBOSE
  435. printf("error in file descriptor! *fdes %d\n", *fdes);
  436. #endif
  437. return -4;
  438. }
  439. else {
  440. #ifdef VERBOSE
  441. printf("file descriptor = %d\n",*fdes );
  442. #endif
  443. }
  444. /* Read data as requested */
  445. if (BAREAD & *mode &&
  446. ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
  447. #ifdef VERBOSE
  448. printf("Error, trying to read while in write only mode!\n");
  449. #endif
  450. return -5;
  451. }
  452. else if (BAREAD & *mode ) {
  453. /* Read in some data */
  454. if (! (*mode & NOSEEK) ) {
  455. seekret = lseek(*fdes, *start, SEEK_SET);
  456. if (seekret == -1) {
  457. #ifdef VERBOSE
  458. printf("error in seeking to %d\n",*start);
  459. #endif
  460. return -6;
  461. }
  462. #ifdef VERBOSE
  463. else {
  464. printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
  465. }
  466. #endif
  467. }
  468. jret = read(*fdes, datary, *no*(*size) );
  469. if (jret != *no*(*size) ) {
  470. #ifdef VERBOSE
  471. printf("did not read in the requested number of items\n");
  472. printf("read in %d items of %d \n",jret/(*size), *no);
  473. #endif
  474. *nactual = jret/(*size);
  475. *newpos = *start + jret;
  476. }
  477. #ifdef VERBOSE
  478. printf("read in %d items \n", jret/(*size));
  479. #endif
  480. *nactual = jret/(*size);
  481. *newpos = *start + jret;
  482. }
  483. /* Done with reading */
  484. /* See if we should be writing */
  485. if ( BAWRITE & *mode && BAOPEN_RONLY & *mode ) {
  486. #ifdef VERBOSE
  487. printf("Trying to write on a read only file \n");
  488. #endif
  489. return -7;
  490. }
  491. else if ( BAWRITE & *mode ) {
  492. if (! (*mode & NOSEEK) ) {
  493. seekret = lseek(*fdes, *start, SEEK_SET);
  494. if (seekret == -1) {
  495. #ifdef VERBOSE
  496. printf("error in seeking to %d\n",*start);
  497. #endif
  498. return -8;
  499. }
  500. #ifdef VERBOSE
  501. else {
  502. printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
  503. }
  504. #endif
  505. }
  506. jret = write(*fdes, datary, *no*(*size));
  507. if (jret != *no*(*size)) {
  508. #ifdef VERBOSE
  509. printf("did not write out the requested number of items\n");
  510. printf("wrote %d items instead\n", jret/(*size) );
  511. #endif
  512. *nactual = jret/(*size) ;
  513. *newpos = *start + jret;
  514. }
  515. else {
  516. #ifdef VERBOSE
  517. printf("wrote %d items \n", jret/(*size) );
  518. #endif
  519. *nactual = jret/(*size) ;
  520. *newpos = *start + jret;
  521. }
  522. }
  523. /* Done with writing */
  524. /* Close file if requested */
  525. if (BACLOSE & *mode ) {
  526. jret = close(*fdes);
  527. if (jret != 0) {
  528. #ifdef VERBOSE
  529. printf("close failed! jret = %d\n",jret);
  530. #endif
  531. return -9;
  532. }
  533. }
  534. /* Done closing */
  535. /* Check that if we were reading or writing, that we actually got what */
  536. /* we expected, else return a -10. Return 0 (success) if we're here */
  537. /* and weren't reading or writing */
  538. if ( (*mode & BAREAD || *mode & BAWRITE) && (*nactual != *no) ) {
  539. return -10;
  540. }
  541. else {
  542. return 0;
  543. }
  544. }