-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improved version of mkdtemp() that support ebcdic (#40)
* add mkdtemp() * ignore build.cache * add test case and make stdlib.h work for ebcdic too * getenv replacement is for ascii only * remove zos-mkdtemp.cc * fix a bug & add comments
- Loading branch information
Showing
6 changed files
with
168 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,4 +18,8 @@ test/cctest_a | |
# Build artifacts | ||
*.a | ||
install/ | ||
build.cache | ||
build/ | ||
zoslib.xml | ||
zoslib_a.xml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ set(libsrc | |
zos-tls.cc | ||
zos.cc | ||
zos-mount.c | ||
zos-mkdtemp.c | ||
) | ||
set(zoslib-help zoslib-help.cc) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
////////////////////////////////////////////////////////////////////////////// | ||
//// Licensed Materials - Property of IBM | ||
//// ZOSLIB | ||
//// (C) Copyright IBM Corp. 2020. All Rights Reserved. | ||
//// US Government Users Restricted Rights - Use, duplication | ||
//// or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. | ||
///////////////////////////////////////////////////////////////////////////////// | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include <time.h> | ||
#include <stdlib.h> | ||
#include <errno.h> | ||
#include <sys/stat.h> | ||
|
||
typedef enum { | ||
cp_ebcdic, | ||
cp_ascii | ||
} CodePage; | ||
|
||
#define XXXXXX "XXXXXX" | ||
#define ValidChars "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.,-" | ||
typedef struct CodePage { | ||
char xes[sizeof(XXXXXX)]; | ||
char validChars[sizeof(ValidChars)]; | ||
} CodePage_t; | ||
|
||
#pragma convert("IBM-1047") | ||
static const CodePage_t CharTraitsEbcdic = { | ||
XXXXXX, | ||
ValidChars | ||
}; | ||
#pragma convert(pop) | ||
|
||
#pragma convert("ISO8859-1") | ||
static const CodePage_t CharTraitsAscii = { | ||
XXXXXX, | ||
ValidChars | ||
}; | ||
#pragma convert(pop) | ||
|
||
enum { | ||
TempLen = sizeof(XXXXXX)-1 | ||
}; | ||
|
||
char *real_mkdtemp(CodePage_t cp, char *templ) { | ||
if (!templ) { | ||
errno=EINVAL; | ||
return NULL; | ||
} | ||
int len = strlen(templ); | ||
|
||
if (len <TempLen || strncmp(templ+len-TempLen,cp.xes ,TempLen)!=0) { | ||
errno=EINVAL; | ||
return NULL; | ||
} | ||
#define validChars cp.validChars | ||
srand(time(NULL)); | ||
#define RANDOM_INT(max) (1 + rand()/((RAND_MAX + 1u) / (max) )) | ||
#define UPDATE_CHAR(n) templ[len-TempLen+n-1] = validChars[(s##n+c##n)%(sizeof validChars)] | ||
|
||
// Pick the first random letter for each X | ||
int s1 = RANDOM_INT(sizeof validChars); | ||
int s2 = RANDOM_INT(sizeof validChars); | ||
int s3 = RANDOM_INT(sizeof validChars); | ||
int s4 = RANDOM_INT(sizeof validChars); | ||
int s5 = RANDOM_INT(sizeof validChars); | ||
int s6 = RANDOM_INT(sizeof validChars); | ||
// Loop over all of the possible combinations until we find | ||
// a name that doesn't exist. For example: start with | ||
// dir-aaaaaa, if that doesn't exist try dir-aaaaab. | ||
// Of course the try is something more random than dir-aaaaaa. | ||
for (int c1=0; c1<sizeof validChars; ++c1) { | ||
UPDATE_CHAR(1); // dir-aXXXXX | ||
for (int c2=0; c2<sizeof validChars; ++c2) { | ||
UPDATE_CHAR(2); // dir-aaXXXX | ||
for (int c3=0; c3<sizeof validChars; ++c3) { | ||
UPDATE_CHAR(3); // dir-aaaXXX | ||
for (int c4=0; c4<sizeof validChars; ++c4) { | ||
UPDATE_CHAR(4); // dir-aaaaXX | ||
for (int c5=0; c5<sizeof validChars; ++c5) { | ||
UPDATE_CHAR(5); // dir-aaaaaX | ||
for (int c6=0; c6<sizeof validChars; ++c6) { | ||
UPDATE_CHAR(6); // dir-aaaaaa | ||
int rc = mkdir(templ, 0700); | ||
if (rc==0) | ||
return templ; | ||
if (errno!=EEXIST) { | ||
// restore the X's in the template | ||
strncpy(templ+len-TempLen,cp.xes ,TempLen); | ||
return NULL; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
// restore the X's in the template | ||
strncpy(templ+len-TempLen,cp.xes,TempLen); | ||
return NULL; | ||
} | ||
|
||
__Z_EXPORT char *__mkdtemp_a(char *templ) { | ||
return real_mkdtemp(CharTraitsAscii, templ); | ||
} | ||
|
||
__Z_EXPORT char *__mkdtemp_e(char *templ) { | ||
return real_mkdtemp(CharTraitsEbcdic, templ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include "test-args.h" | ||
#include "zos.h" | ||
#include "gtest/gtest.h" | ||
#include <sys/stat.h> | ||
#include <unistd.h> | ||
|
||
namespace { | ||
|
||
TEST(MkdtempTest, MkdtempCC) { | ||
char templ[] = "/tmp/dirXXXXXX"; | ||
char * dirname = mkdtemp(templ); | ||
EXPECT_NE(dirname, nullptr); | ||
|
||
struct stat stats; | ||
int rc = stat(dirname, &stats); | ||
rmdir(dirname); | ||
EXPECT_EQ(rc, 0); | ||
EXPECT_TRUE(S_ISDIR(stats.st_mode)); | ||
} | ||
|
||
} |