r1005: Increase the number of displayed digits for resample audio dialog box
[cinelerra_cv/mob.git] / cinelerra / pipe.C
blobf5d7b49a952f9f19484037e38ea1928efd2309c5
1 #include <fcntl.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <signal.h>
6 #include "bchash.h"
7 #include "file.h"
8 #include "guicast.h"
9 #include "interlacemodes.h"
10 #include "pipe.h"
12 extern "C" 
14         int pipe_sigpipe_received;
16         void pipe_handle_sigpipe(int signum) 
17         {
18                 printf("Received sigpipe\n");
19                 pipe_sigpipe_received++;
20         }
23 Pipe::Pipe(char *command, char *sub_str, char sub_char) 
24
25         this->command = command;
26         this->sub_str = sub_str;
27         this->sub_char = sub_char;
29         complete[0] = '\0';
30         file = NULL;
31         fd = -1;
33         // FUTURE: could probably set to SIG_IGN once things work
34         signal(SIGPIPE, pipe_handle_sigpipe);
37 Pipe::~Pipe() 
39         close();
42 int Pipe::substitute() 
44         if (command == NULL) 
45         {
46                 strcpy(complete, "");
47                 return 0;
48         }
50         if (sub_str == NULL || sub_char == '\0') 
51         {
52                 strcpy(complete, command);
53                 return 0;
54         }
56         int count = 0;
57         char *c = command;
58         char *f = complete;
59         while (*c) 
60         {
61                 // directly copy anything substitution char
62                 if (*c != sub_char) 
63                 {
64                         *f++ = *c++;
65                         continue;
66                 }
67                 
68                 // move over the substitution character
69                 c++;
71                 // two substitution characters in a row is literal
72                 if (*c == sub_char) {
73                         *f++ = *c++;
74                         continue;
75                 }
77                 // insert the file string at the substitution point
78                 if (f + strlen(sub_str) - complete > sizeof(complete))
79                 {
80                         printf("Pipe::substitute(): max length exceeded\n");
81                         return -1;
82                 }
83                 strcpy(f, sub_str);
84                 f += strlen(sub_str);
85                 count++;
86         }
88         return count;
90         
91         
93 int Pipe::open(char *mode) 
95         if (file) close();
97         if (mode == NULL) 
98         {
99                 printf("Pipe::open(): no mode given\n");
100                 return 1;
101         }
103         if (substitute() < 0) 
104                 return 1;
106         if (complete == NULL || strlen(complete) == 0) 
107         {
108                 printf("Pipe::open(): no pipe to open\n");
109                 return 1;
110         }
112         printf("trying popen(%s)\n", complete);
113         file = popen(complete, mode);
114         if (file != NULL) 
115         {
116                 fd = fileno(file);
117                 return 0;
118         }
120         // NOTE: popen() fails only if fork/exec fails
121         //       there is no immediate way to see if command failed
122         //       As such, one must expect to raise SIGPIPE on failure
123         printf("Pipe::open(%s,%s) failed: %s\n", 
124                complete, mode, strerror(errno));
125         return 1;
126 }       
128 int Pipe::open_read() 
130         return open("r");
133 int Pipe::open_write() 
135         return open("w");
138 void Pipe::close() 
140         pclose(file);
141         file = 0;
142         fd = -1;