2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31 #include "PyrPrimitive.h"
32 #include "PyrObject.h"
33 #include "PyrKernel.h"
35 #include "VMGlobals.h"
38 #include "SC_DirUtils.h"
43 #include "SC_Win32Utils.h"
48 extern bool compiledOK
;
49 PyrSymbol
* s_unixCmdAction
;
51 int prString_System(struct VMGlobals
*g
, int numArgsPushed
);
52 int prString_System(struct VMGlobals
*g
, int numArgsPushed
)
57 int err
= slotStrVal(a
, cmdline
, 1023);
60 int res
= system(cmdline
);
66 int prString_Basename(struct VMGlobals
*g
, int numArgsPushed
);
67 int prString_Basename(struct VMGlobals
*g
, int numArgsPushed
)
72 int err
= slotStrVal(a
, path
, PATH_MAX
);
75 char *basename0
= basename(path
);
77 int size
= strlen(basename0
);
78 PyrString
*strobj
= newPyrStringN(g
->gc
, size
, 0, true);
79 memcpy(strobj
->s
, basename0
, size
);
86 int prString_Dirname(struct VMGlobals
*g
, int numArgsPushed
);
87 int prString_Dirname(struct VMGlobals
*g
, int numArgsPushed
)
92 int err
= slotStrVal(a
, path
, PATH_MAX
);
95 char *dirname0
= dirname(path
);
97 int size
= strlen(dirname0
);
98 PyrString
*strobj
= newPyrStringN(g
->gc
, size
, 0, true);
99 memcpy(strobj
->s
, dirname0
, size
);
101 SetObject(a
, strobj
);
112 void* string_popen_thread_func(void *data
);
113 void* string_popen_thread_func(void *data
)
115 struct sc_process
*process
= (struct sc_process
*)data
;
116 FILE *stream
= process
->stream
;
117 pid_t pid
= process
->pid
;
120 while (process
->postOutput
) {
121 char *string
= fgets(buf
, 1024, stream
);
123 postText(string
, strlen(string
));
127 res
= sc_pclose(stream
, pid
);
128 res
= WEXITSTATUS(res
);
130 if(process
->postOutput
)
131 postfl("RESULT = %d\n", res
);
135 pthread_mutex_lock (&gLangMutex
);
137 VMGlobals
*g
= gMainVMGlobals
;
139 ++g
->sp
; SetObject(g
->sp
, class_string
);
140 ++g
->sp
; SetInt(g
->sp
, res
);
141 ++g
->sp
; SetInt(g
->sp
, pid
);
142 runInterpreter(g
, s_unixCmdAction
, 3);
143 g
->canCallOS
= false;
145 pthread_mutex_unlock (&gLangMutex
);
150 int prString_POpen(struct VMGlobals
*g
, int numArgsPushed
);
151 int prString_POpen(struct VMGlobals
*g
, int numArgsPushed
)
153 struct sc_process
*process
;
154 PyrSlot
*a
= g
->sp
- 1;
158 if (!isKindOfSlot(a
, class_string
)) return errWrongType
;
160 char *cmdline
= (char*)malloc(slotRawObject(a
)->size
+ 1);
161 err
= slotStrVal(a
, cmdline
, slotRawObject(a
)->size
+ 1);
172 process
= (struct sc_process
*)malloc(sizeof(struct sc_process
));
173 process
->stream
= sc_popen(cmdline
, &process
->pid
, "r");
174 setvbuf(process
->stream
, 0, _IONBF
, 0);
176 process
->postOutput
= IsTrue(b
);
180 if(process
->stream
== NULL
) {
186 pthread_create(&thread
, NULL
, string_popen_thread_func
, (void*)process
);
187 pthread_detach(thread
);
189 SetInt(a
, process
->pid
);
193 int prPidRunning(VMGlobals
*g
, int numArgsPushed
);
194 int prPidRunning(VMGlobals
*g
, int numArgsPushed
)
203 handle
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, slotRawInt(a
));
205 unsigned long exitCode
;
207 if(GetExitCodeProcess(handle
, &exitCode
) == 0)
209 else if(exitCode
== STILL_ACTIVE
)
217 if(kill(slotRawInt(a
), 0) == 0)
226 int prUnix_Errno(struct VMGlobals
*g
, int numArgsPushed
);
227 int prUnix_Errno(struct VMGlobals
*g
, int numArgsPushed
)
239 #include <sys/time.h>
242 double bootSeconds();
244 int prLocalTime(struct VMGlobals
*g
, int numArgsPushed
);
245 int prLocalTime(struct VMGlobals
*g
, int numArgsPushed
)
248 PyrSlot
*slots
= slotRawObject(a
)->slots
;
251 gettimeofday(&tv
, 0);
253 struct tm
* tm
= localtime((const time_t*)&tv
.tv_sec
);
255 SetInt(slots
+0, tm
->tm_year
+ 1900);
256 SetInt(slots
+1, tm
->tm_mon
+ 1); // 0 based month ??
257 SetInt(slots
+2, tm
->tm_mday
);
258 SetInt(slots
+3, tm
->tm_hour
);
259 SetInt(slots
+4, tm
->tm_min
);
260 SetInt(slots
+5, tm
->tm_sec
);
261 SetInt(slots
+6, tm
->tm_wday
);
262 SetFloat(slots
+7, tv
.tv_sec
+ 1e-6 * tv
.tv_usec
);
263 SetFloat(slots
+8, bootSeconds());
268 int prGMTime(struct VMGlobals
*g
, int numArgsPushed
);
269 int prGMTime(struct VMGlobals
*g
, int numArgsPushed
)
272 PyrSlot
*slots
= slotRawObject(a
)->slots
;
275 gettimeofday(&tv
, 0);
277 struct tm
* tm
= gmtime((const time_t*)&tv
.tv_sec
);
279 SetInt(slots
+0, tm
->tm_year
+ 1900);
280 SetInt(slots
+1, tm
->tm_mon
+ 1);
281 SetInt(slots
+2, tm
->tm_mday
);
282 SetInt(slots
+3, tm
->tm_hour
);
283 SetInt(slots
+4, tm
->tm_min
);
284 SetInt(slots
+5, tm
->tm_sec
);
285 SetInt(slots
+6, tm
->tm_wday
);
286 SetFloat(slots
+7, tv
.tv_sec
+ 1e-6 * tv
.tv_usec
);
287 SetFloat(slots
+8, bootSeconds());
292 int prAscTime(struct VMGlobals
*g
, int numArgsPushed
);
293 int prAscTime(struct VMGlobals
*g
, int numArgsPushed
)
296 PyrSlot
*slots
= slotRawObject(a
)->slots
;
298 if (IsNil(slots
+ 0)) {
305 if (slotIntVal(slots
+0, &tm0
.tm_year
)) return errWrongType
;
307 if (slotIntVal(slots
+1, &tm0
.tm_mon
)) return errWrongType
;
309 if (slotIntVal(slots
+2, &tm0
.tm_mday
)) return errWrongType
;
310 if (slotIntVal(slots
+3, &tm0
.tm_hour
)) return errWrongType
;
311 if (slotIntVal(slots
+4, &tm0
.tm_min
)) return errWrongType
;
312 if (slotIntVal(slots
+5, &tm0
.tm_sec
)) return errWrongType
;
313 if (slotIntVal(slots
+6, &tm0
.tm_wday
)) return errWrongType
;
315 const char *text
= asctime(&tm0
);
317 int size
= strlen(text
) - 1; // Discard trailing newline
318 PyrString
*strobj
= newPyrStringN(g
->gc
, size
, 0, true);
319 memcpy(strobj
->s
, text
, size
);
321 SetObject(a
, strobj
);
326 int prStrFTime(struct VMGlobals
*g
, int numArgsPushed
);
327 int prStrFTime(struct VMGlobals
*g
, int numArgsPushed
)
329 PyrSlot
*a
= g
->sp
- 1;
332 PyrSlot
*slots
= slotRawObject(a
)->slots
;
334 if (IsNil(slots
+ 0)) {
341 if (slotIntVal(slots
+0, &tm0
.tm_year
)) return errWrongType
;
343 if (slotIntVal(slots
+1, &tm0
.tm_mon
)) return errWrongType
;
345 if (slotIntVal(slots
+2, &tm0
.tm_mday
)) return errWrongType
;
346 if (slotIntVal(slots
+3, &tm0
.tm_hour
)) return errWrongType
;
347 if (slotIntVal(slots
+4, &tm0
.tm_min
)) return errWrongType
;
348 if (slotIntVal(slots
+5, &tm0
.tm_sec
)) return errWrongType
;
349 if (slotIntVal(slots
+6, &tm0
.tm_wday
)) return errWrongType
;
352 if (slotStrVal(b
, format
, 1024)) return errWrongType
;
355 if (strftime(buffer
, 1024, format
, &tm0
) != 0) {
356 int size
= strlen(buffer
);
357 PyrString
*strobj
= newPyrStringN(g
->gc
, size
, 0, true);
358 memcpy(strobj
->s
, buffer
, size
);
360 SetObject(a
, strobj
);
362 error("could not convert the date to string with the give format");
370 int prTimeSeed(struct VMGlobals
*g
, int numArgsPushed
);
371 int prTimeSeed(struct VMGlobals
*g
, int numArgsPushed
)
374 SetInt(a
, timeseed());
378 int prGetPid(VMGlobals
*g
, int numArgsPushed
);
379 int prGetPid(VMGlobals
*g
, int numArgsPushed
)
386 GetCurrentProcessId()
393 void initUnixPrimitives();
394 void initUnixPrimitives()
398 base
= nextPrimitiveIndex();
400 s_unixCmdAction
= getsym("doUnixCmdAction");
402 definePrimitive(base
, index
++, "_String_System", prString_System
, 1, 0);
403 definePrimitive(base
, index
++, "_String_Basename", prString_Basename
, 1, 0);
404 definePrimitive(base
, index
++, "_String_Dirname", prString_Dirname
, 1, 0);
405 definePrimitive(base
, index
++, "_String_POpen", prString_POpen
, 2, 0);
406 definePrimitive(base
, index
++, "_Unix_Errno", prUnix_Errno
, 1, 0);
407 definePrimitive(base
, index
++, "_LocalTime", prLocalTime
, 1, 0);
408 definePrimitive(base
, index
++, "_GMTime", prGMTime
, 1, 0);
409 definePrimitive(base
, index
++, "_AscTime", prAscTime
, 1, 0);
410 definePrimitive(base
, index
++, "_prStrFTime", prStrFTime
, 2, 0);
411 definePrimitive(base
, index
++, "_TimeSeed", prTimeSeed
, 1, 0);
412 definePrimitive(base
, index
++, "_PidRunning", prPidRunning
, 1, 0);
413 definePrimitive(base
, index
++, "_GetPid", prGetPid
, 1, 0);