home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / git-4.3 / git-4 / git-4.3.11 / src / xio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  4.4 KB  |  273 lines

  1. /* xio.c -- Safe versions of the system io primitives.  It also includes a
  2.    new version of the readlink system call that computes the number of
  3.    characters required to hold the entire link.  */
  4.  
  5. /* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2, or (at your option)
  10.    any later version.
  11.  
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* Written by Tudor Hulubei and Andrei Pitis.  */
  22.  
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. #include <config.h>
  26. #endif
  27.  
  28. #include <sys/types.h>
  29.  
  30. #ifdef HAVE_UNISTD_H
  31. #include <unistd.h>
  32. #endif /* HAVE_UNISTD_H */
  33.  
  34. #ifndef HAVE_GETCWD
  35. #include <sys/param.h>
  36. #ifdef MAXPATHLEN
  37. #define MAXPATHSIZE MAXPATHLEN
  38. #else
  39. #ifdef PATH_MAX
  40. #define MAXPATHSIZE PATH_MAX
  41. #else
  42. #define MAXPATHSIZE 1024
  43. #endif /* PATH_MAX */
  44. #endif /* MAXPATHLEN */
  45. #endif /* HAVE_GETCWD */
  46.  
  47. #include <errno.h>
  48.  
  49. /* Not all systems declare ERRNO in errno.h... and some systems #define it! */
  50. #if !defined (errno)
  51. extern int errno;
  52. #endif /* !errno */
  53.  
  54.  
  55. #include "xmalloc.h"
  56. #include "xstring.h"
  57. #include "xio.h"
  58.  
  59.  
  60. int
  61. xread(fd, buf, count)
  62.     int fd;
  63.     char *buf;
  64.     size_t count;
  65. {
  66.     int chars;
  67.     int old_errno;
  68.  
  69.     if (count <= 0)
  70.     return count;
  71.  
  72. #ifdef EINTR
  73.     old_errno = errno;
  74.  
  75.     do
  76.     chars = read(fd, buf, count);
  77.     while (chars < 0 && errno == EINTR);
  78.  
  79.     errno = old_errno;
  80.     return chars;
  81. #else
  82.     return read(fd, buf, count);
  83. #endif
  84. }
  85.  
  86.  
  87. int
  88. xwrite(fd, buf, count)
  89.     int fd;
  90.     const char *buf;
  91.     size_t count;
  92. {
  93.     int chars;
  94.     int old_errno;
  95.  
  96.     if (count <= 0)
  97.     return count;
  98.  
  99. #ifdef EINTR
  100.     old_errno = errno;
  101.  
  102.     do
  103.     chars = write(fd, buf, count);
  104.     while (chars < 0 && errno == EINTR);
  105.  
  106.     errno = old_errno;
  107.     return chars;
  108. #else
  109.     return write(fd, buf, count);
  110. #endif
  111. }
  112.  
  113.  
  114. int
  115. __xreadlink(path, buf, size)
  116.     const char *path;
  117.     char *buf;
  118.     size_t size;
  119. {
  120.     int chars;
  121.     int old_errno;
  122.  
  123.     if (size <= 0)
  124.     return size;
  125.  
  126. #ifdef EINTR
  127.     old_errno = errno;
  128.  
  129.     do
  130.     {
  131.     chars = readlink(path, buf, size);
  132.     old_errno = size;
  133.     }
  134.     while (chars < 0 && errno == EINTR);
  135.  
  136.     errno = old_errno;
  137.     return chars;
  138. #else
  139.     return read(fd, buf, count);
  140. #endif
  141. }
  142.  
  143.  
  144. int
  145. xreadlink(filename)
  146.     const char *filename;
  147. {
  148.     int size = 100;
  149.  
  150.     for (;;)
  151.     {
  152.     char *buffer = xmalloc(size);
  153.     int  nchars  = __xreadlink(filename, buffer, size);
  154.  
  155.     if (nchars < size)
  156.     {
  157.         xfree(buffer);
  158.         return nchars;
  159.     }
  160.  
  161.     xfree(buffer);
  162.     size *= 2;
  163.     }
  164. }
  165.  
  166.  
  167. int
  168. xfstat(filedes, buf)
  169.     int filedes;
  170.     struct stat *buf;
  171. {
  172.     int result;
  173.  
  174.     do
  175.     result = fstat(filedes, buf);
  176.     while (result < 0 && errno == EINTR);
  177.  
  178.     return result;
  179. }
  180.  
  181.  
  182. int
  183. xstat(filename, buf)
  184.     const char *filename;
  185.     struct stat *buf;
  186. {
  187.     int result;
  188.  
  189.     do
  190.     result = stat(filename, buf);
  191.     while (result < 0 && errno == EINTR);
  192.  
  193.     return result;
  194. }
  195.  
  196.  
  197. int
  198. xlstat(filename, buf)
  199.     const char *filename;
  200.     struct stat *buf;
  201. {
  202.     int result;
  203.  
  204.     do
  205. #ifdef HAVE_LSTAT
  206.     result = lstat(filename, buf);
  207. #else
  208.     result = stat(filename, buf);
  209. #endif /* HAVE_LSTAT */
  210.     while (result < 0 && errno == EINTR);
  211.  
  212.     return result;
  213. }
  214.  
  215.  
  216. char *
  217. xgetcwd()
  218. {
  219.     char *result;
  220.     char *cwd;
  221.  
  222.     errno = 0;
  223.  
  224. #ifdef HAVE_GETCWD
  225.     {
  226.     size_t size;
  227.  
  228.     cwd = xmalloc(size = 64);
  229.  
  230.     while ((result = getcwd(cwd, size)) == NULL && errno == ERANGE)
  231.     {
  232.         cwd = xrealloc(cwd, size += 64);
  233.         errno = 0;
  234.     }
  235.     }
  236. #else
  237.     {
  238.     /* No getcwd() -> getwd(): BSD style... bleah!  */
  239.  
  240.     cwd    = xmalloc(MAXPATHSIZE + 2);
  241.     result = getwd(cwd);
  242.  
  243.     if (result)
  244.         cwd = xrealloc(cwd, strlen(cwd) + 1);
  245.     }
  246. #endif  /* HAVE_GETCWD */
  247.  
  248.     if (result == NULL)
  249.     {
  250.     int old_errno = errno;
  251.     xfree(cwd);
  252.     errno = old_errno;
  253.     return NULL;
  254.     }
  255.  
  256.     return cwd;
  257. }
  258.  
  259.  
  260. char *
  261. xbasename(name)
  262.     char *name;
  263. {
  264.     char *base;
  265.     size_t len = strlen(name);
  266.  
  267.     if (name[len - 1] == '/')
  268.     name[len - 1] = '\0';
  269.  
  270.     base = strrchr(name, '/');
  271.     return base ? base + 1 : name;
  272. }
  273.