amiga-ixemul/stdio/mktemp.c

108 lines
2.6 KiB
C

/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)mktemp.c 5.9 (Berkeley) 6/1/90";
#endif /* LIBC_SCCS and not lint */
#define _KERNEL
#include "ixemul.h"
#include "kprintf.h"
#include <ctype.h>
static int
_gettemp(char *path, int *doopen)
{
register char *start, *trv;
struct stat sbuf;
u_int pid;
usetup;
pid = syscall (SYS_getpid);
for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
while (*--trv == 'X') {
*trv = (pid % 10) + '0';
pid /= 10;
}
/*
* check the target directory; if you have six X's and it
* doesn't exist this runs for a *very* long time.
*/
for (start = trv + 1;; --trv) {
if (trv <= path)
break;
if (*trv == '/') {
*trv = '\0';
if (syscall (SYS_stat, path, &sbuf))
return(0);
if (!S_ISDIR(sbuf.st_mode)) {
errno = ENOTDIR;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return(0);
}
*trv = '/';
break;
}
}
for (;;) {
if (doopen) {
if ((*doopen =
syscall (SYS_open, path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
return(1);
if (errno != EEXIST)
return(0);
}
else if (syscall (SYS_stat, path, &sbuf))
return(errno == ENOENT ? 1 : 0);
/* tricky little algorithm for backward compatibility */
for (trv = start;;) {
if (!*trv)
return(0);
if (*trv == 'z')
*trv++ = 'a';
else {
if (isdigit(*trv))
*trv = 'a';
else
++*trv;
break;
}
}
}
/*NOTREACHED*/
}
int
mkstemp(char *path)
{
int fd;
return (_gettemp(path, &fd) ? fd : -1);
}
char *
mktemp(char *path)
{
return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
}