LibC: Fix and cleanup stdio mode string parsing
The code is now much cleaner andd we are not as strict with the mode string. Also add support for new 'e' and 'x' modifiers
This commit is contained in:
@@ -170,21 +170,49 @@ int fclose(FILE* file)
|
|||||||
|
|
||||||
static mode_t parse_mode_string(const char* mode_str)
|
static mode_t parse_mode_string(const char* mode_str)
|
||||||
{
|
{
|
||||||
size_t len = strlen(mode_str);
|
mode_t mode = 0;
|
||||||
if (len == 0 || len > 3)
|
|
||||||
return 0;
|
|
||||||
if (len == 3 && mode_str[1] == mode_str[2])
|
|
||||||
return 0;
|
|
||||||
if (strspn(mode_str + 1, "tb+") != len - 1)
|
|
||||||
return 0;
|
|
||||||
bool plus = (mode_str[1] == '+' || mode_str[2] == '+');
|
|
||||||
switch (mode_str[0])
|
switch (mode_str[0])
|
||||||
{
|
{
|
||||||
case 'r': return plus ? O_RDWR : O_RDONLY;
|
case 'r':
|
||||||
case 'w': return plus ? O_RDWR | O_CREAT | O_TRUNC : O_WRONLY | O_CREAT | O_TRUNC;
|
break;
|
||||||
case 'a': return plus ? O_RDWR | O_CREAT | O_APPEND : O_WRONLY | O_CREAT | O_APPEND;
|
case 'w':
|
||||||
|
mode |= O_CREAT | O_TRUNC;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
mode |= O_CREAT | O_APPEND;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
bool plus = false;
|
||||||
|
for (size_t i = 1; mode_str[i]; i++)
|
||||||
|
{
|
||||||
|
switch (mode_str[i])
|
||||||
|
{
|
||||||
|
case 'b':
|
||||||
|
case 't':
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
mode |= O_CLOEXEC;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
mode |= O_CREAT | O_EXCL;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
mode |= O_RDWR;
|
||||||
|
plus = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!plus)
|
||||||
|
mode |= (mode_str[0] == 'r') ? O_RDONLY : O_WRONLY;
|
||||||
|
|
||||||
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* fdopen(int fd, const char* mode_str)
|
FILE* fdopen(int fd, const char* mode_str)
|
||||||
|
|||||||
Reference in New Issue
Block a user