delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/02/22/22:52:28

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Thu, 22 Feb 2001 22:52:10 -0500
MIME-Version: 1.0
Subject: O_TEMPORARY v2
Message-ID: <3A95981A.14546.31CA2@localhost>
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com

Hello,
Revision two of O_TEMPORARY support is ready for inspection. I've generalized
the code to permit much more than O_TEMPORARY to be supported if desired.
Support for handling a file opened with O_TEMPORARY and opened with or 
without
O_TEMPORARY has been added. I also added caching so time isn't wasted 
allocating
memory over and over to somewhat like how a FILE struct is allocated.

I have tested this the following small program:

#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

const char temp_file[]="test.txt";

int main()
{
  int fd, fd2, fd3, fd4;

  fd = open(temp_file, O_RDWR | O_CREAT | O_TRUNC, S_IWUSR);
  fd2 = dup(fd);
  fd3 = dup2(fd, 127);
  fd4 = open(temp_file, O_RDWR | O_CREAT | O_TRUNC | O_TEMPORARY, S_IWUSR);
  write(fd, temp_file, sizeof(temp_file) - 1); close(fd); close(fd3);
  close(fd2); close(fd4);

  fd = open(temp_file, O_RDWR | O_CREAT | O_TRUNC | O_TEMPORARY, S_IWUSR);
  fd2 = dup(fd);
  fd3 = dup2(fd, 127);
  fd4 = open(temp_file, O_RDWR | O_CREAT | O_TRUNC, S_IWUSR);
  write(fd, temp_file, sizeof(temp_file) - 1);
  close(fd);
  close(fd3);
  close(fd2);
  close(fd4);

  return 0;
}


*** /dev/null	Thu Feb 22 00:41:21 2001
--- /djgpp/include/libc/fdprops.h	Tue Feb 20 12:07:56 2001
***************
*** 0 ****
--- 1,42 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+ #ifndef __dj_include_libc_fdprops_h__
+ #define __dj_include_libc_fdprops_h__
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ 
+ #ifndef __dj_ENFORCE_ANSI_FREESTANDING
+ 
+ #ifndef __STRICT_ANSI__
+ 
+ #ifndef _POSIX_SOURCE
+ 
+ /* Delete file when the last descriptor referencing it is closed.  */
+ #define FILE_DESC_TEMPORARY 1
+ 
+ typedef struct fd_properties fd_properties;
+ 
+ typedef struct fd_properties
+ {
+   unsigned char ref_count;
+   unsigned long flags;
+   char *filename;
+   fd_properties *prev;
+   fd_properties *next;
+ };
+ 
+ int _set_fd_properties(int _fd, const char * _file, int _oflags);
+ void _dup_fd_properties(int _from, int _to);
+ 
+ extern fd_properties ** __fd_properties;
+ 
+ #endif /* !_POSIX_SOURCE */
+ #endif /* !__STRICT_ANSI__ */
+ #endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif /* __dj_include_libc_fdprops_h__  */
*** /dev/null	Thu Feb 22 00:41:21 2001
--- fdprops.c	Thu Feb 22 00:40:58 2001
***************
*** 0 ****
--- 1,204 ----
+ #include <stdlib.h>
+ #include <limits.h>
+ #include <strings.h>
+ #include <sys/stat.h>
+ #include <stdio.h>
+ #include <sys/stat.h>
+ #include <libc/bss.h>
+ #include <fcntl.h>
+ 
+ #include <libc/fdprops.h>
+ 
+ static void open_fd(fd_properties *fd, int open_flags);
+ static void close_fd(fd_properties *fd);
+ static fd_properties * find_eq_filename(const fd_properties *fd);
+ static fd_properties * alloc_fd_properties();
+ static void free_fd_properties(fd_properties *);
+ static void insert_1ist(fd_properties **, fd_properties *);
+ static void remove_1ist(fd_properties **, fd_properties *);
+ 
+ /* Array of pointers to fd_properties objects associated
+    with a file descriptor.  */
+ fd_properties **__fd_properties = NULL;
+ 
+ /* 1ist of fd_properties objects associated with at least
+    one file descriptor.  */
+ static fd_properties *active_fds;
+ 
+ /* 1ist of fd_properties objects currently not in use.  */
+ static fd_properties *cached_fds;
+ 
+ static int old_bss_count;
+ 
+ /* Set or clear the properties associated with a file descriptor.  */
+ int
+ _set_fd_properties(int fd, const char *file, int open_flags)
+ {
+   if (file)
+   {
+     char buffer[FILENAME_MAX + 1];
+     int len;
+ 
+     if (old_bss_count != __bss_count)
+     {
+       size_t size = 255 * sizeof(fd_properties *);
+       old_bss_count = __bss_count;
+       __fd_properties = malloc(size);
+       active_fds = NULL;
+       cached_fds = NULL;
+       if (__fd_properties == NULL)
+         return -1;
+       memset(__fd_properties, 0, size);
+     }
+ 
+     _truename(file, buffer);
+     len = strlen(buffer);
+     __fd_properties[fd] = alloc_fd_properties();
+     if (__fd_properties[fd] == NULL)
+       return -1;
+ 
+     /* Initialize the object and insert it into 1ist.  */
+     __fd_properties[fd]->ref_count = 1;
+     __fd_properties[fd]->flags = 0;
+     __fd_properties[fd]->filename = strdup(buffer);
+ 
+     insert_1ist(&active_fds, __fd_properties[fd]);
+ 
+     open_fd(__fd_properties[fd], open_flags);
+   }
+   else
+   {
+     /* There are no properties with this descriptor. Punt.  */
+     if (__fd_properties[fd] == NULL)
+       return -1;
+ 
+     if (--(__fd_properties[fd]->ref_count) == 0)
+     {
+       /* The last file descriptor using this object has closed.  Perform
+          any final actions before the object is put into the cache.  */
+       close_fd(__fd_properties[fd]);
+       
+       free(__fd_properties[fd]->filename);
+       __fd_properties[fd]->filename = NULL;
+       free_fd_properties(__fd_properties[fd]);
+     }
+     __fd_properties[fd] = NULL;
+   }
+   return 0;
+ }
+ 
+ /* Set properties of a file descriptor returned by dup or dup2.  */
+ void
+ _dup_fd_properties(int from, int to)
+ {
+   if (__fd_properties[from])
+   {
+     __fd_properties[to] = __fd_properties[from];
+     ++(__fd_properties[to]->ref_count);
+   }
+ }
+ 
+ /* Perform file descriptor specific initialization.  */
+ static void
+ open_fd(fd_properties *cur_fd, int open_flags)
+ {
+   if (cur_fd->filename && open_flags & O_TEMPORARY)
+     cur_fd->flags |= FILE_DESC_TEMPORARY;
+ }
+ 
+ /* Perform file descriptor specific finalization.  */
+ static void
+ close_fd(fd_properties *cur_fd)
+ {
+   /* Delete the file if no other descriptors use the file.  Otherwise,
+      mark the other descriptor with the temporary flag.  */
+   if (cur_fd->flags & FILE_DESC_TEMPORARY)
+   {
+     fd_properties *ptr = find_eq_filename(cur_fd);
+     if (ptr)
+       ptr->flags |= FILE_DESC_TEMPORARY;
+     else
+       remove(cur_fd->filename);
+   }
+ }
+ 
+ /* Find another properties object using the same filename.  */
+ static
+ fd_properties * find_eq_filename(const fd_properties *fd)
+ {
+   fd_properties *ptr = active_fds;
+   
+   while (ptr)
+   {
+     if ((ptr != fd) && (strcmp(fd->filename, ptr->filename) == 0))
+       return ptr;
+     ptr = ptr->next;
+   }
+   return NULL;
+ }
+ 
+ /* Return a properties object to be used with one or more file descriptors. 



+ */ static fd_properties * alloc_fd_properties() {
+   fd_properties *ptr;
+   
+   if (cached_fds == NULL)
+   {
+     ptr = malloc(sizeof(fd_properties));
+     if (ptr == NULL)
+       return ptr;
+   }
+   else
+   {
+     ptr = cached_fds;
+     remove_1ist(&cached_fds, cached_fds);
+   }
+   ptr->prev = NULL;
+   ptr->next = NULL;
+   ptr->ref_count = 1;
+   
+   return ptr;   
+ }
+ 
+ /* Remove the object from the active 1ist, and insert it into the cache.  
*/
+ static void free_fd_properties(fd_properties *fd) {
+   remove_1ist(&active_fds, fd);
+   insert_1ist(&cached_fds, fd);
+ }
+ 
+ /* Insert a properties object into a 1ist.  */
+ static void
+ insert_1ist(fd_properties **head_ptr, fd_properties *item)
+ {
+   fd_properties *head = *head_ptr;
+   item->next = head;
+   item->prev = NULL;
+   if (head)
+     head->prev = item;
+   *head_ptr = item;
+ }
+ 
+ /* Remove a properties object from a 1ist.  */
+ static void
+ remove_1ist(fd_properties **head_ptr, fd_properties *item)
+ {
+   fd_properties *head = *head_ptr;
+   
+   if (item->prev)
+   {
+     (item->prev)->next = item->next;
+     item->prev = NULL;
+   }
+   if (item->next)
+   {
+     (item->next)->prev = item->prev;
+     item->next = NULL;
+   }
+   if (head == item)
+     head = head->next;
+ 
+   *head_ptr = head;
+ }
*** open.c.orig	Mon Aug 28 10:22:34 2000
--- open.c	Mon Feb 19 20:20:04 2001
***************
*** 18,23 ****
--- 18,24 ----
  #include <io.h>

  #include <libc/dosio.h>
+ #include <libc/fdprops.h>

  /* Extra share flags that can be indicated by the user */
  int __djgpp_share_flags;
*************** open(const char* filename, int oflag, ..
*** 152,157 ****
--- 153,161 ----
    if(oflag & O_APPEND)
      lseek(fd, 0, SEEK_END);

+   if (oflag)
+     _set_fd_properties(fd, real_name, oflag);
+     
    return fd;
  }

*** _close.c.orig	Thu Jan  1 19:12:50 1998
--- _close.c	Mon Feb 19 20:18:16 2001
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <unistd.h>
***************
*** 7,13 ****
--- 8,16 ----
  #include <io.h>
  #include <sys/fsext.h>

+ #include <libc/farptrgs.h>
  #include <libc/dosio.h>
+ #include <libc/fdprops.h>

  int
  _close(int handle)
*************** _close(int handle)
*** 37,41 ****
--- 40,49 ----
      errno = EBADF;
      return -1;
    }
+ 
+   if (__fd_properties && __fd_properties[handle])
+     _set_fd_properties(handle, NULL, 0);
+ 
    return 0;
  }
+ 
*** dup.c.orig	Sun Feb 26 19:43:08 1995
--- dup.c	Mon Feb 19 20:19:18 2001
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <libc/stubs.h>
  #include <unistd.h>
***************
*** 5,10 ****
--- 6,12 ----
  #include <errno.h>
  #include <io.h>
  #include <libc/dosio.h>
+ #include <libc/fdprops.h>

  int
  dup(int fd)
*************** dup(int fd)
*** 19,23 ****
--- 21,29 ----
      return -1;
    }
    setmode(r.x.ax, __file_handle_modes[fd]);
+ 
+   if (__fd_properties && __fd_properties[fd])
+     _dup_fd_properties(fd, r.x.ax);
+ 
    return r.x.ax;
  }
*** dup2.c.orig	Sun Sep 29 06:20:56 1996
--- dup2.c	Mon Feb 19 20:19:30 2001
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <libc/stubs.h>
***************
*** 7,12 ****
--- 8,14 ----
  #include <errno.h>
  #include <io.h>
  #include <libc/dosio.h>
+ #include <libc/fdprops.h>

  int
  dup2(int fd, int newfd)
*************** dup2(int fd, int newfd)
*** 25,29 ****
--- 27,39 ----
      return -1;
    }
    setmode(newfd, __file_handle_modes[fd]);
+ 
+   if (__fd_properties)
+   {
+     if (__fd_properties[newfd])
+       _set_fd_properties(newfd, NULL, 0);
+     _dup_fd_properties(fd, newfd);
+   }
+ 
    return newfd;
  }
*** /djgpp/include/fcntl.h.orig	Wed Feb 14 14:30:06 2001
--- /djgpp/include/fcntl.h	Sat Feb 10 11:24:04 2001
*************** int	fcntl(int _fildes, int _cmd, ...);
*** 77,82 ****
--- 77,84 ----
  #define O_NOLINK        0x4000
  #define O_NOFOLLOW      0x8000

+ #define O_TEMPORARY	0x10000 /* Delete file after closing.  */
+ 
  #define SH_COMPAT	0x0000
  #define SH_DENYRW	0x0010
  #define SH_DENYWR	0x0020

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019