blob: 98b857df87c9c37d68a78d2aa5547ad7daaa15eb [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000 Silicon Graphics, Inc.
* All Rights Reserved.
*/
/**************************************************************
*
* OS Testing - Silicon Graphics, Inc.
*
* FUNCTION NAME : parse_open_flags
* openflags2symbols
*
* FUNCTION TITLE : converts open flag symbols into bitmask
* converts open flag bitmask into symbols
*
* SYNOPSIS:
* int parse_open_flags(symbols, badname)
* char *symbols;
* char **badname;
*
* char *openflags2symbols(openflags, sep, mode)
* int openflags;
* char *sep;
* int mode;
*
* AUTHOR : Richard Logan
*
* CO-PILOT(s) : Dean Roehrich
*
* INITIAL RELEASE : UNICOS 8.0
*
* DESIGN DESCRIPTION
* The parse_open_flags function can be used to convert
* a list of comma separated open(2) flag symbols (i.e. O_TRUNC)
* into the bitmask that can be used by open(2).
* If a symbol is unknown and <badname> is not NULL, <badname>
* will updated to point that symbol in <string>.
* Parse_open_flags will return -1 on this error.
* Otherwise parse_open_flags will return the open flag bitmask.
* If parse_open_flags returns, <string> will left unchanged.
*
* The openflags2symbols function attempts to convert open flag
* bits into human readable symbols (i.e. O_TRUNC). If there
* are more than one symbol, the <sep> string will be placed as
* a separator between symbols. Commonly used separators would
* be a comma "," or pipe "|". If <mode> is one and not all
* <openflags> bits can be converted to symbols, the "UNKNOWN"
* symbol will be added to return string.
* Openflags2symbols will return the indentified symbols.
* If no symbols are recognized the return value will be a empty
* string or the "UNKNOWN" symbol.
*
* SPECIAL REQUIREMENTS
* None.
*
* UPDATE HISTORY
* This should contain the description, author, and date of any
* "interesting" modifications (i.e. info should helpful in
* maintaining/enhancing this module).
* username description
* ----------------------------------------------------------------
* rrl This code was first created during the beginning
* of the SFS testing days. I think that was in 1993.
* This code was updated in 05/96.
* (05/96) openflags2symbols was written.
*
* BUGS/LIMITATIONS
* Currently (05/96) all known symbols are coded into openflags2symbols.
* If new open flags are added this code will have to updated
* to know about them or they will not be recognized.
*
**************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/param.h>
#include <string.h> /* strcat */
#include "open_flags.h"
#define UNKNOWN_SYMBOL "UNKNOWN"
static char Open_symbols[512]; /* space for openflags2symbols return value */
struct open_flag_t {
char *symbol;
int flag;
};
static struct open_flag_t Open_flags[] = {
{ "O_RDONLY", O_RDONLY },
{ "O_WRONLY", O_WRONLY },
{ "O_RDWR", O_RDWR },
{ "O_SYNC", O_SYNC },
{ "O_CREAT", O_CREAT },
{ "O_TRUNC", O_TRUNC },
{ "O_EXCL", O_EXCL },
{ "O_APPEND", O_APPEND },
{ "O_NONBLOCK", O_NONBLOCK },
#if O_NOCTTY
{ "O_NOCTTY", O_NOCTTY },
#endif
#if O_DSYNC
{ "O_DSYNC", O_DSYNC },
#endif
#if O_RSYNC
{ "O_RSYNC", O_RSYNC },
#endif
#if O_ASYNC
{ "O_ASYNC", O_ASYNC },
#endif
#if O_PTYIGN
{ "O_PTYIGN", O_PTYIGN },
#endif
#if O_NDELAY
{ "O_NDELAY", O_NDELAY },
#endif
#if O_RAW
{ "O_RAW", O_RAW },
#endif
#ifdef O_SSD
{ "O_SSD", O_SSD },
#endif
#if O_BIG
{ "O_BIG", O_BIG },
#endif
#if O_PLACE
{ "O_PLACE", O_PLACE },
#endif
#if O_RESTART
{ "O_RESTART", O_RESTART },
#endif
#if O_SFSXOP
{ "O_SFSXOP", O_SFSXOP },
#endif
#if O_SFS_DEFER_TM
{ "O_SFS_DEFER_TM", O_SFS_DEFER_TM },
#endif
#if O_WELLFORMED
{ "O_WELLFORMED", O_WELLFORMED },
#endif
#if O_LDRAW
{ "O_LDRAW", O_LDRAW },
#endif
#if O_T3D
{ "O_T3D", O_T3D },
#endif /* O_T3D */
#if O_PARALLEL
{ "O_PARALLEL", O_PARALLEL },
{ "O_FSA", O_PARALLEL|O_WELLFORMED|O_RAW }, /* short cut */
#endif /* O_PARALLEL */
#ifdef O_LARGEFILE
{ "O_LARGEFILE", O_LARGEFILE },
#endif
#ifdef O_DIRECT
{ "O_DIRECT", O_DIRECT },
#endif
#ifdef O_PRIV
{ "O_PRIV", O_PRIV },
#endif
};
int
parse_open_flags(char *string, char **badname)
{
int bits = 0;
char *name;
char *cc;
char savecc;
int found;
int ind;
name=string;
cc=name;
while ( 1 ) {
for(; ((*cc != ',') && (*cc != '\0')); cc++);
savecc = *cc;
*cc = '\0';
found = 0;
for(ind=0; ind < sizeof(Open_flags)/sizeof(struct open_flag_t); ind++) {
if ( strcmp(name, Open_flags[ind].symbol) == 0 ) {
bits |= Open_flags[ind].flag;
found=1;
break;
}
}
*cc = savecc; /* restore string */
if ( found == 0 ) { /* invalid name */
if ( badname != NULL )
*badname = name;
return -1;
}
if ( savecc == '\0' )
break;
name = ++cc;
} /* end while */
return bits;
} /* end of parse_open_flags */
char *
openflags2symbols(int openflags, char *sep, int mode)
{
int ind;
int size;
int bits = openflags;
int havesome=0;
Open_symbols[0]='\0';
size=sizeof(Open_flags)/sizeof(struct open_flag_t);
/*
* Deal with special case of O_RDONLY. If O_WRONLY nor O_RDWR
* bits are not set, assume O_RDONLY.
*/
if ( (bits & (O_WRONLY | O_RDWR)) == 0 ) {
strcat(Open_symbols, "O_RDONLY");
havesome=1;
}
/*
* Loop through all but O_RDONLY elments of Open_flags
*/
for(ind=1; ind < size; ind++) {
if ( (bits & Open_flags[ind].flag) == Open_flags[ind].flag ) {
if ( havesome )
strcat(Open_symbols, sep);
strcat(Open_symbols, Open_flags[ind].symbol);
havesome++;
/* remove flag bits from bits */
bits = bits & (~Open_flags[ind].flag);
}
}
/*
* If not all bits were identified and mode was equal to 1,
* added UNKNOWN_SYMBOL to return string
*/
if ( bits && mode == 1 ) { /* not all bits were identified */
if ( havesome )
strcat(Open_symbols, sep);
strcat(Open_symbols, UNKNOWN_SYMBOL);
}
return Open_symbols;
} /* end of openflags2symbols */
#ifdef UNIT_TEST
/*
* The following code provides a UNIT test main for
* parse_open_flags and openflags2symbols functions.
*/
int
main(argc, argv)
int argc;
char **argv;
{
int bits;
int ret;
char *err;
if (argc == 1 ) {
printf("Usage: %s openflagsbits\n\t%s symbols\n", argv[0], argv[0]);
exit(1);
}
if ( sscanf(argv[1], "%i", &bits) == 1 ) {
printf("openflags2symbols(%#o, \",\", 1) returned %s\n",
bits, openflags2symbols(bits, ",", 1));
} else {
ret=parse_open_flags(argv[1], &err);
if ( ret == -1 )
printf("parse_open_flags(%s, &err) returned -1, err = %s\n",
argv[0], err);
else
printf("parse_open_flags(%s, &err) returned %#o\n", argv[0], ret);
}
exit(0);
}
#endif /* end of UNIT_TEST */