|
|
1.1 moko 1: /** @file
2: Parser: implementation of apr functions.
3:
1.8 moko 4: Copyright (c) 2000-2024 Art. Lebedev Studio (http://www.artlebedev.com)
1.7 moko 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.10 ! moko 12: volatile const char * IDENT_PA_FILE_IO_C="$Id: pa_file_io.C,v 1.9 2024/11/04 17:09:28 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_TYPEMASK) == PA_FLOCK_SHARED)
80: return pa_lock_shared_blocking(file->handle);
81:
82: return pa_lock_exclusive_blocking(file->handle);
83: }
84:
85: pa_status_t pa_file_unlock(pa_file_t *file)
86: {
87: return pa_unlock(file->handle);
88: }
89:
90: pa_status_t pa_file_info_get(pa_finfo_t *finfo,
91: pa_int32_t /*wanted*/,
92: pa_file_t *file)
93: {
94: struct stat info;
95:
96: if (fstat(file->handle, &info) == 0) {
97: finfo->size=info.st_size;
98: return PA_SUCCESS;
99: }
100: else {
101: return errno;
102: }
103: }
104:
105:
106: pa_status_t pa_file_seek(pa_file_t *file,
107: pa_seek_where_t where,
108: pa_off_t *offset)
109: {
110: pa_off_t rv = lseek(file->handle, *offset, where);
111: *offset = rv;
112: return rv == -1? errno: PA_SUCCESS;
113: }
114:
115:
116: pa_status_t pa_file_read_full(pa_file_t *file, void *buf,
117: pa_size_t nbytes,
118: pa_size_t *p_bytes_read)
119: {
120: int l_bytes_read = read(file->handle, buf, nbytes);
1.5 moko 121: if (l_bytes_read == 0) {
1.1 moko 122: return PA_EOF;
1.5 moko 123: } else if (l_bytes_read == -1) {
1.1 moko 124: return errno;
1.5 moko 125: }
1.1 moko 126:
127: if(p_bytes_read)
128: *p_bytes_read=(pa_size_t)l_bytes_read;
129:
130: return PA_SUCCESS;
131: }
132:
133:
134: pa_status_t pa_file_write_full(pa_file_t *file, const void *buf,
135: pa_size_t nbytes,
136: pa_size_t *bytes_written)
137: {
138: pa_size_t rv;
139: do {
140: rv = write(file->handle, buf, nbytes);
141: } while (rv == (pa_size_t)-1 && errno == EINTR);
142:
143: if (rv == (pa_size_t)-1) {
144: if(bytes_written)
145: *bytes_written = 0;
146: return errno;
147: }
148: if(bytes_written)
149: *bytes_written=rv;
150: return PA_SUCCESS;
151: }