be6f80b229974299f07b6a8057037cdd667c9721
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / fileIO.c
1 /*\r
2 AcessOS Basic C Library\r
3 */\r
4 #include "config.h"\r
5 #include <acess/sys.h>\r
6 #include <stdlib.h>\r
7 #include <stdio.h>\r
8 #include "stdio_int.h"\r
9 \r
10 #define DEBUG_BUILD     0\r
11 \r
12 // === CONSTANTS ===\r
13 \r
14 // === PROTOTYPES ===\r
15 struct sFILE    *get_file_struct();\r
16 \r
17 // === GLOBALS ===\r
18 struct sFILE    _iob[STDIO_MAX_STREAMS];        // IO Buffer\r
19 \r
20 // === CODE ===\r
21 /**\r
22  * \fn FILE *freopen(FILE *fp, char *file, char *mode)\r
23  */\r
24 FILE *freopen(FILE *fp, char *file, char *mode)\r
25 {\r
26          int    openFlags = 0;\r
27          int    i;\r
28         \r
29         // Sanity Check Arguments\r
30         if(!fp || !file || !mode)       return NULL;\r
31         \r
32         if(fp->Flags) {\r
33                 fflush(fp);\r
34                 close(fp->FD);\r
35         }\r
36         \r
37         // Get main mode\r
38         switch(mode[0])\r
39         {\r
40         case 'r':       fp->Flags = FILE_FLAG_MODE_READ;        break;\r
41         case 'w':       fp->Flags = FILE_FLAG_MODE_WRITE;       break;\r
42         case 'a':       fp->Flags = FILE_FLAG_MODE_APPEND;      break;\r
43         case 'x':       fp->Flags = FILE_FLAG_MODE_EXEC;        break;\r
44         default:\r
45                 return NULL;\r
46         }\r
47         // Get Modifiers\r
48         for(i=1;mode[i];i++)\r
49         {\r
50                 switch(mode[i])\r
51                 {\r
52                 case '+':       fp->Flags |= FILE_FLAG_M_EXT;\r
53                 }\r
54         }\r
55         \r
56         // Get Open Flags\r
57         switch(mode[0])\r
58         {\r
59         // Read\r
60         case 'r':       openFlags = OPENFLAG_READ;\r
61                 if(fp->Flags & FILE_FLAG_M_EXT)\r
62                         openFlags |= OPENFLAG_WRITE;\r
63                 break;\r
64         // Write\r
65         case 'w':       openFlags = OPENFLAG_WRITE;\r
66                 if(fp->Flags & FILE_FLAG_M_EXT)\r
67                         openFlags |= OPENFLAG_READ;\r
68                 break;\r
69         // Execute\r
70         case 'x':       openFlags = OPENFLAG_EXEC;\r
71                 break;\r
72         }\r
73         \r
74         //Open File\r
75         fp->FD = reopen(fp->FD, file, openFlags);\r
76         if(fp->FD == -1) {\r
77                 fp->Flags = 0;\r
78                 return NULL;\r
79         }\r
80         \r
81         if(mode[0] == 'a') {\r
82                 seek(fp->FD, 0, SEEK_END);      //SEEK_END\r
83         }\r
84         \r
85         return fp;\r
86 }\r
87 /**\r
88  \fn FILE *fopen(char *file, char *mode)\r
89  \brief Opens a file and returns the pointer\r
90  \param file    String - Filename to open\r
91  \param mode    Mode to open in\r
92 */\r
93 FILE *fopen(char *file, char *mode)\r
94 {\r
95         FILE    *retFile;\r
96         \r
97         // Sanity Check Arguments\r
98         if(!file || !mode)      return NULL;\r
99         \r
100         // Create Return Structure\r
101         retFile = get_file_struct();\r
102         \r
103         return freopen(retFile, file, mode);\r
104 }\r
105 \r
106 void fclose(FILE *fp)\r
107 {\r
108         close(fp->FD);\r
109         free(fp);\r
110 }\r
111 \r
112 void fflush(FILE *fp)\r
113 {\r
114         ///\todo Implement\r
115 }\r
116 \r
117 /**\r
118  * \fn int fprintf(FILE *fp, const char *format, ...)\r
119  * \brief Print a formatted string to a stream\r
120  */\r
121 int fprintf(FILE *fp, const char *format, ...)\r
122 {\r
123          int    size;\r
124         char    *buf;\r
125         va_list args;\r
126         \r
127         if(!fp || !format)      return -1;\r
128         \r
129         // Get Size\r
130         va_start(args, format);\r
131         size = ssprintfv((char*)format, args);\r
132         va_end(args);\r
133         \r
134         // Allocate buffer\r
135         buf = (char*)malloc(size+1);\r
136         buf[size] = '\0';\r
137         \r
138         // Print\r
139         va_start(args, format);\r
140         sprintfv(buf, (char*)format, args);\r
141         va_end(args);\r
142         \r
143         // Write to stream\r
144         write(fp->FD, size+1, buf);\r
145         \r
146         // Free buffer\r
147         free(buf);\r
148         \r
149         // Return written byte count\r
150         return size;\r
151 }\r
152 \r
153 // --- INTERNAL ---\r
154 /**\r
155  * \fn FILE *get_file_struct()\r
156  * \brief Returns a file descriptor structure\r
157  */\r
158 FILE *get_file_struct()\r
159 {\r
160          int    i;\r
161         for(i=0;i<STDIO_MAX_STREAMS;i++)\r
162         {\r
163                 if(_iob[i].Flags == 0)  return &_iob[i];\r
164         }\r
165         return NULL;\r
166 }\r

UCC git Repository :: git.ucc.asn.au