1Netpbm subroutine libNreatrpyb:m pLsmiu_bbsrryaosrutyteimFn(ue)nclstiuibborrnaosruytM:iannpeum,a_lseytsct.e(m3()) subroutine, etc.(3)
2
3
4
6 pm_system - run a Netpbm program with program input and output
7
8
10 #include <netpbm/pm_system.h>
11
12 pm_system(void stdinFeeder(int, void *),
13 void * const feederParm,
14 void stdoutAccepter(int, void *),
15 void * const accepterParm,
16 const char * const shellCommand);
17
18 pm_system_lp(const char * const progName,
19 void stdinFeeder(int, void *),
20 void * const feederParm,
21 void stdoutAccepter(int, void *),
22 void * const accepterParm,
23 ...);
24
25 pm_system_vp(const char * const progName,
26 const char ** const argArray,
27 void stdinFeeder(int, void *),
28 void * const feederParm,
29 void stdoutAccepter(int, void *),
30 void * const accepterParm);
31
32 pm_system2(void stdinFeeder(int, void *),
33 void * const feederParm,
34 void stdoutAccepter(int, void *),
35 void * const accepterParm,
36 const char * const shellCommand,
37 int * const termStatusP );
38
39 pm_system2_lp(const char * const progName,
40 void stdinFeeder(int, void *),
41 void * const feederParm,
42 void stdoutAccepter(int, void *),
43 int * const terminationStatusP,
44 void * const accepterParm,
45 ...);
46
47 pm_system2_vp(const char * const progName,
48 const char ** const argArray,
49 void stdinFeeder(int, void *),
50 void * const feederParm,
51 void stdoutAccepter(int, void *),
52 void * const accepterParm,
53 int * const termStatusP);
54
55
56
57
59 This simple example converts a PNM image on Standard Input to a JFIF
60 (JPEG) image on Standard Output. In this case, pm_system() is doing no
61 more than system() would do.
62
63 pm_system(NULL, NULL, NULL, NULL, "pnmtojpeg");
64
65
66 This example does the same thing, but moves the data through memory
67 buffers to illustrate use with memory buffers, and we throw in a stage
68 to shrink the image too:
69 #include <netpbm/pm_system.h>
70
71 char pnmData[100*1024]; /* Input file better be < 100K */
72 char jfifData[100*1024];
73 struct bufferDesc pnmBuffer;
74 struct bufferDesc jfifBuffer;
75 unsigned int jfifSize;
76
77 pnmBuffer.size = fread(pnmData, 1, sizeof(pnmData), stdin);
78 pnmBuffer.buffer = pnmData;
79 pnmBuffer.bytesTransferredP = NULL;
80
81 jfifBuffer.size = sizeof(jfifData);
82 jfifBuffer.buffer = jfifData;
83 jfifBuffer.bytesTransferredP = &jfifSize;
84
85 pm_system(&pm_feed_from_memory, &pnmBuffer,
86 &pm_accept_to_memory, &jfifBuffer,
87 "pamscale .5 | pnmtojpeg");
88
89 fwrite(jfifData, 1, jfifSize, stdout);
90
91
92
93 This example reads an image into libnetpbm PAM structures, then bright‐
94 ens it, then writes it out, to illustrate use of pm_system with PAM
95 structures.
96 #include <netpbm/pam.h>
97 #include <netpbm/pm_system.h>
98
99 struct pam inpam;
100 struct pam outpam;
101 tuple ** inTuples;
102 tuple ** outTuples;
103 struct pamtuples inPamtuples;
104 struct pamtuples outPamtuples;
105
106 inTuples = pnm_readpam(stdin, &inpam, sizeof(inpam));
107
108 outpam = inpam;
109
110 inPamtuples.pamP = &inpam;
111 inPamtuples.tuplesP = &inTuples;
112 outPamtuples.pamP = &outpam;
113 outPamtuples.tuplesP = &outTuples;
114
115 pm_system(&pm_feed_from_pamtuples, &inPamtuples,
116 &pm_accept_to_pamtuples, &outPamtuples,
117 "pambrighten -value +100");
118
119 outpam.file = stdout;
120 pnm_writepam(&outpam, outTuples);
121
122
123
124
125
126
128 These library functions are part of Netpbm(1).
129
130 pm_system() is a lot like the standard C library system() subroutine.
131 It runs a shell and has that shell execute a shell command that you
132 specify. But pm_system() gives you more control over the Standard In‐
133 put and Standard Output of that shell command than system(). system()
134 passes to the shell command as Standard Input and Output whatever is
135 the Standard Input and Output of the process that calls system(). But
136 with pm_system(), you specify as arguments subroutines to execute to
137 generate the shell command's Standard Input stream and to process the
138 shell command's Standard Output stream.
139
140 Your Standard Input feeder subroutine can generate the stream in limit‐
141 less ways. pm_system() gives it a file descriptor of a pipe to which
142 to write the stream it generates. pm_system() hooks up the other end
143 of that pipe to the shell command's Standard Input.
144
145 Likewise, your Standard Output accepter subroutine can do anything it
146 wants with the stream it gets. pm_system() gives it a file descriptor
147 of a pipe from which to read the stream. pm_system() hooks up the
148 other end of that pipe to the shell command's Standard Output.
149
150 The argument stdinFeeder is a function pointer that identifies your
151 Standard Input feeder subroutine. pm_system() runs it in a child
152 process and waits for that process to terminate (and accepts its com‐
153 pletion status) before returning. feederParm is the argument that
154 pm_system() passes to the subroutine; it is opaque to pm_system().
155
156 If you pass stdinFeeder = NULL, pm_system() simply passes your current
157 Standard Input stream to the shell command (as system() would do), and
158 does not create a child process.
159
160 The argument stdoutAccepter is a function pointer that identifies your
161 Standard Output accepter subroutine. pm_system() calls it in the cur‐
162 rent process. accepterParm is an argument analogous to feederParm.
163
164 If you pass stdoutAccepter = NULL, pm_system() simply passes your cur‐
165 rent Standard Output stream to the shell command (as system() would do.
166
167 The argument shellCommand is a null-terminated string containing the
168 shell command that the shell is to execute. It can be any command that
169 means something to the shell and can take a pipe for Standard Input and
170 Output. Example:
171
172 pambrighten -vale +100 | pamdepth 255 | pamscale .5
173
174
175 pm_system() creates a child process to run the shell and waits for that
176 process to terminate (and accepts its completion status) before return‐
177 ing.
178
179 If the shell fails, i.e. does not exit voluntarily with zero exit sta‐
180 tus, pm_system calls pm_error(), which normally issues an error message
181 to Standard Error and exits the program. Use pm_system2() if you don't
182 want that.
183
184 Note that the 'termination status' of a Unix process is a value which
185 is a combination of 1) whether the process exited voluntarily or was
186 killed by the operating system; 2) in the case of termination by the
187 OS, what class of signal did it; and 3) in the case of voluntary exit,
188 what 'exit status' the program declared.
189
190
191 Interface Header File
192 These interfaces are declared by <netpbm/pm_system.h<.
193
194
195
196 pm_system2()
197 This is the same as pm_system() except that rather than respond to the
198 shell process' termination status, it just returns it to you (via your
199 termStatusP argument).
200
201
202
203 pm_system_lp()
204 pm_system_lp() is like pm_system() except that instead of running a
205 shell, which in turn typically runs another program, you run a program
206 of your choice directly.
207
208 Argument progName identifies the program to run, the same way as with
209 execlp() or a shell command: if it contains a slash (/), it is the full
210 name of the file that contains the program. If not, it is a name to be
211 looked up in the system's program search path (determined by the PATH
212 environment variable).
213
214 You identify the arguments to the program the same way as for execlp():
215 with the variable arguments at the end of the pm_system_lp() argument
216 list. Each is a NUL-terminated string. The last argument must be NULL
217 to tell pm_system_lp() where the arguments end.
218
219 Note that the first argument ("arg0") to a program is conventionally
220 the first word of the command used to run the program, as if it were
221 being run for a shell command. In other words, typically the name of
222 the program.
223
224 Example:
225
226 pm_system_lp("pnmtojpeg", NULL, NULL, NULL, NULL,
227 "pnmtojpeg", "mypicture.jpg", "-quality=50", NULL);
228
229
230 pm_system_lp() is much safer than pm_system() when your program com‐
231 putes the arguments or gets them from a user. If you build a shell
232 command using such arguments, unless you're really careful, you may end
233 up building a shell command that does something very different from
234 what you intended, because the argument could contain characters that
235 mean something to the shell such as "|".
236
237 pm_system_lp() can also be considerably faster that pm_system(), since
238 it skips the whole running of the shell.
239
240 If the process fails, i.e. produces nonzero termination status, pm_sys‐
241 tem_lp calls pm_error(), which normally issues an error message to
242 Standard Error and exits the program. Use pm_system2_lp() if you don't
243 want that.
244
245
246
247 pm_system2_lp()
248 This is the same as pm_system_lp() except that rather than respond to
249 the process' termination status, it just returns it to you (via your
250 termStatusP argument).
251
252
253
254 pm_system_vp()
255 pm_system_vp() is like pm_system_lp() except that instead of supplying
256 the program arguments as variable arguments, you supply them as an ar‐
257 ray, as with execvp(). A NULL element in the array identifies the end
258 of the arguments.
259
260 Example:
261
262 const char * argArray[3];
263
264 argArray[0] = "pnmtojpeg";
265 argArray[1] = "-quality=50";
266 argArray[2] = NULL;
267
268 pm_system_vp("pnmtojpeg", argArray, NULL, NULL, NULL, NULL);
269
270
271 If the process fails, i.e. produces nonzero termination status, pm_sys‐
272 tem_vp calls pm_error(), which normally issues an error message to
273 Standard Error and exits the program. Use pm_system2_vp() if you don't
274 want that.
275
276
277
278 pm_system2_vp()
279 This is the same as pm_system_vp() except that rather than respond to
280 the process' termination status, it just returns it to you (via your
281 termStatusP argument).
282
283
284
286 The point of pm_system() and friends is to allow you to write a C pro‐
287 gram that uses other programs internally, as a shell script would.
288 This is particularly desirable with Netpbm, because Netpbm consists of
289 a lot of programs that perform basic graphic manipulations and you'd
290 like to be able to build a program that does a more sophisticated
291 graphic manipulation by calling the more basic Netpbm programs. These
292 building block programs typically take input from Standard Input and
293 write output to Standard Output.
294
295 The obvious alternative is to use a higher level language -- Bourne
296 Shell or Perl, for example. But often you want your program to do ma‐
297 nipulations of your graphical data that are easier and more efficient
298 in C. Or you want to use the Netpbm subroutine library in your pro‐
299 gram. The Netpbm subroutine library is a C-linkage library; the sub‐
300 routines in it are not usable from a Bourne Shell or Perl program.
301
302 A typical use of pm_system() is to place the contents of some graphical
303 image file in memory, run a Netpbm program against it, and have what
304 would ordinarily go into an output file in memory too, for further pro‐
305 cessing. To do that, you can use the memory buffer Standard Input
306 feeder and Standard Output accepter described below.
307
308 If your program uses the Netpbm subroutine library to read, write, and
309 manipulate images, you may have an image in an array of PAM tuples. If
310 you want to manipulate that image with a Netpbm program (perhaps remap
311 the colors using pnmremap), you can use the pamtuple Standard Input
312 feeder and Standard Output acceptor described below.
313
314
316 When you set up a shell command to take input from a pipe, as you do
317 with pm_system(), you need to understand how pipes work with respect to
318 the programs at either end of the pipe agreeing to how much data is to
319 be transferred. Here are some notes on that.
320
321 It is normal to read a pipe before the process on the other end has
322 written the data you hope to read, and it is normal to write to a pipe
323 before the process on the other end has tried to read your data.
324 Writes to a pipe can be buffered until the reading end requests the
325 data. A process reading or writing a pipe can block until the other
326 end is ready. Or a read or write can complete with an indication that
327 the other end is not ready at the moment and therefore no data, or less
328 data than was requested, was transferred.
329
330 The pipe is normally controlled by the writing end. When you read from
331 a pipe, you keep reading until the program on the other end of the pipe
332 closes it, and then you get an end-of-file indication. You then nor‐
333 mally close the reading end of the pipe, since it is no longer useful.
334
335 When you close the reading end of a pipe before getting the end-of-file
336 indication and the writer subsequently tries to write to the pipe, that
337 is an error condition for the writer. In a typical default Unix envi‐
338 ronment, that error causes the writer to receive a SIGPIPE signal and
339 that signal causes the writer process to terminate abnormally. But if,
340 alternatively, the writer has ordered that SIGPIPE be blocked, ignored,
341 or handled, the signal does not cause the death of the writer. In‐
342 stead, the write operation simply completes with an error indication.
343
344
345
347 You can supply anything you like as a Standard Input feeder or Standard
348 Output acceptor, but the Netpbm subroutine library comes with a few
349 that perform commonly needed functions.
350
351
352 Memory Buffer
353 These routines are for when you just want to treat an area of memory as
354 a file. If the shell command would ordinarily read a 513 byte regular
355 file from its Standard Input, you want it to take 513 bytes from a cer‐
356 tain address in your process' memory. Whatever bytes the shell command
357 wants to write to its output file you want it to store at another ad‐
358 dress in your process' memory.
359
360 The Standard Input feeder for this is called pm_feed_from_memory. The
361 Standard Output accepter is pm_accept_to_memory.
362
363 For both of these, the argument is the address of a struct bufferDesc,
364 which is defined as follows:
365
366 struct bufferDesc {
367 unsigned int size;
368 unsigned char * buffer;
369 unsigned int * bytesTransferredP;
370 };
371
372
373 size is the size of the memory buffer and buffer is its location in
374 memory (address). The Standard Input feeder will attempt to feed the
375 entire buffer to the shell command's Standard Input; the Standard Out‐
376 put accepter will not accept any more data from the shell command's
377 Standard Output than will fit in the buffer. Both return the actual
378 amount of data read or written, in bytes, at the location identified by
379 bytesTransferredP. Unless bytesTransferredP is NULL.
380
381 Because a process typically terminates abnormally when it is not able
382 to write everything to a pipe that it wanted to, bytesTransferredP is
383 not usually useful in the Standard Input feeder case.
384
385
386
387 Pamtuple
388 These routines are for when you have images in memory in the data
389 structures used by the PAM family of subroutines in the Netpbm library
390 -- i.e. struct PAM and an array of struct tuple. With these routines,
391 you can run a Netpbm program against such an image just as you would
392 against the same image in a regular file.
393
394 The Standard Input feeder for this is called pm_feed_from_pamtuples.
395 The Standard Output accepter is pm_accept_to_pamtuples.
396
397 For both of these, the argument is the address of a struct pamtuples,
398 which is defined as follows:
399
400 struct pamtuples {
401 struct pam * pamP;
402 tuple *** tuplesP;
403 };
404
405
406 For the Standard Input feeder, you supply a struct pam, valid up
407 through the tuple_type member (except it doesn't matter what the file
408 member is) and array of tuples.
409
410 For the Standard Output Accepter, you supply only space in memory for
411 the struct pam and the address of the tuple array. The routine fills
412 in the struct pam up through the tuple_type member (except leaves the
413 file member undefined) and allocates space for the tuple array with
414 malloc(). You are responsible for freeing that memory.
415
416
418 pm_system() was introduced in Netpbm 10.13 (January 2003).
419
420 pm_system_lp() and pm_system_vp() were introduced in Netpbm 10.40 (Sep‐
421 tember 2007).
422
423 pm_system2(), pm_system2_lp(), and pm_system2_vp() were introduce in
424 Netpbm 10.75 (June 2016).
425
427 This manual page was generated by the Netpbm tool 'makeman' from HTML
428 source. The master documentation is at
429
430 http://netpbm.sourceforge.net/doc/libsystem.html
431
432netpbm documentationNetpbm subrout1i2neMalyib2r0a1r6y: pm_system() subroutine, etc.(3)