|
|
1.1 moko 1: /** @file
2: Parser: implementation of apr functions.
3:
1.7 ! moko 4: Copyright (c) 2000-2023 Art. Lebedev Studio (http://www.artlebedev.com)
! 5: Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
1.1 moko 6: */
7:
8: #include "pa_file_io.h"
9: #include "pa_memory.h"
10: #include "pa_os.h"
11:
1.7 ! moko 12: volatile const char * IDENT_PA_FILE_IO_C="$Id: pa_file_io.C,v 1.6 2020/12/15 17:10:33 moko Exp $";
1.2 moko 13:
1.1 moko 14: struct pa_file_t {
15: int handle;
16: };
17:
18: pa_status_t pa_file_open(pa_file_t **new_file, const char *fname,
19: pa_int32_t flag, pa_fileperms_t perm,
20: pa_pool_t *)
21: {
22: int oflags = 0;
23: #if PA_HAS_THREADS
24: pa_status_t rv;
25: #endif
26:
27: (*new_file) = (pa_file_t*)pa_malloc_atomic(sizeof(pa_file_t));
28: // (*new_file)->flags = flag;
29: (*new_file)->handle = -1;
30:
31: if ((flag & PA_READ) && (flag & PA_WRITE)) {
32: oflags = O_RDWR;
33: }
34: else if (flag & PA_READ) {
35: oflags = O_RDONLY;
36: }
37: else if (flag & PA_WRITE) {
38: oflags = O_WRONLY;
39: }
40: else {
41: return PA_EACCES;
42: }
43:
44: if (flag & PA_CREATE) {
45: oflags |= O_CREAT;
46: if (flag & PA_EXCL) {
47: oflags |= O_EXCL;
48: }
49: }
50: if ((flag & PA_EXCL) && !(flag & PA_CREATE)) {
51: return PA_EACCES;
52: }
53:
54: if (flag & PA_APPEND) {
55: oflags |= O_APPEND;
56: }
57: if (flag & PA_TRUNCATE) {
58: oflags |= O_TRUNC;
59: }
60: #ifdef O_BINARY
61: if (flag & PA_BINARY) {
62: oflags |= O_BINARY;
63: }
64: #endif
65:
66: if(((*new_file)->handle = open(fname, oflags, /*pa_unix_perms2mode*/(perm))) <0 )
67: return errno;
68:
69: return PA_SUCCESS;
70: }
71:
72: pa_status_t pa_file_close(pa_file_t *file)
73: {
74: return close(file->handle);
75: }
76:
77: pa_status_t pa_file_lock(pa_file_t *file, int type)
78: {
79: if(type & PA_FLOCK_NONBLOCK)
80: pa_lock_exclusive_blocking(file->handle);
81:
82: if ((type & PA_FLOCK_TYPEMASK) == PA_FLOCK_SHARED)
83: return pa_lock_shared_blocking(file->handle);
84:
85: return pa_lock_exclusive_blocking(file->handle);
86: }
87:
88: pa_status_t pa_file_unlock(pa_file_t *file)
89: {
90: return pa_unlock(file->handle);
91: }
92:
93: pa_status_t pa_file_info_get(pa_finfo_t *finfo,
94: pa_int32_t /*wanted*/,
95: pa_file_t *file)
96: {
97: struct stat info;
98:
99: if (fstat(file->handle, &info) == 0) {
100: finfo->size=info.st_size;
101: return PA_SUCCESS;
102: }
103: else {
104: return errno;
105: }
106: }
107:
108:
109: pa_status_t pa_file_seek(pa_file_t *file,
110: pa_seek_where_t where,
111: pa_off_t *offset)
112: {
113: pa_off_t rv = lseek(file->handle, *offset, where);
114: *offset = rv;
115: return rv == -1? errno: PA_SUCCESS;
116: }
117:
118:
119: pa_status_t pa_file_read_full(pa_file_t *file, void *buf,
120: pa_size_t nbytes,
121: pa_size_t *p_bytes_read)
122: {
123: int l_bytes_read = read(file->handle, buf, nbytes);
1.5 moko 124: if (l_bytes_read == 0) {
1.1 moko 125: return PA_EOF;
1.5 moko 126: } else if (l_bytes_read == -1) {
1.1 moko 127: return errno;
1.5 moko 128: }
1.1 moko 129:
130: if(p_bytes_read)
131: *p_bytes_read=(pa_size_t)l_bytes_read;
132:
133: return PA_SUCCESS;
134: }
135:
136:
137: pa_status_t pa_file_write_full(pa_file_t *file, const void *buf,
138: pa_size_t nbytes,
139: pa_size_t *bytes_written)
140: {
141: pa_size_t rv;
142: do {
143: rv = write(file->handle, buf, nbytes);
144: } while (rv == (pa_size_t)-1 && errno == EINTR);
145:
146: if (rv == (pa_size_t)-1) {
147: if(bytes_written)
148: *bytes_written = 0;
149: return errno;
150: }
151: if(bytes_written)
152: *bytes_written=rv;
153: return PA_SUCCESS;
154: }