adding missing variable declaration
1 | /* |
2 | * The contents of this file are subject to the AOLserver Public License |
3 | * Version 1.1 (the "License"); you may not use this file except in |
4 | * compliance with the License. You may obtain a copy of the License at |
5 | * http://aolserver.com/. |
6 | * |
7 | * Software distributed under the License is distributed on an "AS IS" |
8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
9 | * the License for the specific language governing rights and limitations |
10 | * under the License. |
11 | * |
12 | * The Original Code is AOLserver Code and related documentation |
13 | * distributed by AOL. |
14 | * |
15 | * The Initial Developer of the Original Code is America Online, |
16 | * Inc. Portions created by AOL are Copyright (C) 1999 America Online, |
17 | * Inc. All Rights Reserved. |
18 | * |
19 | * Alternatively, the contents of this file may be used under the terms |
20 | * of the GNU General Public License (the "GPL"), in which case the |
21 | * provisions of GPL are applicable instead of those above. If you wish |
22 | * to allow use of your version of this file only under the terms of the |
23 | * GPL and not to allow others to use your version of this file under the |
24 | * License, indicate your decision by deleting the provisions above and |
25 | * replace them with the notice and other provisions required by the GPL. |
26 | * If you do not delete the provisions above, a recipient may use your |
27 | * version of this file under either the License or the GPL. |
28 | */ |
29 | |
30 | |
31 | /* |
32 | * tclfile.c -- |
33 | * |
34 | * Tcl commands that do stuff to the filesystem. |
35 | */ |
36 | |
37 | static const char *RCSID = "@(#) $Header: /cvsroot-fuse/aolserver/aolserver/nsd/tclfile.c,v 1.27 2008/05/06 07:43:08 gneumann Exp $, compiled: " __DATE__ " " __TIME__; |
38 | |
39 | #include "nsd.h" |
40 | #ifdef _WIN32 |
41 | #include <sys/utime.h> |
42 | #else |
43 | #include <utime.h> |
44 | #endif |
45 | |
46 | /* |
47 | * Structure handling one registered channel for the [ns_chan] command |
48 | */ |
49 | |
50 | typedef struct _NsRegChan { |
51 | char *name; |
52 | Tcl_Channel chan; |
53 | } NsRegChan; |
54 | |
55 | static void <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_SpliceChannel">SpliceChannel</a>(Tcl_Interp *interp, Tcl_Channel chan); |
56 | static void <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_UnspliceChannel">UnspliceChannel</a>(Tcl_Interp *interp, Tcl_Channel chan); |
57 | |
58 | |
59 | /* |
60 | *---------------------------------------------------------------------- |
61 | * |
62 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_Ns_TclGetOpenChannel">Ns_TclGetOpenChannel</a> -- |
63 | * |
64 | * Return an open channel with an interface similar to the |
65 | * pre-Tcl7.5 Tcl_GetOpenFile, used throughout AOLserver. |
66 | * |
67 | * Results: |
68 | * TCL_OK or TCL_ERROR. |
69 | * |
70 | * Side effects: |
71 | * The value at chanPtr is updated with a valid open Tcl_Channel. |
72 | * |
73 | *---------------------------------------------------------------------- |
74 | */ |
75 | |
76 | static int |
77 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_GetOpenChannel">GetOpenChannel</a>(Tcl_Interp *interp, Tcl_Obj *obj, int write, |
78 | int check, Tcl_Channel *chanPtr) |
79 | { |
80 | return <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_Ns_TclGetOpenChannel">Ns_TclGetOpenChannel</a>(interp, Tcl_GetString(obj), write, check, chanPtr); |
81 | } |
82 | |
83 | int |
84 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_Ns_TclGetOpenChannel">Ns_TclGetOpenChannel</a>(Tcl_Interp *interp, char *chanId, int write, |
85 | int check, Tcl_Channel *chanPtr) |
86 | { |
87 | int mode; |
88 | |
89 | *chanPtr = Tcl_GetChannel(interp, chanId, &mode); |
90 | if (*chanPtr == NULL) { |
91 | return TCL_ERROR; |
92 | } |
93 | if (check && |
94 | ((write && !(mode & TCL_WRITABLE)) || |
95 | (!write && !(mode & TCL_READABLE)))) { |
96 | Tcl_AppendResult(interp, "channel \"", chanId, "\" not open for ", |
97 | write ? "write" : "read", NULL); |
98 | return TCL_ERROR; |
99 | } |
100 | return TCL_OK; |
101 | } |
102 | |
103 | |
104 | /* |
105 | *---------------------------------------------------------------------- |
106 | * |
107 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_Ns_TclGetOpenFd">Ns_TclGetOpenFd</a> -- |
108 | * |
109 | * Return an open Unix file descriptor for the given channel. |
110 | * This routine is used by the AOLserver * routines |
111 | * to provide access to the underlying socket. |
112 | * |
113 | * Results: |
114 | * TCL_OK or TCL_ERROR. |
115 | * |
116 | * Side effects: |
117 | * The value at fdPtr is updated with a valid Unix file descriptor. |
118 | * |
119 | *---------------------------------------------------------------------- |
120 | */ |
121 | |
122 | int |
123 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_Ns_TclGetOpenFd">Ns_TclGetOpenFd</a>(Tcl_Interp *interp, char *chanId, int write, int *fdPtr) |
124 | { |
125 | Tcl_Channel chan; |
126 | ClientData data; |
127 | |
128 | if (<a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_Ns_TclGetOpenChannel">Ns_TclGetOpenChannel</a>(interp, chanId, write, 1, &chan) != TCL_OK) { |
129 | return TCL_ERROR; |
130 | } |
131 | if (Tcl_GetChannelHandle(chan, write ? TCL_WRITABLE : TCL_READABLE, |
132 | (ClientData*) &data) != TCL_OK) { |
133 | Tcl_AppendResult(interp, "could not get handle for channel: ", |
134 | chanId, NULL); |
135 | return TCL_ERROR; |
136 | } |
137 | *fdPtr = (int) data; |
138 | return TCL_OK; |
139 | } |
140 | |
141 | |
142 | /* |
143 | *---------------------------------------------------------------------- |
144 | * |
145 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclCpFpObjCmd">NsTclCpFpObjCmd</a> -- |
146 | * |
147 | * Implements ns_cpfp as obj command. |
148 | * |
149 | * Results: |
150 | * Tcl result. |
151 | * |
152 | * Side effects: |
153 | * See docs. |
154 | * |
155 | *---------------------------------------------------------------------- |
156 | */ |
157 | |
158 | int |
159 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclCpFpObjCmd">NsTclCpFpObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
160 | { |
161 | Tcl_Channel in, out; |
162 | char buf[2048]; |
163 | char *p; |
164 | int tocopy, nread, nwrote, toread, ntotal; |
165 | |
166 | if (objc != 3 && objc != 4) { |
167 | Tcl_WrongNumArgs(interp, 1, objv, "inChan outChan ?ncopy?"); |
168 | return TCL_ERROR; |
169 | } |
170 | if (<a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_GetOpenChannel">GetOpenChannel</a>(interp, objv[1], 0, 1, &in) != TCL_OK || |
171 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_GetOpenChannel">GetOpenChannel</a>(interp, objv[2], 1, 1, &out) != TCL_OK) { |
172 | return TCL_ERROR; |
173 | } |
174 | if (objc == 3) { |
175 | tocopy = -1; |
176 | } else { |
177 | if (Tcl_GetInt(interp, Tcl_GetString(objv[3]), &tocopy) != TCL_OK) { |
178 | return TCL_ERROR; |
179 | } |
180 | if (tocopy < 0) { |
181 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "invalid length \"", |
182 | Tcl_GetString(objv[3]), |
183 | "\": must be >= 0", NULL); |
184 | return TCL_ERROR; |
185 | } |
186 | } |
187 | |
188 | ntotal = 0; |
189 | while (tocopy != 0) { |
190 | toread = sizeof(buf); |
191 | if (tocopy > 0 && toread > tocopy) { |
192 | toread = tocopy; |
193 | } |
194 | nread = Tcl_Read(in, buf, toread); |
195 | if (nread == 0) { |
196 | break; |
197 | } else if (nread < 0) { |
198 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "read failed: ", |
199 | Tcl_PosixError(interp), NULL); |
200 | return TCL_ERROR; |
201 | } |
202 | if (tocopy > 0) { |
203 | tocopy -= nread; |
204 | } |
205 | p = buf; |
206 | while (nread > 0) { |
207 | nwrote = Tcl_Write(out, p, nread); |
208 | if (nwrote < 0) { |
209 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "write failed: ", |
210 | Tcl_PosixError(interp), NULL); |
211 | return TCL_ERROR; |
212 | } |
213 | nread -= nwrote; |
214 | ntotal += nwrote; |
215 | p += nwrote; |
216 | } |
217 | } |
218 | Tcl_SetObjResult(interp, Tcl_NewIntObj(ntotal)); |
219 | return TCL_OK; |
220 | } |
221 | |
222 | |
223 | /* |
224 | *---------------------------------------------------------------------- |
225 | * |
226 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclCpObjCmd">NsTclCpObjCmd</a> -- |
227 | * |
228 | * Implements ns_cp as obj command. |
229 | * |
230 | * Results: |
231 | * Tcl result. |
232 | * |
233 | * Side effects: |
234 | * See docs. |
235 | * |
236 | *---------------------------------------------------------------------- |
237 | */ |
238 | |
239 | int |
240 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclCpObjCmd">NsTclCpObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
241 | { |
242 | int nread, towrite, nwrote; |
243 | char buf[4096], *src, *dst, *p, *emsg, *efile; |
244 | int preserve, result, rfd, wfd; |
245 | struct stat st; |
246 | struct utimbuf ut; |
247 | |
248 | if (objc != 3 && objc != 4) { |
249 | badargs: |
250 | Tcl_WrongNumArgs(interp, 1, objv, "?-preserve? srcfile dstfile"); |
251 | return TCL_ERROR; |
252 | } |
253 | |
254 | emsg = "<unknown>"; |
255 | efile = ""; |
256 | |
257 | wfd = rfd = -1; |
258 | result = TCL_ERROR; |
259 | |
260 | if (objc == 3) { |
261 | preserve = 0; |
262 | src = Tcl_GetString(objv[1]); |
263 | dst = Tcl_GetString(objv[2]); |
264 | } else { |
265 | if (!STREQ(Tcl_GetString(objv[1]), "-preserve")) { |
266 | goto badargs; |
267 | } |
268 | preserve = 1; |
269 | src = Tcl_GetString(objv[2]); |
270 | dst = Tcl_GetString(objv[3]); |
271 | if (stat(src, &st) != 0) { |
272 | emsg = "stat"; |
273 | efile = src; |
274 | goto done; |
275 | } |
276 | } |
277 | |
278 | emsg = "open"; |
279 | rfd = open(src, O_RDONLY|O_BINARY); |
280 | if (rfd < 0) { |
281 | efile = src; |
282 | goto done; |
283 | } |
284 | wfd = open(dst, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); |
285 | if (wfd < 0) { |
286 | efile = dst; |
287 | goto done; |
288 | } |
289 | |
290 | while ((nread = read(rfd, buf, sizeof(buf))) > 0) { |
291 | p = buf; |
292 | towrite = nread; |
293 | while (towrite > 0) { |
294 | nwrote = write(wfd, p, (size_t)towrite); |
295 | if (nwrote <= 0) { |
296 | emsg = "write"; |
297 | efile = dst; |
298 | goto done; |
299 | } |
300 | towrite -= nwrote; |
301 | p += nwrote; |
302 | } |
303 | } |
304 | if (nread < 0) { |
305 | emsg = "read"; |
306 | efile = src; |
307 | goto done; |
308 | } |
309 | |
310 | if (!preserve) { |
311 | result = TCL_OK; |
312 | } else { |
313 | efile = dst; |
314 | if (chmod(dst, st.st_mode) != 0) { |
315 | emsg = "chmod"; |
316 | goto done; |
317 | } |
318 | ut.actime = st.st_atime; |
319 | ut.modtime = st.st_mtime; |
320 | if (utime(dst, &ut) != 0) { |
321 | emsg = "utime"; |
322 | goto done; |
323 | } |
324 | result = TCL_OK; |
325 | } |
326 | |
327 | done: |
328 | if (result != TCL_OK) { |
329 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not ", emsg, " \"", |
330 | efile, "\": ", Tcl_PosixError(interp), NULL); |
331 | } |
332 | if (rfd >= 0) { |
333 | close(rfd); |
334 | } |
335 | if (wfd >= 0) { |
336 | close(wfd); |
337 | } |
338 | return result; |
339 | } |
340 | |
341 | |
342 | /* |
343 | *---------------------------------------------------------------------- |
344 | * |
345 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclMkdirObjCmd">NsTclMkdirObjCmd</a> -- |
346 | * |
347 | * Implements ns_mkdir as obj command. |
348 | * |
349 | * Results: |
350 | * Tcl result. |
351 | * |
352 | * Side effects: |
353 | * See docs. |
354 | * |
355 | *---------------------------------------------------------------------- |
356 | */ |
357 | |
358 | int |
359 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclMkdirObjCmd">NsTclMkdirObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
360 | { |
361 | if (objc != 2) { |
362 | Tcl_WrongNumArgs(interp, 1, objv, "dir"); |
363 | return TCL_ERROR; |
364 | } |
365 | if (mkdir(Tcl_GetString(objv[1]), 0777) != 0) { |
366 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "mkdir (\"", |
367 | Tcl_GetString(objv[1]), |
368 | "\") failed: ", Tcl_PosixError(interp), NULL); |
369 | return TCL_ERROR; |
370 | } |
371 | return TCL_OK; |
372 | } |
373 | |
374 | |
375 | /* |
376 | *---------------------------------------------------------------------- |
377 | * |
378 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclRmdirObjCmd">NsTclRmdirObjCmd</a> -- |
379 | * |
380 | * Implements ns_rmdir |
381 | * |
382 | * Results: |
383 | * Tcl result. |
384 | * |
385 | * Side effects: |
386 | * See docs. |
387 | * |
388 | *---------------------------------------------------------------------- |
389 | */ |
390 | |
391 | int |
392 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclRmdirObjCmd">NsTclRmdirObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
393 | { |
394 | if (objc != 2) { |
395 | Tcl_WrongNumArgs(interp, 1, objv, "dir"); |
396 | return TCL_ERROR; |
397 | } |
398 | if (rmdir(Tcl_GetString(objv[1])) != 0) { |
399 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "rmdir (\"", |
400 | Tcl_GetString(objv[1]), |
401 | "\") failed: ", Tcl_PosixError(interp), NULL); |
402 | return TCL_ERROR; |
403 | } |
404 | return TCL_OK; |
405 | } |
406 | |
407 | |
408 | /* |
409 | *---------------------------------------------------------------------- |
410 | * |
411 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclRollFileObjCmd">NsTclRollFileObjCmd</a> -- |
412 | * |
413 | * Implements ns_rollfile obj command. |
414 | * |
415 | * Results: |
416 | * Tcl result. |
417 | * |
418 | * Side effects: |
419 | * See docs. |
420 | * |
421 | *---------------------------------------------------------------------- |
422 | */ |
423 | |
424 | static int |
425 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_FileObjCmd">FileObjCmd</a>(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], char *cmd) |
426 | { |
427 | int max, status; |
428 | |
429 | if (objc != 3) { |
430 | Tcl_WrongNumArgs(interp, 1, objv, "file backupMax"); |
431 | return TCL_ERROR; |
432 | } |
433 | if (Tcl_GetIntFromObj(interp, objv[2], &max) != TCL_OK) { |
434 | return TCL_ERROR; |
435 | } |
436 | if (max <= 0 || max > 1000) { |
437 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "invalid max \"", |
438 | Tcl_GetString(objv[2]), |
439 | "\": should be > 0 and <= 1000.", NULL); |
440 | return TCL_ERROR; |
441 | } |
442 | if (*cmd == 'p') { |
443 | status = <a href="/cvs/aolserver/aolserver/nsd/rollfile.c#A_Ns_PurgeFiles">Ns_PurgeFiles</a>(Tcl_GetString(objv[1]), max); |
444 | } else { |
445 | status = <a href="/cvs/aolserver/aolserver/nsd/rollfile.c#A_Ns_RollFile">Ns_RollFile</a>(Tcl_GetString(objv[1]), max); |
446 | } |
447 | if (status != NS_OK) { |
448 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not ", cmd, " \"", |
449 | Tcl_GetString(objv[1]), |
450 | "\": ", Tcl_PosixError(interp), NULL); |
451 | return TCL_ERROR; |
452 | } |
453 | return TCL_OK; |
454 | } |
455 | |
456 | int |
457 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclRollFileObjCmd">NsTclRollFileObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
458 | { |
459 | return <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_FileObjCmd">FileObjCmd</a>(interp, objc, objv, "roll"); |
460 | } |
461 | |
462 | int |
463 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclPurgeFilesObjCmd">NsTclPurgeFilesObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
464 | { |
465 | return <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_FileObjCmd">FileObjCmd</a>(interp, objc, objv, "purge"); |
466 | } |
467 | |
468 | |
469 | /* |
470 | *---------------------------------------------------------------------- |
471 | * |
472 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclUnlinkObjCmd">NsTclUnlinkObjCmd</a> -- |
473 | * |
474 | * Implement ns_unlink as obj command. |
475 | * |
476 | * Results: |
477 | * Tcl result. |
478 | * |
479 | * Side effects: |
480 | * See docs. |
481 | * |
482 | *---------------------------------------------------------------------- |
483 | */ |
484 | |
485 | int |
486 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclUnlinkObjCmd">NsTclUnlinkObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
487 | { |
488 | int fComplain = NS_TRUE; |
489 | |
490 | if ((objc != 2) && (objc != 3)) { |
491 | Tcl_WrongNumArgs(interp, 1, objv, "?-nocomplain? filename"); |
492 | return TCL_ERROR; |
493 | } |
494 | |
495 | if (objc == 3) { |
496 | if (!STREQ(Tcl_GetString(objv[1]), "-nocomplain")) { |
497 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "unknown flag \"", |
498 | Tcl_GetString(objv[1]), "\": should be -nocomplain", |
499 | NULL); |
500 | return TCL_ERROR; |
501 | } else { |
502 | fComplain = NS_FALSE; |
503 | } |
504 | } |
505 | |
506 | if (unlink(Tcl_GetString(objv[objc-1])) != 0) { |
507 | if (fComplain || errno != ENOENT) { |
508 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "unlink (\"", |
509 | Tcl_GetString(objv[objc-1]), |
510 | "\") failed: ", Tcl_PosixError(interp), NULL); |
511 | return TCL_ERROR; |
512 | } |
513 | } |
514 | |
515 | return TCL_OK; |
516 | } |
517 | |
518 | |
519 | /* |
520 | *---------------------------------------------------------------------- |
521 | * |
522 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclMkTempCmd">NsTclMkTempCmd</a> -- |
523 | * |
524 | * Implements ns_mktemp. |
525 | * |
526 | * Results: |
527 | * Tcl result. |
528 | * |
529 | * Side effects: |
530 | * Allocates memory for the filename as a TCL_VOLATILE object. |
531 | * |
532 | *---------------------------------------------------------------------- |
533 | */ |
534 | |
535 | int |
536 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclMkTempCmd">NsTclMkTempCmd</a>(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) |
537 | { |
538 | char *buffer; |
539 | |
540 | if (argc != 2) { |
541 | Tcl_AppendResult(interp, "wrong # of args: should be \"", |
542 | argv[0], " template\"", NULL); |
543 | return TCL_ERROR; |
544 | } |
545 | |
546 | buffer = ns_strdup(argv[1]); |
547 | Tcl_SetResult(interp, mktemp(buffer), (Tcl_FreeProc *)ns_free); |
548 | return TCL_OK; |
549 | } |
550 | |
551 | |
552 | /* |
553 | *---------------------------------------------------------------------- |
554 | * |
555 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclTmpNamObjCmd">NsTclTmpNamObjCmd</a> -- |
556 | * |
557 | * Implements ns_tmpnam as obj command. |
558 | * |
559 | * Results: |
560 | * Tcl result. |
561 | * |
562 | * Side effects: |
563 | * See docs. |
564 | * |
565 | *---------------------------------------------------------------------- |
566 | */ |
567 | |
568 | int |
569 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclTmpNamObjCmd">NsTclTmpNamObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
570 | { |
571 | #ifdef WIN32 |
572 | /* |
573 | The WIN32 implmentation of tmpnam() ignores the environment |
574 | variable TMP and generates filenames for the root |
575 | directory. Unfortunately, new WIN versions (Vista) don't allow |
576 | this. The suggested replacement is _tempnam(). |
577 | |
578 | The first argument of _tempnam() is the default directory, in case |
579 | the environment variable TMP is not set or points to a directory |
580 | that does not exist. |
581 | */ |
582 | int i; |
583 | char *buf = _tempnam("/tmp", NULL); |
584 | |
585 | if (buf == NULL) { |
586 | Tcl_SetResult(interp, "could not generate temporary filename.", TCL_STATIC); |
587 | return TCL_ERROR; |
588 | } |
589 | /* |
590 | Change back-slash characters into slash characters, as all other |
591 | paths are slash separated. Even some programs under Windows |
592 | do not allow back-slahed paths (e.g. Oracle's SqlLdr). |
593 | */ |
594 | for (i = 0; i < strlen(buf); i++) { |
595 | if (buf[i] == '\\') buf[i] = '/'; |
596 | } |
597 | /* |
598 | The documentation says that _tempnam() allocates memory via |
599 | malloc(); to be sure, that the "right" free() is used, we do |
600 | not use TCL_DYNAMIC but the TCL_VOLATILE followed by the manual |
601 | free(). |
602 | */ |
603 | Tcl_SetResult(interp, buf, TCL_VOLATILE); |
604 | free(buf); |
605 | #else |
606 | char buf[L_tmpnam]; |
607 | |
608 | if (tmpnam(buf) == NULL) { |
609 | Tcl_SetResult(interp, "could not generate temporary filename.", TCL_STATIC); |
610 | return TCL_ERROR; |
611 | } |
612 | Tcl_SetResult(interp, buf, TCL_VOLATILE); |
613 | #endif |
614 | return TCL_OK; |
615 | } |
616 | |
617 | |
618 | /* |
619 | *---------------------------------------------------------------------- |
620 | * |
621 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclNormalizePathObjCmd">NsTclNormalizePathObjCmd</a> -- |
622 | * |
623 | * Implements ns_normalizepath as obj command. |
624 | * |
625 | * Results: |
626 | * Tcl result. |
627 | * |
628 | * Side effects: |
629 | * See docs. |
630 | * |
631 | *---------------------------------------------------------------------- |
632 | */ |
633 | |
634 | int |
635 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclNormalizePathObjCmd">NsTclNormalizePathObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
636 | { |
637 | Ns_DString ds; |
638 | |
639 | if (objc != 2) { |
640 | Tcl_WrongNumArgs(interp, 1, objv, "path"); |
641 | return TCL_ERROR; |
642 | } |
643 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds); |
644 | <a href="/cvs/aolserver/aolserver/nsd/pathname.c#A_Ns_NormalizePath">Ns_NormalizePath</a>(&ds, Tcl_GetString(objv[1])); |
645 | Tcl_SetResult(interp, ds.string, TCL_VOLATILE); |
646 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&ds); |
647 | |
648 | return TCL_OK; |
649 | } |
650 | |
651 | |
652 | /* |
653 | *---------------------------------------------------------------------- |
654 | * |
655 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclUrl2FileObjCmd">NsTclUrl2FileObjCmd</a> -- |
656 | * |
657 | * Implements ns_url2file as obj command. |
658 | * |
659 | * Results: |
660 | * Tcl result. |
661 | * |
662 | * Side effects: |
663 | * See docs. |
664 | * |
665 | *---------------------------------------------------------------------- |
666 | */ |
667 | |
668 | int |
669 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclUrl2FileObjCmd">NsTclUrl2FileObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
670 | { |
671 | NsInterp *itPtr = arg; |
672 | Ns_DString ds; |
673 | |
674 | if (objc != 2) { |
675 | Tcl_WrongNumArgs(interp, 1, objv, "url"); |
676 | return TCL_ERROR; |
677 | } |
678 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&ds); |
679 | <a href="/cvs/aolserver/aolserver/nsd/fastpath.c#A_NsUrlToFile">NsUrlToFile</a>(&ds, itPtr->servPtr, Tcl_GetString(objv[1])); |
680 | Tcl_SetResult(interp, ds.string, TCL_VOLATILE); |
681 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&ds); |
682 | return TCL_OK; |
683 | } |
684 | |
685 | |
686 | /* |
687 | *---------------------------------------------------------------------- |
688 | * |
689 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclKillObjCmd">NsTclKillObjCmd</a> -- |
690 | * |
691 | * Implements ns_kill as obj command. |
692 | * |
693 | * Results: |
694 | * Tcl result. |
695 | * |
696 | * Side effects: |
697 | * See docs. |
698 | * |
699 | *---------------------------------------------------------------------- |
700 | */ |
701 | |
702 | int |
703 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclKillObjCmd">NsTclKillObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
704 | { |
705 | int pid, signal; |
706 | |
707 | if ((objc != 3) && (objc != 4)) { |
708 | badargs: |
709 | Tcl_WrongNumArgs(interp, 1, objv, "?-nocomplain? pid signal"); |
710 | return TCL_ERROR; |
711 | } |
712 | if (objc == 3) { |
713 | if (Tcl_GetIntFromObj(interp, objv[1], &pid) != TCL_OK) { |
714 | return TCL_ERROR; |
715 | } |
716 | if (Tcl_GetIntFromObj(interp, objv[2], &signal) != TCL_OK) { |
717 | return TCL_ERROR; |
718 | } |
719 | if (<a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_kill">kill</a>(pid, signal) != 0) { |
720 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "<a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_kill">kill</a> (\"", |
721 | Tcl_GetString(objv[1]), ",", |
722 | Tcl_GetString(objv[2]), |
723 | "\") failed: ", Tcl_PosixError(interp), NULL); |
724 | return TCL_ERROR; |
725 | } |
726 | } else { |
727 | if (strcmp(Tcl_GetString(objv[1]), "-nocomplain") != 0) { |
728 | goto badargs; |
729 | } |
730 | if (Tcl_GetIntFromObj(interp, objv[2], &pid) != TCL_OK) { |
731 | return TCL_ERROR; |
732 | } |
733 | if (Tcl_GetIntFromObj(interp, objv[3], &signal) != TCL_OK) { |
734 | return TCL_ERROR; |
735 | } |
736 | <a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_kill">kill</a>(pid, signal); |
737 | } |
738 | return TCL_OK; |
739 | } |
740 | |
741 | |
742 | /* |
743 | *---------------------------------------------------------------------- |
744 | * |
745 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclLinkObjCmd">NsTclLinkObjCmd</a> -- |
746 | * |
747 | * Implements ns_link as obj command. |
748 | * |
749 | * Results: |
750 | * Tcl result. |
751 | * |
752 | * Side effects: |
753 | * See docs. |
754 | * |
755 | *---------------------------------------------------------------------- |
756 | */ |
757 | |
758 | int |
759 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclLinkObjCmd">NsTclLinkObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
760 | { |
761 | if ((objc != 3) && (objc != 4)) { |
762 | Tcl_WrongNumArgs(interp, 1, objv, "?-nocomplain? filename1 filename2"); |
763 | return TCL_ERROR; |
764 | } |
765 | if (objc == 3) { |
766 | if (link(Tcl_GetString(objv[1]), Tcl_GetString(objv[2])) != 0) { |
767 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), |
768 | "link (\"", Tcl_GetString(objv[1]), "\", \"", |
769 | Tcl_GetString(objv[2]), |
770 | "\") failed: ", Tcl_PosixError(interp), NULL); |
771 | return TCL_ERROR; |
772 | } |
773 | } else { |
774 | if (strcmp(Tcl_GetString(objv[1]), "-nocomplain") != 0) { |
775 | Tcl_WrongNumArgs(interp, 1, objv, "?-nocomplain? filename1 filename2"); |
776 | return TCL_ERROR; |
777 | } |
778 | link(Tcl_GetString(objv[2]), Tcl_GetString(objv[3])); |
779 | } |
780 | |
781 | return TCL_OK; |
782 | } |
783 | |
784 | |
785 | /* |
786 | *---------------------------------------------------------------------- |
787 | * |
788 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclSymlinkObjCmd">NsTclSymlinkObjCmd</a> -- |
789 | * |
790 | * Implements ns_symlink as obj command. |
791 | * |
792 | * Results: |
793 | * Tcl result. |
794 | * |
795 | * Side effects: |
796 | * See docs. |
797 | * |
798 | *---------------------------------------------------------------------- |
799 | */ |
800 | |
801 | int |
802 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclSymlinkObjCmd">NsTclSymlinkObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
803 | { |
804 | if ((objc != 3) && (objc != 4)) { |
805 | badargs: |
806 | Tcl_WrongNumArgs(interp, 1, objv, "?-nocomplain? filename1 filename2"); |
807 | return TCL_ERROR; |
808 | } |
809 | |
810 | if (objc == 3) { |
811 | if (<a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_symlink">symlink</a>(Tcl_GetString(objv[1]), Tcl_GetString(objv[2])) != 0) { |
812 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "<a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_symlink">symlink</a> (\"", |
813 | Tcl_GetString(objv[1]), "\", \"", |
814 | Tcl_GetString(objv[2]), |
815 | "\") failed: ", Tcl_PosixError(interp), NULL); |
816 | return TCL_ERROR; |
817 | } |
818 | } else { |
819 | if (strcmp(Tcl_GetString(objv[1]), "-nocomplain") != 0) { |
820 | goto badargs; |
821 | } |
822 | <a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_symlink">symlink</a>(Tcl_GetString(objv[2]), Tcl_GetString(objv[3])); |
823 | } |
824 | |
825 | return TCL_OK; |
826 | } |
827 | |
828 | |
829 | /* |
830 | *---------------------------------------------------------------------- |
831 | * |
832 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclRenameObjCmd">NsTclRenameObjCmd</a> -- |
833 | * |
834 | * Implements ns_rename as obj command. |
835 | * |
836 | * Results: |
837 | * Tcl result. |
838 | * |
839 | * Side effects: |
840 | * See docs. |
841 | * |
842 | *---------------------------------------------------------------------- |
843 | */ |
844 | |
845 | int |
846 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclRenameObjCmd">NsTclRenameObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
847 | { |
848 | if (objc != 3) { |
849 | Tcl_WrongNumArgs(interp, 1, objv, "filename1 filename2"); |
850 | return TCL_ERROR; |
851 | } |
852 | if (rename(Tcl_GetString(objv[1]), Tcl_GetString(objv[2])) != 0) { |
853 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "rename (\"", |
854 | Tcl_GetString(objv[1]), "\", \"", |
855 | Tcl_GetString(objv[2]), |
856 | "\") failed: ", Tcl_PosixError(interp), NULL); |
857 | return TCL_ERROR; |
858 | } |
859 | return TCL_OK; |
860 | } |
861 | |
862 | |
863 | /* |
864 | *---------------------------------------------------------------------- |
865 | * |
866 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclWriteFpObjCmd">NsTclWriteFpObjCmd</a> -- |
867 | * |
868 | * Implements ns_writefp as obj command. |
869 | * |
870 | * Results: |
871 | * Tcl result. |
872 | * |
873 | * Side effects: |
874 | * See docs. |
875 | * |
876 | *---------------------------------------------------------------------- |
877 | */ |
878 | |
879 | int |
880 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclWriteFpObjCmd">NsTclWriteFpObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
881 | { |
882 | NsInterp *itPtr = arg; |
883 | Tcl_Channel chan; |
884 | int nbytes = INT_MAX; |
885 | int result; |
886 | |
887 | if (objc != 2 && objc != 3) { |
888 | Tcl_WrongNumArgs(interp, 1, objv, "fileid ?nbytes?"); |
889 | return TCL_ERROR; |
890 | } |
891 | if (<a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_GetOpenChannel">GetOpenChannel</a>(interp, objv[1], 0, 1, &chan) != TCL_OK) { |
892 | return TCL_ERROR; |
893 | } |
894 | if (objc == 3 && Tcl_GetIntFromObj(interp, objv[2], &nbytes) != TCL_OK) { |
895 | return TCL_ERROR; |
896 | } |
897 | if (itPtr->conn == NULL) { |
898 | Tcl_SetResult(interp, "no connection", TCL_STATIC); |
899 | return TCL_ERROR; |
900 | } |
901 | result = <a href="/cvs/aolserver/aolserver/nsd/connio.c#A_Ns_ConnSendChannel">Ns_ConnSendChannel</a>(itPtr->conn, chan, nbytes); |
902 | if (result != NS_OK) { |
903 | Tcl_SetResult(interp, "i/o failed", TCL_STATIC); |
904 | return TCL_ERROR; |
905 | } |
906 | return TCL_OK; |
907 | } |
908 | |
909 | |
910 | /* |
911 | *---------------------------------------------------------------------- |
912 | * |
913 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclTruncateObjCmd">NsTclTruncateObjCmd</a> -- |
914 | * |
915 | * Implements ns_truncate as obj command. |
916 | * |
917 | * Results: |
918 | * Tcl result. |
919 | * |
920 | * Side effects: |
921 | * See docs. |
922 | * |
923 | *---------------------------------------------------------------------- |
924 | */ |
925 | |
926 | int |
927 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclTruncateObjCmd">NsTclTruncateObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
928 | { |
929 | int length; |
930 | |
931 | if (objc != 2 && objc != 3) { |
932 | Tcl_WrongNumArgs(interp, 1, objv, "file ?length?"); |
933 | return TCL_ERROR; |
934 | } |
935 | |
936 | if (objc == 2) { |
937 | length = 0; |
938 | } else if (Tcl_GetIntFromObj(interp, objv[2], &length) != TCL_OK) { |
939 | return TCL_ERROR; |
940 | } |
941 | |
942 | if (<a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_truncate">truncate</a>(Tcl_GetString(objv[1]), length) != 0) { |
943 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "<a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_truncate">truncate</a> (\"", |
944 | Tcl_GetString(objv[1]), "\", ", |
945 | Tcl_GetString(objv[2]) ? Tcl_GetString(objv[2]) : "0", |
946 | ") failed: ", Tcl_PosixError(interp), NULL); |
947 | return TCL_ERROR; |
948 | } |
949 | |
950 | return TCL_OK; |
951 | } |
952 | |
953 | |
954 | /* |
955 | *---------------------------------------------------------------------- |
956 | * |
957 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclFTruncateObjCmd">NsTclFTruncateObjCmd</a> -- |
958 | * |
959 | * Implements ns_ftruncate as obj command. |
960 | * |
961 | * Results: |
962 | * Tcl result. |
963 | * |
964 | * Side effects: |
965 | * See docs. |
966 | * |
967 | *---------------------------------------------------------------------- |
968 | */ |
969 | |
970 | int |
971 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclFTruncateObjCmd">NsTclFTruncateObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
972 | { |
973 | int length, fd; |
974 | |
975 | if (objc != 2 && objc != 3) { |
976 | Tcl_WrongNumArgs(interp, 1, objv, "fileId ?length?"); |
977 | return TCL_ERROR; |
978 | } |
979 | if (<a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_Ns_TclGetOpenFd">Ns_TclGetOpenFd</a>(interp, Tcl_GetString(objv[1]), 1, &fd) != TCL_OK) { |
980 | return TCL_ERROR; |
981 | } |
982 | if (objc == 2) { |
983 | length = 0; |
984 | } else if (Tcl_GetInt(interp, Tcl_GetString(objv[2]), &length) != TCL_OK) { |
985 | return TCL_ERROR; |
986 | } |
987 | if (ftruncate(fd, length) != 0) { |
988 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "ftruncate (\"", |
989 | Tcl_GetString(objv[1]), "\", ", |
990 | Tcl_GetString(objv[2]) ? Tcl_GetString(objv[2]) : "0", |
991 | ") failed: ", Tcl_PosixError(interp), NULL); |
992 | return TCL_ERROR; |
993 | } |
994 | |
995 | return TCL_OK; |
996 | } |
997 | |
998 | |
999 | /* |
1000 | *---------------------------------------------------------------------- |
1001 | * |
1002 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclChmodObjCmd">NsTclChmodObjCmd</a> -- |
1003 | * |
1004 | * NsTclChmodCmd |
1005 | * |
1006 | * Results: |
1007 | * Tcl result. |
1008 | * |
1009 | * Side effects: |
1010 | * See docs. |
1011 | * |
1012 | *---------------------------------------------------------------------- |
1013 | */ |
1014 | |
1015 | int |
1016 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclChmodObjCmd">NsTclChmodObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
1017 | { |
1018 | int mode; |
1019 | |
1020 | if (objc != 3) { |
1021 | Tcl_WrongNumArgs(interp, 1, objv, "filename mode"); |
1022 | return TCL_ERROR; |
1023 | } |
1024 | |
1025 | if (Tcl_GetIntFromObj(interp, objv[2], &mode) != TCL_OK) { |
1026 | return TCL_ERROR; |
1027 | } |
1028 | |
1029 | if (chmod(Tcl_GetString(objv[1]), (mode_t)mode) != 0) { |
1030 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "chmod (\"", |
1031 | Tcl_GetString(objv[1]), "\", ", |
1032 | Tcl_GetString(objv[2]), |
1033 | ") failed: ", Tcl_PosixError(interp), NULL); |
1034 | return TCL_ERROR; |
1035 | } |
1036 | |
1037 | return TCL_OK; |
1038 | } |
1039 | |
1040 | |
1041 | /* |
1042 | *---------------------------------------------------------------------- |
1043 | * |
1044 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclChanObjCmd">NsTclChanObjCmd</a> -- |
1045 | * |
1046 | * Implement the ns_chan command. |
1047 | * |
1048 | * Results: |
1049 | * Tcl result. |
1050 | * |
1051 | * Side effects: |
1052 | * See docs. |
1053 | * |
1054 | *---------------------------------------------------------------------- |
1055 | */ |
1056 | |
1057 | int |
1058 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_NsTclChanObjCmd">NsTclChanObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
1059 | { |
1060 | NsInterp *itPtr = arg; |
1061 | NsServer *servPtr = itPtr->servPtr; |
1062 | Tcl_Channel chan = NULL; |
1063 | char *name, *chanName; |
1064 | NsRegChan *regChan = NULL; |
1065 | int new, shared; |
1066 | Tcl_HashTable *tabPtr; |
1067 | Tcl_HashEntry *hPtr; |
1068 | Tcl_HashSearch search; |
1069 | static CONST char *opts[] = { |
1070 | "cleanup", "list", "create", "put", "get", NULL |
1071 | }; |
1072 | enum { |
1073 | CCleanupIdx, CListIdx, CCreateIdx, CPutIdx, CGetIdx |
1074 | } _nsmayalias opt; |
1075 | |
1076 | if (objc < 2) { |
1077 | Tcl_WrongNumArgs(interp, 1, objv, "command ?args?"); |
1078 | return TCL_ERROR; |
1079 | } |
1080 | if (Tcl_GetIndexFromObj(interp, objv[1], opts, "option", 0, |
1081 | (int *) &opt) != TCL_OK) { |
1082 | return TCL_ERROR; |
1083 | } |
1084 | |
1085 | switch (opt) { |
1086 | case CCreateIdx: |
1087 | if (objc != 4) { |
1088 | Tcl_WrongNumArgs(interp, 1, objv, "create channel name"); |
1089 | return TCL_ERROR; |
1090 | } |
1091 | chanName = Tcl_GetString(objv[2]); |
1092 | chan = Tcl_GetChannel(interp, chanName, NULL); |
1093 | if (chan == (Tcl_Channel)NULL) { |
1094 | return TCL_ERROR; |
1095 | } |
1096 | if (Tcl_IsChannelShared(chan)) { |
1097 | Tcl_SetResult(interp, "channel is shared", TCL_STATIC); |
1098 | return TCL_ERROR; |
1099 | } |
1100 | name = Tcl_GetString(objv[3]); |
1101 | Ns_MutexLock(&servPtr->chans.lock); |
1102 | hPtr = Tcl_CreateHashEntry(&servPtr->chans.table, name, &new); |
1103 | if (new) { |
1104 | regChan = ns_malloc(sizeof(NsRegChan)); |
1105 | regChan->name = ns_malloc(strlen(chanName)+1); |
1106 | regChan->chan = chan; |
1107 | strcpy(regChan->name, chanName); |
1108 | Tcl_SetHashValue(hPtr, regChan); |
1109 | } |
1110 | Ns_MutexUnlock(&servPtr->chans.lock); |
1111 | if (!new) { |
1112 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), |
1113 | "channel with name \"", Tcl_GetString(objv[3]), |
1114 | "\" already exists", NULL); |
1115 | return TCL_ERROR; |
1116 | } |
1117 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_UnspliceChannel">UnspliceChannel</a>(interp, chan); |
1118 | break; |
1119 | |
1120 | case CGetIdx: |
1121 | if (objc != 3) { |
1122 | Tcl_WrongNumArgs(interp, 1, objv, "get name"); |
1123 | return TCL_ERROR; |
1124 | } |
1125 | name = Tcl_GetString(objv[2]); |
1126 | Ns_MutexLock(&servPtr->chans.lock); |
1127 | hPtr = Tcl_FindHashEntry(&servPtr->chans.table, name); |
1128 | if (hPtr != NULL) { |
1129 | regChan = (NsRegChan*)Tcl_GetHashValue(hPtr); |
1130 | Tcl_DeleteHashEntry(hPtr); |
1131 | } |
1132 | Ns_MutexUnlock(&servPtr->chans.lock); |
1133 | if (hPtr == NULL) { |
1134 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), |
1135 | "no such shared channel: ", name, NULL); |
1136 | return TCL_ERROR; |
1137 | } |
1138 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_SpliceChannel">SpliceChannel</a>(interp, regChan->chan); |
1139 | Tcl_SetResult(interp, regChan->name, TCL_VOLATILE); |
1140 | hPtr = Tcl_CreateHashEntry(&itPtr->chans, name, &new); |
1141 | Tcl_SetHashValue(hPtr, regChan); |
1142 | break; |
1143 | |
1144 | case CPutIdx: |
1145 | if (objc != 3) { |
1146 | Tcl_WrongNumArgs(interp, 1, objv, "put name"); |
1147 | return TCL_ERROR; |
1148 | } |
1149 | name = Tcl_GetString(objv[2]); |
1150 | hPtr = Tcl_FindHashEntry(&itPtr->chans, name); |
1151 | if (hPtr == NULL) { |
1152 | Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), |
1153 | "no such shared channel: ", name, NULL); |
1154 | return TCL_ERROR; |
1155 | } |
1156 | regChan = (NsRegChan*)Tcl_GetHashValue(hPtr); |
1157 | chan = Tcl_GetChannel(interp, regChan->name, NULL); |
1158 | if (chan == (Tcl_Channel)NULL || chan != regChan->chan) { |
1159 | Tcl_DeleteHashEntry(hPtr); |
1160 | if (chan != regChan->chan) { |
1161 | Tcl_SetResult(interp, "channel mismatch", TCL_STATIC); |
1162 | } |
1163 | return TCL_ERROR; |
1164 | } |
1165 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_UnspliceChannel">UnspliceChannel</a>(interp, regChan->chan); |
1166 | Tcl_DeleteHashEntry(hPtr); |
1167 | Ns_MutexLock(&servPtr->chans.lock); |
1168 | hPtr = Tcl_CreateHashEntry(&servPtr->chans.table, name, &new); |
1169 | Tcl_SetHashValue(hPtr, regChan); |
1170 | Ns_MutexUnlock(&servPtr->chans.lock); |
1171 | break; |
1172 | |
1173 | case CListIdx: |
1174 | if (objc != 2 && objc != 3) { |
1175 | Tcl_WrongNumArgs(interp, 1, objv, "list ?-shared?"); |
1176 | return TCL_ERROR; |
1177 | } |
1178 | shared = (objc == 3); |
1179 | if (shared) { |
1180 | Ns_MutexLock(&servPtr->chans.lock); |
1181 | tabPtr = &servPtr->chans.table; |
1182 | } else { |
1183 | tabPtr = &itPtr->chans; |
1184 | } |
1185 | hPtr = Tcl_FirstHashEntry(tabPtr, &search); |
1186 | while (hPtr != NULL) { |
1187 | Tcl_AppendElement(interp, Tcl_GetHashKey(tabPtr, hPtr)); |
1188 | hPtr = Tcl_NextHashEntry(&search); |
1189 | } |
1190 | if (shared) { |
1191 | Ns_MutexUnlock(&servPtr->chans.lock); |
1192 | } |
1193 | break; |
1194 | |
1195 | case CCleanupIdx: |
1196 | if (objc != 2 && objc != 3) { |
1197 | Tcl_WrongNumArgs(interp, 1, objv, "cleanup ?-shared?"); |
1198 | return TCL_ERROR; |
1199 | } |
1200 | shared = (objc == 3); |
1201 | if (shared) { |
1202 | Ns_MutexLock(&servPtr->chans.lock); |
1203 | tabPtr = &servPtr->chans.table; |
1204 | } else { |
1205 | tabPtr = &itPtr->chans; |
1206 | } |
1207 | hPtr = Tcl_FirstHashEntry(tabPtr, &search); |
1208 | while (hPtr != NULL) { |
1209 | regChan = (NsRegChan*)Tcl_GetHashValue(hPtr); |
1210 | if (shared) { |
1211 | Tcl_SpliceChannel(regChan->chan); |
1212 | Tcl_UnregisterChannel((Tcl_Interp*)NULL, regChan->chan); |
1213 | } else { |
1214 | Tcl_UnregisterChannel(interp, regChan->chan); |
1215 | } |
1216 | ns_free(regChan->name); |
1217 | ns_free(regChan); |
1218 | Tcl_DeleteHashEntry(hPtr); |
1219 | hPtr = Tcl_NextHashEntry(&search); |
1220 | } |
1221 | if (shared) { |
1222 | Ns_MutexUnlock(&servPtr->chans.lock); |
1223 | } |
1224 | break; |
1225 | } |
1226 | return TCL_OK; |
1227 | } |
1228 | |
1229 | |
1230 | /* |
1231 | *---------------------------------------------------------------------- |
1232 | * |
1233 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_SpliceChannel">SpliceChannel</a> |
1234 | * |
1235 | * Adds the shared channel in the interp/thread. |
1236 | * |
1237 | * Results: |
1238 | * None. |
1239 | * |
1240 | * Side effects: |
1241 | * New channel appears in the interp. |
1242 | * |
1243 | *---------------------------------------------------------------------- |
1244 | */ |
1245 | |
1246 | static void |
1247 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_SpliceChannel">SpliceChannel</a>(Tcl_Interp *interp, Tcl_Channel chan) |
1248 | { |
1249 | Tcl_SpliceChannel(chan); |
1250 | Tcl_RegisterChannel(interp, chan); |
1251 | Tcl_UnregisterChannel((Tcl_Interp*)NULL, chan); /* Prevent closing */ |
1252 | } |
1253 | |
1254 | |
1255 | /* |
1256 | *---------------------------------------------------------------------- |
1257 | * |
1258 | * <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_UnspliceChannel">UnspliceChannel</a> |
1259 | * |
1260 | * Divorces the channel from its owning interp/thread. |
1261 | * |
1262 | * Results: |
1263 | * None. |
1264 | * |
1265 | * Side effects: |
1266 | * Channel is not accesible by Tcl scripts any more. |
1267 | * |
1268 | *---------------------------------------------------------------------- |
1269 | */ |
1270 | |
1271 | static void |
1272 | <a href="/cvs/aolserver/aolserver/nsd/tclfile.c#A_UnspliceChannel">UnspliceChannel</a>(Tcl_Interp *interp, Tcl_Channel chan) |
1273 | { |
1274 | Tcl_ClearChannelHandlers(chan); |
1275 | Tcl_RegisterChannel((Tcl_Interp*)NULL, chan); /* Prevent closing */ |
1276 | Tcl_UnregisterChannel(interp, chan); |
1277 | Tcl_CutChannel(chan); |
1278 | } |
1279 |
Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use