SIONlib  1.7.3
Scalable I/O library for parallel access to task-local files
sion_file.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** SIONLIB http://www.fz-juelich.de/jsc/sionlib **
3 *****************************************************************************
4 ** Copyright (c) 2008-2019 **
5 ** Forschungszentrum Juelich, Juelich Supercomputing Centre **
6 ** **
7 ** See the file COPYRIGHT in the package base directory for details **
8 ****************************************************************************/
9 
14 #define _XOPEN_SOURCE 700
15 
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <time.h>
20 #include <assert.h>
21 
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <errno.h>
27 
28 #include "sion.h"
29 #include "sion_debug.h"
30 #include "sion_error_handler.h"
31 #include "sion_internal.h"
32 #include "sion_file.h"
33 
42 _sion_fileptr *_sion_file_open(const char *fname, unsigned int flags, unsigned int addflags) {
43 
44  if(flags & SION_FILE_FLAG_ANSI) {
46  sion_fileptr->flags |= SION_FILE_FLAG_ANSI;
47 
48  if(flags & SION_FILE_FLAG_WRITE) {
49  sion_fileptr->flags |= SION_FILE_FLAG_WRITE;
50 
51  if(flags & SION_FILE_FLAG_CREATE) {
52  sion_fileptr->flags |= SION_FILE_FLAG_CREATE;
53  sion_fileptr->fileptr=_sion_file_open_ansi_write_create(fname,addflags);
54  } else {
55  sion_fileptr->fileptr=_sion_file_open_ansi_write_existing(fname,addflags);
56  }
57  } else {
58  sion_fileptr->flags |= SION_FILE_FLAG_READ;
59  sion_fileptr->fileptr=_sion_file_open_ansi_read(fname,addflags);
60  }
61 
62  /* could not open ANSI file */
63  if(!sion_fileptr->fileptr) {
64  free(sion_fileptr);
65  _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_WARN,"error: could not open file (ANSI), %s %d %d, aborting ...\n", fname, flags, addflags);
66  return(NULL);
67  }
68 
69  return(sion_fileptr);
70  } else if (flags & SION_FILE_FLAG_POSIX) {
72  sion_fileptr->flags |= SION_FILE_FLAG_POSIX;
73 
74  if(flags & SION_FILE_FLAG_WRITE) {
75  sion_fileptr->flags |= SION_FILE_FLAG_WRITE;
76  if(flags & SION_FILE_FLAG_CREATE) {
77  sion_fileptr->flags |= SION_FILE_FLAG_CREATE;
78  sion_fileptr->fd=_sion_file_open_posix_write_create(fname,addflags);
79  } else {
80  sion_fileptr->fd=_sion_file_open_posix_write_existing(fname,addflags);
81  }
82  } else {
83  sion_fileptr->flags |= SION_FILE_FLAG_READ;
84  sion_fileptr->fd=_sion_file_open_posix_read(fname,addflags);
85  }
86 
87  /* could not open POSIX file */
88  if(sion_fileptr->fd<0) {
89  free(sion_fileptr);
90  _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_WARN,"error: could not open file (POSIX), %s %d %d, aborting ...\n", fname, flags, addflags);
91  return(NULL);
92  }
93 
94  return(sion_fileptr);
95  } else {
96  /* unknown mode? */
97  _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_WARN,"internal error: unknown open type, %s %d %d, aborting ...\n", fname, flags, addflags);
98  return(NULL);
99  }
100 }
101 
102 #define DFUNCTION "_sion_file_close"
103 
109 int _sion_file_close( _sion_fileptr *sion_fileptr ) {
110  if (NULL == sion_fileptr) return SION_NOT_SUCCESS;
111 
112  int rc;
113  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
114  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
115  _sion_file_close_ansi(sion_fileptr->second_fileptr);
116  sion_fileptr->second_fileptr=NULL;
117  }
118  rc=_sion_file_close_ansi(sion_fileptr->fileptr);
119  sion_fileptr->fileptr=NULL;
120  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
121  rc=_sion_file_close_posix(sion_fileptr->fd);
122  } else {
123  rc = SION_NOT_SUCCESS;
124  }
125 
126  DPRINTFP((32, DFUNCTION, -1, "free now fileptr=%x %d rc=%d\n",sion_fileptr,sion_fileptr->flags,rc));
127  free(sion_fileptr);
128 
129  return (rc);
130 }
131 #undef DFUNCTION
132 
141 sion_int64 _sion_file_write(const void *data, sion_int64 bytes, _sion_fileptr *sion_fileptr ) {
142  if (NULL == sion_fileptr) return SION_SIZE_NOT_VALID;
143 
144  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
145  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI)
146  return _sion_file_write_ansi(data,bytes,sion_fileptr->second_fileptr);
147  else
148  return _sion_file_write_ansi(data,bytes,sion_fileptr->fileptr);
149  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
150  return _sion_file_write_posix(data,bytes,sion_fileptr->fd);
151  } else {
152  return _sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_file_write: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
153  }
154 }
155 
166 sion_int64 _sion_file_read(void *data, sion_int64 bytes, _sion_fileptr *sion_fileptr ) {
167  if (NULL == sion_fileptr) return SION_SIZE_NOT_VALID;
168 
169  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
170  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI)
171  return _sion_file_read_ansi(data,bytes,sion_fileptr->second_fileptr);
172  else
173  return _sion_file_read_ansi(data,bytes,sion_fileptr->fileptr);
174  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
175  return _sion_file_read_posix(data,bytes,sion_fileptr->fd);
176  } else {
177  return _sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_file_read: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
178  }
179 }
180 
188  if (NULL == sion_fileptr) return SION_SIZE_NOT_VALID;
189 
190  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
191  return _sion_file_get_opt_blksize_ansi(sion_fileptr->fileptr);
192  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
193  return _sion_file_get_opt_blksize_posix(sion_fileptr->fd);
194  } else {
195  return _sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_file_get_opt_blksize: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
196  }
197 }
198 
205 int _sion_file_stat_file(const char *fname) {
206 #if defined(_SION_LINUX) || defined(_SION_DARWIN) || defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
207  struct stat sbuf;
208  return 0 == stat(fname, &sbuf);
209 #endif
210 }
211 
219 sion_int64 _sion_file_set_position( _sion_fileptr *sion_fileptr, sion_int64 startpointer ) {
220  if (NULL == sion_fileptr) return SION_SIZE_NOT_VALID;
221 
222  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
223  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
224  return _sion_file_set_position_ansi(sion_fileptr->second_fileptr, startpointer);
225  } else {
226  return _sion_file_set_position_ansi(sion_fileptr->fileptr, startpointer);
227  }
228  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
229  return _sion_file_set_position_posix(sion_fileptr->fd, startpointer);
230  } else {
231  return _sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_file_set_position: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
232  }
233 }
234 
241 sion_int64 _sion_file_get_position( _sion_fileptr *sion_fileptr ) {
242  if (NULL == sion_fileptr) return SION_SIZE_NOT_VALID;
243 
244  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
245  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
246  return _sion_file_get_position_ansi(sion_fileptr->second_fileptr);
247  } else {
248  return _sion_file_get_position_ansi(sion_fileptr->fileptr);
249  }
250  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
251  return _sion_file_get_position_posix(sion_fileptr->fd);
252  } else {
253  return _sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_file_get_position: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
254  }
255 }
256 
263 int _sion_file_flush( _sion_fileptr *sion_fileptr ) {
264  if (NULL == sion_fileptr) return SION_NOT_SUCCESS;
265 
266  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
267  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
268  return _sion_file_flush_ansi(sion_fileptr->second_fileptr);
269  } else {
270  return _sion_file_flush_ansi(sion_fileptr->fileptr);
271  }
272  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
273  return _sion_file_flush_posix(sion_fileptr->fd);
274  } else {
275  return _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_file_flush: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
276  }
277 }
278 
285 int _sion_file_purge( _sion_fileptr *sion_fileptr ) {
286  if( sion_fileptr == NULL ) return SION_NOT_SUCCESS;
287 
288  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
289  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
290  return _sion_file_purge_ansi(sion_fileptr->second_fileptr);
291  } else {
292  return _sion_file_purge_ansi(sion_fileptr->fileptr);
293  }
294  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
295  return _sion_file_purge_posix(sion_fileptr->fd);
296  } else {
297  return _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_file_purge: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
298  }
299 }
300 
309 int _sion_file_set_buffer(_sion_fileptr *sion_fileptr, char *buffer, sion_int32 buffer_size) {
310  if( sion_fileptr == NULL ) return SION_NOT_SUCCESS;
311 
312  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
313  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
314  return _sion_file_set_buffer_ansi(sion_fileptr->second_fileptr, buffer, buffer_size);
315  } else {
316  return _sion_file_set_buffer_ansi(sion_fileptr->fileptr, buffer, buffer_size);
317  }
318  } else if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
319  return _sion_file_set_buffer_posix(sion_fileptr->fd, buffer, buffer_size);
320  } else {
321  return _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_file_set_buffer: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
322  }
323 }
324 
332 int _sion_file_set_second_fileptr( _sion_fileptr *sion_fileptr, FILE* fileptr) {
333  if( sion_fileptr == NULL ) return SION_NOT_SUCCESS;
334 
335  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
336  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
337  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"internal error: second fileptr already set, aborting ...\n"));
338  } else {
339  sion_fileptr->flags |= SION_FILE_FLAG_SCNDANSI;
340  sion_fileptr->second_fileptr=fileptr;
341  return SION_SUCCESS;
342  }
343  } else {
344  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"internal error: second fileptr could not be set for non-ANSI file, aborting ...\n"));
345  }
346 }
347 
355  if( sion_fileptr == NULL ) return SION_NOT_SUCCESS;
356 
357  if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
358  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
359  sion_fileptr->flags &= ~SION_FILE_FLAG_SCNDANSI;
360  sion_fileptr->second_fileptr=NULL;
361  return SION_SUCCESS;
362  } else {
363  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"internal error: second fileptr was not set, aborting ...\n"));
364  }
365  } else {
366  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"internal error: second fileptr could not be unset for non-ANSI file, aborting ...\n"));
367  }
368 }
369 
376 int _sion_file_get_fd( _sion_fileptr *sion_fileptr) {
377  if( sion_fileptr == NULL ) return SION_ID_UNDEF;
378 
379  if(sion_fileptr->flags & SION_FILE_FLAG_POSIX) {
380  return sion_fileptr->fd;
381  } else if(sion_fileptr->flags & SION_FILE_FLAG_ANSI) {
382  if(sion_fileptr->flags & SION_FILE_FLAG_SCNDANSI) {
383  return fileno(sion_fileptr->second_fileptr);
384  } else {
385  return fileno(sion_fileptr->fileptr);
386  }
387  } else {
388  return _sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"_sion_file_get_fd: cannot find valid file flag (flags=%d)\n",sion_fileptr->flags);
389  }
390 }
391 
392 /* ********************************************************************************************** */
393 /* *** INTERFACE Functions */
394 /* ********************************************************************************************** */
395 
403 FILE *_sion_file_open_ansi_write_create(const char *fname, unsigned int addflags) {
404 #if defined(_SION_LINUX) || defined(_SION_DARWIN)
405  return fopen(fname, "w");
406 #elif defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
407  int fd = open64(fname, O_CREAT | O_RDWR, 0664);
408  return fdopen(fd, "w");
409 #else
410 #error "No platform selected."
411  return NULL;
412 #endif
413 }
414 
422 FILE *_sion_file_open_ansi_write_existing(const char *fname, unsigned int addflags) {
423 #if defined(_SION_LINUX) || defined(_SION_DARWIN)
424  /* changed from w to r+ to prevent time truncation of empty existing file */
425  return fopen(fname, "r+");
426 #elif defined(_SION_AIX)
427  int fd = open64(fname, O_CREAT | O_RDWR, 0664);
428  return fdopen(fd, "r+");
429 #elif defined(_SION_BGP) || defined(_SION_BGQ)
430  int fd = open64(fname, O_RDWR, 0664);
431  return fdopen(fd, "r+");
432 #else
433 #error "No platform selected."
434  return NULL;
435 #endif
436 }
437 
445 FILE *_sion_file_open_ansi_read(const char *fname, unsigned int addflags) {
446 #if defined(_SION_LINUX) || defined(_SION_DARWIN)
447  return fopen(fname, "r");
448 #elif defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
449  int fd = open64(fname, O_RDONLY, 0664);
450  return fdopen(fd, "r");
451 #else
452 #error "No platform selected."
453  return NULL;
454 #endif
455 }
456 
463 int _sion_file_close_ansi(FILE *fileptr) {
464 #if defined(_SION_LINUX) || defined(_SION_DARWIN) || defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
465  return (0 == fclose(fileptr)) ? SION_SUCCESS : SION_NOT_SUCCESS;
466 #else
467 #error "No platform selected."
468  return SION_NOT_SUCCESS;
469 #endif
470 }
471 
478 long _sion_file_get_opt_blksize_ansi( FILE *fileptr ) {
479 #if defined(_SION_LINUX) || defined(_SION_DARWIN) || defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
480  int fd = fileno(fileptr);
481  struct stat sbuf;
482  if (fstat(fd, &sbuf) == 0) {
483  return sbuf.st_blksize;
484  } else {
485  return SION_SIZE_NOT_VALID;
486  }
487 #else
488 #error "No platform selected."
489  return SION_SIZE_NOT_VALID;
490 #endif
491 }
492 
500 sion_int64 _sion_file_set_position_ansi(FILE *fileptr, sion_int64 startpointer) {
501  sion_int64 newpos;
502 
503  DPRINTFP((32, "_sion_set_position_ansi", -1, "enter (to %lld) (to %ld)\n", (long long) startpointer, (long) startpointer));
504 
505 #if defined(_SION_LINUX) || defined(_SION_BGP) || defined(_SION_BGQ)
506  off_t offset = (off_t) startpointer;
507  if (offset != startpointer) {
508  DPRINTFP((32, "_sion_set_position_ansi", -1, "_sion_set_position_ansi: cannot set position to %ld (%zu),%lld (%zu) offset conversion error\n",
509  offset, sizeof(offset), startpointer, sizeof(startpointer)));
510  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_set_position_ansi: cannot set position to %ld (%zu),%lld (%zu) offset conversion error\n",
511  offset, sizeof(offset), startpointer, sizeof(startpointer)));
512  }
513  int fd = fileno(fileptr);
514  off_t result;
515  newpos = result = lseek(fd, offset, SEEK_SET);
516 #if defined(_SION_LINUX)
517  DPRINTFP((1024, "_sion_set_position_ansi", -1, "set position=%lld (LINUX)\n", (long long) result));
518 #endif
519 #elif defined(_SION_DARWIN)
520  long offset = (long) startpointer;
521  if (offset != startpointer) {
522  DPRINTFP((32, "_sion_set_position_ansi", -1, "_sion_set_position_ansi: cannot set position to %ld (%zu),%lld (%zu) offset conversion error\n",
523  offset, sizeof(offset), startpointer, sizeof(startpointer)));
524  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_set_position_ansi: cannot set position to %ld (%zu),%lld (%zu) offset conversion error\n",
525  offset, sizeof(offset), startpointer, sizeof(startpointer)));
526  }
527  off_t result;
528  newpos = result = fseek(fileptr, offset, SEEK_SET);
529  DPRINTFP((1024, "_sion_set_position_ansi", -1, "set position=%lld (LINUX)\n", (long long) result));
530 #elif defined(_SION_AIX)
531  off64_t offset = (off_t) startpointer;
532  off64_t result;
533  if (offset != startpointer) {
534  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_set_position_ansi: cannot set position to %ld (%zu),%lld (%zu) offset conversion error\n",
535  offset, sizeof(offset), startpointer, sizeof(startpointer)));
536  }
537  result = fseeko64(fileptr, offset, SEEK_SET);
538  newpos = result = ftello64(fileptr);
539 #else
540 #error "No platform selected."
541  newpos = SION_SIZE_NOT_VALID;
542 #endif
543  DPRINTFP((32, "_sion_set_position_ansi", -1, "leave (%lld --> %lld)\n",(long long) startpointer, (long long) newpos));
544 
545  return newpos;
546 }
547 
554 sion_int64 _sion_file_get_position_ansi(FILE *fileptr) {
555  sion_int64 result;
556 
557 #if defined(_SION_LINUX)
558  off_t resulto;
559  int fd = fileno(fileptr);
560  resulto = lseek(fd,0,SEEK_CUR);
561  result = (sion_int64) resulto;
562  DPRINTFP((4096, "_sion_get_position", -1, "get position=%ld (LINUX)\n", (long) result));
563 #elif defined(_SION_DARWIN)
564  off_t resulto;
565  resulto = ftello(fileptr);
566  result = (sion_int64) resulto;
567  DPRINTFP((4096, "_sion_get_position", -1, "get position=%ld (DARWIN)\n", (long) result));
568 #elif defined(_SION_AIX)
569  result = ftell(fileptr);
570  DPRINTFP((4096, "_sion_get_position", -1, "got position=%lld (AIX)\n", result));
571 #elif defined(_SION_BGP)
572  off_t resulto;
573  int fd = fileno(fileptr);
574  resulto = lseek(fd, 0, SEEK_CUR);
575  result = (sion_int64) resulto;
576  DPRINTFP((4096, "_sion_get_position", -1, "got position=%lld (BGP)\n", result));
577 #elif defined(_SION_BGQ)
578  off_t resulto;
579  int fd = fileno(fileptr);
580  resulto = lseek(fd, 0, SEEK_CUR);
581  result = (sion_int64) resulto;
582  DPRINTFP((4096, "_sion_get_position", -1, "got position=%lld (BGQ)\n", result));
583 #else
584 #error "No platform selected."
585  result = SION_SIZE_NOT_VALID;
586 #endif
587 
588  return (result);
589 }
590 
597 int _sion_file_flush_ansi(FILE *fileptr) {
598  return (0 == fflush(fileptr)) ? SION_SUCCESS : SION_NOT_SUCCESS;
599 }
600 
607 int _sion_file_purge_ansi(FILE *fileptr) {
608  return _sion_file_flush_ansi(fileptr);
609 }
610 
619 int _sion_file_set_buffer_ansi(FILE *fileptr, char *buffer, sion_int32 buffer_size) {
620  DPRINTFP((32, "_sion_file_set_buffer", -1, "set buffer of fileptr\n"));
621  return (0 == setvbuf(fileptr, buffer, _IOFBF, (size_t) buffer_size)) ? SION_SUCCESS : SION_NOT_SUCCESS;
622 }
623 
632 sion_int64 _sion_file_write_ansi(const void *data, sion_int64 bytes, FILE *fileptr ) {
633  return (bytes == fwrite(data, 1, bytes, fileptr)) ? bytes : -1;
634 }
635 
646 sion_int64 _sion_file_read_ansi(void *data, sion_int64 bytes, FILE *fileptr ) {
647  if (fread(data, 1, bytes, fileptr) < bytes) {
648  if (feof(fileptr)) {
649  return bytes;
650  } else {
651  return -1;
652  }
653  } else {
654  return bytes;
655  }
656 }
657 
665 int _sion_file_open_posix_write_create(const char *fname, unsigned int addflags) {
666  int fd;
667 
668 #if defined(_SION_LINUX) || defined(_SION_DARWIN)
669  do {
670  fd = open(fname, O_CREAT | O_RDWR, 0664);
671  } while (-1 == fd && EINTR == errno);
672 #elif defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
673  do {
674  fd = open64(fname, O_CREAT | O_RDWR, 0664);
675  } while (-1 == fd && EINTR == errno);
676 #else
677 #error "No platform selected."
678  fd = -1;
679 #endif
680 
681  return fd;
682 }
683 
691 int _sion_file_open_posix_write_existing(const char *fname, unsigned int addflags) {
692  int fd;
693 
694 #if defined(_SION_LINUX) || defined(_SION_DARWIN)
695  do {
696  fd = open(fname, O_RDWR, 0664);
697  } while (-1 == fd && EINTR == errno);
698 #elif defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
699  do {
700  fd = open64(fname, O_RDWR, 0664);
701  } while (-1 == fd && EINTR == errno);
702 #else
703 #error "No platform selected."
704  fd = -1;
705 #endif
706 
707  return fd;
708 }
709 
717 int _sion_file_open_posix_read(const char *fname, unsigned int addflags) {
718  int fd;
719 
720 #if defined(_SION_LINUX) || defined(_SION_DARWIN)
721  do {
722  fd = open(fname, O_RDONLY, 0664);
723  } while (-1 == fd && EINTR == errno);
724 #elif defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
725  do {
726  fd = open64(fname, O_RDONLY, 0664);
727  } while (-1 == fd && EINTR == errno);
728 #else
729 #error "No platform selected."
730  fd = -1;
731 #endif
732 
733  return (fd);
734 }
735 
743 #if defined(_SION_LINUX) || defined(_SION_DARWIN) || defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
744  return (0 == close(fd)) ? SION_SUCCESS : SION_NOT_SUCCESS;
745 #else
746 #error "No platform selected."
747  return SION_NOT_SUCCESS;
748 #endif
749 }
750 
758 #if defined(_SION_LINUX) || defined(_SION_DARWIN) || defined(_SION_AIX) || defined(_SION_BGP) || defined(_SION_BGQ)
759  struct stat sbuf;
760  if (fstat(fd, &sbuf) == 0) {
761  return sbuf.st_blksize;
762  } else {
763  return SION_SIZE_NOT_VALID;
764  }
765 #else
766 #error "No platform selected."
767  return SION_SIZE_NOT_VALID;
768 #endif
769 }
770 
778 sion_int64 _sion_file_set_position_posix(int fd, sion_int64 startpointer) {
779  sion_int64 newpos = SION_SIZE_NOT_VALID;
780 
781  DPRINTFP((32, "_sion_set_position_posix", -1, "enter (to %lld)\n", (long long) startpointer));
782 
783 #if defined(_SION_LINUX) || defined(_SION_DARWIN) || defined(_SION_BGP) || defined(_SION_BGQ)
784  off_t offset = (off_t) startpointer;
785  if (offset != startpointer) {
786  return (_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_set_position_posix: cannot set position to %ld (%zu),%lld (%zu) offset conversion error\n",
787  offset, sizeof(offset), startpointer, sizeof(startpointer)));
788  }
789  off_t result;
790  newpos = result = lseek(fd, offset, SEEK_SET);
791 #if defined(_SION_LINUX) || defined(_SION_DARWIN)
792  DPRINTFP((4096, "_sion_set_position_posix", -1, "set position=%lld (LINUX)\n", (long long) result));
793 #endif
794 #elif defined(_SION_AIX)
795  off64_t offset = (off_t) startpointer;
796  off64_t result;
797  if (offset != startpointer) {
798  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"_sion_set_position_posix: cannot set position to %ld (%zu),%lld (%zu) offset conversion error\n",
799  offset, sizeof(offset), startpointer, sizeof(startpointer)));
800  }
801  newpos = result = lseek(fd, offset, SEEK_SET);
802 #else
803 #error "No platform selected."
804  newpos = SION_SIZE_NOT_VALID;
805 #endif
806  DPRINTFP((32, "_sion_set_position_posix", -1, "leave (to %lld)\n",(long long) startpointer));
807 
808  return newpos;
809 }
810 
817 sion_int64 _sion_file_get_position_posix(int fd) {
818  sion_int64 result=SION_SIZE_NOT_VALID;
819 
820  off_t resulto;
821  resulto = lseek(fd,0,SEEK_CUR);
822  result = (sion_int64) resulto;
823 
824 #if defined(_SION_LINUX)
825  DPRINTFP((4096, "_sion_get_position", -1, "get position=%ld (LINUX)\n", (long) result));
826 #elif defined(_SION_DARWIN)
827  DPRINTFP((4096, "_sion_get_position", -1, "get position=%ld (DARWIN)\n", (long) result));
828 #elif defined(_SION_AIX)
829  DPRINTFP((4096, "_sion_get_position", -1, "get position=%ld (AIX)\n", (long) result));
830 #elif defined(_SION_BGP)
831  DPRINTFP((4096, "_sion_get_position", -1, "get position=%ld (BGP)\n", (long) result));
832 #elif defined(_SION_BGQ)
833  DPRINTFP((4096, "_sion_get_position", -1, "get position=%ld (BGQ)\n", (long) result));
834 #endif
835 
836  return (result);
837 }
838 
846  int frc;
847 
848 #if defined(_SION_BGQ)
849  /* BGQ 20.09.13: bad fsync performance since V1R2M1, try without */
850  frc = 0;
851 #else
852  do {
853  frc = fsync(fd);
854  } while (frc != 0 && EINTR == errno);
855 #endif
856 
857  return (0 == frc) ? SION_SUCCESS : SION_NOT_SUCCESS;
858 }
859 
869  int frc;
870 
871 #if defined(_SION_BGQ)
872  /* BGQ 20.09.13: bad fsync performance since V1R2M1, try without */
873  frc = 1
874 #else
875  do {
876  frc = fsync(fd);
877  } while (frc != 0 && EINTR == errno);
878 #endif
879 
880  return (0 == frc) ? SION_SUCCESS : SION_NOT_SUCCESS;
881 }
882 
891 int _sion_file_set_buffer_posix(int fd, char *buffer, sion_int32 buffer_size) {
892  DPRINTFP((32, "_sion_file_set_buffer", -1, "set buffer of fileptr\n"));
893  return SION_SUCCESS;
894 }
895 
904 sion_int64 _sion_file_write_posix(const void *data, sion_int64 bytes, int fd ) {
905  ssize_t n = 0, k;
906  while (1) {
907  k = write(fd, data, bytes);
908  if (k == -1) {
909  if (errno != EINTR) {
910  // I/O error, return -1
911  return -1;
912  } // else, interrupted before starting, retry
913  } else if (k == bytes) {
914  // requested amount has been written
915  return n + k;
916  } else {
917  // k < bytes, presumably interrupted or no space left, retry
918  // - retry after interruption should continue
919  // - retry with no space left should lead to error
920  bytes -= k;
921  n += k;
922  data = (char*)data + k;
923  }
924  }
925 }
926 
937 sion_int64 _sion_file_read_posix(void *data, sion_int64 bytes, int fd ) {
938  ssize_t n = 0, k;
939  while (1) {
940  k = read(fd, data, bytes);
941  if (k == -1) {
942  if (errno != EINTR) {
943  // I/O error, return -1
944  return -1;
945  } // else, interrupted before starting, retry
946  } else if (k == 0) {
947  // presumably EOF, return number of bytes read up to here
948  return n;
949  } else if (k == bytes) {
950  // requested amount has been read
951  return n + k;
952  } else {
953  // k < bytes, presumably interrupted or EOF, retry
954  // - retry after interruption should continue
955  // - retry at EOF should lead to k == 0 next
956  bytes -= k;
957  n += k;
958  data = (char*)data + k;
959  }
960  }
961 }
962 
968  _sion_fileptr *sion_fileptr;
969 
970  sion_fileptr = (_sion_fileptr *) malloc(sizeof(_sion_fileptr));
971  if (sion_fileptr == NULL) {
972  _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"cannot allocate _sion_fileptr structure of size %lu (_sion_fileptr), aborting ...\n",
973  (unsigned long) sizeof(_sion_fileptr));
974  return(NULL);
975  }
976  sion_fileptr->fileptr = NULL;
977  sion_fileptr->second_fileptr = NULL;
978  sion_fileptr->fd = -1;
979  sion_fileptr->flags = 0;
980 
981  return (sion_fileptr);
982 }
983 
984 #define STR_PRT(X) case X: return # X
985 
988 char* _sion_fileptrflags_to_str (unsigned int flag) {
989  switch (flag) {
990  STR_PRT(SION_FILE_FLAG_ANSI);
991  STR_PRT(SION_FILE_FLAG_SCNDANSI);
992  STR_PRT(SION_FILE_FLAG_POSIX);
993  STR_PRT(SION_FILE_FLAG_CREATE);
994  STR_PRT(SION_FILE_FLAG_WRITE);
995  STR_PRT(SION_FILE_FLAG_READ);
996  }
997  return "";
998 }
999 
1004  int flags;
1005  if(!sion_fileptr) return("<undefined>");
1006  flags = sion_fileptr->flags;
1007 
1008  if(flags & SION_FILE_FLAG_ANSI) {
1009  if(flags & SION_FILE_FLAG_WRITE) {
1010  if(flags & SION_FILE_FLAG_CREATE) {
1011  return("<ANSI,WRITE,CREATE>");
1012  } else {
1013  return("<ANSI,WRITE>");
1014  }
1015  } else {
1016  return("<ANSI,READ>");
1017  }
1018  } else {
1019  if (flags & SION_FILE_FLAG_POSIX) {
1020  if(flags & SION_FILE_FLAG_WRITE) {
1021  if(flags & SION_FILE_FLAG_CREATE) {
1022  return("<POSIX,WRITE,CREATE>");
1023  } else {
1024  return("<POSIX,WRITE>");
1025  }
1026  } else {
1027  return("<POSIX,READ>");
1028  }
1029  }
1030  }
1031  return("<unknown>");
1032 }
sion_int64 _sion_file_write(const void *data, sion_int64 bytes, _sion_fileptr *sion_fileptr)
Write data to file.
Definition: sion_file.c:141
long _sion_file_get_opt_blksize(_sion_fileptr *sion_fileptr)
Get optional file system block size for a file.
Definition: sion_file.c:187
sion_int64 _sion_file_get_position(_sion_fileptr *sion_fileptr)
Get new position in file.
Definition: sion_file.c:241
sion_int64 _sion_file_set_position(_sion_fileptr *sion_fileptr, sion_int64 startpointer)
Set new position in file.
Definition: sion_file.c:219
_sion_fileptr * _sion_file_alloc_and_init_sion_fileptr(void)
Create and return _sion_fileptr.
Definition: sion_file.c:967
_sion_fileptr * _sion_file_open(const char *fname, unsigned int flags, unsigned int addflags)
Create and open a new file for writing.
Definition: sion_file.c:42
char * _sion_fileptrflags_to_str(unsigned int flag)
Definition: sion_file.c:988
long _sion_file_get_opt_blksize_ansi(FILE *fileptr)
ANSI: Get optional file system block size for a file.
Definition: sion_file.c:478
#define SION_FILE_FLAG_WRITE
Definition: sion_file.h:26
int _sion_file_purge(_sion_fileptr *sion_fileptr)
Purge data to file.
Definition: sion_file.c:285
sion_int64 _sion_file_read(void *data, sion_int64 bytes, _sion_fileptr *sion_fileptr)
Read data from file.
Definition: sion_file.c:166
int _sion_file_set_buffer(_sion_fileptr *sion_fileptr, char *buffer, sion_int32 buffer_size)
Set buffer of fp.
Definition: sion_file.c:309
sion_int64 _sion_file_set_position_posix(int fd, sion_int64 startpointer)
POSIX: Set the start position for the current task.
Definition: sion_file.c:778
int _sion_file_get_fd(_sion_fileptr *sion_fileptr)
Utility function: Get POSIX fp.
Definition: sion_file.c:376
#define SION_FILE_FLAG_READ
Definition: sion_file.h:27
sion_int64 _sion_file_set_position_ansi(FILE *fileptr, sion_int64 startpointer)
ANSI: Set the start position for the current task.
Definition: sion_file.c:500
sion_int64 _sion_file_get_position_posix(int fd)
POSIX: Get the current position in file.
Definition: sion_file.c:817
long _sion_file_get_opt_blksize_posix(int fd)
POSIX: Get optional file system block size for a file.
Definition: sion_file.c:757
sion_int64 _sion_file_read_ansi(void *data, sion_int64 bytes, FILE *fileptr)
ANSI: Read data from file.
Definition: sion_file.c:646
#define SION_FILE_FLAG_POSIX
Definition: sion_file.h:24
sion_int64 _sion_file_get_position_ansi(FILE *fileptr)
ANSI: Get the current position in file.
Definition: sion_file.c:554
int _sion_file_set_buffer_ansi(FILE *fileptr, char *buffer, sion_int32 buffer_size)
ANSI: set buffer of fp.
Definition: sion_file.c:619
int _sion_file_stat_file(const char *fname)
Check if file exists (LARGE_FILE support on BlueGene)
Definition: sion_file.c:205
#define SION_FILE_FLAG_ANSI
Definition: sion_file.h:22
#define SION_FILE_FLAG_CREATE
Definition: sion_file.h:25
char * _sion_get_fileptr_desc(_sion_fileptr *sion_fileptr)
Definition: sion_file.c:1003
int _sion_file_close(_sion_fileptr *sion_fileptr)
Close file and destroys fileptr structure.
Definition: sion_file.c:109
FILE * _sion_file_open_ansi_read(const char *fname, unsigned int addflags)
ANSI: Open a file for reading.
Definition: sion_file.c:445
sion_int64 _sion_file_write_ansi(const void *data, sion_int64 bytes, FILE *fileptr)
ANSI: Write data to file.
Definition: sion_file.c:632
int _sion_file_flush_posix(int fd)
POSIX: Flush the data to the disk.
Definition: sion_file.c:845
int _sion_file_set_second_fileptr(_sion_fileptr *sion_fileptr, FILE *fileptr)
Set second fileptr for file if opened with ANSI.
Definition: sion_file.c:332
int _sion_file_unset_second_fileptr(_sion_fileptr *sion_fileptr)
Unset second fileptr for file if opened with ANSI.
Definition: sion_file.c:354
sion_int64 _sion_file_read_posix(void *data, sion_int64 bytes, int fd)
POSIX: Read data from file.
Definition: sion_file.c:937
sion_int64 _sion_file_write_posix(const void *data, sion_int64 bytes, int fd)
POSIX: Write data to file.
Definition: sion_file.c:904
int _sion_file_flush_ansi(FILE *fileptr)
ANSI: Flush the data to the disk.
Definition: sion_file.c:597
FILE * _sion_file_open_ansi_write_create(const char *fname, unsigned int addflags)
ANSI: Create and open a new file for writing.
Definition: sion_file.c:403
int _sion_file_open_posix_write_create(const char *fname, unsigned int addflags)
POSIX: Create and open a new file for writing.
Definition: sion_file.c:665
int _sion_file_open_posix_write_existing(const char *fname, unsigned int addflags)
POSIX: Open a new file for writing.
Definition: sion_file.c:691
int _sion_file_purge_ansi(FILE *fileptr)
ANSI: Purge the data to the disk.
Definition: sion_file.c:607
int _sion_file_open_posix_read(const char *fname, unsigned int addflags)
POSIX: Open a file for reading.
Definition: sion_file.c:717
int _sion_file_flush(_sion_fileptr *sion_fileptr)
Flush data to file.
Definition: sion_file.c:263
FILE * _sion_file_open_ansi_write_existing(const char *fname, unsigned int addflags)
ANSI: Open a new file for writing.
Definition: sion_file.c:422
int _sion_file_purge_posix(int fd)
POSIX: Purge the data to the disk.
Definition: sion_file.c:868
int _sion_file_close_posix(int fd)
POSIX: Close a file.
Definition: sion_file.c:742
int _sion_file_set_buffer_posix(int fd, char *buffer, sion_int32 buffer_size)
POSIX: set buffer of fd.
Definition: sion_file.c:891
int _sion_file_close_ansi(FILE *fileptr)
ANSI: Close a file.
Definition: sion_file.c:463
#define SION_FILE_FLAG_SCNDANSI
Definition: sion_file.h:23