New plugins system
[opsoft.git] / gclib2 / modules / Core / dexec.cxx
blob13733d8af456fa570728e134865c8bd7d86895b7
1 /*
2 * (c) Oleg Puchinin 2007
3 * graycardinalster@gmail.com
5 */
7 #include <string.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <gc_strings_low.h>
12 #include <gc_io.h>
13 #include <djob_t.h>
14 #include <dexec.h>
15 #include <fcntl.h>
16 #include <sys/wait.h>
17 #include <stdint.h>
18 #include <Macroses.h>
19 #include <sys/mman.h>
21 __export void Dexec_init (struct __djob_t * ctx)
23 memset (ctx, 0, sizeof (struct __djob_t));
24 ctx->stdIn = -1;
25 ctx->stdOut = -1;
26 ctx->stdErr = -1;
27 ctx->pipe_in[0] = -1;
28 ctx->pipe_in[1] = -1;
29 ctx->pipe_out[0] = -1;
30 ctx->pipe_out[1] = -1;
31 ctx->pipe_err[0] = -1;
32 ctx->pipe_err[1] = -1;
33 ctx->otmp_name = (char *) malloc (128);
34 ctx->etmp_name = (char *) malloc (128);
35 ctx->otmp_name[0] = '\0';
36 ctx->etmp_name[0] = '\0';
37 ctx->shared_mem = NULL;
38 ctx->pid = 0;
41 int Dexec_done (struct __djob_t *ctx)
43 if (! ctx)
44 return 0;
46 if (ctx->otmp_name)
47 free (ctx->otmp_name);
49 if (ctx->etmp_name)
50 free (ctx->etmp_name);
52 if (ctx->shared_mem)
53 munmap (ctx->shared_mem, ctx->shm_size);
55 fdclose (&ctx->stdIn);
56 fdclose (&ctx->stdOut);
57 fdclose (&ctx->stdErr);
58 free (ctx);
59 return 0;
62 void __dexec_init_pipes (__djob_t * ctx, uint32_t opts)
64 if (! ctx)
65 return;
66 if (opts & DEXEC_IPIPE)
67 pipe (ctx->pipe_in);
68 if (opts & DEXEC_OPIPE)
69 pipe (ctx->pipe_out);
70 if (opts & DEXEC_EPIPE)
71 pipe (ctx->pipe_err);
74 void __dexec_parent (__djob_t * ctx, int opts, char * cmd)
76 int status;
78 if (! ctx)
79 return;
80 if (opts & DEXEC_IPIPE)
81 fdclose (&ctx->pipe_in[0]);
82 if (opts & DEXEC_OPIPE)
83 fdclose (&ctx->pipe_out[1]);
84 if (opts & DEXEC_EPIPE)
85 fdclose (&ctx->pipe_err[1]);
86 if (opts & DEXEC_WAIT)
87 waitpid (ctx->pid, &status, 0);
90 void __dexec_child (__djob_t * ctx, int opts, char * cmd)
92 int fd;
94 if (! ctx)
95 return;
97 if (opts & DEXEC_IPIPE) {
98 fdclose (&ctx->pipe_in[1]);
99 dup2 (ctx->pipe_in[0], fileno (stdin));
102 if (opts & DEXEC_OPIPE) {
103 fdclose (&ctx->pipe_out[0]);
104 dup2 (ctx->pipe_out[1], fileno (stdout));
107 if (opts & DEXEC_EPIPE) {
108 fdclose (&ctx->pipe_err[0]);
109 dup2 (ctx->pipe_err[1], fileno (stderr));
112 if (opts & DEXEC_INULL) {
113 fd = open ("/dev/null", O_RDONLY);
114 dup2 (fd, fileno (stdin));
117 if (opts & DEXEC_ONULL) {
118 fd = open ("/dev/null", O_WRONLY);
119 dup2 (fd, fileno (stdout));
122 if (opts & DEXEC_ENULL) {
123 fd = open ("/dev/null", O_WRONLY);
124 dup2 (fd, fileno (stderr));
127 if (cmd)
128 exit (execlp ("/bin/sh", "/bin/sh", "-c", cmd, NULL));
131 __export __djob_t * Dexec (unsigned int opts, char * cmd)
133 __djob_t * ctx;
134 int fdo = -1;
135 int fde = -1;
137 ctx = CNEW (__djob_t, 1);
138 Dexec_init (ctx);
139 __dexec_init_pipes (ctx, opts);
141 if (opts & DEXEC_OTMP)
142 fdo = Dtmpfd (ctx->otmp_name);
143 if (opts & DEXEC_ETMP)
144 fde = Dtmpfd (ctx->etmp_name);
146 ctx->pid = fork ();
147 if (ctx->pid == 0) {
148 if (opts & DEXEC_OTMP) {
149 dup2 (fdo, fileno (stdout));
150 fdclose (&fdo);
152 if (opts & DEXEC_ETMP) {
153 dup2 (fde, fileno (stderr));
154 fdclose (&fde);
156 __dexec_child (ctx, opts, cmd);
157 } else if (ctx->pid > 0) {
158 fdclose (&fdo);
159 fdclose (&fde);
160 __dexec_parent (ctx, opts, cmd);
161 return ctx;
162 } else
163 return NULL;
165 return ctx;