Changeset 366 for trunk/System/Sources/libc/src/stdio.c
- Timestamp:
- Mar 11, 2009, 3:34:37 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/System/Sources/libc/src/stdio.c
r330 r366 1 /* $Id: stdio.c,v 1. 75 2008/10/22 14:19:14khorben Exp $ */1 /* $Id: stdio.c,v 1.80 2009/02/24 14:20:57 khorben Exp $ */ 2 2 /* Copyright (c) 2009 Pierre Pronchery <khorben@defora.org> */ 3 3 /* This file is part of DeforaOS System libc */ … … 29 29 30 30 31 /* private */ 31 32 /* types */ 32 33 typedef enum _FILEDirection { FD_READ = 0, FD_WRITE = 1 } FILEDirection; … … 66 67 67 68 68 /* functions */ 69 /* private */ 70 /* PRE 71 * POST 72 * -1 error 73 * else corresponding mode */ 74 static int _fopen_mode(char const * mode) 75 { 76 int flags; 77 78 if(*mode == 'r') 79 { 80 flags = O_RDONLY; 81 if(*++mode == 'b') 82 ++mode; 83 if(*mode == '\0') 84 return flags; 85 if(*mode == '+' && ++mode) 86 flags = O_RDWR; 87 } 88 else if(*mode == 'w') 89 { 90 flags = O_WRONLY | O_CREAT; 91 if(*++mode == 'b') 92 ++mode; 93 if(*mode == '\0') 94 return flags; 95 if(*mode == '+' && ++mode) 96 flags = O_RDWR | O_CREAT; 97 } 98 else if(*mode == 'a') 99 { 100 flags = O_APPEND; 101 if(*++mode == 'b') 102 ++mode; 103 if(*mode == '\0') 104 return flags; 105 if(*mode == '+' && ++mode) 106 flags |= O_CREAT; 107 } 108 else 109 { 110 errno = EINVAL; 111 return -1; 112 } 113 if(*mode == 'b') 114 ++mode; 115 if(*mode != '\0') 116 { 117 errno = EINVAL; 118 return -1; 119 } 120 return flags; 121 } 69 /* prototypes */ 70 static int _fopen_mode(char const * mode); 71 static FILE * _fopen_new(int fd, int flags, int fbuf); 122 72 123 73 … … 145 95 FILE * fdopen(int fd, char const * mode) 146 96 { 147 FILE * file; 148 149 if((file = malloc(sizeof(FILE))) == NULL) 150 return NULL; 151 if((file->flags = _fopen_mode(mode)) == -1) 152 { 153 free(file); 154 return NULL; 155 } 156 file->fd = fd; 157 file->len = 0; 158 file->pos = 0; 159 file->eof = 0; 160 file->error = 0; 161 file->dir = file->flags & O_WRONLY ? FD_WRITE : FD_READ; 162 file->fbuf = isatty(file->fd) ? _IONBF : _IOFBF; 163 return file; 97 return _fopen_new(fd, _fopen_mode(mode), isatty(fd) ? _IONBF : _IOFBF); 164 98 } 165 99 … … 264 198 265 199 /* fopen */ 266 /* FIXME factor code with fdopen() */267 200 FILE * fopen(char const * path, char const * mode) 268 201 { 269 202 FILE * file; 270 271 if((file = malloc(sizeof(FILE))) == NULL) 272 return NULL; 273 if((file->flags = _fopen_mode(mode)) == -1 274 || (file->fd = open(path, file->flags, 0777)) < 0) 275 { 276 free(file); 277 return NULL; 278 } 279 file->len = 0; 280 file->pos = 0; 281 file->eof = 0; 282 file->error = 0; 283 file->dir = file->flags & O_WRONLY ? FD_WRITE : FD_READ; 284 file->fbuf = isatty(file->fd) ? _IONBF : _IOFBF; 203 int flags; 204 int fd; 205 206 if((flags = _fopen_mode(mode)) == -1 207 || (fd = open(path, file->flags, 0777)) < 0) 208 return NULL; 209 if((file = _fopen_new(fd, flags, isatty(fd) ? _IONBF : _IOFBF)) == NULL) 210 { 211 close(fd); 212 return NULL; 213 } 285 214 return file; 286 215 } … … 512 441 if(s != NULL && *s != '\0') 513 442 fprintf(stderr, "%s%s", s, ": "); 443 /* strerror() never returns NULL */ 514 444 fputs(strerror(errno), stderr); 515 445 fputc('\n', stderr); … … 518 448 519 449 /* popen */ 450 static void _popen_child(char const * command, int flags, int * fd); 451 520 452 FILE * popen(char const * command, char const * mode) 521 453 { 522 /* FIXME implement */ 523 errno = ENOSYS; 524 return NULL; 454 int flags; 455 pid_t pid; 456 int fd[2]; 457 int res; 458 459 if((flags = _fopen_mode(mode)) == -1) 460 return NULL; 461 if((res = pipe(fd)) != 0) 462 return NULL; 463 if((pid = fork()) == -1) 464 { 465 close(fd[0]); 466 close(fd[1]); 467 return NULL; 468 } 469 if(pid == 0) /* child */ 470 _popen_child(command, flags, fd); 471 if(flags & O_WRONLY) 472 close(fd[0]); 473 else 474 close(fd[1]); 475 return _fopen_new(flags & O_WRONLY ? fd[1] : fd[0], flags, _IONBF); 476 } 477 478 static void _popen_child(char const * command, int flags, int * fd) 479 { 480 if(flags & O_WRONLY) 481 { 482 close(fd[1]); 483 if(dup2(fd[0], 0) == -1) 484 exit(127); 485 } 486 else 487 { 488 close(fd[0]); 489 if(dup2(fd[1], 1) == -1) 490 exit(127); 491 } 492 execlp("/bin/sh", "sh", "-c", command, NULL); 493 exit(127); 525 494 } 526 495 … … 1128 1097 return ret; 1129 1098 } 1099 1100 1101 /* private */ 1102 /* functions */ 1103 /* fopen_mode */ 1104 /* PRE 1105 * POST 1106 * -1 error 1107 * else corresponding mode */ 1108 static int _fopen_mode(char const * mode) 1109 { 1110 int flags; 1111 1112 if(*mode == 'r') 1113 { 1114 flags = O_RDONLY; 1115 if(*++mode == 'b') 1116 ++mode; 1117 if(*mode == '\0') 1118 return flags; 1119 if(*mode == '+' && ++mode) 1120 flags = O_RDWR; 1121 } 1122 else if(*mode == 'w') 1123 { 1124 flags = O_WRONLY | O_CREAT; 1125 if(*++mode == 'b') 1126 ++mode; 1127 if(*mode == '\0') 1128 return flags; 1129 if(*mode == '+' && ++mode) 1130 flags = O_RDWR | O_CREAT; 1131 } 1132 else if(*mode == 'a') 1133 { 1134 flags = O_APPEND; 1135 if(*++mode == 'b') 1136 ++mode; 1137 if(*mode == '\0') 1138 return flags; 1139 if(*mode == '+' && ++mode) 1140 flags |= O_CREAT; 1141 } 1142 else 1143 { 1144 errno = EINVAL; 1145 return -1; 1146 } 1147 if(*mode == 'b') 1148 ++mode; 1149 if(*mode != '\0') 1150 { 1151 errno = EINVAL; 1152 return -1; 1153 } 1154 return flags; 1155 } 1156 1157 1158 /* fopen_new */ 1159 static FILE * _fopen_new(int fd, int flags, int fbuf) 1160 { 1161 FILE * file; 1162 1163 if(flags == -1) 1164 return NULL; 1165 if((file = malloc(sizeof(*file))) == NULL) 1166 return NULL; 1167 file->flags = flags; 1168 file->fd = fd; 1169 file->len = 0; 1170 file->pos = 0; 1171 file->eof = 0; 1172 file->error = 0; 1173 file->dir = file->flags & O_WRONLY ? FD_WRITE : FD_READ; 1174 file->fbuf = fbuf; 1175 return file; 1176 }
Note: See TracChangeset
for help on using the changeset viewer.