summaryrefslogtreecommitdiffstats
path: root/isys/gzlib/binding.c
blob: 55e512d264c2c38bf18d943445ca42504b502078 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <sys/signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

#include "gzlib.h"

int gunzip_main(int decompress);

struct gzFile_s {
    int fd;
};

gzFile gunzip_dopen(int fd) {
    int p[2];
    void * oldsig;
    pid_t child;
    gzFile str;

    pipe(p);

    oldsig = signal(SIGCLD, SIG_IGN);

    child = fork();
    if (!child) {
	if (fork()) exit(0);

	dup2(fd, 0);
	dup2(p[1], 1);
	close(p[0]);
	close(p[1]);
	if (fd > 2) close(fd);
	gunzip_main(1);
	exit(0);
    }

    waitpid(child, NULL, 0);
    signal(SIGCLD, oldsig);

    close(p[1]);

    str = malloc(sizeof(*str));
    str->fd = p[0];

    return str;
}

gzFile gunzip_open(const char * file) {
    int fd;
    gzFile rc;

    fd = open(file, O_RDONLY);
    if (fd < 0) return NULL;

    rc = gunzip_dopen(fd);
    close(fd);

    return rc;
}

gzFile gzip_dopen(int fd) {
    int p[2];
    void * oldsig;
    pid_t child;
    gzFile str;

    pipe(p);

    oldsig = signal(SIGCLD, SIG_IGN);

    child = fork();
    if (!child) {
	if (fork()) exit(0);

	dup2(p[0], 0);
	dup2(fd, 1);
	close(p[0]);
	close(p[1]);
	if (fd > 2) close(fd);
	gunzip_main(0);
	exit(0);
    }

    waitpid(child, NULL, 0);
    signal(SIGCLD, oldsig);

    close(p[0]);

    str = malloc(sizeof(*str));
    str->fd = p[1];

    return str;
}


gzFile gzip_open(const char * file, int flags, int perms) {
    int fd;
    gzFile rc;

    fd = open(file, flags, perms);
    if (fd < 0) return NULL;

    rc = gzip_dopen(fd);
    close(fd);

    return rc;
}

int gunzip_read(gzFile str, void * buf, int bytes) {
    int pos = 0;
    int i = 0;

    while ((pos != bytes) &&
      (i = read(str->fd, ((char *) buf) + pos, bytes - pos)) > 0) {
	pos += i;
    }

    if (i < 0) return -1;

    return pos;
}

int gzip_write(gzFile str, void * buf, int bytes) {
    return write(str->fd, buf, bytes);
}

int gunzip_close(gzFile str) {
    close(str->fd);
    
    return 0;
}

int gzip_close(gzFile str) {
    close(str->fd);
    
    return 0;
}