source: trunk/athena/bin/delete/stack.c @ 10977

Revision 10977, 3.5 KB checked in by danw, 27 years ago (diff)
assume POSIX. (from svalente)
Line 
1/*
2 * $Source: /afs/dev.mit.edu/source/repository/athena/bin/delete/stack.c,v $
3 * $Author: danw $
4 *
5 * This program is part of a package including delete, undelete,
6 * lsdel, expunge and purge.  The software suite is meant as a
7 * replacement for rm which allows for file recovery.
8 *
9 * Copyright (c) 1989 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file "mit-copying.h."
11 */
12
13#if (!defined(lint) && !defined(SABER))
14     static char rcsid_stack_c[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/delete/stack.c,v 1.11 1997-12-31 22:36:01 danw Exp $";
15#endif
16
17#include <sys/types.h>
18#include <stdio.h>
19#include <errno.h>
20#include "stack.h"
21#include "delete_errs.h"
22#include "errors.h"
23#include "mit-copying.h"
24#include "util.h"
25
26#define STACK_INC       25
27
28
29
30int dostack(data, op, bytes)
31caddr_t data;
32int op, bytes;
33{
34     static caddr_t stack = (caddr_t) NULL;
35     static int size = 0, count = 0;
36     
37     switch (op) {
38     case EMPTY_STACK:
39          if (size) {
40               free(stack);
41               stack = (caddr_t) NULL;
42               size = count = 0;
43          }
44#ifdef STACK_DEBUG
45          fprintf(stderr, "dostack: return 1 (EMPTY_STACK).\n");
46#endif
47          return 0;
48     case STACK_PUSH:
49          if (bytes == 0) {
50#ifdef STACK_DEBUG
51               fprintf(stderr, "Pushing 0 bytes at %d offset.\n", count);
52               fprintf(stderr, "dostack: return 2 (STACK_PUSH).\n");
53#endif
54               return 0;
55          }
56          if (size - count < bytes) {
57               do
58                    size += STACK_INC;
59               while (size - count < bytes);
60               stack = (caddr_t) (stack ? realloc((char *) stack,
61                                                  (unsigned) size) :
62                                  Malloc((unsigned) size));
63#ifdef MALLOC_0_RETURNS_NULL
64               if ((! stack) && size)
65#else
66               if (! stack)
67#endif
68               {
69                    size = count = 0;
70                    set_error(errno);
71                    error("Malloc");
72#ifdef STACK_DEBUG
73                    fprintf(stderr, "dostack: return 3 (STACK_PUSH).\n");
74#endif
75                    return error_code;
76               }
77          }
78#ifdef STACK_DEBUG
79          fprintf(stderr, "Pushing %d bytes at %d offset.\n", bytes, count);
80#endif
81          memcpy(stack + count, data, bytes);
82          count += bytes;
83#ifdef STACK_DEBUG
84          fprintf(stderr, "dostack: return 4 (STACK_PUSH).\n");
85#endif
86          return 0;
87     case STACK_POP:
88          if (bytes == 0) {
89#ifdef STACK_DEBUG
90               fprintf(stderr, "Popping 0 bytes at %d offset.\n", count);
91               fprintf(stderr, "dostack: return 5 (STACK_POP).\n");
92#endif
93               return 0;
94          }
95          if (count == 0) {
96               set_status(STACK_EMPTY);
97#ifdef STACK_DEBUG
98               fprintf(stderr, "dostack: return 6 (STACK_POP).\n");
99#endif
100               return error_code;
101          }
102          else {
103               int newblocks, newsize;
104
105               count -= bytes;
106#ifdef STACK_DEBUG
107               fprintf(stderr, "Popping %d bytes at %d offset.\n", bytes,
108                       count);
109#endif
110               memcpy(data, stack + count, bytes);
111               newblocks = count / STACK_INC + ((count % STACK_INC) ? 1 : 0);
112               newsize = newblocks * STACK_INC;
113               if (newsize < size) {
114                    size = newsize;
115                    stack = (caddr_t) realloc((char *) stack, (unsigned) size);
116#ifdef MALLOC_0_RETURNS_NULL
117                    if ((! stack) && size)
118#else
119                    if (! stack)
120#endif
121                    {
122                         set_error(errno);
123                         error("realloc");
124#ifdef STACK_DEBUG
125                         fprintf(stderr, "dostack: return 7 (STACK_POP).\n");
126#endif
127                         return error_code;
128                    }
129               }
130#ifdef STACK_DEBUG
131               fprintf(stderr, "dostack: return 8 (STACK_POP).\n");
132#endif
133               return 0;
134          }
135     default:
136          set_error(STACK_BAD_OP);
137#ifdef STACK_DEBUG
138          fprintf(stderr, "dostack: return 9.\n");
139#endif
140          return error_code;
141     }
142}
Note: See TracBrowser for help on using the repository browser.