home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / dev / gcc / ixemulsrc.lha / ixemul / stdio / mktemp.c < prev    next >
C/C++ Source or Header  |  1996-12-11  |  3KB  |  107 lines

  1. /*
  2.  * Copyright (c) 1987 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that: (1) source distributions retain this entire copyright
  7.  * notice and comment, and (2) distributions including binaries display
  8.  * the following acknowledgement:  ``This product includes software
  9.  * developed by the University of California, Berkeley and its contributors''
  10.  * in the documentation or other materials provided with the distribution
  11.  * and in all advertising materials mentioning features or use of this
  12.  * software. Neither the name of the University nor the names of its
  13.  * contributors may be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #if defined(LIBC_SCCS) && !defined(lint)
  21. static char sccsid[] = "@(#)mktemp.c    5.9 (Berkeley) 6/1/90";
  22. #endif /* LIBC_SCCS and not lint */
  23.  
  24. #define _KERNEL
  25. #include "ixemul.h"
  26. #include "kprintf.h"
  27.  
  28. #include <ctype.h>
  29.  
  30. static int
  31. _gettemp(char *path, int *doopen)
  32. {
  33.     register char *start, *trv;
  34.     struct stat sbuf;
  35.     u_int pid;
  36.  
  37.     pid = syscall (SYS_getpid);
  38.     for (trv = path; *trv; ++trv);        /* extra X's get set to 0's */
  39.     while (*--trv == 'X') {
  40.         *trv = (pid % 10) + '0';
  41.         pid /= 10;
  42.     }
  43.  
  44.     /*
  45.      * check the target directory; if you have six X's and it
  46.      * doesn't exist this runs for a *very* long time.
  47.      */
  48.     for (start = trv + 1;; --trv) {
  49.         if (trv <= path)
  50.             break;
  51.         if (*trv == '/') {
  52.             *trv = '\0';
  53.             if (syscall (SYS_stat, path, &sbuf))
  54.                 return(0);
  55.             if (!S_ISDIR(sbuf.st_mode)) {
  56.                 errno = ENOTDIR;
  57.                   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  58.                 return(0);
  59.             }
  60.             *trv = '/';
  61.             break;
  62.         }
  63.     }
  64.  
  65.     for (;;) {
  66.         if (doopen) {
  67.             if ((*doopen =
  68.                 syscall (SYS_open, path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
  69.                 return(1);
  70.             if (errno != EEXIST)
  71.                 return(0);
  72.         }
  73.         else if (syscall (SYS_stat, path, &sbuf))
  74.             return(errno == ENOENT ? 1 : 0);
  75.  
  76.         /* tricky little algorithm for backward compatibility */
  77.         for (trv = start;;) {
  78.             if (!*trv)
  79.                 return(0);
  80.             if (*trv == 'z')
  81.                 *trv++ = 'a';
  82.             else {
  83.                 if (isdigit(*trv))
  84.                     *trv = 'a';
  85.                 else
  86.                     ++*trv;
  87.                 break;
  88.             }
  89.         }
  90.     }
  91.     /*NOTREACHED*/
  92. }
  93.  
  94. int
  95. mkstemp(char *path)
  96. {
  97.     int fd;
  98.  
  99.     return (_gettemp(path, &fd) ? fd : -1);
  100. }
  101.  
  102. char *
  103. mktemp(char *path)
  104. {
  105.     return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
  106. }
  107.