Skip to content

Instantly share code, notes, and snippets.

@betawaffle
Created August 18, 2010 22:54
Show Gist options
  • Save betawaffle/536447 to your computer and use it in GitHub Desktop.
Save betawaffle/536447 to your computer and use it in GitHub Desktop.
OpenAnonymous()
#define NUMBERS "0123456789"
#define LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
int
OpenAnonymous(char const* aFormat)
{
size_t i, s;
char* n, c;
int f;
#define fail(e, ...) throw e(##__VA_ARGS__)
if (s = strlen(aFormat) + 1, s == 0) fail(InvalidArgument);
if (n = (char*) malloc(s), n == 0) fail(InsufficientMemory);
#undef fail
#define fail(e, ...) free(n), throw e(##__VA_ARGS__)
name:
for (i = 0; i < s, i++) {
switch (c = aFormat[i]) {
case '#': c = NUMBERS[rand() % 10]; break;
case '@': c = LETTERS[rand() % 26];
}
if (' ' > c || c > '~') fail(InvalidArgument);
n[i] = c;
}
if (access(n, F_OK) == 0) goto n;
switch (errno) {
case ENOENT: break;
default:
fail(InvalidArgument);
}
open: n[--i] = '\0';
if (f = open(n, O_RDWR | O_CREAT | O_EXCL, 0000), f < 0) {
switch (errno) {
case EINTR: goto open;
case EEXIST: goto name;
case ENOENT:
case ENOTDIR: fail(InvalidArgument);
case EMFILE:
case ENFILE: fail(InsufficientDescriptors);
case ENOSPC: fail(InsufficientSpace);
}
fail(UnexpectedError, errno, "open");
}
#undef fail
return unlink(n), free(n), f;
}
#define ERROR(e) fprintf(stderr, "%s (line %i): %s\n", __FILE__, __LINE__, #e)
#define NUMBERS "0123456789"
#define LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
int
OpenAnonymous(char const* aFormat)
{
size_t i, s;
char* n, c;
int f;
#define fail(e) return ERROR(e), -1
if (s = strlen(aFormat), s == 0) fail(InvalidArgument);
if (n = (char*) malloc(s + 1), n == 0) fail(InsufficientMemory);
#undef fail
#define fail(e) return ERROR(e), free(n), -1
name:
for (i = 0; i < s; i++) {
switch (c = aFormat[i]) {
case '#': c = NUMBERS[rand() % 10]; break;
case '@': c = LETTERS[rand() % 26];
}
if (c < 0x20 || c > 0x7E)
fail(InvalidArgument);
n[i] = c;
}
if (access(n, F_OK) == 0) goto name;
switch (errno) {
case ENOENT: break;
default:
fail(InvalidArgument);
}
open: n[s] = '\0';
if (f = open(n, O_RDWR | O_CREAT | O_EXCL, 0000), f < 0) {
switch (errno) {
case EINTR: goto open;
case EEXIST: goto name;
case ENOENT:
case ENOTDIR: fail(InvalidArgument);
case EMFILE:
case ENFILE: fail(InsufficientDescriptors);
case ENOSPC: fail(InsufficientSpace);
}
fail(UnexpectedError);
}
#undef fail
return unlink(n), free(n), f;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment