added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / rom / dos / lock.c
blob349856d7cb49abd359badc8f2cbdc0cc16b03438
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Locks a file or directory.
6 Lang: English
7 */
9 #include <proto/exec.h>
10 #include <utility/tagitem.h>
11 #include <dos/dosextens.h>
12 #include <dos/filesystem.h>
13 #include <proto/dos.h>
14 #include <proto/utility.h>
15 #include "dos_intern.h"
17 #define DEBUG 0
18 #include <aros/debug.h>
21 /*****************************************************************************
23 NAME */
24 #include <proto/dos.h>
26 AROS_LH2(BPTR, Lock,
28 /* SYNOPSIS */
29 AROS_LHA(CONST_STRPTR, name, D1),
30 AROS_LHA(LONG, accessMode, D2),
32 /* LOCATION */
33 struct DosLibrary *, DOSBase, 14, Dos)
35 /* FUNCTION
36 Gets a lock on a file or directory. There may be more than one
37 shared lock on a file but only one if it is an exclusive one.
38 Locked files or directories may not be deleted.
40 INPUTS
41 name - NUL terminated name of the file or directory.
42 accessMode - One of SHARED_LOCK
43 EXCLUSIVE_LOCK
45 RESULT
46 Handle to the file or directory or 0 if the object couldn't be locked.
47 IoErr() gives additional information in that case.
49 NOTES
50 The lock structure returned by this function is different
51 from that of AmigaOS (in fact it is identical to a filehandle).
52 Do not try to read any internal fields.
54 *****************************************************************************/
57 AROS_LIBFUNC_INIT
59 struct DevProc *dvp;
60 LONG error;
62 ASSERT_VALID_PTR(name);
64 /* Sanity check */
65 if (name == NULL)
66 return NULL;
68 /* Get pointer to process structure */
69 struct Process *
70 me = (struct Process *)FindTask(NULL);
72 /* Create filehandle */
73 struct FileHandle *
74 ret = (struct FileHandle *)AllocDosObject(DOS_FILEHANDLE, NULL);
76 if (ret != NULL)
78 /* Get pointer to I/O request. Use stackspace for now. */
79 struct IOFileSys iofs;
81 /* Prepare I/O request. */
82 InitIOFS(&iofs, FSA_OPEN, DOSBase);
84 switch (accessMode)
86 case EXCLUSIVE_LOCK:
87 iofs.io_Union.io_OPEN.io_FileMode = FMF_LOCK | FMF_READ;
88 break;
90 case SHARED_LOCK:
91 iofs.io_Union.io_OPEN.io_FileMode = FMF_READ;
92 break;
94 default:
95 D(bug("[Lock] incompatible mode %d\n", accessMode));
96 FreeDosObject(DOS_FILEHANDLE, ret);
97 SetIoErr(ERROR_ACTION_NOT_KNOWN);
98 return NULL;
101 /* catch the zero-length special case. we can't (currently) call
102 * GetDeviceProc(), as it will call NameFromLock(), which will
103 * DupLock(), which will end up here */
104 if (*name == '\0') {
105 BPTR cur;
106 struct FileHandle *fh;
108 cur = me->pr_CurrentDir;
109 if (!cur)
110 cur = DOSBase->dl_SYSLock;
112 if (cur) {
113 fh = BADDR(cur);
115 iofs.io_Union.io_OPEN.io_Filename = "";
117 iofs.IOFS.io_Device = fh->fh_Device;
118 iofs.IOFS.io_Unit = fh->fh_Unit;
120 DosDoIO(&iofs.IOFS);
122 error = me->pr_Result2 = iofs.io_DosError;
123 } else {
124 error = ERROR_OBJECT_NOT_FOUND;
125 SetIoErr(error);
129 else {
130 iofs.io_Union.io_OPEN.io_Filename = StripVolume(name);
132 dvp = NULL;
134 do {
135 if ((dvp = GetDeviceProc(name, dvp)) == NULL) {
136 error = IoErr();
137 break;
140 error = DoIOFS(&iofs, dvp, NULL, DOSBase);
141 } while (error == ERROR_OBJECT_NOT_FOUND);
143 if (error == ERROR_NO_MORE_ENTRIES)
144 error = me->pr_Result2 = ERROR_OBJECT_NOT_FOUND;
146 FreeDeviceProc(dvp);
149 if (!error)
151 ret->fh_Device = iofs.IOFS.io_Device;
152 ret->fh_Unit = iofs.IOFS.io_Unit;
154 return MKBADDR(ret);
156 else
158 FreeDosObject(DOS_FILEHANDLE, ret);
161 else
163 SetIoErr(ERROR_NO_FREE_STORE);
166 return NULL;
168 AROS_LIBFUNC_EXIT
169 } /* Lock */