11#include <stdio.h>
2+ #include <stdlib.h>
3+ #include <fcntl.h>
4+ #include <errno.h>
5+
6+ /*
7+ * Return the (stdio) flags for a given mode. Store the flags
8+ * to be passed to an open() syscall through *optr.
9+ * Return 0 on error.
10+ */
11+ int convert_to_stdio_open_flags (const char * mode , int * optr ) {
12+ int ret = 0 , m = 0 , o = 0 ;
13+ switch (* mode ++ ) {
14+ case 'r' : /* open for reading */
15+ ret = 1 ;
16+ m = O_RDONLY ;
17+ o = 0 ;
18+ break ;
19+ case 'w' : /* open for writing */
20+ ret = 2 ;
21+ m = O_WRONLY ;
22+ o = O_CREAT | O_TRUNC ;
23+ break ;
24+ case 'a' : /* open for appending */
25+ ret = 2 ;
26+ m = O_WRONLY ;
27+ o = O_CREAT | O_APPEND ;
28+ break ;
29+ default : /* illegal mode */
30+ errno = EINVAL ;
31+ return 0 ;
32+ }
33+ /* [rwa]\+ or [rwa]b\+ means read and write */
34+ if (* mode == '+' || (* mode == 'b' && mode [1 ] == '+' )) {
35+ ret = 3 ;
36+ m = O_RDWR ;
37+ }
38+ * optr = m | o ;
39+ return ret ;
40+ }
41+
42+ FILE * fopen (const char * file , const char * mode ) {
43+ FILE * fp ;
44+ int f , oflags = 0 ;
45+ if (convert_to_stdio_open_flags (mode , & oflags ) == 0 )
46+ return NULL ;
47+ if ((fp = malloc (sizeof (FILE ))) == NULL )
48+ return NULL ;
49+ if (oflags & O_CREAT ) {
50+ if ((f = open (file , oflags , S_IRWXU )) < 0 )
51+ return NULL ;
52+ } else {
53+ if ((f = open (file , oflags )) < 0 )
54+ return NULL ;
55+ }
56+ fp -> _fileno = f ;
57+ fp -> _mode = oflags ;
58+ return fp ;
59+ }
60+
61+ int get_file_descriptor (FILE * stream ) {
62+ if (stream == stdin ) {
63+ return 0 ;
64+ }
65+ if (stream == stdout ) {
66+ return 1 ;
67+ }
68+ if (stream == stderr ) {
69+ return 2 ;
70+ }
71+ return stream -> _fileno ;
72+ }
273
374int fgetc (FILE * stream ) {
4- int fd = fileno (stream );
75+ if (stream == NULL ) {
76+ return 0 ;
77+ }
78+
79+ int fd = get_file_descriptor (stream );
580 unsigned char buf ;
681 ssize_t read_byte = read (fd , & buf , 1 );
782 if (read_byte == 1 ) {
@@ -12,7 +87,11 @@ int fgetc(FILE *stream) {
1287}
1388
1489int getc (FILE * stream ) {
15- int fd = fileno (stream );
90+ if (stream == NULL ) {
91+ return 0 ;
92+ }
93+
94+ int fd = get_file_descriptor (stream );
1695 unsigned char buf ;
1796 ssize_t read_byte = read (fd , & buf , 1 );
1897 if (read_byte == 1 ) {
@@ -23,18 +102,25 @@ int getc(FILE *stream) {
23102}
24103
25104size_t fread (void * buffer , size_t size , size_t count , FILE * stream ) {
26- int fd = fileno (stream );
105+ if (stream == NULL ) {
106+ return 0 ;
107+ }
108+
109+ int fd = get_file_descriptor (stream );
27110 ssize_t read_byte = read (fd , buffer , size * count );
28111 if (read_byte == -1 ) {
29112 return 0 ;
30113 }
31114 return read_byte / size ;
32115}
33116
34- char * fgets (char * s , int n , FILE * stream )
35- {
117+ char * fgets (char * s , int n , FILE * stream ) {
118+ if (stream == NULL ) {
119+ return 0 ;
120+ }
121+
36122 char * p = s ;
37- if (s == NULL || n <= 0 || ferror ( stream ) || feof ( stream ) ) {
123+ if (s == NULL || n <= 0 ) {
38124 return NULL ;
39125 }
40126
@@ -44,7 +130,7 @@ char* fgets(char *s, int n, FILE *stream)
44130 break ;
45131 }
46132 }
47- if (ferror ( stream ) || ( c == EOF && p == s ) ) {
133+ if (c == EOF && p == s ) {
48134 return NULL ;
49135 }
50136 * p = '\0' ;
@@ -77,7 +163,11 @@ char* gets(char *s)
77163}
78164
79165int fputc (int c , FILE * stream ) {
80- int fd = fileno (stream );
166+ if (stream == NULL ) {
167+ return 0 ;
168+ }
169+
170+ int fd = get_file_descriptor (stream );
81171 unsigned char symb = c ;
82172 int write_byte = write (fd , & symb , 1 );
83173 if (write_byte == 1 ) {
@@ -88,7 +178,11 @@ int fputc(int c, FILE *stream) {
88178}
89179
90180int putc (int c , FILE * stream ) {
91- int fd = fileno (stream );
181+ if (stream == NULL ) {
182+ return 0 ;
183+ }
184+
185+ int fd = get_file_descriptor (stream );
92186 unsigned char symb = c ;
93187 int write_byte = write (fd , & symb , 1 );
94188 if (write_byte == 1 ) {
@@ -99,16 +193,24 @@ int putc(int c, FILE *stream) {
99193}
100194
101195size_t fwrite (const void * buffer , size_t size , size_t count , FILE * stream ) {
102- int fd = fileno (stream );
196+ if (stream == NULL ) {
197+ return 0 ;
198+ }
199+
200+ int fd = get_file_descriptor (stream );
103201 void * cop_buf = buffer ;
104202 int write_byte = write (fd , cop_buf , size * count );
105- if (write == -1 ) {
203+ if (write_byte == -1 ) {
106204 return 0 ;
107205 }
108206 return write_byte / size ;
109207}
110208
111209int fputs (const char * str , FILE * stream ) {
210+ if (stream == NULL ) {
211+ return 0 ;
212+ }
213+
112214 if (str == NULL ) {
113215 return EOF ;
114216 }
0 commit comments