Mail Archives: djgpp-workers/2001/02/22/22:52:28
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 -