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

Revision 11165, 3.4 KB checked in by ghudson, 27 years ago (diff)
Assume any system's malloc(0) may return NULL.
Line 
1/*
2 * $Source: /afs/dev.mit.edu/source/repository/athena/bin/delete/stack.c,v $
3 * $Author: ghudson $
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.12 1998-02-25 22:27:24 ghudson 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               if ((! stack) && size)
64               {
65                    size = count = 0;
66                    set_error(errno);
67                    error("Malloc");
68#ifdef STACK_DEBUG
69                    fprintf(stderr, "dostack: return 3 (STACK_PUSH).\n");
70#endif
71                    return error_code;
72               }
73          }
74#ifdef STACK_DEBUG
75          fprintf(stderr, "Pushing %d bytes at %d offset.\n", bytes, count);
76#endif
77          memcpy(stack + count, data, bytes);
78          count += bytes;
79#ifdef STACK_DEBUG
80          fprintf(stderr, "dostack: return 4 (STACK_PUSH).\n");
81#endif
82          return 0;
83     case STACK_POP:
84          if (bytes == 0) {
85#ifdef STACK_DEBUG
86               fprintf(stderr, "Popping 0 bytes at %d offset.\n", count);
87               fprintf(stderr, "dostack: return 5 (STACK_POP).\n");
88#endif
89               return 0;
90          }
91          if (count == 0) {
92               set_status(STACK_EMPTY);
93#ifdef STACK_DEBUG
94               fprintf(stderr, "dostack: return 6 (STACK_POP).\n");
95#endif
96               return error_code;
97          }
98          else {
99               int newblocks, newsize;
100
101               count -= bytes;
102#ifdef STACK_DEBUG
103               fprintf(stderr, "Popping %d bytes at %d offset.\n", bytes,
104                       count);
105#endif
106               memcpy(data, stack + count, bytes);
107               newblocks = count / STACK_INC + ((count % STACK_INC) ? 1 : 0);
108               newsize = newblocks * STACK_INC;
109               if (newsize < size) {
110                    size = newsize;
111                    stack = (caddr_t) realloc((char *) stack, (unsigned) size);
112                    if ((! stack) && size)
113                    {
114                         set_error(errno);
115                         error("realloc");
116#ifdef STACK_DEBUG
117                         fprintf(stderr, "dostack: return 7 (STACK_POP).\n");
118#endif
119                         return error_code;
120                    }
121               }
122#ifdef STACK_DEBUG
123               fprintf(stderr, "dostack: return 8 (STACK_POP).\n");
124#endif
125               return 0;
126          }
127     default:
128          set_error(STACK_BAD_OP);
129#ifdef STACK_DEBUG
130          fprintf(stderr, "dostack: return 9.\n");
131#endif
132          return error_code;
133     }
134}
Note: See TracBrowser for help on using the repository browser.