mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-31 11:30:56 +08:00
Importing Egor's testsuite.
This commit is contained in:
parent
312a668a22
commit
42f03f6757
65
winsup/testsuite/libltp/include/dataascii.h
Normal file
65
winsup/testsuite/libltp/include/dataascii.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _DATAASCII_H_
|
||||||
|
#define _DATAASCII_H_
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* int dataasciigen(listofchars, buffer, size, offset)
|
||||||
|
*
|
||||||
|
* This function fills buffer with ascii characters.
|
||||||
|
* The ascii characters are obtained from listofchars or the CHARS array
|
||||||
|
* if listofchars is NULL.
|
||||||
|
* Each char is selected by an index. The index is the remainder
|
||||||
|
* of count divided by the array size.
|
||||||
|
* This method allows more than one process to write to a location
|
||||||
|
* in a file without corrupting it for another process' point of view.
|
||||||
|
*
|
||||||
|
* The return value will be the number of character written in buffer
|
||||||
|
* (size).
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
int dataasciigen(char *, char *, int, int);
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* int dataasciichk(listofchars, buffer, size, count, errmsg)
|
||||||
|
*
|
||||||
|
* This function checks the contents of a buffer produced by
|
||||||
|
* dataasciigen.
|
||||||
|
*
|
||||||
|
* return values:
|
||||||
|
* >= 0 : error at character count
|
||||||
|
* < 0 : no error
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
int dataasciichk(char *, char *, int, int, char**);
|
||||||
|
|
||||||
|
#endif
|
44
winsup/testsuite/libltp/include/databin.h
Normal file
44
winsup/testsuite/libltp/include/databin.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef _DATABIN_H_
|
||||||
|
#define _DATABIN_H_
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* NAME
|
||||||
|
* databingen - fill a buffer with a data pattern
|
||||||
|
*
|
||||||
|
* SYNOPSIS
|
||||||
|
* (void) databingen(mode, buffer, bsize, offset)
|
||||||
|
* int mode;
|
||||||
|
* char *buffer;
|
||||||
|
* int bsize;
|
||||||
|
* int offset;
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* datagen fills the buffer pointed to by 'buffer' with 'bsize' bytes
|
||||||
|
* of data of the form indicated by 'mode'.
|
||||||
|
* All modes (expect r -random) are file offset based.
|
||||||
|
* This allows more than process to do writing to the file without
|
||||||
|
* corrupting it if the same modes were used.
|
||||||
|
* They data modes to choose from, these are:
|
||||||
|
*
|
||||||
|
* 'a' - writes an alternating bit pattern (i.e. 0x5555555...)
|
||||||
|
*
|
||||||
|
* 'c' - writes a checkerboard pattern (i.e. 0xff00ff00ff00...)
|
||||||
|
*
|
||||||
|
* 'C' - writes counting pattern (i.e. 0 - 07, 0 - 07, ...);
|
||||||
|
*
|
||||||
|
* 'o' - writes all bits set (i.e. 0xffffffffffffff...)
|
||||||
|
*
|
||||||
|
* 'z' - writes all bits cleared (i.e. 0x000000000...);
|
||||||
|
*
|
||||||
|
* 'r' - writes random integers
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
void databingen( int mode, unsigned char *buffer, int bsize, int offset );
|
||||||
|
|
||||||
|
void databinchedk( int mode, unsigned char *buffer, int bsize, int offset, char **errmsg);
|
||||||
|
|
||||||
|
#endif
|
40
winsup/testsuite/libltp/include/file_lock.h
Normal file
40
winsup/testsuite/libltp/include/file_lock.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _FILE_LOCK_H_
|
||||||
|
#define _FILE_LOCK_H_
|
||||||
|
|
||||||
|
extern char Fl_syscall_str[128];
|
||||||
|
|
||||||
|
int file_lock( int , int, char ** );
|
||||||
|
int record_lock( int , int , int , int , char ** );
|
||||||
|
|
||||||
|
#endif /* _FILE_LOCK_H_ */
|
63
winsup/testsuite/libltp/include/forker.h
Normal file
63
winsup/testsuite/libltp/include/forker.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _FORKER_H_
|
||||||
|
#define _FORKER_H_
|
||||||
|
|
||||||
|
#define FORKER_MAX_PIDS 4098
|
||||||
|
|
||||||
|
extern int Forker_pids[FORKER_MAX_PIDS]; /* holds pids of forked processes */
|
||||||
|
extern int Forker_npids; /* number of entries in Forker_pids */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function will fork and the parent will exit zero and
|
||||||
|
* the child will return. This will orphan the returning process
|
||||||
|
* putting it in the background.
|
||||||
|
*/
|
||||||
|
int background( char * );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forker will fork ncopies-1 copies of self.
|
||||||
|
*
|
||||||
|
* arg 1: Number of copies of the process to be running after return.
|
||||||
|
* This value minus one is the number of forks performed.
|
||||||
|
* arg 2: mode: 0 - all children are first generation descendents.
|
||||||
|
* 1 - each subsequent child is a descendent of another
|
||||||
|
* descendent, resulting in only one direct descendent of the
|
||||||
|
* parent and each other child is a child of another child in
|
||||||
|
* relation to the parent.
|
||||||
|
* arg 3: prefix: string to preceed any error messages. A value of NULL
|
||||||
|
* results in no error messages on failure.
|
||||||
|
* returns: returns to parent the number of children forked.
|
||||||
|
*/
|
||||||
|
int forker( int , int , char * );
|
||||||
|
|
||||||
|
#endif /* _FORKER_H_ */
|
73
winsup/testsuite/libltp/include/open_flags.h
Normal file
73
winsup/testsuite/libltp/include/open_flags.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _OPEN_FLAGS_H_
|
||||||
|
#define _OPEN_FLAGS_H_
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* This 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.
|
||||||
|
*
|
||||||
|
* Return Value
|
||||||
|
* openflags2symbols will return the indentified symbols.
|
||||||
|
* If no symbols are recognized the return value will be a empty
|
||||||
|
* string or the "UNKNOWN" symbol.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* The Open_symbols must be large enough to hold all possible symbols
|
||||||
|
* for a given system.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
char *openflags2symbols( int, char *, int );
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* This function will take a string of comma separated open flags symbols
|
||||||
|
* and translate them into an open flag bitmask.
|
||||||
|
* If any symbol is not valid, -1 is returned. On this error condition
|
||||||
|
* the badname pointer is updated if not NULL. badname will point
|
||||||
|
* to the beginning location of where the invalid symbol was found.
|
||||||
|
* string will be returned unchanged.
|
||||||
|
*
|
||||||
|
* A signal received while parsing string could cause the string to
|
||||||
|
* contain a NULL character in the middle of it.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
int parse_open_flags( char *, char ** );
|
||||||
|
|
||||||
|
#endif
|
90
winsup/testsuite/libltp/include/pattern.h
Normal file
90
winsup/testsuite/libltp/include/pattern.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _PATTERN_H_
|
||||||
|
#define _PATTERN_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pattern_check(buf, buflen, pat, patlen, patshift)
|
||||||
|
*
|
||||||
|
* Check a buffer of length buflen against repeated occurrances of
|
||||||
|
* a pattern whose length is patlen. Patshift can be used to rotate
|
||||||
|
* the pattern by patshift bytes to the left.
|
||||||
|
*
|
||||||
|
* Patshift may be greater than patlen, the pattern will be rotated by
|
||||||
|
* (patshift % patshift) bytes.
|
||||||
|
*
|
||||||
|
* pattern_check returns -1 if the buffer does not contain repeated
|
||||||
|
* occurrances of the indicated pattern (shifted by patshift).
|
||||||
|
*
|
||||||
|
* The algorithm used to check the buffer relies on the fact that buf is
|
||||||
|
* supposed to be repeated copies of pattern. The basic algorithm is
|
||||||
|
* to validate the first patlen bytes of buf against the pat argument
|
||||||
|
* passed in - then validate the next patlen bytes against the 1st patlen
|
||||||
|
* bytes - the next (2*patlen) bytes against the 1st (2*pathen) bytes, and
|
||||||
|
* so on. This algorithm only works when the assumption of a buffer full
|
||||||
|
* of repeated copies of a pattern holds, and gives MUCH better results
|
||||||
|
* then walking the buffer byte by byte.
|
||||||
|
*
|
||||||
|
* Performance wise, It appears to be about 5% slower than doing a straight
|
||||||
|
* memcmp of 2 buffers, but the big win is that it does not require a
|
||||||
|
* 2nd comparison buffer, only the pattern.
|
||||||
|
*/
|
||||||
|
int pattern_check( char * , int , char * , int , int );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pattern_fill(buf, buflen, pat, patlen, patshift)
|
||||||
|
*
|
||||||
|
* Fill a buffer of length buflen with repeated occurrances of
|
||||||
|
* a pattern whose length is patlen. Patshift can be used to rotate
|
||||||
|
* the pattern by patshift bytes to the left.
|
||||||
|
*
|
||||||
|
* Patshift may be greater than patlen, the pattern will be rotated by
|
||||||
|
* (patshift % patlen) bytes.
|
||||||
|
*
|
||||||
|
* If buflen is not a multiple of patlen, a partial pattern will be written
|
||||||
|
* in the last part of the buffer. This implies that a buffer which is
|
||||||
|
* shorter than the pattern length will receive only a partial pattern ...
|
||||||
|
*
|
||||||
|
* pattern_fill always returns 0 - no validation of arguments is done.
|
||||||
|
*
|
||||||
|
* The algorithm used to fill the buffer relies on the fact that buf is
|
||||||
|
* supposed to be repeated copies of pattern. The basic algorithm is
|
||||||
|
* to fill the first patlen bytes of buf with the pat argument
|
||||||
|
* passed in - then copy the next patlen bytes with the 1st patlen
|
||||||
|
* bytes - the next (2*patlen) bytes with the 1st (2*pathen) bytes, and
|
||||||
|
* so on. This algorithm only works when the assumption of a buffer full
|
||||||
|
* of repeated copies of a pattern holds, and gives MUCH better results
|
||||||
|
* then filling the buffer 1 byte at a time.
|
||||||
|
*/
|
||||||
|
int pattern_fill( char * , int , char * , int , int );
|
||||||
|
|
||||||
|
#endif
|
45
winsup/testsuite/libltp/include/random_range.h
Normal file
45
winsup/testsuite/libltp/include/random_range.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _RANDOM_RANGE_H_
|
||||||
|
#define _RANDOM_RANGE_H_
|
||||||
|
|
||||||
|
int parse_ranges ( char *, int, int, int, int (*)(), char **, char ** );
|
||||||
|
int range_min ( char *, int );
|
||||||
|
int range_max ( char *, int );
|
||||||
|
int range_mult ( char *, int );
|
||||||
|
long random_range ( int, int, int, char ** );
|
||||||
|
long random_rangel ( long, long, long, char ** );
|
||||||
|
long long random_rangell ( long long, long long, long long, char ** );
|
||||||
|
void random_range_seed( long );
|
||||||
|
long random_bit ( long );
|
||||||
|
|
||||||
|
#endif
|
12
winsup/testsuite/libltp/include/rmobj.h
Normal file
12
winsup/testsuite/libltp/include/rmobj.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _RMOBJ_H_
|
||||||
|
#define _RMOBJ_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rmobj() - Remove the specified object. If the specified object is a
|
||||||
|
* directory, recursively remove everything inside of it. If
|
||||||
|
* there are any problems, set errmsg (if it is not NULL) and
|
||||||
|
* return -1. Otherwise return 0.
|
||||||
|
*/
|
||||||
|
int rmobj( char *object , char **errmesg );
|
||||||
|
|
||||||
|
#endif
|
36
winsup/testsuite/libltp/include/search_path.h
Normal file
36
winsup/testsuite/libltp/include/search_path.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
|
||||||
|
int search_path(char *cmd, char *res_path, int access_mode, int fullpath);
|
39
winsup/testsuite/libltp/include/str_to_bytes.h
Normal file
39
winsup/testsuite/libltp/include/str_to_bytes.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _STR_TO_BYTES_
|
||||||
|
#define _STR_TO_BYTES_
|
||||||
|
|
||||||
|
int str_to_bytes ( char * );
|
||||||
|
long str_to_lbytes ( char * );
|
||||||
|
long long str_to_llbytes( char * );
|
||||||
|
|
||||||
|
#endif
|
48
winsup/testsuite/libltp/include/string_to_tokens.h
Normal file
48
winsup/testsuite/libltp/include/string_to_tokens.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _STRING_TO_TOKENS_H_
|
||||||
|
#define _STRING_TO_TOKENS_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* string_to_tokens()
|
||||||
|
*
|
||||||
|
* This function parses the string 'arg_string', placing pointers to
|
||||||
|
* the 'separator' separated tokens into the elements of 'arg_array'.
|
||||||
|
* The array is terminated with a null pointer.
|
||||||
|
*
|
||||||
|
* NOTE: This function uses strtok() to parse 'arg_string', and thus
|
||||||
|
* physically alters 'arg_string' by placing null characters where the
|
||||||
|
* separators originally were.
|
||||||
|
*/
|
||||||
|
int string_to_tokens(char *, char **, int, char *);
|
||||||
|
|
||||||
|
#endif
|
216
winsup/testsuite/libltp/include/test.h
Normal file
216
winsup/testsuite/libltp/include/test.h
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef __TEST_H__
|
||||||
|
#define __TEST_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define TPASS 0 /* Test passed flag */
|
||||||
|
#define TFAIL 1 /* Test failed flag */
|
||||||
|
#define TBROK 2 /* Test broken flag */
|
||||||
|
#define TWARN 4 /* Test warning flag */
|
||||||
|
#define TRETR 8 /* Test retire flag */
|
||||||
|
#define TINFO 16 /* Test information flag */
|
||||||
|
#define TCONF 32 /* Test not appropriate for configuration flag */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To determine if you are on a Umk or Unicos system,
|
||||||
|
* use sysconf(_SC_CRAY_SYSTEM). But since _SC_CRAY_SYSTEM
|
||||||
|
* is not defined until 90, it will be define here if not already
|
||||||
|
* defined.
|
||||||
|
* if ( sysconf(_SC_CRAY_SYSTEM) == 1 )
|
||||||
|
* on UMK
|
||||||
|
* else # returned 0 or -1
|
||||||
|
* on Unicos
|
||||||
|
* This is only being done on CRAY systems.
|
||||||
|
*/
|
||||||
|
#ifdef CRAY
|
||||||
|
#ifndef _SC_CRAY_SYSTEM
|
||||||
|
#define _SC_CRAY_SYSTEM 140
|
||||||
|
#endif /* ! _SC_CRAY_SYSTEM */
|
||||||
|
#endif /* CRAY */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure that NUMSIGS is defined.
|
||||||
|
* It should be defined in signal.h or sys/signal.h on
|
||||||
|
* UNICOS/mk and IRIX systems. On UNICOS systems,
|
||||||
|
* it is not defined, thus it is being set to UNICOS's NSIG.
|
||||||
|
* Note: IRIX's NSIG (signals are 1-(NSIG-1))
|
||||||
|
* is not same meaning as UNICOS/UMK's NSIG (signals 1-NSIG)
|
||||||
|
*/
|
||||||
|
#ifndef NUMSIGS
|
||||||
|
#define NUMSIGS NSIG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* defines for unexpected signal setup routine (set_usig.c) */
|
||||||
|
#define FORK 1 /* SIGCLD is to be ignored */
|
||||||
|
#define NOFORK 0 /* SIGCLD is to be caught */
|
||||||
|
#define DEF_HANDLER 0 /* tells set_usig() to use default signal handler */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following defines are used to control tst_res and t_result reporting.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TOUTPUT "TOUTPUT" /* The name of the environment variable */
|
||||||
|
/* that can be set to one of the following */
|
||||||
|
/* strings to control tst_res output */
|
||||||
|
/* If not set, TOUT_VERBOSE_S is assumed */
|
||||||
|
|
||||||
|
#define TOUT_VERBOSE_S "VERBOSE" /* All test cases reported */
|
||||||
|
#define TOUT_CONDENSE_S "CONDENSE" /* ranges are used where identical messages*/
|
||||||
|
/* occur for sequential test cases */
|
||||||
|
#define TOUT_NOPASS_S "NOPASS" /* No pass test cases are reported */
|
||||||
|
#define TOUT_DISCARD_S "DISCARD" /* No output is reported */
|
||||||
|
|
||||||
|
#define TST_NOBUF "TST_NOBUF" /* The name of the environment variable */
|
||||||
|
/* that can be set to control whether or not */
|
||||||
|
/* tst_res will buffer output into 4096 byte */
|
||||||
|
/* blocks of output */
|
||||||
|
/* If not set, buffer is done. If set, no */
|
||||||
|
/* internal buffering will be done in tst_res */
|
||||||
|
/* t_result does not have internal buffering */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following defines are used to control tst_tmpdir, tst_wildcard and t_mkchdir
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TDIRECTORY "TDIRECTORY" /* The name of the environment variable */
|
||||||
|
/* that if is set, the value (directory) */
|
||||||
|
/* is used by all tests as their working */
|
||||||
|
/* directory. tst_rmdir and t_rmdir will */
|
||||||
|
/* not attempt to clean up. */
|
||||||
|
/* This environment variable should only */
|
||||||
|
/* be set when doing system testing since */
|
||||||
|
/* tests will collide and break and fail */
|
||||||
|
/* because of setting it. */
|
||||||
|
|
||||||
|
#define TEMPDIR "/tmp" /* This is the default temporary directory. */
|
||||||
|
/* The environment variable TMPDIR is */
|
||||||
|
/* used prior to this valid by tempnam(3). */
|
||||||
|
/* To control the base location of the */
|
||||||
|
/* temporary directory, set the TMPDIR */
|
||||||
|
/* environment variable to desired path */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following contains support for error message passing.
|
||||||
|
* See test_error.c for details.
|
||||||
|
*/
|
||||||
|
#define TST_ERR_MESG_SIZE 1023 /* max size of error message */
|
||||||
|
#define TST_ERR_FILE_SIZE 511 /* max size of module name used by compiler */
|
||||||
|
#define TST_ERR_FUNC_SIZE 127 /* max size of func name */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int te_line; /* line where last error was reported. Use */
|
||||||
|
/* "__LINE__" and let compiler do the rest */
|
||||||
|
int te_level; /* If set, will prevent current stored */
|
||||||
|
/* error to not be overwritten */
|
||||||
|
char te_func[TST_ERR_FUNC_SIZE+1]; /* name of function of last error */
|
||||||
|
/* Name of function or NULL */
|
||||||
|
char te_file[TST_ERR_FILE_SIZE+1]; /* module of last error. Use */
|
||||||
|
/* "__FILE__" and let compiler do the rest */
|
||||||
|
char te_mesg[TST_ERR_MESG_SIZE+1]; /* string of last error */
|
||||||
|
|
||||||
|
} _TST_ERROR;
|
||||||
|
|
||||||
|
extern _TST_ERROR Tst_error; /* defined in test_error.c */
|
||||||
|
#if __STDC__
|
||||||
|
extern void tst_set_error(char *file, int line, char *func, char *fmt, ...);
|
||||||
|
#else
|
||||||
|
extern void tst_set_error();
|
||||||
|
#endif
|
||||||
|
extern void tst_clear_error();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following define contains the name of an environmental variable
|
||||||
|
* that can be used to specify the number of iterations.
|
||||||
|
* It is supported in parse_opts.c and USC_setup.c.
|
||||||
|
*/
|
||||||
|
#define USC_ITERATION_ENV "USC_ITERATIONS"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following define contains the name of an environmental variable
|
||||||
|
* that can be used to specify to iteration until desired time
|
||||||
|
* in floating point seconds has gone by.
|
||||||
|
* Supported in USC_setup.c.
|
||||||
|
*/
|
||||||
|
#define USC_LOOP_WALLTIME "USC_LOOP_WALLTIME"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following define contains the name of an environmental variable
|
||||||
|
* that can be used to specify that no functional checks are wanted.
|
||||||
|
* It is supported in parse_opts.c and USC_setup.c.
|
||||||
|
*/
|
||||||
|
#define USC_NO_FUNC_CHECK "USC_NO_FUNC_CHECK"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following define contains the name of an environmental variable
|
||||||
|
* that can be used to specify the delay between each loop iteration.
|
||||||
|
* The value is in seconds (fractional numbers are allowed).
|
||||||
|
* It is supported in parse_opts.c.
|
||||||
|
*/
|
||||||
|
#define USC_LOOP_DELAY "USC_LOOP_DELAY"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following prototypes are needed to remove compile errors
|
||||||
|
* on IRIX systems when compiled with -n32 and -64.
|
||||||
|
*/
|
||||||
|
extern void tst_res(int ttype, char *fname, char *arg_fmt, ...);
|
||||||
|
extern void tst_resm(int ttype, char *arg_fmt, ...);
|
||||||
|
extern void tst_brk(int ttype, char *fname, void (*func)(),
|
||||||
|
char *arg_fmt, ...);
|
||||||
|
extern void tst_brkloop(int ttype, char *fname, void (*func)(),
|
||||||
|
char *arg_fmt, ...);
|
||||||
|
extern void tst_brkm(int ttype, void (*func)(), char *arg_fmt, ...);
|
||||||
|
extern void tst_brkloopm(int ttype, void (*func)(), char *arg_fmt, ...);
|
||||||
|
|
||||||
|
extern int tst_environ();
|
||||||
|
extern void tst_exit();
|
||||||
|
extern void tst_flush();
|
||||||
|
|
||||||
|
/* prototypes for the t_res.c functions */
|
||||||
|
extern void t_result(char *tcid, int tnum, int ttype, char *tmesg);
|
||||||
|
extern void tt_exit();
|
||||||
|
extern int t_environ();
|
||||||
|
extern void t_breakum(char *tcid, int total, int typ, char *msg, void (*fnc)());
|
||||||
|
|
||||||
|
extern void tst_sig(int fork_flag, void (*handler)(), void (*cleanup)());
|
||||||
|
extern void tst_tmpdir();
|
||||||
|
extern void tst_rmdir();
|
||||||
|
|
||||||
|
#endif /* end of __TEST_H__ */
|
148
winsup/testsuite/libltp/include/tlibio.h
Normal file
148
winsup/testsuite/libltp/include/tlibio.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIO_IO_SYNC 00001 /* read/write */
|
||||||
|
#define LIO_IO_ASYNC 00002 /* reada/writea/aio_write/aio_read */
|
||||||
|
#define LIO_IO_SLISTIO 00004 /* single stride sync listio */
|
||||||
|
#define LIO_IO_ALISTIO 00010 /* single stride async listio */
|
||||||
|
#define LIO_IO_SYNCV 00020 /* single-buffer readv/writev */
|
||||||
|
#define LIO_IO_SYNCP 00040 /* pread/pwrite */
|
||||||
|
|
||||||
|
#ifdef sgi
|
||||||
|
#define LIO_IO_ATYPES 00077 /* all io types */
|
||||||
|
#define LIO_IO_TYPES 00061 /* all io types, non-async */
|
||||||
|
#endif /* sgi */
|
||||||
|
#ifdef linux
|
||||||
|
#define LIO_IO_TYPES 00021 /* all io types */
|
||||||
|
#endif /* linux */
|
||||||
|
#ifdef CRAY
|
||||||
|
#define LIO_IO_TYPES 00017 /* all io types */
|
||||||
|
#endif /* CRAY */
|
||||||
|
|
||||||
|
#define LIO_WAIT_NONE 00010000 /* return asap -- use with care */
|
||||||
|
#define LIO_WAIT_ACTIVE 00020000 /* spin looking at iosw fields, or EINPROGRESS */
|
||||||
|
#define LIO_WAIT_RECALL 00040000 /* call recall(2)/aio_suspend(3) */
|
||||||
|
#define LIO_WAIT_SIGPAUSE 00100000 /* call pause */
|
||||||
|
#define LIO_WAIT_SIGACTIVE 00200000 /* spin waiting for signal */
|
||||||
|
#ifdef sgi
|
||||||
|
#define LIO_WAIT_CBSUSPEND 00400000 /* aio_suspend waiting for callback */
|
||||||
|
#define LIO_WAIT_SIGSUSPEND 01000000 /* aio_suspend waiting for signal */
|
||||||
|
#define LIO_WAIT_ATYPES 01760000 /* all async wait types, except nowait */
|
||||||
|
#define LIO_WAIT_TYPES 00020000 /* all sync wait types (sorta) */
|
||||||
|
#endif /* sgi */
|
||||||
|
#ifdef linux
|
||||||
|
#define LIO_WAIT_TYPES 00300000 /* all wait types, except nowait */
|
||||||
|
#endif /* linux */
|
||||||
|
#ifdef CRAY
|
||||||
|
#define LIO_WAIT_TYPES 00360000 /* all wait types, except nowait */
|
||||||
|
#endif /* CRAY */
|
||||||
|
|
||||||
|
/* meta wait io */
|
||||||
|
/* 00 000 0000 */
|
||||||
|
|
||||||
|
#ifdef sgi
|
||||||
|
/* all callback wait types */
|
||||||
|
#define LIO_WAIT_CBTYPES (LIO_WAIT_CBSUSPEND)
|
||||||
|
/* all signal wait types */
|
||||||
|
#define LIO_WAIT_SIGTYPES (LIO_WAIT_SIGPAUSE|LIO_WAIT_SIGACTIVE|LIO_WAIT_SIGSUSPEND)
|
||||||
|
/* all aio_{read,write} or lio_listio */
|
||||||
|
#define LIO_IO_ASYNC_TYPES (LIO_IO_ASYNC|LIO_IO_SLISTIO|LIO_IO_ALISTIO)
|
||||||
|
#endif /* sgi */
|
||||||
|
#ifdef linux
|
||||||
|
/* all signal wait types */
|
||||||
|
#define LIO_WAIT_SIGTYPES (LIO_WAIT_SIGPAUSE)
|
||||||
|
#endif /* linux */
|
||||||
|
#ifdef CRAY
|
||||||
|
/* all signal wait types */
|
||||||
|
#define LIO_WAIT_SIGTYPES (LIO_WAIT_SIGPAUSE|LIO_WAIT_SIGACTIVE)
|
||||||
|
#endif /* CRAY */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This bit provides a way to randomly pick an io type and wait method.
|
||||||
|
* lio_read_buffer() and lio_write_buffer() functions will call
|
||||||
|
* lio_random_methods() with the given method.
|
||||||
|
*/
|
||||||
|
#define LIO_RANDOM 010000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This bit provides a way for the programmer to use async i/o with
|
||||||
|
* signals and to use their own signal handler. By default,
|
||||||
|
* the signal will only be given to the system call if the wait
|
||||||
|
* method is LIO_WAIT_SIGPAUSE or LIO_WAIT_SIGACTIVE.
|
||||||
|
* Whenever these wait methods are used, libio signal handler
|
||||||
|
* will be used.
|
||||||
|
*/
|
||||||
|
#define LIO_USE_SIGNAL 020000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prototypes/structures for functions in the libio.c module. See comments
|
||||||
|
* in that module, or man page entries for information on the individual
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int stride_bounds(int offset, int stride, int nstrides,
|
||||||
|
int bytes_per_stride, int *min_byte, int *max_byte);
|
||||||
|
|
||||||
|
int lio_set_debug(int level);
|
||||||
|
int lio_parse_io_arg1(char *string);
|
||||||
|
void lio_help1(char *prefex);
|
||||||
|
int lio_parse_io_arg2(char *string, char **badtoken);
|
||||||
|
void lio_help2(char *prefex);
|
||||||
|
int lio_write_buffer(int fd, int method, char *buffer, int size,
|
||||||
|
int sig, char **errmsg, long wrd);
|
||||||
|
|
||||||
|
int lio_read_buffer(int fd, int method, char *buffer, int size,
|
||||||
|
int sig, char **errmsg, long wrd);
|
||||||
|
int lio_random_methods(long mask);
|
||||||
|
|
||||||
|
#if CRAY
|
||||||
|
#include <sys/iosw.h>
|
||||||
|
int lio_wait4asyncio(int method, int fd, struct iosw **statptr);
|
||||||
|
int lio_check_asyncio(char *io_type, int size, struct iosw *status);
|
||||||
|
#endif /* CRAY */
|
||||||
|
#ifdef sgi
|
||||||
|
#include <aio.h>
|
||||||
|
int lio_wait4asyncio(int method, int fd, aiocb_t *aiocbp);
|
||||||
|
int lio_check_asyncio(char *io_type, int size, aiocb_t *aiocbp, int method);
|
||||||
|
#endif /* sgi */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the structure that contains the infomation that is used
|
||||||
|
* by the parsing and help functions.
|
||||||
|
*/
|
||||||
|
struct lio_info_type {
|
||||||
|
char *token;
|
||||||
|
int bits;
|
||||||
|
char *desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
319
winsup/testsuite/libltp/include/usctest.h
Normal file
319
winsup/testsuite/libltp/include/usctest.h
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
*
|
||||||
|
* IRIX/Linux Feature Test and Evaluation - Silicon Graphics, Inc.
|
||||||
|
*
|
||||||
|
* FUNCTION NAME : usctest.h
|
||||||
|
*
|
||||||
|
* FUNCTION TITLE : System Call Test Macros
|
||||||
|
*
|
||||||
|
* SYNOPSIS:
|
||||||
|
* See DESCRIPTION below.
|
||||||
|
*
|
||||||
|
* AUTHOR : William Roske
|
||||||
|
*
|
||||||
|
* INITIAL RELEASE : UNICOS 7.0
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* TEST(SCALL) - calls a system call
|
||||||
|
* TEST_VOID(SCALL) - same as TEST() but for syscalls with no return value.
|
||||||
|
* TEST_CLEANUP - print the log of errno return counts if STD_ERRNO_LOG
|
||||||
|
* is set.
|
||||||
|
* TEST_PAUSEF(HAND) - Pause for SIGUSR1 if the pause flag is set.
|
||||||
|
* Use "hand" as the interrupt handling function
|
||||||
|
* TEST_PAUSE - Pause for SIGUSR1 if the pause flag is set.
|
||||||
|
* Use internal function to do nothing on signal and go on.
|
||||||
|
* TEST_LOOPING(COUNTER) - Conditional to check if test should
|
||||||
|
* loop. Evaluates to TRUE (1) or FALSE (0).
|
||||||
|
* TEST_ERROR_LOG(eno) - log that this errno was received,
|
||||||
|
* if STD_ERRNO_LOG is set.
|
||||||
|
* TEST_EXP_ENOS(array) - set the bits in TEST_VALID_ENO array at
|
||||||
|
* positions specified in integer "array"
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* TEST(SCALL) - Global Variables set:
|
||||||
|
* int TEST_RETURN=return code from SCALL
|
||||||
|
* int TEST_ERRNO=value of errno at return from SCALL
|
||||||
|
* TEST_VOID(SCALL) - Global Variables set:
|
||||||
|
* int TEST_ERRNO=value of errno at return from SCALL
|
||||||
|
* TEST_CLEANUP - None.
|
||||||
|
* TEST_PAUSEF(HAND) - None.
|
||||||
|
* TEST_PAUSE - None.
|
||||||
|
* TEST_LOOPING(COUNTER) - True if COUNTER < STD_LOOP_COUNT or
|
||||||
|
* STD_INFINITE is set.
|
||||||
|
* TEST_ERROR_LOG(eno) - None
|
||||||
|
* TEST_EXP_ENOS(array) - None
|
||||||
|
*
|
||||||
|
* KNOWN BUGS
|
||||||
|
* If you use the TEST_PAUSE or TEST_LOOPING macros, you must
|
||||||
|
* link in parse_opts.o, which contains the code for those functions.
|
||||||
|
*
|
||||||
|
*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
|
||||||
|
|
||||||
|
#ifndef __USCTEST_H__
|
||||||
|
#define __USCTEST_H__ 1
|
||||||
|
|
||||||
|
#ifndef _SC_CLK_TCK
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure that PATH_MAX is defined
|
||||||
|
*/
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#ifdef MAXPATHLEN
|
||||||
|
#define PATH_MAX MAXPATHLEN
|
||||||
|
#else
|
||||||
|
#define PATH_MAX 1024
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRAY
|
||||||
|
#ifndef BSIZE
|
||||||
|
#define BSIZE BBSIZE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Define option_t structure type.
|
||||||
|
* Entries in this struct are used by the parse_opts routine
|
||||||
|
* to indicate valid options and return option arguments
|
||||||
|
***********************************************************************/
|
||||||
|
typedef struct {
|
||||||
|
char *option; /* Valid option string (one option only) like "a:" */
|
||||||
|
int *flag; /* pointer to location to set true if option given */
|
||||||
|
char **arg; /* pointer to location to place argument, if needed */
|
||||||
|
} option_t;
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* The following globals are defined in parse_opts.c but must be
|
||||||
|
* externed here because they are used in the macros defined below.
|
||||||
|
***********************************************************************/
|
||||||
|
extern int STD_FUNCTIONAL_TEST, /* turned off by -f to not do functional test */
|
||||||
|
STD_TIMING_ON, /* turned on by -t to print timing stats */
|
||||||
|
STD_PAUSE, /* turned on by -p to pause before loop */
|
||||||
|
STD_INFINITE, /* turned on by -c0 to loop forever */
|
||||||
|
STD_LOOP_COUNT, /* changed by -cn to set loop count to n */
|
||||||
|
STD_ERRNO_LOG, /* turned on by -e to log errnos returned */
|
||||||
|
STD_ERRNO_LIST[], /* counts of errnos returned. indexed by errno */
|
||||||
|
STD_COPIES,
|
||||||
|
STD_argind;
|
||||||
|
|
||||||
|
extern float STD_LOOP_DURATION, /* wall clock time to iterate */
|
||||||
|
STD_LOOP_DELAY; /* delay time after each iteration */
|
||||||
|
|
||||||
|
#define USC_MAX_ERRNO 2000
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Prototype for parse_opts routine
|
||||||
|
**********************************************************************/
|
||||||
|
extern char *parse_opts(int ac, char **av, option_t *user_optarr, void (*uhf)());
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* define a structure
|
||||||
|
*/
|
||||||
|
struct usc_errno_t {
|
||||||
|
int flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
****
|
||||||
|
****
|
||||||
|
****
|
||||||
|
**********************************************************************/
|
||||||
|
#ifdef _USC_LIB_
|
||||||
|
|
||||||
|
extern int TEST_RETURN;
|
||||||
|
extern int TEST_ERRNO;
|
||||||
|
|
||||||
|
#else
|
||||||
|
/***********************************************************************
|
||||||
|
* Global array of bit masks to indicate errnos that are expected.
|
||||||
|
* Bits set by TEST_EXP_ENOS() macro and used by TEST_CLEANUP() macro.
|
||||||
|
***********************************************************************/
|
||||||
|
struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Globals for returning the return code and errno from the system call
|
||||||
|
* test macros.
|
||||||
|
***********************************************************************/
|
||||||
|
int TEST_RETURN;
|
||||||
|
int TEST_ERRNO;
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* temporary variables for determining max and min times in TEST macro
|
||||||
|
***********************************************************************/
|
||||||
|
long btime, etime, tmptime;
|
||||||
|
|
||||||
|
#endif /* _USC_LIB_ */
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* structure for timing accumulator and counters
|
||||||
|
***********************************************************************/
|
||||||
|
struct tblock {
|
||||||
|
long tb_max;
|
||||||
|
long tb_min;
|
||||||
|
long tb_total;
|
||||||
|
long tb_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* The following globals are externed here so that they are accessable
|
||||||
|
* in the macros that follow.
|
||||||
|
***********************************************************************/
|
||||||
|
extern struct tblock tblock;
|
||||||
|
extern void STD_go();
|
||||||
|
extern int (*_TMP_FUNC)(void);
|
||||||
|
extern void STD_opts_help();
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TEST: calls a system call
|
||||||
|
*
|
||||||
|
* parameters:
|
||||||
|
* SCALL = system call and parameters to execute
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
#define TEST(SCALL) TEST_RETURN = (unsigned) SCALL; TEST_ERRNO=errno;
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TEST_VOID: calls a system call
|
||||||
|
*
|
||||||
|
* parameters:
|
||||||
|
* SCALL = system call and parameters to execute
|
||||||
|
*
|
||||||
|
* Note: This is IDENTICAL to the TEST() macro except that it is intended
|
||||||
|
* for use with syscalls returning no values (void syscall()). The
|
||||||
|
* Typecasting nothing (void) into an unsigned integer causes compilation
|
||||||
|
* errors.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
#define TEST_VOID(SCALL) SCALL; TEST_ERRNO=errno;
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TEST_CLEANUP: print system call timing stats and errno log entries
|
||||||
|
* to stdout if STD_TIMING_ON and STD_ERRNO_LOG are set, respectively.
|
||||||
|
* Do NOT print ANY information if no system calls logged.
|
||||||
|
*
|
||||||
|
* parameters:
|
||||||
|
* none
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
#define TEST_CLEANUP \
|
||||||
|
if ( STD_ERRNO_LOG ) { \
|
||||||
|
for (tmptime=0; tmptime<USC_MAX_ERRNO; tmptime++) { \
|
||||||
|
if ( STD_ERRNO_LIST[tmptime] ) { \
|
||||||
|
if ( TEST_VALID_ENO[tmptime].flag ) \
|
||||||
|
tst_resm(TINFO, "ERRNO %d:\tReceived %d Times", \
|
||||||
|
tmptime, STD_ERRNO_LIST[tmptime]); \
|
||||||
|
else \
|
||||||
|
tst_resm(TINFO, \
|
||||||
|
"ERRNO %d:\tReceived %d Times ** UNEXPECTED **", \
|
||||||
|
tmptime, STD_ERRNO_LIST[tmptime]); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TEST_PAUSEF: Pause for SIGUSR1 if the pause flag is set.
|
||||||
|
* Set the user specified function as the interrupt
|
||||||
|
* handler instead of "STD_go"
|
||||||
|
*
|
||||||
|
* parameters:
|
||||||
|
* none
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
#define TEST_PAUSEF(HANDLER) \
|
||||||
|
if ( STD_PAUSE ) { \
|
||||||
|
_TMP_FUNC = (int (*)())signal(SIGUSR1, HANDLER); \
|
||||||
|
pause(); \
|
||||||
|
signal(SIGUSR1, (void (*)())_TMP_FUNC); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TEST_PAUSE: Pause for SIGUSR1 if the pause flag is set.
|
||||||
|
* Just continue when signal comes in.
|
||||||
|
*
|
||||||
|
* parameters:
|
||||||
|
* none
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
#define TEST_PAUSE usc_global_setup_hook();
|
||||||
|
int usc_global_setup_hook();
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TEST_LOOPING now call the usc_test_looping function.
|
||||||
|
* The function will return 1 if the test should continue
|
||||||
|
* iterating.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
#define TEST_LOOPING usc_test_looping
|
||||||
|
int usc_test_looping(int counter);
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TEST_ERROR_LOG(eno): log this errno if STD_ERRNO_LOG flag set
|
||||||
|
*
|
||||||
|
* parameters:
|
||||||
|
* int eno: the errno location in STD_ERRNO_LIST to log.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
#define TEST_ERROR_LOG(eno) \
|
||||||
|
if ( STD_ERRNO_LOG ) \
|
||||||
|
if ( eno < USC_MAX_ERRNO ) \
|
||||||
|
STD_ERRNO_LIST[eno]++; \
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TEST_EXP_ENOS(array): set the bits associated with the nput errnos
|
||||||
|
* in the TEST_VALID_ENO array.
|
||||||
|
*
|
||||||
|
* parameters:
|
||||||
|
* int array[]: a zero terminated array of errnos expected.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
#define TEST_EXP_ENOS(array) \
|
||||||
|
tmptime=0; \
|
||||||
|
while (array[tmptime] != 0) { \
|
||||||
|
if (array[tmptime] < USC_MAX_ERRNO) \
|
||||||
|
TEST_VALID_ENO[array[tmptime]].flag=1; \
|
||||||
|
tmptime++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* end of __USCTEST_H__ */
|
169
winsup/testsuite/libltp/include/write_log.h
Normal file
169
winsup/testsuite/libltp/include/write_log.h
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#ifndef _WRITE_LOG_H_
|
||||||
|
#define _WRITE_LOG_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constants defining the max size of various wlog_rec fields. ANY SIZE
|
||||||
|
* CHANGES HERE MUST BE REFLECTED IN THE WLOG_REC_DISK STRUCTURE DEFINED
|
||||||
|
* BELOW.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WLOG_MAX_PATH 128
|
||||||
|
#define WLOG_MAX_PATTERN 64
|
||||||
|
#define WLOG_MAX_HOST 8
|
||||||
|
#define WLOG_REC_MAX_SIZE (sizeof(struct wlog_rec)+WLOG_MAX_PATH+WLOG_MAX_PATTERN+WLOG_MAX_HOST+2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User view of a write log record. Note that this is not necessiliary
|
||||||
|
* how the data is formatted on disk (signifigant compression occurrs), so
|
||||||
|
* don't expect to od the write log file and see things formatted this way.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct wlog_rec {
|
||||||
|
int w_pid; /* pid doing the write */
|
||||||
|
int w_offset; /* file offset */
|
||||||
|
int w_nbytes; /* # bytes written */
|
||||||
|
int w_oflags; /* low-order open() flags */
|
||||||
|
int w_done; /* 1 if io confirmed done */
|
||||||
|
int w_async; /* 1 if async write (writea) */
|
||||||
|
|
||||||
|
char w_host[WLOG_MAX_HOST+1]; /* host doing write - */
|
||||||
|
/* null terminated */
|
||||||
|
int w_hostlen; /* host name length */
|
||||||
|
char w_path[WLOG_MAX_PATH+1]; /* file written to - */
|
||||||
|
/* null terminated */
|
||||||
|
int w_pathlen; /* file name length */
|
||||||
|
char w_pattern[WLOG_MAX_PATTERN+1]; /* pattern written - */
|
||||||
|
/* null terminated */
|
||||||
|
int w_patternlen; /* pattern length */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef uint
|
||||||
|
#define uint unsigned int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On-disk structure of a wlog_rec. Actually, the record consists of
|
||||||
|
* 3 parts: [wlog_rec_disk structure][variable length data][length]
|
||||||
|
* where length is a 2 byte field containing the total record length
|
||||||
|
* (including the 2 bytes). It is used for scanning the logfile in reverse
|
||||||
|
* order.
|
||||||
|
*
|
||||||
|
* The variable length data includes the path, host, and pattern (in that
|
||||||
|
* order). The lengths of these pieces of data are held in the
|
||||||
|
* wlog_rec_disk structure. Thus, the actual on-disk record looks like
|
||||||
|
* this (top is lower byte offset):
|
||||||
|
*
|
||||||
|
* struct wlog_rec_disk
|
||||||
|
* path (w_pathlen bytes - not null terminated)
|
||||||
|
* host (w_hostlen bytes - not null terminated)
|
||||||
|
* pattern (w_patternlen bytes - not null terminated)
|
||||||
|
* 2-byte record length
|
||||||
|
*
|
||||||
|
* Another way of looking at it is:
|
||||||
|
*
|
||||||
|
* <struct wlog_rec_disk><path (wpathlen bytes)>-->
|
||||||
|
* --><host (w_hostlen bytes)><pattern (w_patternlen bytes)><length (2 bytes)>
|
||||||
|
*
|
||||||
|
* The maximum length of this record is defined by the WLOG_REC_MAX_SIZE
|
||||||
|
* record. Note that the 2-byte record length forces this to be
|
||||||
|
* <= 64k bytes.
|
||||||
|
*
|
||||||
|
* Note that there is lots of bit-masking done here. The w_pathlen,
|
||||||
|
* w_hostlen, and w_patternlen fields MUST have enough bits to hold
|
||||||
|
* WLOG_MAX_PATH, WLOG_MAX_HOST, and WLOG_MAX_PATTERN bytes respectivly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct wlog_rec_disk {
|
||||||
|
#ifdef CRAY
|
||||||
|
uint w_offset : 44; /* file offset */
|
||||||
|
uint w_extra0 : 20; /* EXTRA BITS IN WORD 0 */
|
||||||
|
#else
|
||||||
|
uint w_offset : 32; /* file offset */
|
||||||
|
uint w_extra0 : 32; /* EXTRA BITS IN WORD 0 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint w_nbytes : 32; /* # bytes written */
|
||||||
|
uint w_oflags : 32; /* low-order open() flags */
|
||||||
|
|
||||||
|
uint w_pid : 17; /* pid doing the write */
|
||||||
|
uint w_pathlen : 7; /* length of file path */
|
||||||
|
uint w_patternlen: 6; /* length of pattern */
|
||||||
|
uint w_hostlen : 4; /* length of host */
|
||||||
|
uint w_done : 1; /* 1 if io confirmed done */
|
||||||
|
uint w_async : 1; /* 1 if async write (writea) */
|
||||||
|
uint w_extra2 : 28; /* EXTRA BITS IN WORD 2 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write log file datatype. wlog_open() initializes this structure
|
||||||
|
* which is then passed around to the various wlog_xxx routines.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct wlog_file {
|
||||||
|
int w_afd; /* append fd */
|
||||||
|
int w_rfd; /* random-access fd */
|
||||||
|
char w_file[1024]; /* name of the write_log */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return value defines for the user-supplied function to
|
||||||
|
* wlog_scan_backward().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WLOG_STOP_SCAN 0
|
||||||
|
#define WLOG_CONTINUE_SCAN 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wlog prototypes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if __STDC__
|
||||||
|
extern int wlog_open(struct wlog_file *wfile, int trunc, int mode);
|
||||||
|
extern int wlog_close(struct wlog_file *wfile);
|
||||||
|
extern int wlog_record_write(struct wlog_file *wfile,
|
||||||
|
struct wlog_rec *wrec, long offset);
|
||||||
|
extern int wlog_scan_backward(struct wlog_file *wfile, int nrecs,
|
||||||
|
int (*func)(struct wlog_rec *rec),
|
||||||
|
long data);
|
||||||
|
#else
|
||||||
|
int wlog_open();
|
||||||
|
int wlog_close();
|
||||||
|
int wlog_record_write();
|
||||||
|
int wlog_scan_backward();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern char Wlog_Error_String[];
|
||||||
|
|
||||||
|
#endif /* _WRITE_LOG_H_ */
|
||||||
|
|
218
winsup/testsuite/libltp/lib/dataascii.c
Normal file
218
winsup/testsuite/libltp/lib/dataascii.c
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "dataascii.h"
|
||||||
|
|
||||||
|
#define CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjiklmnopqrstuvwxyz\n"
|
||||||
|
#define CHARS_SIZE sizeof(CHARS)
|
||||||
|
|
||||||
|
#ifdef UNIT_TEST
|
||||||
|
#include <stdlib.h> /* malloc */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char Errmsg[80];
|
||||||
|
|
||||||
|
int
|
||||||
|
dataasciigen(listofchars, buffer, bsize, offset)
|
||||||
|
char *listofchars; /* a null terminated list of characters */
|
||||||
|
char *buffer;
|
||||||
|
int bsize;
|
||||||
|
int offset;
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
int total;
|
||||||
|
int ind; /* index into CHARS array */
|
||||||
|
char *chr;
|
||||||
|
int chars_size;
|
||||||
|
char *charlist;
|
||||||
|
|
||||||
|
chr=buffer;
|
||||||
|
total=offset+bsize;
|
||||||
|
|
||||||
|
if ( listofchars == NULL ) {
|
||||||
|
charlist=CHARS;
|
||||||
|
chars_size=CHARS_SIZE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
charlist=listofchars;
|
||||||
|
chars_size=strlen(listofchars);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(cnt=offset; cnt<total; cnt++) {
|
||||||
|
ind=cnt%chars_size;
|
||||||
|
*chr++=charlist[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
return bsize;
|
||||||
|
|
||||||
|
} /* end of dataasciigen */
|
||||||
|
|
||||||
|
int
|
||||||
|
dataasciichk(listofchars, buffer, bsize, offset, errmsg)
|
||||||
|
char *listofchars; /* a null terminated list of characters */
|
||||||
|
char *buffer;
|
||||||
|
int bsize;
|
||||||
|
int offset;
|
||||||
|
char **errmsg;
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
int total;
|
||||||
|
int ind; /* index into CHARS array */
|
||||||
|
char *chr;
|
||||||
|
int chars_size;
|
||||||
|
char *charlist;
|
||||||
|
|
||||||
|
chr=buffer;
|
||||||
|
total=offset+bsize;
|
||||||
|
|
||||||
|
if ( listofchars == NULL ) {
|
||||||
|
charlist=CHARS;
|
||||||
|
chars_size=CHARS_SIZE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
charlist=listofchars;
|
||||||
|
chars_size=strlen(listofchars);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
*errmsg = Errmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(cnt=offset; cnt<total; chr++, cnt++) {
|
||||||
|
ind=cnt%chars_size;
|
||||||
|
if ( *chr != charlist[ind] ) {
|
||||||
|
sprintf(Errmsg,
|
||||||
|
"data mismatch at offset %d, exp:%#o, act:%#o", cnt,
|
||||||
|
charlist[ind], *chr);
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
|
||||||
|
return -1; /* buffer is ok */
|
||||||
|
|
||||||
|
} /* end of dataasciichk */
|
||||||
|
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* main for doing unit testing
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
main(ac, ag)
|
||||||
|
int ac;
|
||||||
|
char **ag;
|
||||||
|
{
|
||||||
|
|
||||||
|
int size=1023;
|
||||||
|
char *buffer;
|
||||||
|
int ret;
|
||||||
|
char *errmsg;
|
||||||
|
|
||||||
|
if ((buffer=(char *)malloc(size)) == NULL ) {
|
||||||
|
perror("malloc");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataasciigen(NULL, buffer, size, 0);
|
||||||
|
printf("dataasciigen(NULL, buffer, %d, 0)\n", size);
|
||||||
|
|
||||||
|
ret=dataasciichk(NULL, buffer, size, 0, &errmsg);
|
||||||
|
printf("dataasciichk(NULL, buffer, %d, 0, &errmsg) returned %d %s\n",
|
||||||
|
size, ret, errmsg);
|
||||||
|
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value is -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value is %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
ret=dataasciichk(NULL, &buffer[1], size-1, 1, &errmsg);
|
||||||
|
printf("dataasciichk(NULL, &buffer[1], %d, 1, &errmsg) returned %d %s\n",
|
||||||
|
size-1, ret, errmsg);
|
||||||
|
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value is -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value is %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
buffer[25]= 0x0;
|
||||||
|
printf("changing char 25\n");
|
||||||
|
|
||||||
|
ret=dataasciichk(NULL, &buffer[1], size-1, 1, &errmsg);
|
||||||
|
printf("dataasciichk(NULL, &buffer[1], %d, 1, &errmsg) returned %d %s\n",
|
||||||
|
size-1, ret, errmsg);
|
||||||
|
|
||||||
|
if ( ret == 25 )
|
||||||
|
printf("\tPASS return value is 25 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value is %d, expected 25\n", ret);
|
||||||
|
|
||||||
|
dataasciigen("this is a test of the my string" , buffer, size, 0);
|
||||||
|
printf("dataasciigen(\"this is a test of the my string\", buffer, %d, 0)\n", size);
|
||||||
|
|
||||||
|
ret=dataasciichk("this is a test of the my string", buffer, size, 0, &errmsg);
|
||||||
|
printf("dataasciichk(\"this is a test of the my string\", buffer, %d, 0, &errmsg) returned %d %s\n",
|
||||||
|
size, ret, errmsg);
|
||||||
|
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value is -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value is %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
ret=dataasciichk("this is a test of the my string", &buffer[1], size-1, 1, &errmsg);
|
||||||
|
printf("dataasciichk(\"this is a test of the my string\", &buffer[1], %d, 1, &errmsg) returned %d %s\n",
|
||||||
|
size-1, ret, errmsg);
|
||||||
|
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value is -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value is %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
buffer[25]= 0x0;
|
||||||
|
printf("changing char 25\n");
|
||||||
|
|
||||||
|
ret=dataasciichk("this is a test of the my string", &buffer[1], size-1, 1, &errmsg);
|
||||||
|
printf("dataasciichk(\"this is a test of the my string\", &buffer[1], %d, 1, &errmsg) returned %d %s\n",
|
||||||
|
size-1, ret, errmsg);
|
||||||
|
|
||||||
|
if ( ret == 25 )
|
||||||
|
printf("\tPASS return value is 25 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value is %d, expected 25\n", ret);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
298
winsup/testsuite/libltp/lib/databin.c
Normal file
298
winsup/testsuite/libltp/lib/databin.c
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <string.h> /* memset */
|
||||||
|
#include <stdlib.h> /* rand */
|
||||||
|
#include "databin.h"
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char Errmsg[80];
|
||||||
|
|
||||||
|
void
|
||||||
|
databingen (mode, buffer, bsize, offset)
|
||||||
|
int mode; /* either a, c, r, o, z or C */
|
||||||
|
unsigned char *buffer; /* buffer pointer */
|
||||||
|
int bsize; /* size of buffer */
|
||||||
|
int offset; /* offset into the file where buffer starts */
|
||||||
|
{
|
||||||
|
int ind;
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 'a': /* alternating bit pattern */
|
||||||
|
memset(buffer,0x55,bsize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c': /* checkerboard pattern */
|
||||||
|
memset(buffer,0xf0,bsize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'C': /* */
|
||||||
|
for (ind=0;ind< bsize;ind++) {
|
||||||
|
buffer[ind] = ((offset+ind)%8 & 0177);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
memset(buffer,0xff,bsize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z':
|
||||||
|
memset(buffer,0x0,bsize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r': /* random */
|
||||||
|
for (ind=0;ind< bsize;ind++) {
|
||||||
|
buffer[ind] = (rand () & 0177) | 0100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* return values:
|
||||||
|
* >= 0 : error at byte offset into the file, offset+buffer[0-(bsize-1)]
|
||||||
|
* < 0 : no error
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
databinchk(mode, buffer, bsize, offset, errmsg)
|
||||||
|
int mode; /* either a, c, r, z, o, or C */
|
||||||
|
unsigned char *buffer; /* buffer pointer */
|
||||||
|
int bsize; /* size of buffer */
|
||||||
|
int offset; /* offset into the file where buffer starts */
|
||||||
|
char **errmsg;
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
unsigned char *chr;
|
||||||
|
int total;
|
||||||
|
long expbits;
|
||||||
|
long actbits;
|
||||||
|
|
||||||
|
chr=buffer;
|
||||||
|
total=bsize;
|
||||||
|
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
*errmsg = Errmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 'a': /* alternating bit pattern */
|
||||||
|
expbits=0x55;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c': /* checkerboard pattern */
|
||||||
|
expbits=0xf0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'C': /* counting pattern */
|
||||||
|
for (cnt=0;cnt< bsize;cnt++) {
|
||||||
|
expbits = ((offset+cnt)%8 & 0177);
|
||||||
|
|
||||||
|
if ( buffer[cnt] != expbits ) {
|
||||||
|
sprintf(Errmsg,
|
||||||
|
"data mismatch at offset %d, exp:%#lo, act:%#o",
|
||||||
|
offset+cnt, expbits, buffer[cnt]);
|
||||||
|
return offset+cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
expbits=0xff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z':
|
||||||
|
expbits=0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
return -1; /* no check can be done for random */
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cnt=0; cnt<bsize; chr++, cnt++) {
|
||||||
|
actbits = (long)*chr;
|
||||||
|
|
||||||
|
if ( actbits != expbits ) {
|
||||||
|
sprintf(Errmsg, "data mismatch at offset %d, exp:%#lo, act:%#lo",
|
||||||
|
offset+cnt, expbits, actbits);
|
||||||
|
return offset+cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
|
||||||
|
return -1; /* all ok */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* main for doing unit testing
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
main(ac, ag)
|
||||||
|
int ac;
|
||||||
|
char **ag;
|
||||||
|
{
|
||||||
|
|
||||||
|
int size=1023;
|
||||||
|
int offset;
|
||||||
|
int number;
|
||||||
|
unsigned char *buffer;
|
||||||
|
int ret;
|
||||||
|
char *errmsg;
|
||||||
|
|
||||||
|
if ((buffer=(unsigned char *)malloc(size)) == NULL ) {
|
||||||
|
perror("malloc");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("***** for a ****************************\n");
|
||||||
|
databingen('a', buffer, size, 0);
|
||||||
|
printf("databingen('a', buffer, %d, 0)\n", size);
|
||||||
|
|
||||||
|
ret=databinchk('a', buffer, size, 0, &errmsg);
|
||||||
|
printf("databinchk('a', buffer, %d, 0, &errmsg) returned %d: %s\n",
|
||||||
|
size, ret, errmsg);
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value of -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
offset=232400;
|
||||||
|
ret=databinchk('a', &buffer[1], size-1, offset, &errmsg);
|
||||||
|
printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
|
||||||
|
size, offset, ret, errmsg);
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value of -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
buffer[15]= 0x0;
|
||||||
|
printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset, offset+15);
|
||||||
|
number=offset+15;
|
||||||
|
|
||||||
|
ret=databinchk('a', &buffer[1], size-1, offset+1, &errmsg);
|
||||||
|
printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
|
||||||
|
size-1, offset+1, ret, errmsg);
|
||||||
|
if ( ret == number )
|
||||||
|
printf("\tPASS return value of %d as expected\n", number);
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected %d\n", ret, number);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
printf("***** for c ****************************\n");
|
||||||
|
databingen('c', buffer, size, 0);
|
||||||
|
printf("databingen('c', buffer, %d, 0)\n", size);
|
||||||
|
|
||||||
|
ret=databinchk('c', buffer, size, 0, &errmsg);
|
||||||
|
printf("databinchk('c', buffer, %d, 0, &errmsg) returned %d: %s\n",
|
||||||
|
size, ret, errmsg);
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value of -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
offset=232400;
|
||||||
|
ret=databinchk('c', &buffer[1], size-1, offset, &errmsg);
|
||||||
|
printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
|
||||||
|
size, offset, ret, errmsg);
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value of -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
buffer[15]= 0x0;
|
||||||
|
printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset, offset+15);
|
||||||
|
number=offset+15;
|
||||||
|
|
||||||
|
ret=databinchk('c', &buffer[1], size-1, offset+1, &errmsg);
|
||||||
|
printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
|
||||||
|
size-1, offset+1, ret, errmsg);
|
||||||
|
if ( ret == number )
|
||||||
|
printf("\tPASS return value of %d as expected\n", number);
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected %d\n", ret, number);
|
||||||
|
|
||||||
|
printf("***** for C ****************************\n");
|
||||||
|
|
||||||
|
databingen('C', buffer, size, 0);
|
||||||
|
printf("databingen('C', buffer, %d, 0)\n", size);
|
||||||
|
|
||||||
|
ret=databinchk('C', buffer, size, 0, &errmsg);
|
||||||
|
printf("databinchk('C', buffer, %d, 0, &errmsg) returned %d: %s\n",
|
||||||
|
size, ret, errmsg);
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value of -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
offset=18;
|
||||||
|
ret=databinchk('C', &buffer[18], size-18, 18, &errmsg);
|
||||||
|
printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
|
||||||
|
size-18, ret, errmsg);
|
||||||
|
if ( ret == -1 )
|
||||||
|
printf("\tPASS return value of -1 as expected\n");
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected -1\n", ret);
|
||||||
|
|
||||||
|
buffer[20]= 0x0;
|
||||||
|
buffer[21]= 0x0;
|
||||||
|
printf("changing char 20 and 21 to 0x0 (offset %d and %d)\n", 20,
|
||||||
|
21);
|
||||||
|
|
||||||
|
ret=databinchk('C', &buffer[18], size-18, 18, &errmsg);
|
||||||
|
printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
|
||||||
|
size-18, ret, errmsg);
|
||||||
|
|
||||||
|
if ( ret == 20 || ret == 21 )
|
||||||
|
printf("\tPASS return value of %d or %d as expected\n",
|
||||||
|
20, 21);
|
||||||
|
else
|
||||||
|
printf("\tFAIL return value %d, expected %d or %d\n", ret,
|
||||||
|
20, 21 );
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
374
winsup/testsuite/libltp/lib/datapid.c
Normal file
374
winsup/testsuite/libltp/lib/datapid.c
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
/************
|
||||||
|
|
||||||
|
64 bits in a Cray word
|
||||||
|
|
||||||
|
12345678901234567890123456789012
|
||||||
|
1234567890123456789012345678901234567890123456789012345678901234
|
||||||
|
________________________________________________________________
|
||||||
|
< pid >< word-offset in file (same #) >< pid >
|
||||||
|
|
||||||
|
1234567890123456789012345678901234567890123456789012345678901234
|
||||||
|
________________________________________________________________
|
||||||
|
< pid >< offset in file of this word >< pid >
|
||||||
|
|
||||||
|
|
||||||
|
8 bits to a bytes == character
|
||||||
|
NBPW 8
|
||||||
|
************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#ifdef UNIT_TEST
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char Errmsg[80];
|
||||||
|
|
||||||
|
#define LOWER16BITS(X) (X & 0177777)
|
||||||
|
#define LOWER32BITS(X) (X & 0xffffffff)
|
||||||
|
|
||||||
|
/***
|
||||||
|
#define HIGHBITS(WRD, bits) ( (-1 << (64-bits)) & WRD)
|
||||||
|
#define LOWBITS(WRD, bits) ( (-1 >> (64-bits)) & WRD)
|
||||||
|
****/
|
||||||
|
|
||||||
|
#define NBPBYTE 8 /* number bits per byte */
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
#define DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 15 bytes
|
||||||
|
* 1234567890123456789012345678901234567890123456789012345678901234 bits
|
||||||
|
* ________________________________________________________________ 1 word
|
||||||
|
* < pid >< offset in file of this word >< pid >
|
||||||
|
*
|
||||||
|
* the words are put together where offset zero is the start.
|
||||||
|
* thus, offset 16 is the start of the second full word
|
||||||
|
* Thus, offset 8 is in middle of word 1
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
datapidgen(pid, buffer, bsize, offset)
|
||||||
|
int pid;
|
||||||
|
char *buffer;
|
||||||
|
int bsize;
|
||||||
|
int offset;
|
||||||
|
{
|
||||||
|
#if CRAY
|
||||||
|
|
||||||
|
int cnt;
|
||||||
|
int tmp;
|
||||||
|
char *chr;
|
||||||
|
long *wptr;
|
||||||
|
long word;
|
||||||
|
int woff; /* file offset for the word */
|
||||||
|
int boff; /* buffer offset or index */
|
||||||
|
int num_full_words;
|
||||||
|
|
||||||
|
num_full_words = bsize/NBPW;
|
||||||
|
boff = 0;
|
||||||
|
|
||||||
|
if ( cnt=(offset % NBPW) ) { /* partial word */
|
||||||
|
|
||||||
|
woff = offset - cnt;
|
||||||
|
#if DEBUG
|
||||||
|
printf("partial at beginning, cnt = %d, woff = %d\n", cnt, woff);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
|
||||||
|
|
||||||
|
chr = (char *)&word;
|
||||||
|
|
||||||
|
for (tmp=0; tmp<cnt; tmp++) { /* skip unused bytes */
|
||||||
|
chr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; boff<(NBPW-cnt) && boff<bsize; boff++, chr++) {
|
||||||
|
buffer[boff] = *chr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* full words
|
||||||
|
*/
|
||||||
|
|
||||||
|
num_full_words = (bsize-boff)/NBPW;
|
||||||
|
|
||||||
|
woff = offset+boff;
|
||||||
|
|
||||||
|
for (cnt=0; cnt<num_full_words; woff += NBPW, cnt++ ) {
|
||||||
|
|
||||||
|
word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
|
||||||
|
|
||||||
|
chr = (char *)&word;
|
||||||
|
for(tmp=0; tmp<NBPW; tmp++, chr++) {
|
||||||
|
buffer[boff++] = *chr;
|
||||||
|
}
|
||||||
|
/****** Only if wptr is a word ellined
|
||||||
|
wptr = (long *)&buffer[boff];
|
||||||
|
*wptr = word;
|
||||||
|
boff += NBPW;
|
||||||
|
*****/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* partial word at end of buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( cnt=((bsize-boff) % NBPW) ) {
|
||||||
|
#if DEBUG
|
||||||
|
printf("partial at end\n");
|
||||||
|
#endif
|
||||||
|
word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
|
||||||
|
|
||||||
|
chr = (char *)&word;
|
||||||
|
|
||||||
|
for (tmp=0; tmp<cnt && boff<bsize; tmp++, chr++) {
|
||||||
|
buffer[boff++] = *chr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bsize;
|
||||||
|
|
||||||
|
#else
|
||||||
|
return -1; /* not support on non-64 bits word machines */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
datapidchk(pid, buffer, bsize, offset, errmsg)
|
||||||
|
int pid;
|
||||||
|
char *buffer;
|
||||||
|
int bsize;
|
||||||
|
int offset;
|
||||||
|
char **errmsg;
|
||||||
|
{
|
||||||
|
#if CRAY
|
||||||
|
|
||||||
|
int cnt;
|
||||||
|
int tmp;
|
||||||
|
char *chr;
|
||||||
|
long *wptr;
|
||||||
|
long word;
|
||||||
|
int woff; /* file offset for the word */
|
||||||
|
int boff; /* buffer offset or index */
|
||||||
|
int num_full_words;
|
||||||
|
|
||||||
|
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
*errmsg = Errmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
num_full_words = bsize/NBPW;
|
||||||
|
boff = 0;
|
||||||
|
|
||||||
|
if ( cnt=(offset % NBPW) ) { /* partial word */
|
||||||
|
woff = offset - cnt;
|
||||||
|
word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
|
||||||
|
|
||||||
|
chr = (char *)&word;
|
||||||
|
|
||||||
|
for (tmp=0; tmp<cnt; tmp++) { /* skip unused bytes */
|
||||||
|
chr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; boff<(NBPW-cnt) && boff<bsize; boff++, chr++) {
|
||||||
|
if (buffer[boff] != *chr) {
|
||||||
|
sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
|
||||||
|
offset+boff, *chr, buffer[boff]);
|
||||||
|
return offset+boff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* full words
|
||||||
|
*/
|
||||||
|
|
||||||
|
num_full_words = (bsize-boff)/NBPW;
|
||||||
|
|
||||||
|
woff = offset+boff;
|
||||||
|
|
||||||
|
for (cnt=0; cnt<num_full_words; woff += NBPW, cnt++ ) {
|
||||||
|
word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
|
||||||
|
|
||||||
|
chr = (char *)&word;
|
||||||
|
for(tmp=0; tmp<NBPW; tmp++, boff++, chr++) {
|
||||||
|
if ( buffer[boff] != *chr ) {
|
||||||
|
sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
|
||||||
|
woff, *chr, buffer[boff]);
|
||||||
|
return woff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****** only if a word elined
|
||||||
|
wptr = (long *)&buffer[boff];
|
||||||
|
if ( *wptr != word ) {
|
||||||
|
sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
|
||||||
|
woff, word, *wptr);
|
||||||
|
return woff;
|
||||||
|
}
|
||||||
|
boff += NBPW;
|
||||||
|
******/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* partial word at end of buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( cnt=((bsize-boff) % NBPW) ) {
|
||||||
|
#if DEBUG
|
||||||
|
printf("partial at end\n");
|
||||||
|
#endif
|
||||||
|
word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
|
||||||
|
|
||||||
|
chr = (char *)&word;
|
||||||
|
|
||||||
|
|
||||||
|
for (tmp=0; tmp<cnt && boff<bsize; boff++, tmp++, chr++) {
|
||||||
|
if ( buffer[boff] != *chr ) {
|
||||||
|
sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
|
||||||
|
offset+boff, *chr, buffer[boff]);
|
||||||
|
return offset+boff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
|
||||||
|
return -1; /* buffer is ok */
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
*errmsg = Errmsg;
|
||||||
|
}
|
||||||
|
sprintf(Errmsg, "Not supported on this OS.");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
} /* end of datapidchk */
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* main for doing unit testing
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
main(ac, ag)
|
||||||
|
int ac;
|
||||||
|
char **ag;
|
||||||
|
{
|
||||||
|
|
||||||
|
int size=1234;
|
||||||
|
char *buffer;
|
||||||
|
int ret;
|
||||||
|
char *errmsg;
|
||||||
|
|
||||||
|
if ((buffer=(char *)malloc(size)) == NULL ) {
|
||||||
|
perror("malloc");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
datapidgen(-1, buffer, size, 3);
|
||||||
|
|
||||||
|
/***
|
||||||
|
fwrite(buffer, size, 1, stdout);
|
||||||
|
fwrite("\n", 1, 1, stdout);
|
||||||
|
****/
|
||||||
|
|
||||||
|
printf("datapidgen(-1, buffer, size, 3)\n");
|
||||||
|
|
||||||
|
ret=datapidchk(-1, buffer, size, 3, &errmsg);
|
||||||
|
printf("datapidchk(-1, buffer, %d, 3, &errmsg) returned %d %s\n",
|
||||||
|
size, ret, errmsg);
|
||||||
|
ret=datapidchk(-1, &buffer[1], size-1, 4, &errmsg);
|
||||||
|
printf("datapidchk(-1, &buffer[1], %d, 4, &errmsg) returned %d %s\n",
|
||||||
|
size-1, ret, errmsg);
|
||||||
|
|
||||||
|
buffer[25]= 0x0;
|
||||||
|
buffer[26]= 0x0;
|
||||||
|
buffer[27]= 0x0;
|
||||||
|
buffer[28]= 0x0;
|
||||||
|
printf("changing char 25-28\n");
|
||||||
|
|
||||||
|
ret=datapidchk(-1, &buffer[1], size-1, 4, &errmsg);
|
||||||
|
printf("datapidchk(-1, &buffer[1], %d, 4, &errmsg) returned %d %s\n",
|
||||||
|
size-1, ret, errmsg);
|
||||||
|
|
||||||
|
printf("------------------------------------------\n");
|
||||||
|
|
||||||
|
datapidgen(getpid(), buffer, size, 5);
|
||||||
|
|
||||||
|
/*******
|
||||||
|
fwrite(buffer, size, 1, stdout);
|
||||||
|
fwrite("\n", 1, 1, stdout);
|
||||||
|
******/
|
||||||
|
|
||||||
|
printf("\ndatapidgen(getpid(), buffer, size, 5)\n");
|
||||||
|
|
||||||
|
ret=datapidchk(getpid(), buffer, size, 5, &errmsg);
|
||||||
|
printf("datapidchk(getpid(), buffer, %d, 5, &errmsg) returned %d %s\n",
|
||||||
|
size, ret, errmsg);
|
||||||
|
|
||||||
|
ret=datapidchk(getpid(), &buffer[1], size-1, 6, &errmsg);
|
||||||
|
printf("datapidchk(getpid(), &buffer[1], %d, 6, &errmsg) returned %d %s\n",
|
||||||
|
size-1, ret, errmsg);
|
||||||
|
|
||||||
|
buffer[25]= 0x0;
|
||||||
|
printf("changing char 25\n");
|
||||||
|
|
||||||
|
ret=datapidchk(getpid(), &buffer[1], size-1, 6, &errmsg);
|
||||||
|
printf("datapidchk(getpid(), &buffer[1], %d, 6, &errmsg) returned %d %s\n",
|
||||||
|
size-1, ret, errmsg);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
285
winsup/testsuite/libltp/lib/forker.c
Normal file
285
winsup/testsuite/libltp/lib/forker.c
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
/**************************************************************
|
||||||
|
*
|
||||||
|
* OS Testing - Silicon Graphics, Inc.
|
||||||
|
*
|
||||||
|
* FUNCTION NAME : forker
|
||||||
|
* background
|
||||||
|
*
|
||||||
|
* FUNCTION TITLE : fork desired number of copies of the current process
|
||||||
|
* fork a process and return control to caller
|
||||||
|
*
|
||||||
|
* SYNOPSIS:
|
||||||
|
* int forker(ncopies, mode, prefix)
|
||||||
|
* int ncopies;
|
||||||
|
* int mode;
|
||||||
|
* char *prefix;
|
||||||
|
*
|
||||||
|
* int background(prefix);
|
||||||
|
* char *prefix;
|
||||||
|
*
|
||||||
|
* extern int Forker_pids[];
|
||||||
|
* extern int Forker_npids;
|
||||||
|
*
|
||||||
|
* AUTHOR : Richard Logan
|
||||||
|
*
|
||||||
|
* CO-PILOT(s) : Dean Roehrich
|
||||||
|
*
|
||||||
|
* INITIAL RELEASE : UNICOS 8.0
|
||||||
|
*
|
||||||
|
* DESIGN DESCRIPTION
|
||||||
|
* The background function will do a fork of the current process.
|
||||||
|
* The parent process will then exit, thus orphaning the
|
||||||
|
* child process. Doing this will not nice the child process
|
||||||
|
* like executing a cmd in the background using "&" from the shell.
|
||||||
|
* If the fork fails and prefix is not NULL, a error message is printed
|
||||||
|
* to stderr and the process will exit with a value of errno.
|
||||||
|
*
|
||||||
|
* The forker function will fork <ncopies> minus one copies
|
||||||
|
* of the current process. There are two modes in how the forks
|
||||||
|
* will be done. Mode 0 (default) will have all new processes
|
||||||
|
* be childern of the parent process. Using Mode 1,
|
||||||
|
* the parent process will have one child and that child will
|
||||||
|
* fork the next process, if necessary, and on and on.
|
||||||
|
* The forker function will return the number of successful
|
||||||
|
* forks. This value will be different for the parent and each child.
|
||||||
|
* Using mode 0, the parent will get the total number of successful
|
||||||
|
* forks. Using mode 1, the newest child will get the total number
|
||||||
|
* of forks. The parent will get a return value of 1.
|
||||||
|
*
|
||||||
|
* The forker function also updates the global variables
|
||||||
|
* Forker_pids[] and Forker_npids. The Forker_pids array will
|
||||||
|
* be updated to contain the pid of each new process. The
|
||||||
|
* Forker_npids variable contains the number of entries
|
||||||
|
* in Forker_pids. Note, not all processes will have
|
||||||
|
* access to all pids via Forker_pids. If using mode 0, only the
|
||||||
|
* parent process and the last process will have all information.
|
||||||
|
* If using mode 1, only the last child process will have all information.
|
||||||
|
*
|
||||||
|
* If the prefix parameter is not NULL and the fork system call fails,
|
||||||
|
* a error message will be printed to stderr. The error message
|
||||||
|
* the be preceeded with prefix string. If prefix is NULL,
|
||||||
|
* no error message is printed.
|
||||||
|
*
|
||||||
|
* 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 functions will first written during
|
||||||
|
* the SFS testing days, 1993.
|
||||||
|
*
|
||||||
|
* BUGS/LIMITATIONS
|
||||||
|
* The child pids are stored in the fixed array, Forker_pids.
|
||||||
|
* The array only has space for 4098 pids. Only the first
|
||||||
|
* 4098 pids will be stored in the array.
|
||||||
|
*
|
||||||
|
**************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h> /* fork, getpid, sleep */
|
||||||
|
#include <string.h>
|
||||||
|
#include "forker.h"
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
|
||||||
|
int Forker_pids[FORKER_MAX_PIDS]; /* holds pids of forked processes */
|
||||||
|
int Forker_npids=0; /* number of entries in Forker_pids */
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* This function will fork and the parent will exit zero and
|
||||||
|
* the child will return. This will orphan the returning process
|
||||||
|
* putting it in the background.
|
||||||
|
*
|
||||||
|
* Return Value
|
||||||
|
* 0 : if fork did not fail
|
||||||
|
* !0 : if fork failed, the return value will be the errno.
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
background(prefix)
|
||||||
|
char *prefix;
|
||||||
|
{
|
||||||
|
switch (fork()) {
|
||||||
|
case -1:
|
||||||
|
if ( prefix != NULL )
|
||||||
|
fprintf(stderr, "%s: In %s background(), fork() failed, errno:%d %s\n",
|
||||||
|
prefix, __FILE__, errno, strerror(errno));
|
||||||
|
exit(errno);
|
||||||
|
|
||||||
|
case 0: /* child process */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} /* end of background */
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Forker will fork ncopies-1 copies of self.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
forker(ncopies, mode, prefix)
|
||||||
|
int ncopies;
|
||||||
|
int mode; /* 0 - all childern of parent, 1 - only 1 direct child */
|
||||||
|
char *prefix; /* if ! NULL, an message will be printed to stderr */
|
||||||
|
/* if fork fails. The prefix (program name) will */
|
||||||
|
/* preceed the message */
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
int pid;
|
||||||
|
static int ind = 0;
|
||||||
|
|
||||||
|
Forker_pids[ind]=0;
|
||||||
|
|
||||||
|
for ( cnt=1; cnt < ncopies; cnt++ ) {
|
||||||
|
|
||||||
|
switch ( mode ) {
|
||||||
|
case 1 : /* only 1 direct child */
|
||||||
|
if ( (pid = fork()) == -1 ) {
|
||||||
|
if ( prefix != NULL )
|
||||||
|
fprintf(stderr, "%s: %s,forker(): fork() failed, errno:%d %s\n",
|
||||||
|
prefix, __FILE__, errno, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Forker_npids++;
|
||||||
|
|
||||||
|
switch (pid ) {
|
||||||
|
case 0: /* child - continues the forking */
|
||||||
|
|
||||||
|
if ( Forker_npids < FORKER_MAX_PIDS )
|
||||||
|
Forker_pids[Forker_npids-1]=getpid();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* parent - stop the forking */
|
||||||
|
if ( Forker_npids < FORKER_MAX_PIDS )
|
||||||
|
Forker_pids[Forker_npids-1]=pid;
|
||||||
|
return cnt-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default : /* all new processes are childern of parent */
|
||||||
|
if ( (pid = fork()) == -1 ) {
|
||||||
|
if ( prefix != NULL )
|
||||||
|
fprintf(stderr, "%s: %s,forker(): fork() failed, errno:%d %s\n",
|
||||||
|
prefix, __FILE__, errno, strerror(errno));
|
||||||
|
return cnt-1;
|
||||||
|
}
|
||||||
|
Forker_npids++;
|
||||||
|
|
||||||
|
switch (pid ) {
|
||||||
|
case 0: /* child - stops the forking */
|
||||||
|
if ( Forker_npids < FORKER_MAX_PIDS )
|
||||||
|
Forker_pids[Forker_npids-1]=getpid();
|
||||||
|
return cnt;
|
||||||
|
|
||||||
|
default: /* parent - continues the forking */
|
||||||
|
if ( Forker_npids < FORKER_MAX_PIDS )
|
||||||
|
Forker_pids[Forker_npids-1]=pid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Forker_npids < FORKER_MAX_PIDS )
|
||||||
|
Forker_pids[Forker_npids]=0;
|
||||||
|
return cnt-1;
|
||||||
|
|
||||||
|
} /* end of forker */
|
||||||
|
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following is a unit test main for the background and forker
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
int ncopies=1;
|
||||||
|
int mode=0;
|
||||||
|
int ret;
|
||||||
|
int ind;
|
||||||
|
|
||||||
|
if ( argc == 1 ) {
|
||||||
|
printf("Usage: %s ncopies [mode]\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( sscanf(argv[1], "%i", &ncopies) != 1 ) {
|
||||||
|
printf("%s: ncopies argument must be integer\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( argc == 3 )
|
||||||
|
if ( sscanf(argv[2], "%i", &mode) != 1 ) {
|
||||||
|
printf("%s: mode argument must be integer\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Starting Pid = %d\n", getpid());
|
||||||
|
ret=background(argv[0]);
|
||||||
|
printf("After background() ret:%d, pid = %d\n", ret, getpid());
|
||||||
|
|
||||||
|
ret=forker(ncopies, mode, argv[0]);
|
||||||
|
|
||||||
|
printf("forker(%d, %d, %s) ret:%d, pid = %d, sleeping 30 seconds.\n",
|
||||||
|
ncopies, mode, argv[0], ret, getpid());
|
||||||
|
|
||||||
|
printf("%d My version of Forker_pids[], Forker_npids = %d\n",
|
||||||
|
getpid(), Forker_npids);
|
||||||
|
|
||||||
|
for (ind=0; ind<Forker_npids; ind++){
|
||||||
|
printf("%d ind:%-2d pid:%d\n", getpid(), ind, Forker_pids[ind]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(30);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* UNIT_TEST */
|
15
winsup/testsuite/libltp/lib/get_high_address.c
Normal file
15
winsup/testsuite/libltp/lib/get_high_address.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (C) COPYRIGHT CRAY RESEARCH, INC.
|
||||||
|
* UNPUBLISHED PROPRIETARY INFORMATION.
|
||||||
|
* ALL RIGHTS RESERVED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
get_high_address()
|
||||||
|
{
|
||||||
|
return (char *)sbrk(0) + 16384;
|
||||||
|
}
|
330
winsup/testsuite/libltp/lib/open_flags.c
Normal file
330
winsup/testsuite/libltp/lib/open_flags.c
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
/**************************************************************
|
||||||
|
*
|
||||||
|
* 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 */
|
876
winsup/testsuite/libltp/lib/parse_opts.c
Normal file
876
winsup/testsuite/libltp/lib/parse_opts.c
Normal file
@ -0,0 +1,876 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
*
|
||||||
|
* OS Testing - Silicon Graphics, Inc.
|
||||||
|
*
|
||||||
|
* FUNCTION NAME : parse_opts
|
||||||
|
*
|
||||||
|
* FUNCTION TITLE : parse standard & user options for system call tests
|
||||||
|
*
|
||||||
|
* SYNOPSIS:
|
||||||
|
* #include "usctest.h"
|
||||||
|
*
|
||||||
|
* char *parse_opts(ac, av, user_optarr, uhf)
|
||||||
|
* int ac;
|
||||||
|
* char **av;
|
||||||
|
* option_t user_optarr[];
|
||||||
|
* void (*uhf)();
|
||||||
|
*
|
||||||
|
* AUTHOR : William Roske/Richard Logan
|
||||||
|
*
|
||||||
|
* INITIAL RELEASE : UNICOS 7.0
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* The parse_opts library routine takes that argc and argv parameters
|
||||||
|
* recevied by main() and an array of structures defining user options.
|
||||||
|
* It parses the command line setting flag and argument locations
|
||||||
|
* associated with the options. It uses getopt to do the actual cmd line
|
||||||
|
* parsing. uhf() is a function to print user define help
|
||||||
|
*
|
||||||
|
* This module contains the functions usc_global_setup_hook and
|
||||||
|
* usc_test_looping, which are called by marcos defined in usctest.h.
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* parse_opts returns a pointer to an error message if an error occurs.
|
||||||
|
* This pointer is (char *)NULL if parsing is successful.
|
||||||
|
*
|
||||||
|
*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#include <getopt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
#include <time.h>
|
||||||
|
#endif /* UNIT_TEST */
|
||||||
|
|
||||||
|
#include "test.h"
|
||||||
|
#define _USC_LIB_ 1 /* indicates we are the library to the usctest.h include */
|
||||||
|
#include "usctest.h"
|
||||||
|
|
||||||
|
#ifndef USC_COPIES
|
||||||
|
#define USC_COPIES "USC_COPIES"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST
|
||||||
|
#define UNIT_TEST 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
#define DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The timing information block. */
|
||||||
|
struct tblock tblock={0,((long) -1)>>1,0,0};
|
||||||
|
|
||||||
|
|
||||||
|
/* Define flags and args for standard options */
|
||||||
|
int STD_FUNCTIONAL_TEST=1, /* flag indicating to do functional testing code */
|
||||||
|
STD_TIMING_ON=0, /* flag indicating to print timing stats */
|
||||||
|
STD_PAUSE=0, /* flag indicating to pause before actual start, */
|
||||||
|
/* for contention mode */
|
||||||
|
STD_INFINITE=0, /* flag indciating to loop forever */
|
||||||
|
STD_LOOP_COUNT=1, /* number of iterations */
|
||||||
|
STD_COPIES=1, /* number of copies */
|
||||||
|
STD_ERRNO_LOG=0; /* flag indicating to do errno logging */
|
||||||
|
|
||||||
|
float STD_LOOP_DURATION=0.0, /* duration value in fractional seconds */
|
||||||
|
STD_LOOP_DELAY=0.0; /* loop delay value in fractional seconds */
|
||||||
|
|
||||||
|
|
||||||
|
char **STD_opt_arr = NULL; /* array of option strings */
|
||||||
|
int STD_nopts=0, /* number of elements in STD_opt_arr */
|
||||||
|
STD_argind=1; /* argv index to next argv element */
|
||||||
|
/* (first argument) */
|
||||||
|
/* To getopt users, it is like optind */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following variables are to support system testing additions.
|
||||||
|
*/
|
||||||
|
static int STD_TP_barrier=0; /* flag to do barrier in TEST_PAUSE */
|
||||||
|
/* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
|
||||||
|
static int STD_LP_barrier=0; /* flag to do barrier in TEST_LOOPING */
|
||||||
|
/* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
|
||||||
|
static int STD_TP_shmem_sz=0; /* shmalloc this many words per pe in TEST_PAUSE */
|
||||||
|
static int STD_LD_shmem=0; /* flag to do shmem_puts and shmem_gets during delay */
|
||||||
|
static int STD_LP_shmem=0; /* flag to do shmem_puts and gets during TEST_LOOPING */
|
||||||
|
static int STD_LD_recfun=0; /* do recressive function calls in loop delay */
|
||||||
|
static int STD_LP_recfun=0; /* do recressive function calls in TEST_LOOPING */
|
||||||
|
static int STD_TP_sbrk=0; /* do sbrk in TEST_PAUSE */
|
||||||
|
static int STD_LP_sbrk=0; /* do sbrk in TEST_LOOPING */
|
||||||
|
static char *STD_start_break=0; /* original sbrk size */
|
||||||
|
static int Debug=0;
|
||||||
|
|
||||||
|
struct std_option_t {
|
||||||
|
char *optstr;
|
||||||
|
char *help;
|
||||||
|
char *flag;
|
||||||
|
char **arg;
|
||||||
|
} std_options[] = {
|
||||||
|
{ "c:", " -c n Run n copies concurrently\n", NULL, NULL},
|
||||||
|
{ "e" , " -e Turn on errno logging\n", NULL, NULL},
|
||||||
|
{ "f" , " -f Turn off functional testing\n", NULL, NULL},
|
||||||
|
{ "h" , " -h Show this help screen\n", NULL, NULL},
|
||||||
|
{ "i:", " -i n Execute test n times\n", NULL, NULL},
|
||||||
|
{ "I:", " -I x Execute test for x seconds\n", NULL, NULL},
|
||||||
|
{ "p" , " -p Pause for SIGUSR1 before starting\n", NULL, NULL},
|
||||||
|
{ "P:", " -P x Pause for x seconds between iterations\n", NULL, NULL},
|
||||||
|
{ "t" , " -t Turn on syscall timing\n", NULL, NULL},
|
||||||
|
{NULL, NULL, NULL, NULL}};
|
||||||
|
|
||||||
|
void print_help(void (*user_help)());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure for usc_recressive_func argument
|
||||||
|
*/
|
||||||
|
struct usc_bigstack_t {
|
||||||
|
char space[4096];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct usc_bigstack_t *STD_bigstack=NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Counter of errnos returned (-e option). Indexed by errno.
|
||||||
|
* Make the array USC_MAX_ERRNO long. That is the first Fortran
|
||||||
|
* Lib errno. No syscall should return an errno that high.
|
||||||
|
*/
|
||||||
|
int STD_ERRNO_LIST[USC_MAX_ERRNO];
|
||||||
|
|
||||||
|
/* define the string length for Mesg and Mesg2 strings */
|
||||||
|
#define STRLEN 2048
|
||||||
|
|
||||||
|
static char Mesg2[STRLEN]; /* holds possible return string */
|
||||||
|
static void usc_recressive_func();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define bits for options that might have env variable default
|
||||||
|
*/
|
||||||
|
#define OPT_iteration 01
|
||||||
|
#define OPT_nofunccheck 02
|
||||||
|
#define OPT_duration 04
|
||||||
|
#define OPT_delay 010
|
||||||
|
#define OPT_copies 020
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* parse_opts:
|
||||||
|
**********************************************************************/
|
||||||
|
char *
|
||||||
|
parse_opts(int ac, char **av, option_t *user_optarr, void (*uhf)())
|
||||||
|
{
|
||||||
|
int found; /* flag to indicate that an option specified was */
|
||||||
|
/* found in the user's list */
|
||||||
|
int k; /* scratch integer for returns and short time usage */
|
||||||
|
float ftmp; /* tmp float for parsing env variables */
|
||||||
|
char *ptr; /* used in getting env variables */
|
||||||
|
int options=0; /* no options specified */
|
||||||
|
int optstrlen, i;
|
||||||
|
char *optionstr;
|
||||||
|
int opt; /* return of getopt */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If not the first time this function is called, release the old STD_opt_arr
|
||||||
|
* vector.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( STD_opt_arr != NULL ) {
|
||||||
|
free(STD_opt_arr);
|
||||||
|
STD_opt_arr=NULL;
|
||||||
|
}
|
||||||
|
/* Calculate how much space we need for the option string */
|
||||||
|
optstrlen = 0;
|
||||||
|
for (i = 0; std_options[i].optstr; ++i)
|
||||||
|
optstrlen += strlen(std_options[i].optstr);
|
||||||
|
if (user_optarr)
|
||||||
|
for (i = 0; user_optarr[i].option; ++i) {
|
||||||
|
if (strlen(user_optarr[i].option) > 2)
|
||||||
|
return "parse_opts: ERROR - Only short options are allowed";
|
||||||
|
optstrlen += strlen(user_optarr[i].option);
|
||||||
|
}
|
||||||
|
optstrlen += 1;
|
||||||
|
|
||||||
|
/* Create the option string for getopt */
|
||||||
|
optionstr = (char *)malloc(optstrlen);
|
||||||
|
if (!optionstr)
|
||||||
|
return "parse_opts: ERROR - Could not allocate memory for optionstr";
|
||||||
|
|
||||||
|
for (i = 0; std_options[i].optstr; ++i)
|
||||||
|
strcat(optionstr, std_options[i].optstr);
|
||||||
|
if (user_optarr)
|
||||||
|
for (i = 0; user_optarr[i].option; ++i)
|
||||||
|
/* only add the option if it wasn't there already */
|
||||||
|
if (strchr(optionstr, user_optarr[i].option[0]) == NULL)
|
||||||
|
strcat(optionstr, user_optarr[i].option);
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
printf("STD_nopts = %d\n", STD_nopts);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loop through av parsing options.
|
||||||
|
*/
|
||||||
|
while ( (opt = getopt(ac, av, optionstr)) > 0) {
|
||||||
|
|
||||||
|
STD_argind = optind;
|
||||||
|
#if DEBUG > 0
|
||||||
|
printf("parse_opts: getopt returned '%c'\n", opt);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (opt) {
|
||||||
|
case '?': /* Unknown option */
|
||||||
|
return "Unknown option";
|
||||||
|
break;
|
||||||
|
case ':': /* Missing Arg */
|
||||||
|
return "Missing argument";
|
||||||
|
break;
|
||||||
|
case 'i': /* Iterations */
|
||||||
|
options |= OPT_iteration;
|
||||||
|
STD_LOOP_COUNT = atoi(optarg);
|
||||||
|
if (STD_LOOP_COUNT == 0) STD_INFINITE = 1;
|
||||||
|
break;
|
||||||
|
case 'P': /* Delay between iterations */
|
||||||
|
options |= OPT_delay;
|
||||||
|
STD_LOOP_DELAY = atof(optarg);
|
||||||
|
break;
|
||||||
|
case 'I': /* Time duration */
|
||||||
|
options |= OPT_duration;
|
||||||
|
STD_LOOP_DURATION = atof(optarg);
|
||||||
|
if ( STD_LOOP_DURATION == 0.0 ) STD_INFINITE=1;
|
||||||
|
break;
|
||||||
|
case 'c': /* Copies */
|
||||||
|
options |= OPT_copies;
|
||||||
|
STD_COPIES = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'f': /* Functional testing */
|
||||||
|
STD_FUNCTIONAL_TEST = 0;
|
||||||
|
break;
|
||||||
|
case 'p': /* Pause for SIGUSR1 */
|
||||||
|
STD_PAUSE = 1;
|
||||||
|
break;
|
||||||
|
case 't': /* syscall timing */
|
||||||
|
STD_TIMING_ON = 1;
|
||||||
|
break;
|
||||||
|
case 'e': /* errno loggin */
|
||||||
|
STD_ERRNO_LOG = 1;
|
||||||
|
break;
|
||||||
|
case 'h': /* Help */
|
||||||
|
print_help(uhf);
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
/* Check all the user specified options */
|
||||||
|
found=0;
|
||||||
|
for(i = 0; user_optarr[i].option; ++i) {
|
||||||
|
|
||||||
|
if (opt == user_optarr[i].option[0]) {
|
||||||
|
/* Yup, This is a user option, set the flag and look for argument */
|
||||||
|
if ( user_optarr[i].flag ) {
|
||||||
|
*user_optarr[i].flag=1;
|
||||||
|
}
|
||||||
|
found++;
|
||||||
|
|
||||||
|
/* save the argument at the user's location */
|
||||||
|
if ( user_optarr[i].option[strlen(user_optarr[i].option)-1] == ':' ) {
|
||||||
|
*user_optarr[i].arg=optarg;
|
||||||
|
}
|
||||||
|
break; /* option found - break out of the for loop */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* This condition "should never happen". SO CHECK FOR IT!!!! */
|
||||||
|
if ( ! found ) {
|
||||||
|
sprintf(Mesg2,
|
||||||
|
"parse_opts: ERROR - option:\"%c\" NOT FOUND... INTERNAL ERROR", opt);
|
||||||
|
return(Mesg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end of while */
|
||||||
|
|
||||||
|
STD_argind = optind;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turn on debug
|
||||||
|
*/
|
||||||
|
if ( (ptr=getenv("USC_DEBUG")) != NULL ) {
|
||||||
|
Debug=1;
|
||||||
|
printf("env USC_DEBUG is defined, turning on debug\n");
|
||||||
|
}
|
||||||
|
if ( (ptr=getenv("USC_VERBOSE")) != NULL ) {
|
||||||
|
Debug=1;
|
||||||
|
printf("env USC_VERBOSE is defined, turning on debug\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the USC_ITERATION_ENV environmental variable is set to
|
||||||
|
* a number, use that number as iteration count (same as -c option).
|
||||||
|
* The -c option with arg will be used even if this env var is set.
|
||||||
|
*/
|
||||||
|
if ( !(options & OPT_iteration) && (ptr=getenv(USC_ITERATION_ENV)) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1) {
|
||||||
|
if ( k == 0 ) { /* if arg is 0, set infinite loop flag */
|
||||||
|
STD_INFINITE=1;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env %s, set STD_INFINITE to 1\n",
|
||||||
|
USC_ITERATION_ENV);
|
||||||
|
} else { /* else, set the loop count to the arguement */
|
||||||
|
STD_LOOP_COUNT=k;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env %s, set STD_LOOP_COUNT to %d\n",
|
||||||
|
USC_ITERATION_ENV, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the USC_NO_FUNC_CHECK environmental variable is set, we'll
|
||||||
|
* unset the STD_FUNCTIONAL_TEST variable.
|
||||||
|
*/
|
||||||
|
if ( !(options & OPT_nofunccheck) && (ptr=getenv(USC_NO_FUNC_CHECK)) != NULL ) {
|
||||||
|
STD_FUNCTIONAL_TEST=0; /* Turn off functional testing */
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env %s, set STD_FUNCTIONAL_TEST to 0\n",
|
||||||
|
USC_NO_FUNC_CHECK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the USC_LOOP_WALLTIME environmental variable is set,
|
||||||
|
* use that number as duration (same as -I option).
|
||||||
|
* The -I option with arg will be used even if this env var is set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( !(options & OPT_duration) && (ptr=getenv(USC_LOOP_WALLTIME)) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) {
|
||||||
|
STD_LOOP_DURATION=ftmp;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env %s, set STD_LOOP_DURATION to %f\n",
|
||||||
|
USC_LOOP_WALLTIME, ftmp);
|
||||||
|
if ( STD_LOOP_DURATION == 0.0 ) { /* if arg is 0, set infinite loop flag */
|
||||||
|
STD_INFINITE=1;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env %s, set STD_INFINITE to 1\n", USC_LOOP_WALLTIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !(options & OPT_duration) && (ptr=getenv("USC_DURATION")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) {
|
||||||
|
STD_LOOP_DURATION=ftmp;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_DURATION, set STD_LOOP_DURATION to %f\n", ftmp);
|
||||||
|
if ( STD_LOOP_DURATION == 0.0 ) { /* if arg is 0, set infinite loop flag */
|
||||||
|
STD_INFINITE=1;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_DURATION, set STD_INFINITE to 1\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If the USC_LOOP_DELAY environmental variable is set,
|
||||||
|
* use that number as delay in factional seconds (same as -P option).
|
||||||
|
* The -P option with arg will be used even if this env var is set.
|
||||||
|
*/
|
||||||
|
if ( !(options & OPT_delay) && (ptr=getenv(USC_LOOP_DELAY)) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) {
|
||||||
|
STD_LOOP_DELAY=ftmp;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env %s, set STD_LOOP_DELAY = %f\n",
|
||||||
|
USC_LOOP_DELAY, ftmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the USC_COPIES environmental variable is set,
|
||||||
|
* use that number as copies (same as -c option).
|
||||||
|
* The -c option with arg will be used even if this env var is set.
|
||||||
|
*/
|
||||||
|
if ( !(options & OPT_copies) && (ptr=getenv(USC_COPIES)) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%d", &STD_COPIES) == 1 && STD_COPIES >= 0 ) {
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env %s, set STD_COPIES = %d\n",
|
||||||
|
USC_COPIES, STD_COPIES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following are special system testing envs to turn on special
|
||||||
|
* hooks in the code.
|
||||||
|
*/
|
||||||
|
if ( (ptr=getenv("USC_TP_BARRIER")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_TP_barrier=k;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
STD_TP_barrier=1;
|
||||||
|
if ( Debug )
|
||||||
|
printf("using env USC_TP_BARRIER, Set STD_TP_barrier to %d\n",
|
||||||
|
STD_TP_barrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ptr=getenv("USC_LP_BARRIER")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_LP_barrier=k;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
STD_LP_barrier=1;
|
||||||
|
if ( Debug )
|
||||||
|
printf("using env USC_LP_BARRIER, Set STD_LP_barrier to %d\n",
|
||||||
|
STD_LP_barrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ptr=getenv("USC_TP_SHMEM")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_TP_shmem_sz=k;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_TP_SHMEM, Set STD_TP_shmem_sz to %d\n",
|
||||||
|
STD_TP_shmem_sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ptr=getenv("USC_LP_SHMEM")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_LP_shmem=k;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_LP_SHMEM, Set STD_LP_shmem to %d\n",
|
||||||
|
STD_LP_shmem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ptr=getenv("USC_LD_SHMEM")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_LD_shmem=k;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_LD_SHMEM, Set STD_LD_shmem to %d\n",
|
||||||
|
STD_LD_shmem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ptr=getenv("USC_TP_SBRK")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_TP_sbrk=k;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_TP_SBRK, Set STD_TP_sbrk to %d\n",
|
||||||
|
STD_TP_sbrk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ptr=getenv("USC_LP_SBRK")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_LP_sbrk=k;
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_LP_SBRK, Set STD_LP_sbrk to %d\n",
|
||||||
|
STD_LP_sbrk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ptr=getenv("USC_LP_RECFUN")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_LP_recfun=k;
|
||||||
|
if ( STD_bigstack != (struct usc_bigstack_t *)NULL )
|
||||||
|
STD_bigstack=(struct usc_bigstack_t *)
|
||||||
|
malloc(sizeof(struct usc_bigstack_t));
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_LP_RECFUN, Set STD_LP_recfun to %d\n",
|
||||||
|
STD_LP_recfun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ptr=getenv("USC_LD_RECFUN")) != NULL ) {
|
||||||
|
if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
|
||||||
|
STD_LD_recfun=k;
|
||||||
|
if ( STD_bigstack != (struct usc_bigstack_t *)NULL )
|
||||||
|
STD_bigstack=(struct usc_bigstack_t *)
|
||||||
|
malloc(sizeof(struct usc_bigstack_t));
|
||||||
|
if ( Debug )
|
||||||
|
printf("Using env USC_LD_RECFUN, Set STD_LD_recfun to %d\n",
|
||||||
|
STD_LD_recfun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
printf("The following variables after option and env parsing:\n");
|
||||||
|
printf("STD_FUNCTIONAL_TEST = %d\n", STD_FUNCTIONAL_TEST);
|
||||||
|
printf("STD_LOOP_DURATION = %f\n", STD_LOOP_DURATION);
|
||||||
|
printf("STD_LOOP_DELAY = %f\n", STD_LOOP_DELAY);
|
||||||
|
printf("STD_COPIES = %d\n", STD_COPIES);
|
||||||
|
printf("STD_LOOP_COUNT = %d\n", STD_LOOP_COUNT);
|
||||||
|
printf("STD_INFINITE = %d\n", STD_INFINITE);
|
||||||
|
printf("STD_TIMING_ON = %d\n", STD_TIMING_ON);
|
||||||
|
printf("STD_ERRNO_LOG = %d\n", STD_ERRNO_LOG);
|
||||||
|
printf("STD_PAUSE = %d\n", STD_PAUSE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return((char *) NULL);
|
||||||
|
|
||||||
|
} /* end of parse_opts */
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* print_help() - print help message and user help message
|
||||||
|
*********************************************************************/
|
||||||
|
void print_help(void (*user_help)())
|
||||||
|
{
|
||||||
|
STD_opts_help();
|
||||||
|
|
||||||
|
if (user_help) user_help();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* STD_opts_help() - return a help string for the STD_OPTIONS.
|
||||||
|
*********************************************************************/
|
||||||
|
void
|
||||||
|
STD_opts_help()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; std_options[i].optstr; ++i) {
|
||||||
|
if (std_options[i].help)
|
||||||
|
printf(std_options[i].help);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* routine to goto when we get the SIGUSR1 for STD_PAUSE
|
||||||
|
*/
|
||||||
|
void STD_go(int sig)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* This function will do desired end of global setup test
|
||||||
|
* hooks.
|
||||||
|
* Currently it will only do a pause waiting for sigusr1 if
|
||||||
|
* STD_PAUSE is set.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
usc_global_setup_hook()
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
/* temp variable to store old signal action to be restored after pause */
|
||||||
|
int (*_TMP_FUNC)(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fork STD_COPIES-1 copies.
|
||||||
|
*/
|
||||||
|
for(cnt=1;cnt<STD_COPIES;cnt++) {
|
||||||
|
switch(fork() ) {
|
||||||
|
case -1:
|
||||||
|
fprintf(stderr, "%s: fork() failed, errno:%d %s\n",
|
||||||
|
__FILE__, errno, strerror(errno));
|
||||||
|
break;
|
||||||
|
case 0: /* child */
|
||||||
|
cnt=STD_COPIES; /* to stop the forking */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* parent */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pause waiting for sigusr1.
|
||||||
|
*/
|
||||||
|
if ( STD_PAUSE ) {
|
||||||
|
_TMP_FUNC = (int (*)())signal(SIGUSR1, STD_go);
|
||||||
|
pause();
|
||||||
|
signal(SIGUSR1, (void (*)())_TMP_FUNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( STD_TP_sbrk || STD_LP_sbrk) {
|
||||||
|
STD_start_break=sbrk(0); /* get original sbreak size */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( STD_TP_sbrk ) {
|
||||||
|
sbrk(STD_TP_sbrk);
|
||||||
|
if ( Debug )
|
||||||
|
printf("after sbrk(%d)\n", STD_TP_sbrk);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define USECS_PER_SEC 1000000 /* microseconds per second */
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* This function returns the number of get_current_time()'s return
|
||||||
|
* per second.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_timepersec()
|
||||||
|
{
|
||||||
|
return USECS_PER_SEC; /* microseconds per second */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* this function will get current time in microseconds since 1970.
|
||||||
|
***********************************************************************/
|
||||||
|
static int
|
||||||
|
get_current_time()
|
||||||
|
{
|
||||||
|
struct timeval curtime;
|
||||||
|
|
||||||
|
gettimeofday(&curtime, NULL);
|
||||||
|
|
||||||
|
/* microseconds since 1970 */
|
||||||
|
return (curtime.tv_sec*USECS_PER_SEC) + curtime.tv_usec;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* This function will determine if test should continue iterating
|
||||||
|
* If the STD_INFINITE flag is set, return 1.
|
||||||
|
* If the STD_LOOP_COUNT variable is set, compare it against
|
||||||
|
* the counter.
|
||||||
|
* If the STD_LOOP_DURATION variable is set, compare current time against
|
||||||
|
* calculated stop_time.
|
||||||
|
* This function will return 1 until all desired looping methods
|
||||||
|
* have been met.
|
||||||
|
*
|
||||||
|
* counter integer is supplied by the user program.
|
||||||
|
***********************************************************************/
|
||||||
|
int
|
||||||
|
usc_test_looping(counter)
|
||||||
|
int counter;
|
||||||
|
{
|
||||||
|
static int first_time = 1;
|
||||||
|
static int stop_time = 0; /* stop time in rtc or usecs */
|
||||||
|
static int delay; /* delay in clocks or usecs */
|
||||||
|
int hz=0; /* clocks per second or usecs per second */
|
||||||
|
int ct, end; /* current time, end delay time */
|
||||||
|
int keepgoing=0; /* used to determine return value */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is the first iteration and we are looping for
|
||||||
|
* duration of STD_LOOP_DURATION seconds (fractional) or
|
||||||
|
* doing loop delays, get the clocks per second.
|
||||||
|
*/
|
||||||
|
if ( first_time ) {
|
||||||
|
|
||||||
|
first_time=0;
|
||||||
|
if ( STD_LOOP_DELAY || STD_LOOP_DURATION ) {
|
||||||
|
hz = get_timepersec();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If looping for duration, calculate stop time in
|
||||||
|
* clocks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( STD_LOOP_DURATION) {
|
||||||
|
ct=get_current_time();
|
||||||
|
stop_time=(int)((float)hz * STD_LOOP_DURATION) + ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If doing delay each iteration, calcuate the number
|
||||||
|
* of clocks for each delay.
|
||||||
|
*/
|
||||||
|
if ( STD_LOOP_DELAY ) {
|
||||||
|
delay=(int)((float)hz * STD_LOOP_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if delay each iteration, loop for delay clocks.
|
||||||
|
* This will not be done on first iteration.
|
||||||
|
* The delay will happen before determining if
|
||||||
|
* there will be another iteration.
|
||||||
|
*/
|
||||||
|
else if ( STD_LOOP_DELAY ) {
|
||||||
|
ct=get_current_time();
|
||||||
|
end=ct+delay;
|
||||||
|
while ( ct < end ) {
|
||||||
|
/*
|
||||||
|
* The following are special test hooks in the delay loop.
|
||||||
|
*/
|
||||||
|
if ( STD_LD_recfun ) {
|
||||||
|
if ( Debug )
|
||||||
|
printf("calling usc_recressive_func(0, %d, &STD_bigstack)\n",
|
||||||
|
STD_LD_recfun);
|
||||||
|
usc_recressive_func(0, STD_LD_recfun, &STD_bigstack);
|
||||||
|
}
|
||||||
|
|
||||||
|
ct=get_current_time();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( STD_INFINITE ) {
|
||||||
|
keepgoing++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( STD_LOOP_COUNT && counter < STD_LOOP_COUNT ) {
|
||||||
|
keepgoing++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( STD_LOOP_DURATION != 0.0 && get_current_time() < stop_time ) {
|
||||||
|
keepgoing++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( keepgoing == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following code allows special system testing hooks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( STD_LP_recfun ) {
|
||||||
|
if ( Debug )
|
||||||
|
printf("calling usc_recressive_func(0, %d, &STD_bigstack)\n",
|
||||||
|
STD_LP_recfun);
|
||||||
|
usc_recressive_func(0, STD_LP_recfun, &STD_bigstack);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( STD_LP_sbrk ) {
|
||||||
|
if ( Debug )
|
||||||
|
printf("about to do sbrk(%d)\n", STD_LP_sbrk);
|
||||||
|
sbrk(STD_LP_sbrk);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( keepgoing )
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0; /* done - stop iterating */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function recressively calls itself max times.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
usc_recressive_func(cnt, max, bstack)
|
||||||
|
int cnt;
|
||||||
|
int max;
|
||||||
|
struct usc_bigstack_t bstack;
|
||||||
|
{
|
||||||
|
if ( cnt < max )
|
||||||
|
usc_recressive_func(cnt+1, max, bstack);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
/******************************************************************************
|
||||||
|
* UNIT TEST CODE
|
||||||
|
* UNIT TEST CODE
|
||||||
|
*
|
||||||
|
* this following code is provide so that unit testing can
|
||||||
|
* be done fairly easily.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
int Help = 0;
|
||||||
|
int Help2 = 0;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Code from usctest.h that not part of this file since we are the library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Globals for returning the return code and errno from the system call
|
||||||
|
* test macros.
|
||||||
|
***********************************************************************/
|
||||||
|
int TEST_RETURN;
|
||||||
|
int TEST_ERRNO;
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* temporary variables for determining max and min times in TEST macro
|
||||||
|
***********************************************************************/
|
||||||
|
long btime, etime, tmptime;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* for test specific parse_opts options */
|
||||||
|
option_t Options[] = {
|
||||||
|
{ "help", &Help2, NULL }, /* -help option */
|
||||||
|
{ "h", &Help, NULL }, /* -h option */
|
||||||
|
{ TIMING, NULL, NULL}, /* disable -timing option */
|
||||||
|
|
||||||
|
#if INVALID_TEST_CASES
|
||||||
|
{ "missingflag", NULL, &ptr }, /* error */
|
||||||
|
{ "missingarg:", &Help, NULL }, /* error */
|
||||||
|
#endif /* INVALID_TEST_CASES */
|
||||||
|
|
||||||
|
{ NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
int lc;
|
||||||
|
char *msg;
|
||||||
|
struct timeval t;
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
if ( (msg=parse_opts(argc, argv,
|
||||||
|
(option_t *) Options)) != (char *) NULL ) {
|
||||||
|
printf("ERROR : %s\n", msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_PAUSE;
|
||||||
|
|
||||||
|
for (lc=0; TEST_LOOPING(lc); lc++) {
|
||||||
|
|
||||||
|
TEST( gettimeofday(&t, NULL) );
|
||||||
|
printf("iter=%d: sec:%d, usec:%6.6d %s", lc+1, t.tv_sec,
|
||||||
|
t.tv_usec, ctime(&t.tv_sec));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CLEANUP;
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* UNIT_TEST */
|
168
winsup/testsuite/libltp/lib/pattern.c
Normal file
168
winsup/testsuite/libltp/lib/pattern.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include "pattern.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The routines in this module are used to fill/check a data buffer
|
||||||
|
* with/against a known pattern.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
pattern_check(buf, buflen, pat, patlen, patshift)
|
||||||
|
char *buf;
|
||||||
|
int buflen;
|
||||||
|
char *pat;
|
||||||
|
int patlen;
|
||||||
|
int patshift;
|
||||||
|
{
|
||||||
|
int nb, ncmp, nleft;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (patlen)
|
||||||
|
patshift = patshift % patlen;
|
||||||
|
|
||||||
|
cp = buf;
|
||||||
|
nleft = buflen;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following 2 blocks of code are to compare the first patlen
|
||||||
|
* bytes of buf. We need 2 checks if patshift is > 0 since we
|
||||||
|
* must check the last (patlen - patshift) bytes, and then the
|
||||||
|
* first (patshift) bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nb = patlen - patshift;
|
||||||
|
if (nleft < nb) {
|
||||||
|
return (memcmp(cp, pat + patshift, nleft) ? -1 : 0);
|
||||||
|
} else {
|
||||||
|
if (memcmp(cp, pat + patshift, nb))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
nleft -= nb;
|
||||||
|
cp += nb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patshift > 0) {
|
||||||
|
nb = patshift;
|
||||||
|
if (nleft < nb) {
|
||||||
|
return (memcmp(cp, pat, nleft) ? -1 : 0);
|
||||||
|
} else {
|
||||||
|
if (memcmp(cp, pat, nb))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
nleft -= nb;
|
||||||
|
cp += nb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, verify the rest of the buffer using the algorithm described
|
||||||
|
* in the function header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ncmp = cp - buf;
|
||||||
|
while (ncmp < buflen) {
|
||||||
|
nb = (ncmp < nleft) ? ncmp : nleft;
|
||||||
|
if (memcmp(buf, cp, nb))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
cp += nb;
|
||||||
|
ncmp += nb;
|
||||||
|
nleft -= nb;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pattern_fill(buf, buflen, pat, patlen, patshift)
|
||||||
|
char *buf;
|
||||||
|
int buflen;
|
||||||
|
char *pat;
|
||||||
|
int patlen;
|
||||||
|
int patshift;
|
||||||
|
{
|
||||||
|
int trans, ncopied, nleft;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (patlen)
|
||||||
|
patshift = patshift % patlen;
|
||||||
|
|
||||||
|
cp = buf;
|
||||||
|
nleft = buflen;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following 2 blocks of code are to fill the first patlen
|
||||||
|
* bytes of buf. We need 2 sections if patshift is > 0 since we
|
||||||
|
* must first copy the last (patlen - patshift) bytes into buf[0]...,
|
||||||
|
* and then the first (patshift) bytes of pattern following them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
trans = patlen - patshift;
|
||||||
|
if (nleft < trans) {
|
||||||
|
memcpy(cp, pat + patshift, nleft);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
memcpy(cp, pat + patshift, trans);
|
||||||
|
nleft -= trans;
|
||||||
|
cp += trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patshift > 0) {
|
||||||
|
trans = patshift;
|
||||||
|
if (nleft < trans) {
|
||||||
|
memcpy(cp, pat, nleft);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
memcpy(cp, pat, trans);
|
||||||
|
nleft -= trans;
|
||||||
|
cp += trans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, fill the rest of the buffer using the algorithm described
|
||||||
|
* in the function header comment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ncopied = cp - buf;
|
||||||
|
while (ncopied < buflen) {
|
||||||
|
trans = (ncopied < nleft) ? ncopied : nleft;
|
||||||
|
memcpy(cp, buf, trans);
|
||||||
|
cp += trans;
|
||||||
|
ncopied += trans;
|
||||||
|
nleft -= trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
211
winsup/testsuite/libltp/lib/rmobj.c
Normal file
211
winsup/testsuite/libltp/lib/rmobj.c
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
*
|
||||||
|
* OS Testing - Silicon Graphics, Inc.
|
||||||
|
*
|
||||||
|
* FUNCTION NAME : rmobj()
|
||||||
|
*
|
||||||
|
* FUNCTION TITLE : Remove an object
|
||||||
|
*
|
||||||
|
* SYNOPSIS:
|
||||||
|
* int rmobj(char *obj, char **errmsg)
|
||||||
|
*
|
||||||
|
* AUTHOR : Kent Rogers
|
||||||
|
*
|
||||||
|
* INITIAL RELEASE : UNICOS 7.0
|
||||||
|
*
|
||||||
|
* USER DESCRIPTION
|
||||||
|
* This routine will remove the specified object. If the specified
|
||||||
|
* object is a directory, it will recursively remove the directory
|
||||||
|
* and everything underneath it. It assumes that it has privilege
|
||||||
|
* to remove everything that it tries to remove. If rmobj() encounters
|
||||||
|
* any problems, and errmsg is not NULL, errmsg is set to point to a
|
||||||
|
* string explaining the error.
|
||||||
|
*
|
||||||
|
* DETAILED DESCRIPTION
|
||||||
|
* Allocate space for the directory and its contents
|
||||||
|
* Open the directory to get access to what is in it
|
||||||
|
* Loop through the objects in the directory:
|
||||||
|
* If the object is not "." or "..":
|
||||||
|
* Determine the file type by calling lstat()
|
||||||
|
* If the object is not a directory:
|
||||||
|
* Remove the object with unlink()
|
||||||
|
* Else:
|
||||||
|
* Call rmobj(object) to remove the object's contents
|
||||||
|
* Determine the link count on object by calling lstat()
|
||||||
|
* If the link count >= 3:
|
||||||
|
* Remove the directory with unlink()
|
||||||
|
* Else
|
||||||
|
* Remove the directory with rmdir()
|
||||||
|
* Close the directory and free the pointers
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* If there are any problems, rmobj() will set errmsg (if it was not
|
||||||
|
* NULL) and return -1. Otherwise it will return 0.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
#include <errno.h> /* for errno */
|
||||||
|
#include <stdio.h> /* for NULL */
|
||||||
|
#include <stdlib.h> /* for malloc() */
|
||||||
|
#include <string.h> /* for string function */
|
||||||
|
#include <limits.h> /* for PATH_MAX */
|
||||||
|
#include <sys/types.h> /* for opendir(), readdir(), closedir(), stat() */
|
||||||
|
#include <sys/stat.h> /* for [l]stat() */
|
||||||
|
#include <dirent.h> /* for opendir(), readdir(), closedir() */
|
||||||
|
#include <unistd.h> /* for rmdir(), unlink() */
|
||||||
|
#include "rmobj.h"
|
||||||
|
|
||||||
|
#define SYSERR strerror(errno)
|
||||||
|
|
||||||
|
int
|
||||||
|
rmobj(char *obj, char **errmsg)
|
||||||
|
{
|
||||||
|
int ret_val = 0; /* return value from this routine */
|
||||||
|
DIR *dir; /* pointer to a directory */
|
||||||
|
struct dirent *dir_ent; /* pointer to directory entries */
|
||||||
|
char dirobj[PATH_MAX]; /* object inside directory to modify */
|
||||||
|
struct stat statbuf; /* used to hold stat information */
|
||||||
|
static char err_msg[1024]; /* error message */
|
||||||
|
|
||||||
|
/* Determine the file type */
|
||||||
|
if ( lstat(obj, &statbuf) < 0 ) {
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
sprintf(err_msg, "lstat(%s) failed; errno=%d: %s",
|
||||||
|
obj, errno, SYSERR);
|
||||||
|
*errmsg = err_msg;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take appropriate action, depending on the file type */
|
||||||
|
if ( (statbuf.st_mode & S_IFMT) == S_IFDIR ) {
|
||||||
|
/* object is a directory */
|
||||||
|
|
||||||
|
/* Do NOT perform the request if the directory is "/" */
|
||||||
|
if ( !strcmp(obj, "/") ) {
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
sprintf(err_msg, "Cannot remove /");
|
||||||
|
*errmsg = err_msg;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the directory to get access to what is in it */
|
||||||
|
if ( (dir = opendir(obj)) == NULL ) {
|
||||||
|
if ( rmdir(obj) != 0 ) {
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
sprintf(err_msg, "rmdir(%s) failed; errno=%d: %s",
|
||||||
|
obj, errno, SYSERR);
|
||||||
|
*errmsg = err_msg;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop through the entries in the directory, removing each one */
|
||||||
|
for ( dir_ent = (struct dirent *)readdir(dir);
|
||||||
|
dir_ent != NULL;
|
||||||
|
dir_ent = (struct dirent *)readdir(dir)) {
|
||||||
|
|
||||||
|
/* Don't remove "." or ".." */
|
||||||
|
if ( !strcmp(dir_ent->d_name, ".") || !strcmp(dir_ent->d_name, "..") )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Recursively call this routine to remove the current entry */
|
||||||
|
sprintf(dirobj, "%s/%s", obj, dir_ent->d_name);
|
||||||
|
if ( rmobj(dirobj, errmsg) != 0 )
|
||||||
|
ret_val = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the directory */
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
/* If there were problems removing an entry, don't attempt to
|
||||||
|
remove the directory itself */
|
||||||
|
if ( ret_val == -1 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Get the link count, now that all the entries have been removed */
|
||||||
|
if ( lstat(obj, &statbuf) < 0 ) {
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
sprintf(err_msg, "lstat(%s) failed; errno=%d: %s",
|
||||||
|
obj, errno, SYSERR);
|
||||||
|
*errmsg = err_msg;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the directory itself */
|
||||||
|
if ( statbuf.st_nlink >= 3 ) {
|
||||||
|
/* The directory is linked; unlink() must be used */
|
||||||
|
if ( unlink(obj) < 0 ) {
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
sprintf(err_msg, "unlink(%s) failed; errno=%d: %s",
|
||||||
|
obj, errno, SYSERR);
|
||||||
|
*errmsg = err_msg;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* The directory is not linked; rmdir() can be used */
|
||||||
|
if ( rmdir(obj) < 0 ) {
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
sprintf(err_msg, "rmdir(%s) failed; errno=%d: %s",
|
||||||
|
obj, errno, SYSERR);
|
||||||
|
*errmsg = err_msg;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* object is not a directory; just use unlink() */
|
||||||
|
if ( unlink(obj) < 0 ) {
|
||||||
|
if ( errmsg != NULL ) {
|
||||||
|
sprintf(err_msg, "unlink(%s) failed; errno=%d: %s",
|
||||||
|
obj, errno, SYSERR);
|
||||||
|
*errmsg = err_msg;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} /* if obj is a directory */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Everything must have went ok.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
} /* rmobj() */
|
251
winsup/testsuite/libltp/lib/search_path.c
Normal file
251
winsup/testsuite/libltp/lib/search_path.c
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (C) COPYRIGHT CRAY RESEARCH, INC.
|
||||||
|
* UNPUBLISHED PROPRIETARY INFORMATION.
|
||||||
|
* ALL RIGHTS RESERVED.
|
||||||
|
*/
|
||||||
|
/**********************************************************
|
||||||
|
*
|
||||||
|
* UNICOS Feature Test and Evaluation - Cray Research, Inc.
|
||||||
|
*
|
||||||
|
* FUNCTION NAME : search_path
|
||||||
|
*
|
||||||
|
* FUNCTION TITLE : search PATH locations for desired filename
|
||||||
|
*
|
||||||
|
* SYNOPSIS:
|
||||||
|
* int search_path(cmd, res_path, access_mode, fullpath)
|
||||||
|
* char *cmd;
|
||||||
|
* char *res_path;
|
||||||
|
* int access_mode;
|
||||||
|
* int fullpath;
|
||||||
|
*
|
||||||
|
* AUTHOR : Richard Logan
|
||||||
|
*
|
||||||
|
* INITIAL RELEASE : UNICOS 7.0
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* Search_path will walk through PATH and attempt to find "cmd". If cmd is
|
||||||
|
* a full or relative path, it is checked but PATH locations are not scanned.
|
||||||
|
* search_path will put the resulting path in res_path. It is assumed
|
||||||
|
* that res_path points to a string that is at least PATH_MAX
|
||||||
|
* (or MAXPATHLEN on the suns) in size. Access_mode is just as is
|
||||||
|
* says, the mode to be used on access to determine if cmd can be found.
|
||||||
|
* If fullpath is set, res_path will contain the full path to cmd.
|
||||||
|
* If it is not set, res_path may or may not contain the full path to cmd.
|
||||||
|
* If fullpath is not set, the path in PATH prepended to cmd is used,
|
||||||
|
* which could be a relative path. If fullpath is set, the current
|
||||||
|
* directory is prepended to path/cmd before access is called.
|
||||||
|
* If cmd is found, search_path will return 0. If cmd cannot be
|
||||||
|
* found, 1 is returned. If an error has occurred, -1 is returned
|
||||||
|
* and an error mesg is placed in res_path.
|
||||||
|
* If the length of path/cmd is larger then PATH_MAX, then that path
|
||||||
|
* location is skipped.
|
||||||
|
*
|
||||||
|
*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
#ifndef AS_CMD
|
||||||
|
#define AS_CMD 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure PATH_MAX is defined. Define it to MAXPATHLEN, if set. Otherwise
|
||||||
|
* set it to 1024.
|
||||||
|
*/
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#ifndef MAXPATHLEN
|
||||||
|
#define PATH_MAX 1024
|
||||||
|
#else /* MAXPATHLEN */
|
||||||
|
#define PATH_MAX MAXPATHLEN
|
||||||
|
#endif /* MAXPATHLEN */
|
||||||
|
#endif /* PATH_MAX */
|
||||||
|
|
||||||
|
|
||||||
|
#if AS_CMD
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int ind;
|
||||||
|
|
||||||
|
if (argc <= 1 ) {
|
||||||
|
printf("missing argument\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(ind=1;ind < argc; ind++) {
|
||||||
|
if ( search_path(argv[ind], path, F_OK, 0) < 0 ) {
|
||||||
|
printf("ERROR: %s\n", path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("path of %s is %s\n", argv[ind], path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
search_path(cmd, res_path, access_mode, fullpath)
|
||||||
|
char *cmd; /* The requested filename */
|
||||||
|
char *res_path; /* The resulting path or error mesg */
|
||||||
|
int access_mode; /* the mode used by access(2) */
|
||||||
|
int fullpath; /* if set, cwd will be prepended to all non-full paths */
|
||||||
|
{
|
||||||
|
char *cp; /* used to scan PATH for directories */
|
||||||
|
int ret; /* return value from access */
|
||||||
|
char *pathenv;
|
||||||
|
char tmppath[PATH_MAX];
|
||||||
|
char curpath[PATH_MAX];
|
||||||
|
char *path;
|
||||||
|
int lastpath;
|
||||||
|
int toolong=0;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("search_path: cmd = %s, access_mode = %d, fullpath = %d\n", cmd, access_mode, fullpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* full or relative path was given
|
||||||
|
*/
|
||||||
|
if ( (cmd[0] == '/') || ( (cp=strchr(cmd, '/')) != NULL )) {
|
||||||
|
if ( access(cmd, access_mode) == 0 ) {
|
||||||
|
|
||||||
|
if ( cmd[0] != '/' ) { /* relative path */
|
||||||
|
if ( getcwd(curpath, PATH_MAX) == NULL ) {
|
||||||
|
strcpy(res_path, curpath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( (strlen(curpath) + strlen(cmd) + 1) > (size_t)PATH_MAX ) {
|
||||||
|
sprintf(res_path, "cmd (as relative path) and cwd is longer than %d",
|
||||||
|
PATH_MAX);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sprintf(res_path, "%s/%s", curpath, cmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy(res_path, cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(res_path, "file %s not found", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the PATH variable */
|
||||||
|
if ( (pathenv=getenv("PATH")) == NULL) {
|
||||||
|
/* no path to scan, return */
|
||||||
|
sprintf(res_path, "Unable to get PATH env. variable");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* walk through each path in PATH.
|
||||||
|
* Each path in PATH is placed in tmppath.
|
||||||
|
* pathenv cannot be modified since it will affect PATH.
|
||||||
|
* If a signal came in while we have modified the PATH
|
||||||
|
* memory, we could create a problem for the caller.
|
||||||
|
*/
|
||||||
|
|
||||||
|
curpath[0]='\0';
|
||||||
|
|
||||||
|
cp = pathenv;
|
||||||
|
path = pathenv;
|
||||||
|
lastpath = 0;
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
if ( lastpath )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( cp != pathenv )
|
||||||
|
path = ++cp; /* already set on first iteration */
|
||||||
|
|
||||||
|
/* find end of current path */
|
||||||
|
|
||||||
|
for (; ((*cp != ':') && (*cp != '\0')); cp++);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* copy path to tmppath so it can be NULL terminated
|
||||||
|
* and so we do not modify path memory.
|
||||||
|
*/
|
||||||
|
strncpy(tmppath, path, (cp-path) );
|
||||||
|
tmppath[cp-path]='\0';
|
||||||
|
#if DEBUG
|
||||||
|
printf("search_path: tmppath = %s\n", tmppath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( *cp == '\0' )
|
||||||
|
lastpath=1; /* this is the last path entry */
|
||||||
|
|
||||||
|
/* Check lengths so not to overflow res_path */
|
||||||
|
if ( strlen(tmppath) + strlen(cmd) + 2 > (size_t)PATH_MAX ) {
|
||||||
|
toolong++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(res_path, "%s/%s", tmppath, cmd);
|
||||||
|
#if DEBUG
|
||||||
|
printf("search_path: res_path = '%s'\n", res_path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* if the path is not full at this point, prepend the current
|
||||||
|
* path to get the full path.
|
||||||
|
* Note: this could not be wise to do when under a protected
|
||||||
|
* directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( fullpath && res_path[0] != '/' ) { /* not a full path */
|
||||||
|
if ( curpath[0] == '\0' ) {
|
||||||
|
if ( getcwd(curpath, PATH_MAX) == NULL ) {
|
||||||
|
strcpy(res_path, curpath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( (strlen(curpath) + strlen(res_path) + 2) > (size_t)PATH_MAX ) {
|
||||||
|
toolong++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sprintf(tmppath, "%s/%s", curpath, res_path);
|
||||||
|
strcpy(res_path, tmppath);
|
||||||
|
#if DEBUG
|
||||||
|
printf("search_path: full res_path= '%s'\n", res_path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( (ret=access(res_path, access_mode)) == 0 ) {
|
||||||
|
#if DEBUG
|
||||||
|
printf("search_path: found res_path = %s\n", res_path);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return failure */
|
||||||
|
if ( toolong )
|
||||||
|
sprintf(res_path,
|
||||||
|
"Unable to find file, %d path/file strings were too long", toolong);
|
||||||
|
else
|
||||||
|
strcpy(res_path, "Unable to find file");
|
||||||
|
return 1; /* not found */
|
||||||
|
}
|
||||||
|
|
211
winsup/testsuite/libltp/lib/str_to_bytes.c
Normal file
211
winsup/testsuite/libltp/lib/str_to_bytes.c
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include "str_to_bytes.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* str_to_bytes(s)
|
||||||
|
*
|
||||||
|
* Computes the number of bytes described by string s. s is assumed to be
|
||||||
|
* a base 10 positive (ie. >= 0) number followed by an optional single
|
||||||
|
* character multiplier. The following multipliers are supported:
|
||||||
|
*
|
||||||
|
* char mult
|
||||||
|
* -----------------
|
||||||
|
* b BSIZE or BBSIZE
|
||||||
|
* k 1024 bytes
|
||||||
|
* K 1024 * sizeof(long)
|
||||||
|
* m 2^20 (1048576)
|
||||||
|
* M 2^20 (1048576 * sizeof(long)
|
||||||
|
* g 2^30 (1073741824)
|
||||||
|
* G 2^30 (1073741824) * sizeof(long)
|
||||||
|
*
|
||||||
|
* for instance, "1k" and "1024" would both cause str_to_bytes to return 1024.
|
||||||
|
*
|
||||||
|
* Returns -1 if mult is an invalid character, or if the integer portion of
|
||||||
|
* s is not a positive integer.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CRAY
|
||||||
|
#define B_MULT BSIZE /* block size */
|
||||||
|
#elif sgi
|
||||||
|
#define B_MULT BBSIZE /* block size */
|
||||||
|
#elif linux
|
||||||
|
#define B_MULT DEV_BSIZE /* block size */
|
||||||
|
#elif __CYGWIN__
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#define B_MULT S_BLKSIZE /* block size */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define K_MULT 1024 /* Kilo or 2^10 */
|
||||||
|
#define M_MULT 1048576 /* Mega or 2^20 */
|
||||||
|
#define G_MULT 1073741824 /* Giga or 2^30 */
|
||||||
|
#define T_MULT 1099511627776 /* tera or 2^40 */
|
||||||
|
|
||||||
|
int
|
||||||
|
str_to_bytes(s)
|
||||||
|
char *s;
|
||||||
|
{
|
||||||
|
char mult, junk;
|
||||||
|
int nconv;
|
||||||
|
float num;
|
||||||
|
|
||||||
|
nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
|
||||||
|
if (nconv == 0 || nconv == 3 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (nconv == 1)
|
||||||
|
return num;
|
||||||
|
|
||||||
|
switch (mult) {
|
||||||
|
case 'b':
|
||||||
|
return (int)(num * (float)B_MULT);
|
||||||
|
case 'k':
|
||||||
|
return (int)(num * (float)K_MULT);
|
||||||
|
case 'K':
|
||||||
|
return (int)((num * (float)K_MULT) * sizeof(long));
|
||||||
|
case 'm':
|
||||||
|
return (int)(num * (float)M_MULT);
|
||||||
|
case 'M':
|
||||||
|
return (int)((num * (float)M_MULT) * sizeof(long));
|
||||||
|
case 'g':
|
||||||
|
return (int)(num * (float)G_MULT);
|
||||||
|
case 'G':
|
||||||
|
return (int)((num * (float)G_MULT) * sizeof(long));
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
str_to_lbytes(s)
|
||||||
|
char *s;
|
||||||
|
{
|
||||||
|
char mult, junk;
|
||||||
|
long nconv;
|
||||||
|
float num;
|
||||||
|
|
||||||
|
nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
|
||||||
|
if (nconv == 0 || nconv == 3 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (nconv == 1)
|
||||||
|
return (long)num;
|
||||||
|
|
||||||
|
switch (mult) {
|
||||||
|
case 'b':
|
||||||
|
return (long)(num * (float)B_MULT);
|
||||||
|
case 'k':
|
||||||
|
return (long)(num * (float)K_MULT);
|
||||||
|
case 'K':
|
||||||
|
return (long)((num * (float)K_MULT) * sizeof(long));
|
||||||
|
case 'm':
|
||||||
|
return (long)(num * (float)M_MULT);
|
||||||
|
case 'M':
|
||||||
|
return (long)((num * (float)M_MULT) * sizeof(long));
|
||||||
|
case 'g':
|
||||||
|
return (long)(num * (float)G_MULT);
|
||||||
|
case 'G':
|
||||||
|
return (long)((num * (float)G_MULT) * sizeof(long));
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force 64 bits number when compiled as 32 IRIX binary.
|
||||||
|
* This allows for a number bigger than 2G.
|
||||||
|
*/
|
||||||
|
|
||||||
|
long long
|
||||||
|
str_to_llbytes(s)
|
||||||
|
char *s;
|
||||||
|
{
|
||||||
|
char mult, junk;
|
||||||
|
long nconv;
|
||||||
|
double num;
|
||||||
|
|
||||||
|
nconv = sscanf(s, "%lf%c%c", &num, &mult, &junk);
|
||||||
|
if (nconv == 0 || nconv == 3 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (nconv == 1)
|
||||||
|
return (long long)num;
|
||||||
|
|
||||||
|
switch (mult) {
|
||||||
|
case 'b':
|
||||||
|
return (long long)(num * (float)B_MULT);
|
||||||
|
case 'k':
|
||||||
|
return (long long)(num * (float)K_MULT);
|
||||||
|
case 'K':
|
||||||
|
return (long long)((num * (float)K_MULT) * sizeof(long long));
|
||||||
|
case 'm':
|
||||||
|
return (long long)(num * (float)M_MULT);
|
||||||
|
case 'M':
|
||||||
|
return (long long)((num * (float)M_MULT) * sizeof(long long));
|
||||||
|
case 'g':
|
||||||
|
return (long long)(num * (float)G_MULT);
|
||||||
|
case 'G':
|
||||||
|
return (long long)((num * (float)G_MULT) * sizeof(long long));
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UNIT_TEST
|
||||||
|
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ind;
|
||||||
|
|
||||||
|
if (argc == 1 ) {
|
||||||
|
fprintf(stderr, "missing str_to_bytes() parameteres\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ind=1; ind<argc; ind++) {
|
||||||
|
|
||||||
|
printf("str_to_bytes(%s) returned %d\n",
|
||||||
|
argv[ind], str_to_bytes(argv[ind]));
|
||||||
|
|
||||||
|
printf("str_to_lbytes(%s) returned %ld\n",
|
||||||
|
argv[ind], str_to_lbytes(argv[ind]));
|
||||||
|
|
||||||
|
printf("str_to_llbytes(%s) returned %lld\n",
|
||||||
|
argv[ind], str_to_llbytes(argv[ind]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
109
winsup/testsuite/libltp/lib/string_to_tokens.c
Normal file
109
winsup/testsuite/libltp/lib/string_to_tokens.c
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
/**********************************************************
|
||||||
|
*
|
||||||
|
* OS Testing - Silicon Graphics, Inc.
|
||||||
|
*
|
||||||
|
* FUNCTION NAME : string_to_tokens
|
||||||
|
*
|
||||||
|
* FUNCTION TITLE : Break a string into its tokens
|
||||||
|
*
|
||||||
|
* SYNOPSIS:
|
||||||
|
*
|
||||||
|
* int string_to_tokens(arg_string, arg_array, array_size, separator)
|
||||||
|
* char *arg_string;
|
||||||
|
* char *arg_array[];
|
||||||
|
* int array_size;
|
||||||
|
* char *separator;
|
||||||
|
*
|
||||||
|
* AUTHOR : Richard Logan
|
||||||
|
*
|
||||||
|
* DATE : 10/94
|
||||||
|
*
|
||||||
|
* INITIAL RELEASE : UNICOS 7.0
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* This function parses the string 'arg_string', placing pointers to
|
||||||
|
* the 'separator' separated tokens into the elements of 'arg_array'.
|
||||||
|
* The array is terminated with a null pointer.
|
||||||
|
* 'arg_array' must contains at least 'array_size' elements.
|
||||||
|
* Only the first 'array_size' minus one tokens will be placed into
|
||||||
|
* 'arg_array'. If there are more than 'array_size'-1 tokens, the rest are
|
||||||
|
* ignored by this routine.
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* This function returns the number of 'separator' separated tokens that
|
||||||
|
* were found in 'arg_string'.
|
||||||
|
* If 'arg_array' or 'separator' is NULL or 'array_size' is less than 2, -1 is returned.
|
||||||
|
*
|
||||||
|
* WARNING
|
||||||
|
* This function uses strtok() to parse 'arg_string', and thus
|
||||||
|
* physically alters 'arg_string' by placing null characters where the
|
||||||
|
* separators originally were.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h> /* for string functions */
|
||||||
|
#include "string_to_tokens.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
string_to_tokens(char *arg_string, char *arg_array[], int array_size, char *separator)
|
||||||
|
{
|
||||||
|
int num_toks = 0; /* number of tokens found */
|
||||||
|
char *strtok();
|
||||||
|
|
||||||
|
if ( arg_array == NULL || array_size <= 1 || separator == NULL )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use strtok() to parse 'arg_string', placing pointers to the
|
||||||
|
* individual tokens into the elements of 'arg_array'.
|
||||||
|
*/
|
||||||
|
if ( (arg_array[num_toks] = strtok(arg_string, separator)) == NULL ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (num_toks=1;num_toks<array_size; num_toks++) {
|
||||||
|
if ( (arg_array[num_toks] = strtok(NULL, separator)) == NULL )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( num_toks == array_size )
|
||||||
|
arg_array[num_toks] = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the number of tokens that were found in 'arg_string'.
|
||||||
|
*/
|
||||||
|
return(num_toks);
|
||||||
|
|
||||||
|
} /* end of string_to_tokens */
|
964
winsup/testsuite/libltp/lib/tst_res.c
Normal file
964
winsup/testsuite/libltp/lib/tst_res.c
Normal file
@ -0,0 +1,964 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
*
|
||||||
|
* OS Testing - Silicon Graphics, Inc.
|
||||||
|
*
|
||||||
|
* FUNCTION NAME :
|
||||||
|
* tst_res() - Print result message (include file contents)
|
||||||
|
* tst_resm() - Print result message
|
||||||
|
* tst_brk() - Print result message (include file contents)
|
||||||
|
* and break remaining test cases
|
||||||
|
* tst_brkm() - Print result message and break remaining test
|
||||||
|
* cases
|
||||||
|
* tst_brkloop() - Print result message (include file contents)
|
||||||
|
* and break test cases remaining in current loop
|
||||||
|
* tst_brkloopm() - Print result message and break test case
|
||||||
|
* remaining in current loop
|
||||||
|
* tst_flush() - Print any messages pending because of
|
||||||
|
* CONDENSE mode, and flush output stream
|
||||||
|
* tst_exit() - Exit test with a meaningful exit value.
|
||||||
|
* tst_environ() - Keep results coming to original stdout
|
||||||
|
*
|
||||||
|
* FUNCTION TITLE : Standard automated test result reporting mechanism
|
||||||
|
*
|
||||||
|
* SYNOPSIS:
|
||||||
|
* #include "test.h"
|
||||||
|
*
|
||||||
|
* void tst_res(ttype, fname, tmesg [,arg]...)
|
||||||
|
* int ttype;
|
||||||
|
* char *fname;
|
||||||
|
* char *tmesg;
|
||||||
|
*
|
||||||
|
* void tst_resm(ttype, tmesg [,arg]...)
|
||||||
|
* int ttype;
|
||||||
|
* char *tmesg;
|
||||||
|
*
|
||||||
|
* void tst_brk(ttype, fname, cleanup, tmesg, [,argv]...)
|
||||||
|
* int ttype;
|
||||||
|
* char *fname;
|
||||||
|
* void (*cleanup)();
|
||||||
|
* char *tmesg;
|
||||||
|
*
|
||||||
|
* void tst_brkm(ttype, cleanup, tmesg [,arg]...)
|
||||||
|
* int ttype;
|
||||||
|
* void (*cleanup)();
|
||||||
|
* char *tmesg;
|
||||||
|
*
|
||||||
|
* void tst_brkloop(ttype, fname, cleanup, char *tmesg, [,argv]...)
|
||||||
|
* int ttype;
|
||||||
|
* char *fname;
|
||||||
|
* void (*cleanup)();
|
||||||
|
* char *tmesg;
|
||||||
|
*
|
||||||
|
* void tst_brkloopm(ttype, cleanup, tmesg [,arg]...)
|
||||||
|
* int ttype;
|
||||||
|
* void (*cleanup)();
|
||||||
|
* char *tmesg;
|
||||||
|
*
|
||||||
|
* void tst_flush()
|
||||||
|
*
|
||||||
|
* void tst_exit()
|
||||||
|
*
|
||||||
|
* int tst_environ()
|
||||||
|
*
|
||||||
|
* AUTHOR : Kent Rogers (from Dave Fenner's original)
|
||||||
|
*
|
||||||
|
* CO-PILOT : Rich Logan
|
||||||
|
*
|
||||||
|
* DATE STARTED : 05/01/90 (rewritten 1/96)
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* See the man page(s).
|
||||||
|
*
|
||||||
|
*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h> /* for I/O functions, BUFSIZ */
|
||||||
|
#include <stdlib.h> /* for getenv() */
|
||||||
|
#include <stdarg.h> /* for varargs stuff */
|
||||||
|
#include <unistd.h> /* for access() */
|
||||||
|
#include "test.h" /* for output display mode & result type */
|
||||||
|
/* defines */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define some useful macros.
|
||||||
|
*/
|
||||||
|
#define VERBOSE 1 /* flag values for the T_mode variable */
|
||||||
|
#define CONDENSE 2
|
||||||
|
#define NOPASS 3
|
||||||
|
#define DISCARD 4
|
||||||
|
|
||||||
|
#define MAXMESG 80 /* max length of internal messages */
|
||||||
|
#define USERMESG 2048 /* max length of user message */
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EXPAND_VAR_ARGS - Expand the variable portion (arg_fmt) of a result
|
||||||
|
* message into the specified string.
|
||||||
|
*/
|
||||||
|
#define EXPAND_VAR_ARGS(arg_fmt, str) { \
|
||||||
|
va_list ap; /* varargs mechanism */ \
|
||||||
|
\
|
||||||
|
if ( arg_fmt != NULL ) { \
|
||||||
|
if ( Expand_varargs == TRUE ) { \
|
||||||
|
va_start(ap, arg_fmt); \
|
||||||
|
vsprintf(str, arg_fmt, ap); \
|
||||||
|
va_end(ap); \
|
||||||
|
Expand_varargs = FALSE; \
|
||||||
|
} else { \
|
||||||
|
strcpy(str, arg_fmt); \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
str[0] = '\0'; \
|
||||||
|
} \
|
||||||
|
} /* EXPAND_VAR_ARGS() */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define local function prototypes.
|
||||||
|
*/
|
||||||
|
static void check_env();
|
||||||
|
static void tst_condense(int tnum, int ttype, char *tmesg);
|
||||||
|
static void tst_print(char *tcid, int tnum, int trange, int ttype, char *tmesg);
|
||||||
|
static void cat_file(char *filename);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define some static/global variables.
|
||||||
|
*/
|
||||||
|
static FILE *T_out = NULL; /* tst_res() output file descriptor */
|
||||||
|
static char *File; /* file whose contents is part of result */
|
||||||
|
static int T_exitval = 0; /* exit value used by tst_exit() */
|
||||||
|
static int T_mode = VERBOSE; /* flag indicating print mode: VERBOSE, */
|
||||||
|
/* CONDENSE, NOPASS, DISCARD */
|
||||||
|
|
||||||
|
static int Expand_varargs = TRUE; /* if TRUE, expand varargs stuff */
|
||||||
|
static char Warn_mesg[MAXMESG]; /* holds warning messages */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are used for condensing output when NOT in verbose mode.
|
||||||
|
*/
|
||||||
|
static int Buffered = FALSE; /* TRUE if condensed output is currently */
|
||||||
|
/* buffered (i.e. not yet printed) */
|
||||||
|
static char *Last_tcid; /* previous test case id */
|
||||||
|
static int Last_num; /* previous test case number */
|
||||||
|
static int Last_type; /* previous test result type */
|
||||||
|
static char *Last_mesg; /* previous test result message */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These globals may be externed by the test.
|
||||||
|
*/
|
||||||
|
int Tst_count = 0; /* current count of test cases executed; NOTE: */
|
||||||
|
/* Tst_count may be externed by other programs */
|
||||||
|
int Tst_lptotal = 0; /* tst_brkloop() external */
|
||||||
|
int Tst_lpstart = 0; /* tst_brkloop() external */
|
||||||
|
int Tst_range = 1; /* for specifying multiple results */
|
||||||
|
int Tst_nobuf = 1; /* this is a no-op; buffering is never done, but */
|
||||||
|
/* this will stay for compatibility reasons */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These globals must be defined in the test.
|
||||||
|
*/
|
||||||
|
extern char *TCID; /* Test case identifier from the test source */
|
||||||
|
extern int TST_TOTAL; /* Total number of test cases from the test */
|
||||||
|
/* source */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This global is used by the temp. dir. maintenance functions,
|
||||||
|
* tst_tmpdir()/tst_rmdir(), tst_wildcard()/tst_tr_rmdir(). It is the
|
||||||
|
* name of the directory created (if any). It is defined here, so that
|
||||||
|
* it only has to be declared once and can then be referenced from more
|
||||||
|
* than one module. Also, since the temp. dir. maintenance functions
|
||||||
|
* rely on the tst_res.c package this seemed like a reasonable place.
|
||||||
|
*/
|
||||||
|
char *TESTDIR = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_res() - Main result reporting function. Handle test information
|
||||||
|
* appropriately depending on output display mode. Call
|
||||||
|
* tst_condense() or tst_print() to actually print results.
|
||||||
|
* All result functions (tst_resm(), tst_brk(), etc.)
|
||||||
|
* eventually get here to print the results.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tst_res(int ttype, char *fname, char *arg_fmt, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char tmesg[USERMESG]; /* expanded message */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_res; Tst_count = %d; Tst_range = %d\n",
|
||||||
|
Tst_count, Tst_range); fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand the arg_fmt string into tmesg, if necessary.
|
||||||
|
*/
|
||||||
|
EXPAND_VAR_ARGS(arg_fmt, tmesg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the test result type by ORing ttype into the current exit
|
||||||
|
* value (used by tst_exit()).
|
||||||
|
*/
|
||||||
|
T_exitval |= ttype;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unless T_out has already been set by tst_environ(), make tst_res()
|
||||||
|
* output go to standard output.
|
||||||
|
*/
|
||||||
|
if ( T_out == NULL )
|
||||||
|
T_out = stdout;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check TOUTPUT environment variable (if first time) and set T_mode
|
||||||
|
* flag.
|
||||||
|
*/
|
||||||
|
check_env();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A negative or NULL range is invalid.
|
||||||
|
*/
|
||||||
|
if ( Tst_range <= 0 ) {
|
||||||
|
Tst_range = 1;
|
||||||
|
tst_print(TCID, 0, 1, TWARN,
|
||||||
|
"tst_res(): Tst_range must be positive");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a filename was specified, set 'File' if it exists.
|
||||||
|
*/
|
||||||
|
if ( fname != NULL && access(fname, F_OK) == 0 )
|
||||||
|
File = fname;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the test case number and print the results, depending on the
|
||||||
|
* display type.
|
||||||
|
*/
|
||||||
|
if ( ttype == TWARN || ttype == TINFO ) {
|
||||||
|
/*
|
||||||
|
* Handle WARN and INFO results (test case number is 0).
|
||||||
|
*/
|
||||||
|
if ( Tst_range > 1 ) {
|
||||||
|
tst_print(TCID, 0, 1, TWARN,
|
||||||
|
"tst_res(): Range not valid for TINFO or TWARN types");
|
||||||
|
}
|
||||||
|
tst_print(TCID, 0, 1, ttype, tmesg);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Handle all other types of results other than WARN and INFO.
|
||||||
|
*/
|
||||||
|
if ( Tst_count < 0 )
|
||||||
|
tst_print(TCID, 0, 1, TWARN,
|
||||||
|
"tst_res(): Tst_count < 0 is not valid");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process each display type.
|
||||||
|
*/
|
||||||
|
switch ( T_mode ) {
|
||||||
|
case DISCARD:
|
||||||
|
/* do not print any results */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NOPASS: /* passing result types are filtered by tst_print() */
|
||||||
|
case CONDENSE:
|
||||||
|
tst_condense(Tst_count + 1, ttype, tmesg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* VERBOSE */
|
||||||
|
for ( i = 1 ; i <= Tst_range ; i++ )
|
||||||
|
tst_print(TCID, Tst_count + i, Tst_range, ttype, tmesg);
|
||||||
|
break;
|
||||||
|
} /* end switch() */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Increment Tst_count.
|
||||||
|
*/
|
||||||
|
Tst_count += Tst_range;
|
||||||
|
} /* if ( ttype == TWARN || ttype == TINFO ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset some values.
|
||||||
|
*/
|
||||||
|
Tst_range = 1;
|
||||||
|
Expand_varargs = TRUE;
|
||||||
|
} /* tst_res() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_condense() - Handle test cases in CONDENSE or NOPASS mode (i.e.
|
||||||
|
* buffer the current result and print the last result
|
||||||
|
* if different than the current). If a file was
|
||||||
|
* specified, print the current result and do not
|
||||||
|
* buffer it.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
tst_condense(int tnum, int ttype, char *tmesg)
|
||||||
|
{
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_condense: tcid = %s, tnum = %d, ttype = %d, tmesg = %s\n",
|
||||||
|
TCID, tnum, ttype, tmesg);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this result is the same as the previous result, return.
|
||||||
|
*/
|
||||||
|
if ( Buffered == TRUE ) {
|
||||||
|
if ( strcmp(Last_tcid, TCID) == 0 && Last_type == ttype &&
|
||||||
|
strcmp(Last_mesg, tmesg) == 0 && File == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This result is different from the previous result. First,
|
||||||
|
* print the previous result.
|
||||||
|
*/
|
||||||
|
file = File;
|
||||||
|
File = NULL;
|
||||||
|
tst_print(Last_tcid, Last_num, tnum - Last_num, Last_type,
|
||||||
|
Last_mesg);
|
||||||
|
free(Last_tcid);
|
||||||
|
free(Last_mesg);
|
||||||
|
File = file;
|
||||||
|
} /* if ( Buffered == TRUE ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a file was specified, print the current result since we have no
|
||||||
|
* way of retaining the file contents for comparing with future
|
||||||
|
* results. Otherwise, buffer the current result info for next time.
|
||||||
|
*/
|
||||||
|
if ( File != NULL ) {
|
||||||
|
tst_print(TCID, tnum, Tst_range, ttype, tmesg);
|
||||||
|
Buffered = FALSE;
|
||||||
|
} else {
|
||||||
|
Last_tcid = (char *)malloc(strlen(TCID) + 1);
|
||||||
|
strcpy(Last_tcid, TCID);
|
||||||
|
Last_num = tnum;
|
||||||
|
Last_type = ttype;
|
||||||
|
Last_mesg = (char *)malloc(strlen(tmesg) + 1);
|
||||||
|
strcpy(Last_mesg, tmesg);
|
||||||
|
Buffered = TRUE;
|
||||||
|
}
|
||||||
|
} /* tst_condense() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_flush() - Print any messages pending because of CONDENSE mode,
|
||||||
|
* and flush T_out.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tst_flush()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_flush\n");
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print out last line if in CONDENSE or NOPASS mode.
|
||||||
|
*/
|
||||||
|
if ( Buffered == TRUE && (T_mode == CONDENSE || T_mode == NOPASS) ) {
|
||||||
|
tst_print(Last_tcid, Last_num, Tst_count - Last_num + 1,
|
||||||
|
Last_type, Last_mesg);
|
||||||
|
Buffered = FALSE;
|
||||||
|
}
|
||||||
|
fflush(T_out);
|
||||||
|
} /* tst_flush() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_print() - Actually print a line or range of lines to the output
|
||||||
|
* stream.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
tst_print(char *tcid, int tnum, int trange, int ttype, char *tmesg)
|
||||||
|
{
|
||||||
|
char type[5];
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_print: tnum = %d, trange = %d, ttype = %d, tmesg = %s\n",
|
||||||
|
tnum, trange, ttype, tmesg);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the test result type by ORing ttype into the current exit
|
||||||
|
* value (used by tst_exit()). This is already done in tst_res(), but
|
||||||
|
* is also done here to catch internal warnings. For internal warnings,
|
||||||
|
* tst_print() is called directly with a case of TWARN.
|
||||||
|
*/
|
||||||
|
T_exitval |= ttype;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If output mode is DISCARD, or if the output mode is NOPASS and
|
||||||
|
* this result is not one of FAIL, BROK, or WARN, just return. This
|
||||||
|
* check is necessary even though we check for DISCARD mode inside of
|
||||||
|
* tst_res(), since occasionally we get to this point without going
|
||||||
|
* through tst_res() (e.g. internal TWARN messages).
|
||||||
|
*/
|
||||||
|
if ( T_mode == DISCARD || (T_mode == NOPASS && ttype != TFAIL &&
|
||||||
|
ttype != TBROK && ttype != TWARN) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in the type string according to ttype.
|
||||||
|
*/
|
||||||
|
switch ( ttype ) {
|
||||||
|
case TPASS:
|
||||||
|
strcpy(type, "PASS");
|
||||||
|
break;
|
||||||
|
case TFAIL:
|
||||||
|
strcpy(type, "FAIL");
|
||||||
|
break;
|
||||||
|
case TBROK:
|
||||||
|
strcpy(type, "BROK");
|
||||||
|
break;
|
||||||
|
case TRETR:
|
||||||
|
strcpy(type, "RETR");
|
||||||
|
break;
|
||||||
|
case TCONF:
|
||||||
|
strcpy(type, "CONF");
|
||||||
|
break;
|
||||||
|
case TWARN:
|
||||||
|
strcpy(type, "WARN");
|
||||||
|
break;
|
||||||
|
case TINFO:
|
||||||
|
strcpy(type, "INFO");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcpy(type, "????");
|
||||||
|
break;
|
||||||
|
} /* switch ( ttype ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build the result line and print it.
|
||||||
|
*/
|
||||||
|
if ( T_mode == VERBOSE ) {
|
||||||
|
fprintf(T_out, "%-8s %4d %s : %s\n", tcid, tnum, type, tmesg);
|
||||||
|
} else {
|
||||||
|
/* condense results if a range is specified */
|
||||||
|
if ( trange > 1 )
|
||||||
|
fprintf(T_out, "%-8s %4d-%-4d %s : %s\n",
|
||||||
|
tcid, tnum, tnum + trange - 1, type, tmesg);
|
||||||
|
else
|
||||||
|
fprintf(T_out, "%-8s %4d %s : %s\n",
|
||||||
|
tcid, tnum, type, tmesg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If tst_res() was called with a file, append file contents to the
|
||||||
|
* end of last printed result.
|
||||||
|
*/
|
||||||
|
if ( File != NULL )
|
||||||
|
cat_file(File);
|
||||||
|
File = NULL;
|
||||||
|
} /* tst_print() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check_env() - Check the value of the environment variable TOUTPUT and
|
||||||
|
* set the global variable T_mode. The TOUTPUT environment
|
||||||
|
* variable should be set to "VERBOSE", "CONDENSE",
|
||||||
|
* "NOPASS", or "DISCARD". If TOUTPUT does not exist or
|
||||||
|
* is not set to a valid value, the default is "VERBOSE".
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
check_env()
|
||||||
|
{
|
||||||
|
static int first_time = 1;
|
||||||
|
char *value; /* value of TOUTPUT environment variable */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN check_env\n");
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( !first_time )
|
||||||
|
return;
|
||||||
|
|
||||||
|
first_time = 0;
|
||||||
|
|
||||||
|
if ( (value = getenv(TOUTPUT)) == NULL ) {
|
||||||
|
/* TOUTPUT not defined, use default */
|
||||||
|
T_mode = VERBOSE;
|
||||||
|
} else if ( strcmp(value, TOUT_CONDENSE_S) == 0 ) {
|
||||||
|
T_mode = CONDENSE;
|
||||||
|
} else if ( strcmp(value, TOUT_NOPASS_S) == 0 ) {
|
||||||
|
T_mode = NOPASS;
|
||||||
|
} else if ( strcmp(value, TOUT_DISCARD_S) == 0 ) {
|
||||||
|
T_mode = DISCARD;
|
||||||
|
} else {
|
||||||
|
/* default */
|
||||||
|
T_mode = VERBOSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} /* check_env() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_exit() - Call exit() with the value T_exitval, set up by
|
||||||
|
* tst_res(). T_exitval has a bit set for most of the
|
||||||
|
* result types that were seen (including TPASS, TFAIL,
|
||||||
|
* TBROK, TWARN, TCONF). Also, print the last result (if
|
||||||
|
* necessary) before exiting.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tst_exit()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_exit\n"); fflush(stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call tst_flush() flush any ouput in the buffer or the last
|
||||||
|
* result not printed because of CONDENSE mode.
|
||||||
|
*/
|
||||||
|
tst_flush();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mask out TRETR, TINFO, and TCONF results from the exit status.
|
||||||
|
*/
|
||||||
|
exit(T_exitval & ~(TRETR | TINFO | TCONF));
|
||||||
|
} /* tst_exit() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_environ() - Preserve the tst_res() output location, despite any
|
||||||
|
* changes to stdout.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
tst_environ()
|
||||||
|
{
|
||||||
|
FILE *fdopen();
|
||||||
|
|
||||||
|
if ( (T_out = fdopen(dup(fileno(stdout)), "w")) == NULL )
|
||||||
|
return(-1);
|
||||||
|
else
|
||||||
|
return(0);
|
||||||
|
} /* tst_environ() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_brk() - Fail or break current test case, and break the remaining
|
||||||
|
* tests cases.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tst_brk(int ttype, char *fname, void (*func)(), char *arg_fmt, ...)
|
||||||
|
{
|
||||||
|
char tmesg[USERMESG]; /* expanded message */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_brk\n"); fflush(stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand the arg_fmt string into tmesg, if necessary.
|
||||||
|
*/
|
||||||
|
EXPAND_VAR_ARGS(arg_fmt, tmesg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only FAIL, BROK, CONF, and RETR are supported by tst_brk().
|
||||||
|
*/
|
||||||
|
if ( ttype != TFAIL && ttype != TBROK && ttype != TCONF &&
|
||||||
|
ttype != TRETR ) {
|
||||||
|
sprintf(Warn_mesg, "tst_brk(): Invalid Type: %d. Using TBROK",
|
||||||
|
ttype);
|
||||||
|
tst_print(TCID, 0, 1, TWARN, Warn_mesg);
|
||||||
|
ttype = TBROK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the first result, if necessary.
|
||||||
|
*/
|
||||||
|
if ( Tst_count < TST_TOTAL )
|
||||||
|
tst_res(ttype, fname, tmesg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the number of results left to report.
|
||||||
|
*/
|
||||||
|
Tst_range = TST_TOTAL - Tst_count;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the rest of the results, if necessary.
|
||||||
|
*/
|
||||||
|
if ( Tst_range > 0 ) {
|
||||||
|
if ( ttype == TCONF )
|
||||||
|
tst_res(ttype, NULL,
|
||||||
|
"Remaining cases not appropriate for configuration");
|
||||||
|
else if ( ttype == TRETR )
|
||||||
|
tst_res(ttype, NULL, "Remaining cases retired");
|
||||||
|
else
|
||||||
|
tst_res(TBROK, NULL, "Remaining cases broken");
|
||||||
|
} else {
|
||||||
|
Tst_range = 1;
|
||||||
|
Expand_varargs = TRUE;
|
||||||
|
} /* if ( Tst_range > 0 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If no cleanup function was specified, just return to the caller.
|
||||||
|
* Otherwise call the specified function. If specified function
|
||||||
|
* returns, call tst_exit().
|
||||||
|
*/
|
||||||
|
if ( func != NULL ) {
|
||||||
|
(*func)();
|
||||||
|
tst_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} /* tst_brk() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_brkloop() - Fail or break current test case, and break the
|
||||||
|
* remaining test cases within test case loop.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tst_brkloop(int ttype, char *fname, void (*func)(), char *arg_fmt, ...)
|
||||||
|
{
|
||||||
|
char tmesg[USERMESG]; /* expanded message */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_brkloop\n"); fflush(stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand the arg_fmt string into tmesg.
|
||||||
|
*/
|
||||||
|
EXPAND_VAR_ARGS(arg_fmt, tmesg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify that Tst_lpstart & Tst_lptotal are valid.
|
||||||
|
*/
|
||||||
|
if ( Tst_lpstart < 0 || Tst_lptotal < 0 ) {
|
||||||
|
tst_print(TCID, 0, 1, TWARN,
|
||||||
|
"tst_brkloop(): Tst_lpstart & Tst_lptotal must both be assigned non-negative values");
|
||||||
|
Expand_varargs = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only FAIL, BROK, CONF, and RETR are supported by tst_brkloop().
|
||||||
|
*/
|
||||||
|
if ( ttype != TFAIL && ttype != TBROK && ttype != TCONF &&
|
||||||
|
ttype != TRETR ) {
|
||||||
|
sprintf(Warn_mesg,
|
||||||
|
"tst_brkloop(): Invalid Type: %d. Using TBROK",
|
||||||
|
ttype);
|
||||||
|
tst_print(TCID, 0, 1, TWARN, Warn_mesg);
|
||||||
|
ttype = TBROK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the first result, if necessary.
|
||||||
|
*/
|
||||||
|
if ( Tst_count < Tst_lpstart + Tst_lptotal )
|
||||||
|
tst_res(ttype, fname, tmesg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the number of results left to report.
|
||||||
|
*/
|
||||||
|
Tst_range = Tst_lptotal + Tst_lpstart - Tst_count;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the rest of the results, if necessary.
|
||||||
|
*/
|
||||||
|
if ( Tst_range > 0 ) {
|
||||||
|
if ( ttype == TCONF )
|
||||||
|
tst_res(ttype, NULL,
|
||||||
|
"Remaining cases in loop not appropriate for configuration");
|
||||||
|
else if ( ttype == TRETR )
|
||||||
|
tst_res(ttype, NULL, "Remaining cases in loop retired");
|
||||||
|
else
|
||||||
|
tst_res(TBROK, NULL, "Remaining cases in loop broken");
|
||||||
|
} else {
|
||||||
|
Tst_range = 1;
|
||||||
|
Expand_varargs = TRUE;
|
||||||
|
} /* if ( Tst_range > 0 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a cleanup function was specified, call it.
|
||||||
|
*/
|
||||||
|
if ( func != NULL )
|
||||||
|
(*func)();
|
||||||
|
} /* tst_brkloop() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_resm() - Interface to tst_res(), with no filename.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tst_resm(int ttype, char *arg_fmt, ...)
|
||||||
|
{
|
||||||
|
char tmesg[USERMESG]; /* expanded message */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_resm\n"); fflush(stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand the arg_fmt string into tmesg.
|
||||||
|
*/
|
||||||
|
EXPAND_VAR_ARGS(arg_fmt, tmesg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call tst_res with a null filename argument.
|
||||||
|
*/
|
||||||
|
tst_res(ttype, NULL, tmesg);
|
||||||
|
} /* tst_resm() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_brkm() - Interface to tst_brk(), with no filename.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tst_brkm(int ttype, void (*func)(), char *arg_fmt, ...)
|
||||||
|
{
|
||||||
|
char tmesg[USERMESG]; /* expanded message */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_brkm\n"); fflush(stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand the arg_fmt string into tmesg.
|
||||||
|
*/
|
||||||
|
EXPAND_VAR_ARGS(arg_fmt, tmesg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call tst_brk with a null filename argument.
|
||||||
|
*/
|
||||||
|
tst_brk(ttype, NULL, func, tmesg);
|
||||||
|
} /* tst_brkm() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_brkloopm() - Interface to tst_brkloop(), with no filename.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tst_brkloopm(int ttype, void (*func)(), char *arg_fmt, ...)
|
||||||
|
{
|
||||||
|
char tmesg[USERMESG]; /* expanded message */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN tst_brkloopm\n");
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand the arg_fmt string into tmesg.
|
||||||
|
*/
|
||||||
|
EXPAND_VAR_ARGS(arg_fmt, tmesg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call tst_brkloop with a null filename argument.
|
||||||
|
*/
|
||||||
|
tst_brkloop(ttype, NULL, func, tmesg);
|
||||||
|
} /* tst_brkloopm() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cat_file() - Print the contents of a file to standard out.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
cat_file(char *filename)
|
||||||
|
{
|
||||||
|
FILE *fp; /* file pointer */
|
||||||
|
int b_read; /* number of bytes read with read() */
|
||||||
|
int b_written; /* number of bytes written with write() */
|
||||||
|
char buffer[BUFSIZ]; /* read/write buffer; BUFSIZ defined in */
|
||||||
|
/* stdio.h */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("IN cat_file\n"); fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the file for reading.
|
||||||
|
*/
|
||||||
|
if ( (fp = fopen(filename, "r")) == NULL ) {
|
||||||
|
sprintf(Warn_mesg,
|
||||||
|
"tst_res(): fopen(%s, \"r\") failed; errno = %d: %s",
|
||||||
|
filename, errno, strerror(errno));
|
||||||
|
tst_print(TCID, 0, 1, TWARN, Warn_mesg);
|
||||||
|
return;
|
||||||
|
} /* if ( fopen(filename, "r") == -1 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* While something to read, continue to read blocks.
|
||||||
|
* From fread(3) man page:
|
||||||
|
* If an error occurs, or the end-of-file is reached, the return
|
||||||
|
* value is zero.
|
||||||
|
*/
|
||||||
|
errno = 0;
|
||||||
|
while ( (b_read = fread((void *)buffer, 1, BUFSIZ, fp)) != (size_t)0 ) {
|
||||||
|
/*
|
||||||
|
* Write what was read to the result output stream.
|
||||||
|
*/
|
||||||
|
if ( (b_written = fwrite((void *)buffer, 1, b_read, T_out)) !=
|
||||||
|
b_read ) {
|
||||||
|
sprintf(Warn_mesg,
|
||||||
|
"tst_res(): While trying to cat \"%s\", fwrite() wrote only %d of %d bytes",
|
||||||
|
filename, b_written, b_read);
|
||||||
|
tst_print(TCID, 0, 1, TWARN, Warn_mesg);
|
||||||
|
break;
|
||||||
|
} /* if ( b_written != b_read ) */
|
||||||
|
} /* while ( fread() != 0 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for an fread() error.
|
||||||
|
*/
|
||||||
|
if ( !feof(fp) ) {
|
||||||
|
sprintf(Warn_mesg,
|
||||||
|
"tst_res(): While trying to cat \"%s\", fread() failed, errno = %d: %s",
|
||||||
|
filename, errno, strerror(errno));
|
||||||
|
tst_print(TCID, 0, 1, TWARN, Warn_mesg);
|
||||||
|
} /* if ( !feof() ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close the file.
|
||||||
|
*/
|
||||||
|
if ( fclose(fp) == EOF ) {
|
||||||
|
sprintf(Warn_mesg,
|
||||||
|
"tst_res(): While trying to cat \"%s\", fclose() failed, errno = %d: %s",
|
||||||
|
filename, errno, strerror(errno));
|
||||||
|
tst_print(TCID, 0, 1, TWARN, Warn_mesg);
|
||||||
|
} /* if ( fclose(fp) == EOF ) */
|
||||||
|
} /* cat_file() */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef UNIT_TEST
|
||||||
|
/****************************************************************************
|
||||||
|
* Unit test code: Takes input from stdin and can make the following
|
||||||
|
* calls: tst_res(), tst_resm(), tst_brk(), tst_brkm(),
|
||||||
|
* tst_flush_buf(), tst_exit().
|
||||||
|
****************************************************************************/
|
||||||
|
int TST_TOTAL = 10;
|
||||||
|
char *TCID = "TESTTCID";
|
||||||
|
|
||||||
|
#define RES "tst_res.c UNIT TEST message; ttype = %d; contents of \"%s\":"
|
||||||
|
#define RESM "tst_res.c UNIT TEST message; ttype = %d"
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int ttype;
|
||||||
|
int range;
|
||||||
|
char *chrptr;
|
||||||
|
char chr;
|
||||||
|
char fname[MAXMESG];
|
||||||
|
|
||||||
|
printf("UNIT TEST of tst_res.c. Options for ttype:\n\
|
||||||
|
-1 : call tst_exit()\n\
|
||||||
|
-2 : call tst_flush()\n\
|
||||||
|
-3 : call tst_brk()\n\
|
||||||
|
-4 : call tst_brkloop()\n\
|
||||||
|
-5 : call tst_res() with a range\n\
|
||||||
|
0 : call tst_res(TPASS, ...)\n\
|
||||||
|
1 : call tst_res(TFAIL, ...)\n\
|
||||||
|
2 : call tst_res(TBROK, ...)\n\
|
||||||
|
4 : call tst_res(TWARN, ...)\n\
|
||||||
|
8 : call tst_res(TRETR, ...)\n\
|
||||||
|
16 : call tst_res(TINFO, ...)\n\
|
||||||
|
32 : call tst_res(TCONF, ...)\n\n");
|
||||||
|
|
||||||
|
while ( 1 ) {
|
||||||
|
printf("Enter ttype (-5,-4,-3,-2,-1,0,1,2,4,8,16,32): ");
|
||||||
|
(void) scanf("%d%c", &ttype, &chr);
|
||||||
|
|
||||||
|
|
||||||
|
switch ( ttype ) {
|
||||||
|
case -1:
|
||||||
|
tst_exit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -2:
|
||||||
|
tst_flush();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -3:
|
||||||
|
printf("Enter the current type (1=FAIL, 2=BROK, 8=RETR, 32=CONF): ");
|
||||||
|
(void) scanf("%d%c", &ttype, &chr);
|
||||||
|
printf("Enter file name (<cr> for none): ");
|
||||||
|
gets(fname);
|
||||||
|
if ( strcmp(fname, "") == 0 )
|
||||||
|
tst_brkm(ttype, tst_exit, RESM, ttype);
|
||||||
|
else
|
||||||
|
tst_brk(ttype, fname, tst_exit, RES, ttype, fname);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -4:
|
||||||
|
printf("Enter the size of the loop: ");
|
||||||
|
(void) scanf("%d%c", &range, &chr);
|
||||||
|
Tst_lpstart = Tst_count;
|
||||||
|
Tst_lptotal = range;
|
||||||
|
printf("Enter the current type (1=FAIL, 2=BROK, 8=RETR, 32=CONF): ");
|
||||||
|
(void) scanf("%d%c", &ttype, &chr);
|
||||||
|
printf("Enter file name (<cr> for none): ");
|
||||||
|
gets(fname);
|
||||||
|
if ( strcmp(fname, "") == 0 )
|
||||||
|
tst_brkloopm(ttype, NULL, RESM, ttype);
|
||||||
|
else
|
||||||
|
tst_brkloop(ttype, fname, NULL, RES, ttype, fname);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -5:
|
||||||
|
printf("Enter the size of the range: ");
|
||||||
|
(void) scanf("%d%c", &Tst_range, &chr);
|
||||||
|
printf("Enter the current type (0,1,2,4,8,16,32): ");
|
||||||
|
(void) scanf("%d%c", &ttype, &chr);
|
||||||
|
/* fall through to tst_res() call */
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("Enter file name (<cr> for none): ");
|
||||||
|
gets(fname);
|
||||||
|
if ( strcmp(fname, "") == 0 )
|
||||||
|
tst_resm(ttype, RESM, ttype);
|
||||||
|
else
|
||||||
|
tst_res(ttype, fname, RES, ttype, fname);
|
||||||
|
break;
|
||||||
|
} /* switch() */
|
||||||
|
} /* while() */
|
||||||
|
}
|
||||||
|
#endif /* UNIT_TEST */
|
213
winsup/testsuite/libltp/lib/tst_sig.c
Normal file
213
winsup/testsuite/libltp/lib/tst_sig.c
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
OS Testing - Silicon Graphics, Inc.
|
||||||
|
|
||||||
|
FUNCTION IDENTIFIER : tst_sig Set up for unexpected signals.
|
||||||
|
|
||||||
|
AUTHOR : David D. Fenner
|
||||||
|
|
||||||
|
CO-PILOT : Bill Roske
|
||||||
|
|
||||||
|
DATE STARTED : 06/06/90
|
||||||
|
|
||||||
|
This module may be linked with c-modules requiring unexpected
|
||||||
|
signal handling. The parameters to tst_sig are as follows:
|
||||||
|
|
||||||
|
fork_flag - set to FORK or NOFORK depending upon whether the
|
||||||
|
calling program executes a fork() system call. It
|
||||||
|
is normally the case that the calling program treats
|
||||||
|
SIGCLD as an expected signal if fork() is being used.
|
||||||
|
|
||||||
|
handler - a pointer to the unexpected signal handler to
|
||||||
|
be executed after an unexpected signal has been
|
||||||
|
detected. If handler is set to DEF_HANDLER, a
|
||||||
|
default handler is used. This routine should be
|
||||||
|
declared as function returning an int.
|
||||||
|
|
||||||
|
cleanup - a pointer to a cleanup routine to be executed
|
||||||
|
by the unexpected signal handler before tst_exit is
|
||||||
|
called. This parameter is set to NULL if no cleanup
|
||||||
|
routine is required. An external variable, T_cleanup
|
||||||
|
is set so that other user-defined handlers have
|
||||||
|
access to the cleanup routine. This routine should be
|
||||||
|
declared as returning type void.
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CRAY
|
||||||
|
#define _BSD_SIGNALS 1 /* Specify that we are using BSD signal interface */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
#define MAXMESG 150 /* size of mesg string sent to tst_res */
|
||||||
|
|
||||||
|
void (*T_cleanup)(); /* pointer to cleanup function */
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
static void def_handler(); /* default signal handler */
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* tst_sig() : set-up to catch unexpected signals. fork_flag is set to NOFORK
|
||||||
|
* if SIGCLD is to be an "unexpected signal", otherwise it is set to
|
||||||
|
* FORK. cleanup points to a cleanup routine to be executed before
|
||||||
|
* tst_exit is called (cleanup is set to NULL if no cleanup is desired).
|
||||||
|
* handler is a pointer to the signal handling routine (if handler is
|
||||||
|
* set to NULL, a default handler is used).
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
tst_sig(int fork_flag, void (*handler)(), void (*cleanup)())
|
||||||
|
{
|
||||||
|
char mesg[MAXMESG]; /* message buffer for tst_res */
|
||||||
|
int sig;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save T_cleanup and handler function pointers
|
||||||
|
*/
|
||||||
|
T_cleanup = cleanup; /* used by default handler */
|
||||||
|
|
||||||
|
if (handler == DEF_HANDLER) {
|
||||||
|
/* use default handler */
|
||||||
|
handler = def_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now loop through all signals and set the handlers
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (sig = 1; sig < NSIG; sig++) {
|
||||||
|
/*
|
||||||
|
* SIGKILL is never unexpected.
|
||||||
|
* SIGCLD is only unexpected when
|
||||||
|
* no forking is being done.
|
||||||
|
* SIGINFO is used for file quotas and should be expected
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (sig) {
|
||||||
|
case SIGKILL:
|
||||||
|
case SIGSTOP:
|
||||||
|
case SIGCONT:
|
||||||
|
#ifdef CRAY
|
||||||
|
case SIGINFO:
|
||||||
|
case SIGRECOVERY: /* allow chkpnt/restart */
|
||||||
|
#endif /* CRAY */
|
||||||
|
|
||||||
|
#ifdef SIGSWAP
|
||||||
|
case SIGSWAP:
|
||||||
|
#endif /* SIGSWAP */
|
||||||
|
|
||||||
|
#ifdef SIGCKPT
|
||||||
|
case SIGCKPT:
|
||||||
|
#endif
|
||||||
|
#ifdef SIGRESTART
|
||||||
|
case SIGRESTART:
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* pthread-private signals SIGPTINTR and SIGPTRESCHED.
|
||||||
|
* Setting a handler for these signals is disallowed when
|
||||||
|
* the binary is linked against libpthread.
|
||||||
|
*/
|
||||||
|
#ifdef SIGPTINTR
|
||||||
|
case SIGPTINTR:
|
||||||
|
#endif /* SIGPTINTR */
|
||||||
|
#ifdef SIGPTRESCHED
|
||||||
|
case SIGPTRESCHED:
|
||||||
|
#endif /* SIGPTRESCHED */
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGCLD:
|
||||||
|
if ( fork_flag == FORK )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (signal(sig, handler) == SIG_ERR) {
|
||||||
|
(void) sprintf(mesg,
|
||||||
|
"signal() failed for signal %d. error:%d %s.",
|
||||||
|
sig, errno, strerror(errno));
|
||||||
|
tst_resm(TWARN, mesg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef __sgi
|
||||||
|
/* On irix (07/96), signal() fails when signo is 33 or higher */
|
||||||
|
if ( sig+1 >= 33 )
|
||||||
|
break;
|
||||||
|
#endif /* __sgi */
|
||||||
|
|
||||||
|
} /* endfor */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* def_handler() : default signal handler that is invoked when
|
||||||
|
* an unexpected signal is caught.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
def_handler(int sig)
|
||||||
|
{
|
||||||
|
char mesg[MAXMESG]; /* holds tst_res message */
|
||||||
|
|
||||||
|
/* first reset trap for this signal (except SIGCLD - its weird) */
|
||||||
|
if ((sig != SIGCLD) && (sig != SIGSTOP) && (sig != SIGCONT)) {
|
||||||
|
if (signal(sig, def_handler) == SIG_ERR) {
|
||||||
|
(void) sprintf(mesg,
|
||||||
|
"def_handler: signal() failed for signal %d. error:%d %s.",
|
||||||
|
sig, errno, strerror(errno));
|
||||||
|
tst_resm(TWARN, mesg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) sprintf(mesg, "Unexpected signal %d received.", sig);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Break remaining test cases, do any cleanup, then exit
|
||||||
|
*/
|
||||||
|
tst_brkm(TBROK, 0, mesg);
|
||||||
|
|
||||||
|
/* now cleanup and exit */
|
||||||
|
if (T_cleanup) {
|
||||||
|
(*T_cleanup)();
|
||||||
|
}
|
||||||
|
|
||||||
|
tst_exit();
|
||||||
|
}
|
351
winsup/testsuite/libltp/lib/tst_tmpdir.c
Normal file
351
winsup/testsuite/libltp/lib/tst_tmpdir.c
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
*
|
||||||
|
* OS Testing - Silicon Graphics, Inc.
|
||||||
|
*
|
||||||
|
* FUNCTION NAME : tst_tmpdir, tst_rmdir
|
||||||
|
*
|
||||||
|
* FUNCTION TITLE : Create/remove a testing temp dir
|
||||||
|
*
|
||||||
|
* SYNOPSIS:
|
||||||
|
* void tst_tmpdir();
|
||||||
|
* void tst_rmdir();
|
||||||
|
*
|
||||||
|
* AUTHOR : Dave Fenner
|
||||||
|
*
|
||||||
|
* INITIAL RELEASE : UNICOS 8.0
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* tst_tmpdir() is used to create a unique, temporary testing
|
||||||
|
* directory, and make it the current working directory.
|
||||||
|
* tst_rmdir() is used to remove the directory created by
|
||||||
|
* tst_tmpdir().
|
||||||
|
*
|
||||||
|
* Setting the env variable "TDIRECTORY" will override the creation
|
||||||
|
* of a new temp dir. The directory specified by TDIRECTORY will
|
||||||
|
* be used as the temporary directory, and no removal will be done
|
||||||
|
* in tst_rmdir().
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* Neither tst_tmpdir() or tst_rmdir() has a return value.
|
||||||
|
*
|
||||||
|
*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h> /* for getenv() */
|
||||||
|
#include <string.h> /* for string functions */
|
||||||
|
#include <unistd.h> /* for sysconf(), getcwd(), rmdir() */
|
||||||
|
#include <sys/types.h> /* for mkdir() */
|
||||||
|
#include <sys/stat.h> /* for mkdir() */
|
||||||
|
#include "test.h"
|
||||||
|
#include "rmobj.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define some useful macros.
|
||||||
|
*/
|
||||||
|
#define PREFIX_SIZE 4
|
||||||
|
#define STRING_SIZE 256
|
||||||
|
#define DIR_MODE 0777 /* mode of tmp dir that will be created */
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#ifdef MAXPATHLEN
|
||||||
|
#define PATH_MAX MAXPATHLEN
|
||||||
|
#else
|
||||||
|
#define PATH_MAX 1024
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define function prototypes.
|
||||||
|
*/
|
||||||
|
static void tmpdir_cleanup();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define global variables.
|
||||||
|
*/
|
||||||
|
extern char *TCID; /* defined/initialized in main() */
|
||||||
|
extern int TST_TOTAL; /* defined/initialized in main() */
|
||||||
|
extern char *TESTDIR; /* the directory created; defined in */
|
||||||
|
/* tst_res.c */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tst_tmpdir() - Create a unique temporary directory and chdir() to it.
|
||||||
|
* It expects the caller to have defined/initialized the
|
||||||
|
* TCID/TST_TOTAL global variables. The TESTDIR global
|
||||||
|
* variable will be set to the directory that gets used
|
||||||
|
* as the testing directory.
|
||||||
|
*
|
||||||
|
* NOTE: This function must be called BEFORE any activity
|
||||||
|
* that would require CLEANUP. If tst_tmpdir() fails, it
|
||||||
|
* cleans up afer itself and calls tst_exit() (i.e. does
|
||||||
|
* not return).
|
||||||
|
*/
|
||||||
|
#undef FN_NAME
|
||||||
|
#define FN_NAME "tst_tmpdir()"
|
||||||
|
|
||||||
|
void
|
||||||
|
tst_tmpdir()
|
||||||
|
{
|
||||||
|
char prefix[PREFIX_SIZE]; /* first three characters from TCID */
|
||||||
|
int no_cleanup = 0; /* !0 means TDIRECTORY env var was set */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the TDIRECTORY env variable is not set, a temp dir will be
|
||||||
|
* created.
|
||||||
|
*/
|
||||||
|
if ( (TESTDIR = getenv(TDIRECTORY)) == NULL ) {
|
||||||
|
/*
|
||||||
|
* Create a unique name based on the first three characters of the
|
||||||
|
* TCID. The last byte in "prefix" is for the null.
|
||||||
|
*/
|
||||||
|
strncpy(prefix, TCID, PREFIX_SIZE - 1);
|
||||||
|
prefix[PREFIX_SIZE-1] = '\0';
|
||||||
|
if ( (TESTDIR = tempnam(TEMPDIR, prefix)) == NULL )
|
||||||
|
tst_brkm(TBROK, tmpdir_cleanup, "%s: tempnam(%s, %s) failed",
|
||||||
|
FN_NAME, TEMPDIR, prefix);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the temporary directory.
|
||||||
|
*/
|
||||||
|
if ( mkdir(TESTDIR, DIR_MODE) == -1 )
|
||||||
|
tst_brkm(TBROK, tmpdir_cleanup,
|
||||||
|
"%s: mkdir(%s, %#o) failed; errno = %d: %s",
|
||||||
|
FN_NAME, TESTDIR, DIR_MODE, errno, strerror(errno));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change the group on this temporary directory to be that of the
|
||||||
|
* gid of the person running the tests.
|
||||||
|
*/
|
||||||
|
if ( chown(TESTDIR, -1, getgid()) == -1 )
|
||||||
|
tst_brkm(TBROK, tmpdir_cleanup,
|
||||||
|
"chown(%s, -1, %d) failed; errno = %d: %s",
|
||||||
|
TESTDIR, getgid(), errno, strerror(errno));
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The TDIRECTORY env. variable is set, so no temp dir is created.
|
||||||
|
* Also, no clean up will be done via tst_rmdir().
|
||||||
|
*/
|
||||||
|
no_cleanup++;
|
||||||
|
#if UNIT_TEST
|
||||||
|
printf("TDIRECTORY env var is set\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
printf("TESTDIR = %s\n", TESTDIR);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change to the temporary directory. If the chdir() fails, issue
|
||||||
|
* TBROK messages for all test cases, attempt to remove the
|
||||||
|
* directory (if it was created), and exit. If the removal also
|
||||||
|
* fails, also issue a TWARN message.
|
||||||
|
*/
|
||||||
|
if ( chdir(TESTDIR) == -1 ) {
|
||||||
|
tst_brkm(TBROK, NULL, "%s: chdir(%s) failed; errno = %d: %s",
|
||||||
|
FN_NAME, TESTDIR, errno, strerror(errno) );
|
||||||
|
|
||||||
|
/* Try to remove the directory */
|
||||||
|
if ( !no_cleanup && rmdir(TESTDIR) == -1 )
|
||||||
|
tst_resm(TWARN, "%s: rmdir(%s) failed; errno = %d: %s",
|
||||||
|
FN_NAME, TESTDIR, errno, strerror(errno) );
|
||||||
|
|
||||||
|
tmpdir_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNIT_TEST
|
||||||
|
printf("CWD is %s\n", getcwd((char *)NULL, PATH_MAX));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we made through all this stuff, return.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
} /* tst_tmpdir() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* tst_rmdir() - Recursively remove the temporary directory created by
|
||||||
|
* tst_tmpdir(). This function is intended ONLY as a
|
||||||
|
* companion to tst_tmpdir(). If the TDIRECTORY
|
||||||
|
* environment variable is set, no cleanup will be
|
||||||
|
* attempted.
|
||||||
|
*/
|
||||||
|
#undef FN_NAME
|
||||||
|
#define FN_NAME "tst_rmdir()"
|
||||||
|
|
||||||
|
void
|
||||||
|
tst_rmdir()
|
||||||
|
{
|
||||||
|
char *errmsg;
|
||||||
|
char *tdirectory;
|
||||||
|
char current_dir[PATH_MAX]; /* current working directory */
|
||||||
|
char parent_dir[PATH_MAX]; /* directory above TESTDIR */
|
||||||
|
char *basename; /* basename of the TESTDIR */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the TDIRECTORY env variable is set, this indicates that no
|
||||||
|
* temp dir was created by tst_tmpdir(). Thus no cleanup will be
|
||||||
|
* necessary.
|
||||||
|
*/
|
||||||
|
if ( (tdirectory = getenv(TDIRECTORY)) != NULL ) {
|
||||||
|
#if UNIT_TEST
|
||||||
|
printf("\"TDIRECORY\" env variable is set; no cleanup was performed\n");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that TESTDIR is not NULL.
|
||||||
|
*/
|
||||||
|
if ( TESTDIR == NULL ) {
|
||||||
|
tst_resm(TWARN, "%s: TESTDIR was NULL; no removal attempted",
|
||||||
|
FN_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the value of TESTDIR is not "*" or "/". These could
|
||||||
|
* have disastrous effects in a test run by root.
|
||||||
|
*/
|
||||||
|
if ( strcmp(TESTDIR, "/") == 0 ) {
|
||||||
|
tst_resm(TWARN,
|
||||||
|
"%s: Recursive remove of root directory not attempted",
|
||||||
|
FN_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strchr(TESTDIR, '*') != NULL ) {
|
||||||
|
tst_resm(TWARN, "%s: Recursive remove of '*' not attempted",
|
||||||
|
FN_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the directory name of TESTDIR. If TESTDIR is a relative path,
|
||||||
|
* get full path.
|
||||||
|
*/
|
||||||
|
if ( TESTDIR[0] != '/' ) {
|
||||||
|
if ( getcwd(current_dir,PATH_MAX) == NULL )
|
||||||
|
strcpy(parent_dir, TESTDIR);
|
||||||
|
else
|
||||||
|
sprintf(parent_dir, "%s/%s", current_dir, TESTDIR);
|
||||||
|
} else {
|
||||||
|
strcpy(parent_dir, TESTDIR);
|
||||||
|
}
|
||||||
|
if ( (basename = strrchr(parent_dir, '/')) != NULL ) {
|
||||||
|
*basename='\0'; /* terminate at end of parent_dir */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change directory to parent_dir (The dir above TESTDIR).
|
||||||
|
*/
|
||||||
|
if ( chdir(parent_dir) != 0 )
|
||||||
|
tst_resm(TWARN,
|
||||||
|
"%s: chdir(%s) failed; errno = %d: %s\nAttempting to remove temp dir anyway",
|
||||||
|
FN_NAME, parent_dir, errno, strerror(errno));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt to remove the "TESTDIR" directory, using rmobj().
|
||||||
|
*/
|
||||||
|
if ( rmobj(TESTDIR, &errmsg) == -1 )
|
||||||
|
tst_resm(TWARN, "%s: rmobj(%s) failed: %s",
|
||||||
|
FN_NAME, TESTDIR, errmsg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
} /* tst_rmdir() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tmpdir_cleanup() - This function is used when tst_tmpdir()
|
||||||
|
* encounters an error, and must cleanup and exit.
|
||||||
|
* It prints a warning message via tst_resm(), and
|
||||||
|
* then calls tst_exit().
|
||||||
|
*/
|
||||||
|
#undef FN_NAME
|
||||||
|
#define FN_NAME "tst_tmpdir()"
|
||||||
|
|
||||||
|
static void
|
||||||
|
tmpdir_cleanup()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Print a warning message and call tst_exit() to exit the test.
|
||||||
|
*/
|
||||||
|
tst_resm(TWARN, "%s: No user cleanup function called before exiting",
|
||||||
|
FN_NAME);
|
||||||
|
tst_exit();
|
||||||
|
} /* tmpdir_cleanup() */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef UNIT_TEST
|
||||||
|
/****************************************************************************
|
||||||
|
* Unit test code: Takes input from stdin and can make the following
|
||||||
|
* calls: tst_tmpdir(), tst_rmdir().
|
||||||
|
****************************************************************************/
|
||||||
|
int TST_TOTAL = 10;
|
||||||
|
char *TCID = "TESTTCID";
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int option;
|
||||||
|
char *chrptr;
|
||||||
|
|
||||||
|
printf("UNIT TEST of tst_tmpdir.c. Options to try:\n\
|
||||||
|
-1 : call tst_exit()\n\
|
||||||
|
0 : call tst_tmpdir()\n\
|
||||||
|
1 : call tst_rmdir()\n\n");
|
||||||
|
|
||||||
|
while ( 1 ) {
|
||||||
|
printf("Enter options (-1, 0, 1): ");
|
||||||
|
(void) scanf("%d%c", &option, &chrptr);
|
||||||
|
|
||||||
|
switch ( option ) {
|
||||||
|
case -1:
|
||||||
|
tst_exit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
tst_tmpdir();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
tst_rmdir();
|
||||||
|
break;
|
||||||
|
} /* switch() */
|
||||||
|
} /* while() */
|
||||||
|
}
|
||||||
|
#endif /* UNIT_TEST */
|
468
winsup/testsuite/libltp/lib/write_log.c
Normal file
468
winsup/testsuite/libltp/lib/write_log.c
Normal file
@ -0,0 +1,468 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it would be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/NoticeExplan/
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This module contains code for logging writes to files, and for
|
||||||
|
* perusing the resultant logfile. The main intent of all this is
|
||||||
|
* to provide a 'write history' of a file which can be examined to
|
||||||
|
* judge the state of a file (ie. whether it is corrupted or not) based
|
||||||
|
* on the write activity.
|
||||||
|
*
|
||||||
|
* The main abstractions available to the user are the wlog_file, and
|
||||||
|
* the wlog_rec. A wlog_file is a handle encapsulating a write logfile.
|
||||||
|
* It is initialized with the wlog_open() function. This handle is
|
||||||
|
* then passed to the various wlog_xxx() functions to provide transparent
|
||||||
|
* access to the write logfile.
|
||||||
|
*
|
||||||
|
* The wlog_rec datatype is a structure which contains all the information
|
||||||
|
* about a file write. Examples include the file name, offset, length,
|
||||||
|
* pattern, etc. In addition there is a bit which is cleared/set based
|
||||||
|
* on whether or not the write has been confirmed as complete. This
|
||||||
|
* allows the write logfile to contain information on writes which have
|
||||||
|
* been initiated, but not yet completed (as in async io).
|
||||||
|
*
|
||||||
|
* There is also a function to scan a write logfile in reverse order.
|
||||||
|
*
|
||||||
|
* NOTE: For target file analysis based on a write logfile, the
|
||||||
|
* assumption is made that the file being written to is
|
||||||
|
* locked from simultaneous access, so that the order of
|
||||||
|
* write completion is predictable. This is an issue when
|
||||||
|
* more than 1 process is trying to write data to the same
|
||||||
|
* target file simultaneously.
|
||||||
|
*
|
||||||
|
* The history file created is a collection of variable length records
|
||||||
|
* described by scruct wlog_rec_disk in write_log.h. See that module for
|
||||||
|
* the layout of the data on disk.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "write_log.h"
|
||||||
|
|
||||||
|
#ifndef BSIZE
|
||||||
|
#ifdef linux
|
||||||
|
#define BSIZE DEV_BSIZE
|
||||||
|
#else
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#define BSIZE S_BLKSIZE
|
||||||
|
#else
|
||||||
|
#define BSIZE BBSIZE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 255
|
||||||
|
/*#define PATH_MAX pathconf("/", _PC_PATH_MAX)*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char Wlog_Error_String[256];
|
||||||
|
|
||||||
|
#if __STDC__
|
||||||
|
static int wlog_rec_pack(struct wlog_rec *wrec, char *buf, int flag);
|
||||||
|
static int wlog_rec_unpack(struct wlog_rec *wrec, char *buf);
|
||||||
|
#else
|
||||||
|
static int wlog_rec_pack();
|
||||||
|
static int wlog_rec_unpack();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize a write logfile. wfile is a wlog_file structure that has
|
||||||
|
* the w_file field filled in. The rest of the information in the
|
||||||
|
* structure is initialized by the routine.
|
||||||
|
*
|
||||||
|
* The trunc flag is used to indicate whether or not the logfile should
|
||||||
|
* be truncated if it currently exists. If it is non-zero, the file will
|
||||||
|
* be truncated, otherwise it will be appended to.
|
||||||
|
*
|
||||||
|
* The mode argument is the [absolute] mode which the file will be
|
||||||
|
* given if it does not exist. This mode is not affected by your process
|
||||||
|
* umask.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
wlog_open(wfile, trunc, mode)
|
||||||
|
struct wlog_file *wfile;
|
||||||
|
int trunc;
|
||||||
|
int mode;
|
||||||
|
{
|
||||||
|
int omask, oflags;
|
||||||
|
|
||||||
|
if (trunc)
|
||||||
|
trunc = O_TRUNC;
|
||||||
|
|
||||||
|
omask = umask(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open 1 file descriptor as O_APPEND
|
||||||
|
*/
|
||||||
|
|
||||||
|
oflags = O_WRONLY | O_APPEND | O_CREAT | trunc;
|
||||||
|
wfile->w_afd =
|
||||||
|
open(wfile->w_file, oflags, mode);
|
||||||
|
umask(omask);
|
||||||
|
|
||||||
|
if (wfile->w_afd == -1) {
|
||||||
|
sprintf(Wlog_Error_String,
|
||||||
|
"Could not open write_log - open(%s, %#o, %#o) failed: %s\n",
|
||||||
|
wfile->w_file, oflags, mode, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the next fd as a random access descriptor
|
||||||
|
*/
|
||||||
|
|
||||||
|
oflags = O_RDWR;
|
||||||
|
if ((wfile->w_rfd = open(wfile->w_file, oflags)) == -1) {
|
||||||
|
sprintf(Wlog_Error_String,
|
||||||
|
"Could not open write log - open(%s, %#o) failed: %s\n",
|
||||||
|
wfile->w_file, oflags, strerror(errno));
|
||||||
|
close(wfile->w_afd);
|
||||||
|
wfile->w_afd = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release all resources associated with a wlog_file structure allocated
|
||||||
|
* with the wlog_open() call.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
wlog_close(wfile)
|
||||||
|
struct wlog_file *wfile;
|
||||||
|
{
|
||||||
|
close(wfile->w_afd);
|
||||||
|
close(wfile->w_rfd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a wlog_rec structure to a write logfile. Offset is used to
|
||||||
|
* control where the record will be written. If offset is < 0, the
|
||||||
|
* record will be appended to the end of the logfile. Otherwise, the
|
||||||
|
* record which exists at the indicated offset will be overlayed. This
|
||||||
|
* is so that we can record writes which are outstanding (with the w_done
|
||||||
|
* bit in wrec cleared), but not completed, and then later update the
|
||||||
|
* logfile when the write request completes (as with async io). When
|
||||||
|
* offset is >= 0, only the fixed length portion of the record is
|
||||||
|
* rewritten. See text in write_log.h for details on the format of an
|
||||||
|
* on-disk record.
|
||||||
|
*
|
||||||
|
* The return value of the function is the byte offset in the logfile
|
||||||
|
* where the record begins.
|
||||||
|
*
|
||||||
|
* Note: It is the callers responsibility to make sure that the offset
|
||||||
|
* parameter 'points' to a valid record location when a record is to be
|
||||||
|
* overlayed. This is guarenteed by saving the return value of a previous
|
||||||
|
* call to wlog_record_write() which wrote the record to be overlayed.
|
||||||
|
*
|
||||||
|
* Note2: The on-disk version of the wlog_rec is MUCH different than
|
||||||
|
* the user version. Don't expect to od the logfile and see data formatted
|
||||||
|
* as it is in the wlog_rec structure. Considerable data packing takes
|
||||||
|
* place before the record is written.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
wlog_record_write(wfile, wrec, offset)
|
||||||
|
struct wlog_file *wfile;
|
||||||
|
struct wlog_rec *wrec;
|
||||||
|
long offset;
|
||||||
|
{
|
||||||
|
int reclen;
|
||||||
|
char wbuf[WLOG_REC_MAX_SIZE + 2];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If offset is -1, we append the record at the end of file
|
||||||
|
*
|
||||||
|
* Otherwise, we overlay wrec at the file offset indicated and assume
|
||||||
|
* that the caller passed us the correct offset. We do not record the
|
||||||
|
* fname in this case.
|
||||||
|
*/
|
||||||
|
|
||||||
|
reclen = wlog_rec_pack(wrec, wbuf, (offset < 0));
|
||||||
|
|
||||||
|
if (offset < 0) {
|
||||||
|
/*
|
||||||
|
* Since we're writing a complete new record, we must also tack
|
||||||
|
* its length onto the end so that wlog_scan_backward() will work.
|
||||||
|
* Length is asumed to fit into 2 bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
wbuf[reclen] = reclen / 256;
|
||||||
|
wbuf[reclen+1] = reclen % 256;
|
||||||
|
reclen += 2;
|
||||||
|
|
||||||
|
write(wfile->w_afd, wbuf, reclen);
|
||||||
|
offset = lseek(wfile->w_afd, 0, SEEK_CUR) - reclen;
|
||||||
|
} else {
|
||||||
|
lseek(wfile->w_rfd, offset, SEEK_SET);
|
||||||
|
write(wfile->w_rfd, wbuf, reclen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to scan a logfile in reverse order. Wfile is a valid
|
||||||
|
* wlog_file structure initialized by wlog_open(). nrecs is the number
|
||||||
|
* of records to scan (all records are scanned if nrecs is 0). func is
|
||||||
|
* a user-supplied function to call for each record found. The function
|
||||||
|
* will be passed a single parameter - a wlog_rec structure .
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
wlog_scan_backward(wfile, nrecs, func, data)
|
||||||
|
struct wlog_file *wfile;
|
||||||
|
int nrecs;
|
||||||
|
int (*func)();
|
||||||
|
long data;
|
||||||
|
{
|
||||||
|
int fd, leftover, nbytes, offset, recnum, reclen, rval;
|
||||||
|
char buf[BSIZE*32], *bufend, *cp, *bufstart;
|
||||||
|
char albuf[WLOG_REC_MAX_SIZE];
|
||||||
|
struct wlog_rec wrec;
|
||||||
|
|
||||||
|
fd = wfile->w_rfd;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move to EOF. offset will always hold the current file offset
|
||||||
|
*/
|
||||||
|
|
||||||
|
lseek(fd, 0, SEEK_END);
|
||||||
|
offset = lseek(fd, 0, SEEK_CUR);
|
||||||
|
|
||||||
|
bufend = buf + sizeof(buf);
|
||||||
|
bufstart = buf;
|
||||||
|
|
||||||
|
recnum = 0;
|
||||||
|
leftover = 0;
|
||||||
|
while ((!nrecs || recnum < nrecs) && offset > 0) {
|
||||||
|
/*
|
||||||
|
* Check for beginning of file - if there aren't enough bytes
|
||||||
|
* remaining to fill buf, adjust bufstart.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (offset + leftover < sizeof(buf)) {
|
||||||
|
bufstart = bufend - (offset + leftover);
|
||||||
|
offset = 0;
|
||||||
|
} else {
|
||||||
|
offset -= sizeof(buf) - leftover;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move to the proper file offset, and read into buf
|
||||||
|
*/
|
||||||
|
|
||||||
|
lseek(fd, offset, SEEK_SET);
|
||||||
|
nbytes = read(fd, bufstart, bufend - bufstart - leftover);
|
||||||
|
|
||||||
|
if (nbytes == -1) {
|
||||||
|
sprintf(Wlog_Error_String,
|
||||||
|
"Could not read history file at offset %d - read(%d, %#o, %d) failed: %s\n",
|
||||||
|
offset, fd, (int)bufstart,
|
||||||
|
bufend - bufstart - leftover, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = bufend;
|
||||||
|
leftover = 0;
|
||||||
|
|
||||||
|
while (cp >= bufstart) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If cp-bufstart is not large enough to hold a piece
|
||||||
|
* of record length information, copy remainder to end
|
||||||
|
* of buf and continue reading the file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (cp - bufstart < 2) {
|
||||||
|
leftover = cp - bufstart;
|
||||||
|
memcpy(bufend - leftover, bufstart, leftover);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract the record length. We must do it this way
|
||||||
|
* instead of casting cp to an int because cp might
|
||||||
|
* not be word aligned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
reclen = (*(cp-2) * 256) + *(cp -1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If cp-bufstart isn't large enough to hold a
|
||||||
|
* complete record, plus the length information, copy
|
||||||
|
* the leftover bytes to the end of buf and continue
|
||||||
|
* reading.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (cp - bufstart < reclen + 2) {
|
||||||
|
leftover = cp - bufstart;
|
||||||
|
memcpy(bufend - leftover, bufstart, leftover);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adjust cp to point at the start of the record.
|
||||||
|
* Copy the record into wbuf so that it is word
|
||||||
|
* aligned and pass the record to the user supplied
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
cp -= reclen + 2;
|
||||||
|
memcpy(albuf, cp, reclen);
|
||||||
|
|
||||||
|
wlog_rec_unpack(&wrec, albuf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the user supplied function -
|
||||||
|
* stop if instructed to.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((rval = (*func)(&wrec, data)) == WLOG_STOP_SCAN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
recnum++;
|
||||||
|
|
||||||
|
if (nrecs && recnum >= nrecs)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following 2 routines are used to pack and unpack the user
|
||||||
|
* visible wlog_rec structure to/from a character buffer which is
|
||||||
|
* stored or read from the write logfile. Any changes to either of
|
||||||
|
* these routines must be reflected in the other.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
wlog_rec_pack(wrec, buf, flag)
|
||||||
|
struct wlog_rec *wrec;
|
||||||
|
char *buf;
|
||||||
|
int flag;
|
||||||
|
{
|
||||||
|
char *file, *host, *pattern;
|
||||||
|
struct wlog_rec_disk *wrecd;
|
||||||
|
|
||||||
|
wrecd = (struct wlog_rec_disk *)buf;
|
||||||
|
|
||||||
|
wrecd->w_pid = (uint)wrec->w_pid;
|
||||||
|
wrecd->w_offset = (uint)wrec->w_offset;
|
||||||
|
wrecd->w_nbytes = (uint)wrec->w_nbytes;
|
||||||
|
wrecd->w_oflags = (uint)wrec->w_oflags;
|
||||||
|
wrecd->w_done = (uint)wrec->w_done;
|
||||||
|
wrecd->w_async = (uint)wrec->w_async;
|
||||||
|
|
||||||
|
wrecd->w_pathlen = (wrec->w_pathlen > 0) ? (uint)wrec->w_pathlen : 0;
|
||||||
|
wrecd->w_hostlen = (wrec->w_hostlen > 0) ? (uint)wrec->w_hostlen : 0;
|
||||||
|
wrecd->w_patternlen = (wrec->w_patternlen > 0) ? (uint)wrec->w_patternlen : 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If flag is true, we should also pack the variable length parts
|
||||||
|
* of the wlog_rec. By default, we only pack the fixed length
|
||||||
|
* parts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
file = buf + sizeof(struct wlog_rec_disk);
|
||||||
|
host = file + wrecd->w_pathlen;
|
||||||
|
pattern = host + wrecd->w_hostlen;
|
||||||
|
|
||||||
|
if (wrecd->w_pathlen > 0)
|
||||||
|
memcpy(file, wrec->w_path, wrecd->w_pathlen);
|
||||||
|
|
||||||
|
if (wrecd->w_hostlen > 0)
|
||||||
|
memcpy(host, wrec->w_host, wrecd->w_hostlen);
|
||||||
|
|
||||||
|
if (wrecd->w_patternlen > 0)
|
||||||
|
memcpy(pattern, wrec->w_pattern, wrecd->w_patternlen);
|
||||||
|
|
||||||
|
return (sizeof(struct wlog_rec_disk) +
|
||||||
|
wrecd->w_pathlen + wrecd->w_hostlen + wrecd->w_patternlen);
|
||||||
|
} else {
|
||||||
|
return sizeof(struct wlog_rec_disk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
wlog_rec_unpack(wrec, buf)
|
||||||
|
struct wlog_rec *wrec;
|
||||||
|
char *buf;
|
||||||
|
{
|
||||||
|
char *file, *host, *pattern;
|
||||||
|
struct wlog_rec_disk *wrecd;
|
||||||
|
|
||||||
|
bzero((char *)wrec, sizeof(struct wlog_rec));
|
||||||
|
wrecd = (struct wlog_rec_disk *)buf;
|
||||||
|
|
||||||
|
wrec->w_pid = wrecd->w_pid;
|
||||||
|
wrec->w_offset = wrecd->w_offset;
|
||||||
|
wrec->w_nbytes = wrecd->w_nbytes;
|
||||||
|
wrec->w_oflags = wrecd->w_oflags;
|
||||||
|
wrec->w_hostlen = wrecd->w_hostlen;
|
||||||
|
wrec->w_pathlen = wrecd->w_pathlen;
|
||||||
|
wrec->w_patternlen = wrecd->w_patternlen;
|
||||||
|
wrec->w_done = wrecd->w_done;
|
||||||
|
wrec->w_async = wrecd->w_async;
|
||||||
|
|
||||||
|
if (wrec->w_pathlen > 0) {
|
||||||
|
file = buf + sizeof(struct wlog_rec_disk);
|
||||||
|
memcpy(wrec->w_path, file, wrec->w_pathlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrec->w_hostlen > 0) {
|
||||||
|
host = buf + sizeof(struct wlog_rec_disk) + wrec->w_pathlen;
|
||||||
|
memcpy(wrec->w_host, host, wrec->w_hostlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrec->w_patternlen > 0) {
|
||||||
|
pattern = buf + sizeof(struct wlog_rec_disk) +
|
||||||
|
wrec->w_pathlen + wrec->w_hostlen;
|
||||||
|
memcpy(wrec->w_pattern, pattern, wrec->w_patternlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user